-Wimplicit-fallthrough warning fixes
[deliverable/binutils-gdb.git] / gas / config / tc-metag.c
1 /* tc-metag.c -- Assembler for the Imagination Technologies Meta.
2 Copyright (C) 2013-2016 Free Software Foundation, Inc.
3 Contributed by Imagination Technologies Ltd.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22 #include "as.h"
23 #include "subsegs.h"
24 #include "symcat.h"
25 #include "safe-ctype.h"
26 #include "hashtab.h"
27
28 #include <stdio.h>
29
30 #include "opcode/metag.h"
31
32 const char comment_chars[] = "!";
33 const char line_comment_chars[] = "!#";
34 const char line_separator_chars[] = ";";
35 const char FLT_CHARS[] = "rRsSfFdDxXpP";
36 const char EXP_CHARS[] = "eE";
37 const char metag_symbol_chars[] = "[";
38
39 static char register_chars[256];
40 static char mnemonic_chars[256];
41
42 #define is_register_char(x) (register_chars[(unsigned char) x])
43 #define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
44 #define is_whitespace_char(x) (((x) == ' ') || ((x) == '\t'))
45 #define is_space_char(x) ((x) == ' ')
46
47 #define FPU_PREFIX_CHAR 'f'
48 #define DSP_PREFIX_CHAR 'd'
49
50 /* Instruction mnemonics that need disambiguating with respect to prefixes. */
51 #define FFB_INSN "ffb"
52 #define DCACHE_INSN "dcache"
53 #define DEFR_INSN "defr"
54
55 #define FPU_DOUBLE_CHAR 'd'
56 #define FPU_PAIR_CHAR 'l'
57
58 #define DSP_DUAL_CHAR 'l'
59
60 #define END_OF_INSN '\0'
61
62 /* Maximum length of a mnemonic including all suffixes. */
63 #define MAX_MNEMONIC_LEN 16
64 /* Maximum length of a register name. */
65 #define MAX_REG_LEN 17
66
67 /* Addressing modes must be enclosed with square brackets. */
68 #define ADDR_BEGIN_CHAR '['
69 #define ADDR_END_CHAR ']'
70 /* Immediates must be prefixed with a hash. */
71 #define IMM_CHAR '#'
72
73 #define COMMA ','
74 #define PLUS '+'
75 #define MINUS '-'
76
77 /* Short units are those that can be encoded with 2 bits. */
78 #define SHORT_UNITS "D0, D1, A0 or A1"
79
80 static unsigned int mcpu_opt = CoreMeta12;
81 static unsigned int mfpu_opt = 0;
82 static unsigned int mdsp_opt = 0;
83
84 const char * md_shortopts = "m:";
85
86 struct option md_longopts[] =
87 {
88 {NULL, no_argument, NULL, 0}
89 };
90 size_t md_longopts_size = sizeof (md_longopts);
91
92 /* Parser hash tables. */
93 static htab_t mnemonic_htab;
94 static htab_t reg_htab;
95 static htab_t dsp_reg_htab;
96 static htab_t dsp_tmpl_reg_htab[2];
97 static htab_t scond_htab;
98
99 #define GOT_NAME "__GLOBAL_OFFSET_TABLE__"
100 symbolS * GOT_symbol;
101
102 enum fpu_insn_width {
103 FPU_WIDTH_SINGLE,
104 FPU_WIDTH_DOUBLE,
105 FPU_WIDTH_PAIR,
106 };
107
108 #define FPU_ACTION_ABS_CHAR 'a'
109 #define FPU_ACTION_INV_CHAR 'i'
110 #define FPU_ACTION_QUIET_CHAR 'q'
111 #define FPU_ACTION_ZERO_CHAR 'z'
112
113 #define FPU_ACTION_ABS 0x1
114 #define FPU_ACTION_INV 0x2
115 #define FPU_ACTION_QUIET 0x4
116 #define FPU_ACTION_ZERO 0x8
117
118 enum dsp_insn_width {
119 DSP_WIDTH_SINGLE,
120 DSP_WIDTH_DUAL,
121 };
122
123 #define DSP_ACTION_QR64_CHAR 'q'
124 #define DSP_ACTION_UMUL_CHAR 'u'
125 #define DSP_ACTION_ROUND_CHAR 'r'
126 #define DSP_ACTION_CLAMP9_CHAR 'g'
127 #define DSP_ACTION_CLAMP8_CHAR 'b'
128 #define DSP_ACTION_MOD_CHAR 'm'
129 #define DSP_ACTION_ACC_ZERO_CHAR 'z'
130 #define DSP_ACTION_ACC_ADD_CHAR 'p'
131 #define DSP_ACTION_ACC_SUB_CHAR 'n'
132 #define DSP_ACTION_OV_CHAR 'o'
133
134 #define DSP_ACTION_QR64 0x001
135 #define DSP_ACTION_UMUL 0x002
136 #define DSP_ACTION_ROUND 0x004
137 #define DSP_ACTION_CLAMP9 0x008
138 #define DSP_ACTION_CLAMP8 0x010
139 #define DSP_ACTION_MOD 0x020
140 #define DSP_ACTION_ACC_ZERO 0x040
141 #define DSP_ACTION_ACC_ADD 0x080
142 #define DSP_ACTION_ACC_SUB 0x100
143 #define DSP_ACTION_OV 0x200
144
145 #define DSP_DAOPPAME_8_CHAR 'b'
146 #define DSP_DAOPPAME_16_CHAR 'w'
147 #define DSP_DAOPPAME_TEMP_CHAR 't'
148 #define DSP_DAOPPAME_HIGH_CHAR 'h'
149
150 #define DSP_DAOPPAME_8 0x1
151 #define DSP_DAOPPAME_16 0x2
152 #define DSP_DAOPPAME_TEMP 0x4
153 #define DSP_DAOPPAME_HIGH 0x8
154
155 /* Structure holding information about a parsed instruction. */
156 typedef struct {
157 /* Instruction type. */
158 enum insn_type type;
159 /* Split condition code. */
160 enum scond_code scond;
161
162 /* Instruction bits. */
163 unsigned int bits;
164 /* Size of the instruction in bytes. */
165 size_t len;
166
167 /* FPU instruction encoding. */
168 enum fpu_insn_width fpu_width;
169 unsigned int fpu_action_flags;
170
171 /* DSP instruction encoding. */
172 enum dsp_insn_width dsp_width;
173 unsigned int dsp_action_flags;
174 unsigned int dsp_daoppame_flags;
175
176 /* Reloc encoding information, maximum of one reloc per insn. */
177 enum bfd_reloc_code_real reloc_type;
178 int reloc_pcrel;
179 expressionS reloc_exp;
180 unsigned int reloc_size;
181 } metag_insn;
182
183 /* Structure holding information about a parsed addressing mode. */
184 typedef struct {
185 const metag_reg *base_reg;
186 const metag_reg *offset_reg;
187
188 expressionS exp;
189
190 enum bfd_reloc_code_real reloc_type;
191
192 /* Whether we have an immediate or not. */
193 unsigned short immediate:1;
194 /* Whether or not the base register is updated. */
195 unsigned short update:1;
196 /* Whether the operation uses the address pre or post increment. */
197 unsigned short post_increment:1;
198 /* Whether the immediate should be negated. */
199 unsigned short negate:1;
200 } metag_addr;
201
202 /* Linked list of possible parsers for this instruction. */
203 typedef struct _insn_templates {
204 const insn_template *template;
205 struct _insn_templates *next;
206 } insn_templates;
207
208 /* Parse an instruction that takes no operands. */
209 static const char *
210 parse_none (const char *line, metag_insn *insn,
211 const insn_template *template)
212 {
213 insn->bits = template->meta_opcode;
214 insn->len = 4;
215 return line;
216 }
217
218 /* Return the next non-whitespace character in LINE or NULL. */
219 static const char *
220 skip_whitespace (const char *line)
221 {
222 const char *l = line;
223
224 if (is_whitespace_char (*l))
225 {
226 l++;
227 }
228
229 return l;
230 }
231
232 /* Return the next non-space character in LINE or NULL. */
233 static const char *
234 skip_space (const char *line)
235 {
236 const char *l = line;
237
238 if (is_space_char (*l))
239 {
240 l++;
241 }
242
243 return l;
244 }
245
246 /* Return the character after the current one in LINE if the current
247 character is a comma, otherwise NULL. */
248 static const char *
249 skip_comma (const char *line)
250 {
251 const char *l = line;
252
253 if (l == NULL || *l != COMMA)
254 return NULL;
255
256 l++;
257
258 return l;
259 }
260
261 /* Return the metag_reg struct corresponding to NAME or NULL if no such
262 register exists. */
263 static const metag_reg *
264 parse_gp_reg (const char *name)
265 {
266 const metag_reg *reg;
267 metag_reg entry;
268
269 entry.name = name;
270
271 reg = (const metag_reg *) htab_find (reg_htab, &entry);
272
273 return reg;
274 }
275
276 /* Parse a list of up to COUNT GP registers from LINE, returning the
277 registers parsed in REGS and the number parsed in REGS_READ. Return
278 a pointer to the next character or NULL. */
279 static const char *
280 parse_gp_regs_list (const char *line, const metag_reg **regs, size_t count,
281 size_t *regs_read)
282 {
283 const char *l = line;
284 char reg_buf[MAX_REG_LEN];
285 int seen_regs = 0;
286 size_t i;
287
288 for (i = 0; i < count; i++)
289 {
290 size_t len = 0;
291 const char *next;
292
293 next = l;
294
295 if (i > 0)
296 {
297 l = skip_comma (l);
298 if (l == NULL)
299 {
300 *regs_read = seen_regs;
301 return next;
302 }
303 }
304
305 while (is_register_char (*l))
306 {
307 reg_buf[len] = *l;
308 l++;
309 len++;
310 if (!(len < MAX_REG_LEN))
311 return NULL;
312 }
313
314 reg_buf[len] = '\0';
315
316 if (len)
317 {
318 const metag_reg *reg = parse_gp_reg (reg_buf);
319
320 if (!reg)
321 {
322 *regs_read = seen_regs;
323 return next;
324 }
325 else
326 {
327 regs[i] = reg;
328 seen_regs++;
329 }
330 }
331 else
332 {
333 *regs_read = seen_regs;
334 return next;
335 }
336 }
337
338 *regs_read = seen_regs;
339 return l;
340 }
341
342 /* Parse a list of exactly COUNT GP registers from LINE, returning the
343 registers parsed in REGS. Return a pointer to the next character or NULL. */
344 static const char *
345 parse_gp_regs (const char *line, const metag_reg **regs, size_t count)
346 {
347 const char *l = line;
348 size_t regs_read = 0;
349
350 l = parse_gp_regs_list (l, regs, count, &regs_read);
351
352 if (regs_read != count)
353 return NULL;
354 else
355 return l;
356 }
357
358 /* Parse a list of exactly COUNT FPU registers from LINE, returning the
359 registers parsed in REGS. Return a pointer to the next character or NULL. */
360 static const char *
361 parse_fpu_regs (const char *line, const metag_reg **regs, size_t count)
362 {
363 const char *l = line;
364 size_t regs_read = 0;
365
366 l = parse_gp_regs_list (l, regs, count, &regs_read);
367
368 if (regs_read != count)
369 return NULL;
370 else
371 {
372 size_t i;
373 for (i = 0; i < count; i++)
374 {
375 if (regs[i]->unit != UNIT_FX)
376 return NULL;
377 }
378 return l;
379 }
380 }
381
382 /* Return TRUE if REG1 and REG2 are in paired units. */
383 static bfd_boolean
384 is_unit_pair (const metag_reg *reg1, const metag_reg *reg2)
385 {
386 if ((reg1->unit == UNIT_A0 &&
387 (reg2->unit == UNIT_A1)) ||
388 (reg1->unit == UNIT_A1 &&
389 (reg2->unit == UNIT_A0)) ||
390 (reg1->unit == UNIT_D0 &&
391 (reg2->unit == UNIT_D1)) ||
392 (reg1->unit == UNIT_D1 &&
393 (reg2->unit == UNIT_D0)))
394 return TRUE;
395
396 return FALSE;
397 }
398
399 /* Return TRUE if REG1 and REG2 form a register pair. */
400 static bfd_boolean
401 is_reg_pair (const metag_reg *reg1, const metag_reg *reg2)
402 {
403 if (reg1->unit == UNIT_FX &&
404 reg2->unit == UNIT_FX &&
405 reg2->no == reg1->no + 1)
406 return TRUE;
407
408 if (reg1->no != reg2->no)
409 return FALSE;
410
411 return is_unit_pair (reg1, reg2);
412 }
413
414 /* Parse a pair of GP registers from LINE, returning the registers parsed
415 in REGS. Return a pointer to the next character or NULL. */
416 static const char *
417 parse_pair_gp_regs (const char *line, const metag_reg **regs)
418 {
419 const char *l = line;
420
421 l = parse_gp_regs (line, regs, 2);
422
423 if (l == NULL)
424 {
425 l = parse_gp_regs (line, regs, 1);
426
427 if (l == NULL)
428 return NULL;
429
430 if (regs[0]->unit == UNIT_RD)
431 return l;
432 else
433 return NULL;
434 }
435
436 if (is_reg_pair (regs[0], regs[1]))
437 return l;
438
439 return NULL;
440 }
441
442 /* Parse a unit-to-unit MOV instruction. */
443 static const char *
444 parse_mov_u2u (const char *line, metag_insn *insn,
445 const insn_template *template)
446 {
447 const metag_reg *regs[2];
448
449 line = parse_gp_regs (line, regs, 2);
450
451 if (line == NULL)
452 return NULL;
453
454 if (!mfpu_opt && (regs[0]->unit == UNIT_FX || regs[1]->unit == UNIT_FX))
455 {
456 as_bad (_("no floating point unit specified"));
457 return NULL;
458 }
459
460 insn->bits = (template->meta_opcode |
461 (regs[1]->no << 19) |
462 (regs[0]->no << 14) |
463 (regs[1]->unit << 10) |
464 (regs[0]->unit << 5));
465 insn->len = 4;
466 return line;
467 }
468
469 /* Parse a MOV to port instruction. */
470 static const char *
471 parse_mov_port (const char *line, metag_insn *insn,
472 const insn_template *template)
473 {
474 const char *l = line;
475 unsigned int is_movl = MINOR_OPCODE (template->meta_opcode) == MOVL_MINOR;
476 const metag_reg *dest_regs[2];
477 const metag_reg *port_regs[1];
478
479 if (is_movl)
480 l = parse_gp_regs (l, dest_regs, 2);
481 else
482 l = parse_gp_regs (l, dest_regs, 1);
483
484 if (l == NULL)
485 return NULL;
486
487 if (template->insn_type == INSN_FPU && dest_regs[0]->unit != UNIT_FX)
488 return NULL;
489
490 l = skip_comma (l);
491
492 if (l == NULL ||
493 *l == END_OF_INSN)
494 return NULL;
495
496 l = parse_gp_regs (l, port_regs, 1);
497
498 if (l == NULL)
499 return NULL;
500
501 if (port_regs[0]->unit != UNIT_RD ||
502 port_regs[0]->no != 0)
503 return NULL;
504
505 if (is_movl)
506 {
507 if (!is_unit_pair (dest_regs[0], dest_regs[1]))
508 return NULL;
509
510 insn->bits = (template->meta_opcode |
511 (dest_regs[0]->no << 14) |
512 (dest_regs[1]->no << 9) |
513 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 5));
514 }
515 else
516 insn->bits = (template->meta_opcode |
517 (dest_regs[0]->no << 14) |
518 (dest_regs[0]->unit << 5));
519
520 insn->len = 4;
521 return l;
522 }
523
524 /* Parse a MOVL to TTREC instruction. */
525 static const char *
526 parse_movl_ttrec (const char *line, metag_insn *insn,
527 const insn_template *template)
528 {
529 const char *l = line;
530 const metag_reg *src_regs[2];
531 const metag_reg *dest_regs[1];
532
533 l = parse_gp_regs (l, dest_regs, 1);
534
535 if (l == NULL)
536 return NULL;
537
538 if (dest_regs[0]->unit != UNIT_TT ||
539 dest_regs[0]->no != 3)
540 return NULL;
541
542 l = skip_comma (l);
543
544 if (l == NULL ||
545 *l == END_OF_INSN)
546 return NULL;
547
548 l = parse_gp_regs (l, src_regs, 2);
549
550 if (l == NULL)
551 return NULL;
552
553 if (!is_unit_pair (src_regs[0], src_regs[1]))
554 return NULL;
555
556 insn->bits = (template->meta_opcode |
557 (src_regs[0]->no << 19) |
558 (src_regs[1]->no << 14) |
559 ((src_regs[0]->unit & SHORT_UNIT_MASK) << 7));
560
561 insn->len = 4;
562 return l;
563 }
564
565 /* Parse an incrementing or decrementing addressing mode. */
566 static const char *
567 parse_addr_incr_op (const char *line, metag_addr *addr)
568 {
569 const char *l = line;
570 const char *ll;
571
572 ll = l + 1;
573
574 if (*l == PLUS &&
575 *ll == PLUS)
576 {
577 addr->update = 1;
578 ll++;
579 return ll;
580 }
581 else if (*l == MINUS &&
582 *ll == MINUS)
583 {
584 addr->update = 1;
585 addr->negate = 1;
586 ll++;
587 return ll;
588 }
589 return NULL;
590 }
591
592 /* Parse an pre-incrementing or pre-decrementing addressing mode. */
593 static const char *
594 parse_addr_pre_incr_op (const char *line, metag_addr *addr)
595 {
596 return parse_addr_incr_op (line, addr);
597 }
598
599 /* Parse an post-incrementing or post-decrementing addressing mode. */
600 static const char *
601 parse_addr_post_incr_op (const char *line, metag_addr *addr)
602 {
603 const char *l;
604
605 l = parse_addr_incr_op (line, addr);
606
607 if (l == NULL)
608 return NULL;
609
610 addr->post_increment = 1;
611
612 return l;
613 }
614
615 /* Parse an infix addressing mode. */
616 static const char *
617 parse_addr_op (const char *line, metag_addr *addr)
618 {
619 const char *l = line;
620 const char *ll;
621
622 ll = l + 1;
623
624 if (*l == PLUS)
625 {
626 if (*ll == PLUS)
627 {
628 addr->update = 1;
629 ll++;
630 return ll;
631 }
632 l++;
633 return l;
634 }
635 return NULL;
636 }
637
638 /* Parse the immediate portion of an addrssing mode. */
639 static const char *
640 parse_imm_addr (const char *line, metag_addr *addr)
641 {
642 const char *l = line;
643 char *save_input_line_pointer;
644 expressionS *exp = &addr->exp;
645
646 /* Skip #. */
647 if (*l == '#')
648 l++;
649 else
650 return NULL;
651
652 save_input_line_pointer = input_line_pointer;
653 input_line_pointer = (char *) l;
654
655 expression (exp);
656
657 l = input_line_pointer;
658 input_line_pointer = save_input_line_pointer;
659
660 if (exp->X_op == O_absent || exp->X_op == O_big)
661 {
662 return NULL;
663 }
664 else if (exp->X_op == O_constant)
665 {
666 return l;
667 }
668 else
669 {
670 if (exp->X_op == O_PIC_reloc &&
671 exp->X_md == BFD_RELOC_METAG_GETSET_GOT)
672 {
673 exp->X_op = O_symbol;
674 addr->reloc_type = BFD_RELOC_METAG_GETSET_GOT;
675 }
676 else if (exp->X_op == O_PIC_reloc &&
677 exp->X_md == BFD_RELOC_METAG_TLS_IE)
678 {
679 exp->X_op = O_symbol;
680 addr->reloc_type = BFD_RELOC_METAG_TLS_IE;
681 }
682 else if (exp->X_op == O_PIC_reloc &&
683 exp->X_md == BFD_RELOC_METAG_GOTOFF)
684 {
685 exp->X_op = O_symbol;
686 addr->reloc_type = BFD_RELOC_METAG_GETSET_GOTOFF;
687 }
688 else
689 addr->reloc_type = BFD_RELOC_METAG_GETSETOFF;
690 return l;
691 }
692 }
693
694 /* Parse the offset portion of an addressing mode (register or immediate). */
695 static const char *
696 parse_addr_offset (const char *line, metag_addr *addr, int size)
697 {
698 const char *l = line;
699 const metag_reg *regs[1];
700
701 if (*l == IMM_CHAR)
702 {
703 /* ++ is a valid operator in our addressing but not in an expr. Make
704 sure that the expression parser never sees it. */
705 char *ppp = strstr(l, "++");
706 char ppch = '+';
707
708 if (ppp)
709 *ppp = '\0';
710
711 l = parse_imm_addr (l, addr);
712
713 if (ppp)
714 *ppp = ppch;
715
716 if (l == NULL)
717 return NULL;
718
719 if (addr->exp.X_add_number % size)
720 {
721 as_bad (_("offset must be a multiple of %d"), size);
722 return NULL;
723 }
724
725 addr->immediate = 1;
726 return l;
727 }
728 else
729 {
730 l = parse_gp_regs (l, regs, 1);
731
732 if (l == NULL)
733 return NULL;
734
735 if (regs[0]->unit != addr->base_reg->unit)
736 {
737 as_bad (_("offset and base must be from the same unit"));
738 return NULL;
739 }
740
741 addr->offset_reg = regs[0];
742 return l;
743 }
744 }
745
746 /* Parse an addressing mode. */
747 static const char *
748 parse_addr (const char *line, metag_addr *addr, unsigned int size)
749 {
750 const char *l = line;
751 const char *ll;
752 const metag_reg *regs[1];
753
754 /* Skip opening square bracket. */
755 l++;
756
757 ll = parse_addr_pre_incr_op (l, addr);
758
759 if (ll != NULL)
760 l = ll;
761
762 l = parse_gp_regs (l, regs, 1);
763
764 if (l == NULL)
765 return NULL;
766
767 addr->base_reg = regs[0];
768
769 if (*l == ADDR_END_CHAR)
770 {
771 addr->exp.X_op = O_constant;
772 addr->exp.X_add_symbol = NULL;
773 addr->exp.X_op_symbol = NULL;
774 if (addr->update == 1)
775 {
776 /* We have a pre increment/decrement. */
777 addr->exp.X_add_number = size;
778 }
779 else
780 {
781 /* Simple register with no offset (0 immediate). */
782 addr->exp.X_add_number = 0;
783 }
784 addr->immediate = 1;
785 l++;
786 return l;
787 }
788
789 /* We already had a pre increment/decrement. */
790 if (addr->update == 1)
791 return NULL;
792
793 ll = parse_addr_post_incr_op (l, addr);
794
795 if (ll && *ll == ADDR_END_CHAR)
796 {
797 if (addr->update == 1)
798 {
799 /* We have a post increment/decrement. */
800 addr->exp.X_op = O_constant;
801 addr->exp.X_add_number = size;
802 addr->exp.X_add_symbol = NULL;
803 addr->exp.X_op_symbol = NULL;
804 addr->post_increment = 1;
805 }
806 addr->immediate = 1;
807 ll++;
808 return ll;
809 }
810
811 addr->post_increment = 0;
812
813 l = parse_addr_op (l, addr);
814
815 if (l == NULL)
816 return NULL;
817
818 l = parse_addr_offset (l, addr, size);
819
820 if (l == NULL)
821 return NULL;
822
823 if (*l == ADDR_END_CHAR)
824 {
825 l++;
826 return l;
827 }
828
829 /* We already had a pre increment/decrement. */
830 if (addr->update == 1)
831 return NULL;
832
833 l = parse_addr_post_incr_op (l, addr);
834
835 if (l == NULL)
836 return NULL;
837
838 if (*l == ADDR_END_CHAR)
839 {
840 l++;
841 return l;
842 }
843
844 return NULL;
845 }
846
847 /* Parse a GET or pipeline MOV instruction. */
848 static const char *
849 parse_get (const char *line, const metag_reg **regs, metag_addr *addr,
850 unsigned int size, bfd_boolean is_mov)
851 {
852 const char *l = line;
853
854 if (size == 8)
855 {
856 l = parse_pair_gp_regs (l, regs);
857
858 if (l == NULL)
859 return NULL;
860 }
861 else
862 {
863 l = parse_gp_regs (l, regs, 1);
864
865 if (l == NULL)
866 {
867 if (!is_mov)
868 as_bad (_("invalid destination register"));
869 return NULL;
870 }
871 }
872
873 l = skip_comma (l);
874
875 if (l == NULL ||
876 *l == END_OF_INSN)
877 return NULL;
878
879 l = parse_addr (l, addr, size);
880
881 if (l == NULL)
882 {
883 if (!is_mov)
884 as_bad (_("invalid memory operand"));
885 return NULL;
886 }
887
888 return l;
889 }
890
891 /* Parse a SET instruction. */
892 static const char *
893 parse_set (const char *line, const metag_reg **regs, metag_addr *addr,
894 unsigned int size)
895 {
896 const char *l = line;
897
898 l = parse_addr (l, addr, size);
899
900 if (l == NULL)
901 {
902 as_bad (_("invalid memory operand"));
903 return NULL;
904 }
905
906 l = skip_comma (l);
907
908 if (l == NULL ||
909 *l == END_OF_INSN)
910 return NULL;
911
912 if (size == 8)
913 {
914 const char *ll = l;
915
916 ll = parse_pair_gp_regs (l, regs);
917
918 if (ll == NULL)
919 {
920 /* Maybe this is an RD register, which is 64 bits wide so needs no
921 pair. */
922 l = parse_gp_regs (l, regs, 1);
923
924 if (l == NULL ||
925 regs[0]->unit != UNIT_RD)
926 {
927 return NULL;
928 }
929 }
930 else
931 l = ll;
932 }
933 else
934 {
935 l = parse_gp_regs (l, regs, 1);
936
937 if (l == NULL)
938 {
939 as_bad (_("invalid source register"));
940 return NULL;
941 }
942 }
943
944 return l;
945 }
946
947 /* Check a signed integer value can be represented in the given number
948 of bits. */
949 static bfd_boolean
950 within_signed_range (int value, unsigned int bits)
951 {
952 int min_val = -(1 << (bits - 1));
953 int max_val = (1 << (bits - 1)) - 1;
954 return (value <= max_val) && (value >= min_val);
955 }
956
957 /* Check an unsigned integer value can be represented in the given number
958 of bits. */
959 static bfd_boolean
960 within_unsigned_range (unsigned int value, unsigned int bits)
961 {
962 return value < (unsigned int)(1 << bits);
963 }
964
965 /* Return TRUE if UNIT can be expressed using a short code. */
966 static bfd_boolean
967 is_short_unit (enum metag_unit unit)
968 {
969 switch (unit)
970 {
971 case UNIT_A0:
972 case UNIT_A1:
973 case UNIT_D0:
974 case UNIT_D1:
975 return TRUE;
976 default:
977 return FALSE;
978 }
979 }
980
981 /* Copy reloc data from ADDR to INSN. */
982 static void
983 copy_addr_reloc (metag_insn *insn, metag_addr *addr)
984 {
985 memcpy (&insn->reloc_exp, &addr->exp, sizeof(insn->reloc_exp));
986 insn->reloc_type = addr->reloc_type;
987 }
988
989 /* Parse a GET, SET or pipeline MOV instruction. */
990 static const char *
991 parse_get_set (const char *line, metag_insn *insn,
992 const insn_template *template)
993 {
994 const char *l = line;
995 const metag_reg *regs[2];
996 metag_addr addr;
997 unsigned int size = metag_get_set_size_bytes (template->meta_opcode);
998 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
999 unsigned int reg_no;
1000
1001 memset(&addr, 0, sizeof(addr));
1002 addr.reloc_type = BFD_RELOC_UNUSED;
1003
1004 if (is_get)
1005 {
1006 bfd_boolean is_mov = strncmp (template->name, "MOV", 3) == 0;
1007
1008 l = parse_get (l, regs, &addr, size, is_mov);
1009
1010 if (l == NULL)
1011 return NULL;
1012
1013 if (!(regs[0]->unit == UNIT_D0 ||
1014 regs[0]->unit == UNIT_D1 ||
1015 regs[0]->unit == UNIT_A0 ||
1016 regs[0]->unit == UNIT_A1 ||
1017 (regs[0]->unit == UNIT_RD && is_mov) ||
1018 (regs[0]->unit == UNIT_CT && size == 4) ||
1019 (regs[0]->unit == UNIT_PC && size == 4) ||
1020 (regs[0]->unit == UNIT_TR && size == 4) ||
1021 (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) ||
1022 regs[0]->unit == UNIT_FX))
1023 {
1024 as_bad (_("invalid destination unit"));
1025 return NULL;
1026 }
1027
1028 if (regs[0]->unit == UNIT_RD)
1029 {
1030 if (regs[0]->no == 0)
1031 {
1032 as_bad (_("mov cannot use RD port as destination"));
1033 return NULL;
1034 }
1035 }
1036
1037 reg_no = regs[0]->no;
1038 }
1039 else
1040 {
1041 l = parse_set (l, regs, &addr, size);
1042
1043 if (l == NULL)
1044 return NULL;
1045
1046 if (!(regs[0]->unit == UNIT_D0 ||
1047 regs[0]->unit == UNIT_D1 ||
1048 regs[0]->unit == UNIT_A0 ||
1049 regs[0]->unit == UNIT_A1 ||
1050 regs[0]->unit == UNIT_RD ||
1051 (regs[0]->unit == UNIT_CT && size == 4) ||
1052 (regs[0]->unit == UNIT_PC && size == 4) ||
1053 (regs[0]->unit == UNIT_TR && size == 4) ||
1054 (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) ||
1055 regs[0]->unit == UNIT_FX))
1056 {
1057 as_bad (_("invalid source unit"));
1058 return NULL;
1059 }
1060
1061 if (addr.immediate == 0 &&
1062 (regs[0]->unit == addr.base_reg->unit ||
1063 (size == 8 && is_unit_pair (regs[0], addr.base_reg))))
1064 {
1065 as_bad (_("source and address units must not be shared for this addressing mode"));
1066 return NULL;
1067 }
1068
1069 if (regs[0]->unit == UNIT_RD)
1070 {
1071 if (regs[0]->no != 0)
1072 {
1073 as_bad (_("set can only use RD port as source"));
1074 return NULL;
1075 }
1076 reg_no = 16;
1077 }
1078 else
1079 reg_no = regs[0]->no;
1080 }
1081
1082 insn->bits = (template->meta_opcode |
1083 (reg_no << 19) |
1084 (regs[0]->unit << 1));
1085
1086 if (!is_short_unit (addr.base_reg->unit))
1087 {
1088 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1089 return NULL;
1090 }
1091
1092 insn->bits |= ((addr.base_reg->no << 14) |
1093 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1094
1095 if (addr.immediate)
1096 {
1097 int offset = addr.exp.X_add_number;
1098
1099 copy_addr_reloc (insn, &addr);
1100
1101 if (addr.negate)
1102 offset = -offset;
1103
1104 offset = offset / (int)size;
1105
1106 if (!within_signed_range (offset, GET_SET_IMM_BITS))
1107 {
1108 /* We already tried to encode as an extended GET/SET. */
1109 as_bad (_("offset value out of range"));
1110 return NULL;
1111 }
1112
1113 offset = offset & GET_SET_IMM_MASK;
1114
1115 insn->bits |= (0x1 << 25);
1116 insn->bits |= (offset << 8);
1117 }
1118 else
1119 {
1120 insn->bits |= (addr.offset_reg->no << 9);
1121 }
1122
1123 if (addr.update)
1124 insn->bits |= (0x1 << 7);
1125
1126 if (addr.post_increment)
1127 insn->bits |= 0x1;
1128
1129 insn->len = 4;
1130 return l;
1131 }
1132
1133 /* Parse an extended GET or SET instruction. */
1134 static const char *
1135 parse_get_set_ext (const char *line, metag_insn *insn,
1136 const insn_template *template)
1137 {
1138 const char *l = line;
1139 const metag_reg *regs[2];
1140 metag_addr addr;
1141 unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode);
1142 bfd_boolean is_get = MINOR_OPCODE (template->meta_opcode) == GET_EXT_MINOR;
1143 bfd_boolean is_mov = MINOR_OPCODE (template->meta_opcode) == MOV_EXT_MINOR;
1144 unsigned int reg_unit;
1145
1146 memset(&addr, 0, sizeof(addr));
1147 addr.reloc_type = BFD_RELOC_UNUSED;
1148
1149 if (is_get || is_mov)
1150 {
1151 l = parse_get (l, regs, &addr, size, is_mov);
1152 }
1153 else
1154 {
1155 l = parse_set (l, regs, &addr, size);
1156 }
1157
1158 if (l == NULL)
1159 return NULL;
1160
1161 /* Extended GET/SET does not support incrementing addressing. */
1162 if (addr.update)
1163 return NULL;
1164
1165 if (is_mov)
1166 {
1167 if (regs[0]->unit != UNIT_RD)
1168 {
1169 as_bad (_("destination unit must be RD"));
1170 return NULL;
1171 }
1172 reg_unit = 0;
1173 }
1174 else
1175 {
1176 if (!is_short_unit (regs[0]->unit))
1177 {
1178 return NULL;
1179 }
1180 reg_unit = regs[0]->unit;
1181 }
1182
1183 insn->bits = (template->meta_opcode |
1184 (regs[0]->no << 19) |
1185 ((reg_unit & SHORT_UNIT_MASK) << 3));
1186
1187 if (!is_short_unit (addr.base_reg->unit))
1188 {
1189 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1190 return NULL;
1191 }
1192
1193 if (addr.base_reg->no > 1)
1194 {
1195 return NULL;
1196 }
1197
1198 insn->bits |= ((addr.base_reg->no & EXT_BASE_REG_MASK) |
1199 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1200
1201 if (addr.immediate)
1202 {
1203 int offset = addr.exp.X_add_number;
1204
1205 copy_addr_reloc (insn, &addr);
1206
1207 if (addr.negate)
1208 offset = -offset;
1209
1210 offset = offset / (int)size;
1211
1212 if (!within_signed_range (offset, GET_SET_EXT_IMM_BITS))
1213 {
1214 /* Parsing as a standard GET/SET provides a smaller offset. */
1215 as_bad (_("offset value out of range"));
1216 return NULL;
1217 }
1218
1219 offset = offset & GET_SET_EXT_IMM_MASK;
1220
1221 insn->bits |= (offset << 7);
1222 }
1223 else
1224 {
1225 return NULL;
1226 }
1227
1228 insn->len = 4;
1229 return l;
1230 }
1231
1232 /* Parse an MGET or MSET instruction addressing mode. */
1233 static const char *
1234 parse_mget_mset_addr (const char *line, metag_addr *addr)
1235 {
1236 const char *l = line;
1237 const char *ll;
1238 const metag_reg *regs[1];
1239
1240 /* Skip opening square bracket. */
1241 l++;
1242
1243 l = parse_gp_regs (l, regs, 1);
1244
1245 if (l == NULL)
1246 return NULL;
1247
1248 addr->base_reg = regs[0];
1249
1250 ll = parse_addr_post_incr_op (l, addr);
1251
1252 if (ll != NULL)
1253 l = ll;
1254
1255 if (addr->negate == 1)
1256 return NULL;
1257
1258 if (*l == ADDR_END_CHAR)
1259 {
1260 l++;
1261 return l;
1262 }
1263
1264 return NULL;
1265 }
1266
1267 /* Parse an MGET instruction. */
1268 static const char *
1269 parse_mget (const char *line, const metag_reg **regs, metag_addr *addr,
1270 size_t *regs_read)
1271 {
1272 const char *l = line;
1273
1274 l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read);
1275
1276 if (l == NULL ||
1277 *regs_read == 0)
1278 {
1279 as_bad (_("invalid destination register list"));
1280 return NULL;
1281 }
1282
1283 l = skip_comma (l);
1284
1285 if (l == NULL ||
1286 *l == END_OF_INSN)
1287 return NULL;
1288
1289 l = parse_mget_mset_addr (l, addr);
1290
1291 if (l == NULL)
1292 {
1293 as_bad (_("invalid memory operand"));
1294 return NULL;
1295 }
1296
1297 return l;
1298 }
1299
1300 /* Parse an MSET instruction. */
1301 static const char *
1302 parse_mset (const char *line, const metag_reg **regs, metag_addr *addr,
1303 size_t *regs_read)
1304 {
1305 const char *l = line;
1306
1307 l = parse_mget_mset_addr (l, addr);
1308
1309 if (l == NULL)
1310 {
1311 as_bad (_("invalid memory operand"));
1312 return NULL;
1313 }
1314
1315 l = skip_comma (l);
1316
1317 if (l == NULL ||
1318 *l == END_OF_INSN)
1319 return NULL;
1320
1321 l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read);
1322
1323 if (l == NULL ||
1324 *regs_read == 0)
1325 {
1326 as_bad (_("invalid source register list"));
1327 return NULL;
1328 }
1329
1330 return l;
1331 }
1332
1333 /* Take a register list REGS of size REGS_READ and convert it into an
1334 rmask value if possible. Return the rmask value in RMASK and the
1335 lowest numbered register in LOWEST_REG. Return TRUE if the conversion
1336 was successful. */
1337 static bfd_boolean
1338 check_rmask (const metag_reg **regs, size_t regs_read, bfd_boolean is_fpu,
1339 bfd_boolean is_64bit, unsigned int *lowest_reg,
1340 unsigned int *rmask)
1341 {
1342 unsigned int reg_unit = regs[0]->unit;
1343 size_t i;
1344
1345 for (i = 0; i < regs_read; i++)
1346 {
1347 if (is_fpu)
1348 {
1349 if (is_64bit && regs[i]->no % 2)
1350 {
1351 as_bad (_("register list must be even numbered"));
1352 return FALSE;
1353 }
1354 }
1355 else if (regs[i]->unit != reg_unit)
1356 {
1357 as_bad (_("register list must be from the same unit"));
1358 return FALSE;
1359 }
1360
1361 if (regs[i]->no < *lowest_reg)
1362 *lowest_reg = regs[i]->no;
1363 }
1364
1365 for (i = 0; i < regs_read; i++)
1366 {
1367 unsigned int next_bit, next_reg;
1368 if (regs[i]->no == *lowest_reg)
1369 continue;
1370
1371 if (is_fpu && is_64bit)
1372 next_reg = ((regs[i]->no / 2) - ((*lowest_reg / 2) + 1));
1373 else
1374 next_reg = (regs[i]->no - (*lowest_reg + 1));
1375
1376 next_bit = (1 << next_reg);
1377
1378 if (*rmask & next_bit)
1379 {
1380 as_bad (_("register list must not contain duplicates"));
1381 return FALSE;
1382 }
1383
1384 *rmask |= next_bit;
1385 }
1386
1387 return TRUE;
1388 }
1389
1390 /* Parse an MGET or MSET instruction. */
1391 static const char *
1392 parse_mget_mset (const char *line, metag_insn *insn,
1393 const insn_template *template)
1394 {
1395 const char *l = line;
1396 const metag_reg *regs[MGET_MSET_MAX_REGS];
1397 metag_addr addr;
1398 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
1399 bfd_boolean is_fpu = (MINOR_OPCODE (template->meta_opcode) & 0x6) == 0x6;
1400 bfd_boolean is_64bit = (MINOR_OPCODE (template->meta_opcode) & 0x1) == 0x1;
1401 size_t regs_read = 0;
1402 unsigned int rmask = 0, reg_unit = 0, lowest_reg = 0xffffffff;
1403
1404 memset(&addr, 0, sizeof(addr));
1405 addr.reloc_type = BFD_RELOC_UNUSED;
1406
1407 if (is_get)
1408 {
1409 l = parse_mget (l, regs, &addr, &regs_read);
1410 }
1411 else
1412 {
1413 l = parse_mset (l, regs, &addr, &regs_read);
1414 }
1415
1416 if (l == NULL)
1417 return NULL;
1418
1419 if (!check_rmask (regs, regs_read, is_fpu, is_64bit, &lowest_reg, &rmask))
1420 return NULL;
1421
1422 reg_unit = regs[0]->unit;
1423
1424 if (is_fpu)
1425 {
1426 if (reg_unit != UNIT_FX)
1427 return NULL;
1428
1429 reg_unit = 0;
1430 }
1431 else if (reg_unit == UNIT_FX)
1432 return NULL;
1433
1434 insn->bits = (template->meta_opcode |
1435 (lowest_reg << 19) |
1436 ((reg_unit & SHORT_UNIT_MASK) << 3));
1437
1438 if (!is_short_unit (addr.base_reg->unit))
1439 {
1440 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1441 return NULL;
1442 }
1443
1444 insn->bits |= ((addr.base_reg->no << 14) |
1445 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1446
1447 insn->bits |= (rmask & RMASK_MASK) << 7;
1448
1449 insn->len = 4;
1450 return l;
1451 }
1452
1453 /* Parse a list of registers for MMOV pipeline prime. */
1454 static const char *
1455 parse_mmov_prime_list (const char *line, const metag_reg **regs,
1456 unsigned int *rmask)
1457 {
1458 const char *l = line;
1459 const metag_reg *ra_regs[MMOV_MAX_REGS];
1460 size_t regs_read = 0, i;
1461 unsigned int mask = 0;
1462
1463 l = parse_gp_regs_list (l, regs, 1, &regs_read);
1464
1465 /* First register must be a port. */
1466 if (l == NULL || regs[0]->unit != UNIT_RD)
1467 return NULL;
1468
1469 l = skip_comma (l);
1470
1471 if (l == NULL)
1472 return NULL;
1473
1474 l = parse_gp_regs_list (l, ra_regs, MMOV_MAX_REGS, &regs_read);
1475
1476 if (l == NULL)
1477 return NULL;
1478
1479 /* Check remaining registers match the first.
1480
1481 Note that we also accept RA (0x10) as input for the remaining registers.
1482 Whilst this doesn't represent the instruction in any way we're stuck
1483 with it because the embedded assembler accepts it. */
1484 for (i = 0; i < regs_read; i++)
1485 {
1486 if (ra_regs[i]->unit != UNIT_RD ||
1487 (ra_regs[i]->no != 0x10 && ra_regs[i]->no != regs[0]->no))
1488 return NULL;
1489
1490 mask = (mask << 1) | 0x1;
1491 }
1492
1493 *rmask = mask;
1494
1495 return l;
1496 }
1497
1498 /* Parse a MMOV instruction. */
1499 static const char *
1500 parse_mmov (const char *line, metag_insn *insn,
1501 const insn_template *template)
1502 {
1503 const char *l = line;
1504 unsigned int is_fpu = template->insn_type == INSN_FPU;
1505 unsigned int is_prime = ((MINOR_OPCODE (template->meta_opcode) & 0x2) &&
1506 !is_fpu);
1507 unsigned int is_64bit = MINOR_OPCODE (template->meta_opcode) & 0x1;
1508 unsigned int rmask = 0;
1509
1510 if (is_prime)
1511 {
1512 const metag_reg *reg;
1513 metag_addr addr;
1514
1515 memset (&addr, 0, sizeof(addr));
1516
1517 l = parse_mmov_prime_list (l, &reg, &rmask);
1518
1519 if (l == NULL)
1520 return NULL;
1521
1522 l = skip_comma (l);
1523
1524 if (l == NULL)
1525 return NULL;
1526
1527 l = parse_mget_mset_addr (l, &addr);
1528
1529 if (l == NULL)
1530 {
1531 as_bad (_("invalid memory operand"));
1532 return NULL;
1533 }
1534
1535 insn->bits = (template->meta_opcode |
1536 (reg->no << 19) |
1537 (addr.base_reg->no << 14) |
1538 ((rmask & RMASK_MASK) << 7) |
1539 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1540 }
1541 else
1542 {
1543 const metag_reg *regs[MMOV_MAX_REGS + 1];
1544 unsigned int lowest_reg = 0xffffffff;
1545 size_t regs_read = 0;
1546
1547 l = parse_gp_regs_list (l, regs, MMOV_MAX_REGS + 1, &regs_read);
1548
1549 if (l == NULL || regs_read == 0)
1550 return NULL;
1551
1552 if (!is_short_unit (regs[0]->unit) &&
1553 !(is_fpu && regs[0]->unit == UNIT_FX))
1554 {
1555 return NULL;
1556 }
1557
1558 if (!(regs[regs_read-1]->unit == UNIT_RD &&
1559 regs[regs_read-1]->no == 0))
1560 {
1561 return NULL;
1562 }
1563
1564 if (!check_rmask (regs, regs_read - 1, is_fpu, is_64bit, &lowest_reg,
1565 &rmask))
1566 return NULL;
1567
1568 if (is_fpu)
1569 {
1570 insn->bits = (template->meta_opcode |
1571 (regs[0]->no << 14) |
1572 ((rmask & RMASK_MASK) << 7));
1573 }
1574 else
1575 {
1576 insn->bits = (template->meta_opcode |
1577 (regs[0]->no << 19) |
1578 ((rmask & RMASK_MASK) << 7) |
1579 ((regs[0]->unit & SHORT_UNIT_MASK) << 3));
1580 }
1581 }
1582
1583 insn->len = 4;
1584 return l;
1585 }
1586
1587 /* Parse an immediate constant. */
1588 static const char *
1589 parse_imm_constant (const char *line, metag_insn *insn, int *value)
1590 {
1591 const char *l = line;
1592 char *save_input_line_pointer;
1593 expressionS *exp = &insn->reloc_exp;
1594
1595 /* Skip #. */
1596 if (*l == '#')
1597 l++;
1598 else
1599 return NULL;
1600
1601 save_input_line_pointer = input_line_pointer;
1602 input_line_pointer = (char *) l;
1603
1604 expression (exp);
1605
1606 l = input_line_pointer;
1607 input_line_pointer = save_input_line_pointer;
1608
1609 if (exp->X_op == O_constant)
1610 {
1611 *value = exp->X_add_number;
1612
1613 return l;
1614 }
1615 else
1616 {
1617 return NULL;
1618 }
1619 }
1620
1621 /* Parse an MDRD instruction. */
1622 static const char *
1623 parse_mdrd (const char *line, metag_insn *insn,
1624 const insn_template *template)
1625 {
1626 const char *l = line;
1627 unsigned int rmask = 0;
1628 int value = 0, i;
1629
1630 l = parse_imm_constant (l, insn, &value);
1631
1632 if (l == NULL)
1633 return NULL;
1634
1635 if (value < 1 || value > 8)
1636 {
1637 as_bad (_("MDRD value must be between 1 and 8"));
1638 return NULL;
1639 }
1640
1641 for (i = 1; i < value; i++)
1642 {
1643 rmask <<= 1;
1644 rmask |= 1;
1645 }
1646
1647 insn->bits = (template->meta_opcode |
1648 (rmask << 7));
1649
1650 insn->len = 4;
1651 return l;
1652 }
1653
1654 /* Parse a conditional SET instruction. */
1655 static const char *
1656 parse_cond_set (const char *line, metag_insn *insn,
1657 const insn_template *template)
1658 {
1659 const char *l = line;
1660 const metag_reg *regs[2];
1661 metag_addr addr;
1662 unsigned int size = metag_cond_set_size_bytes (template->meta_opcode);
1663 unsigned int reg_no;
1664
1665 memset(&addr, 0, sizeof(addr));
1666 addr.reloc_type = BFD_RELOC_UNUSED;
1667
1668 l = parse_set (l, regs, &addr, size);
1669
1670 if (l == NULL)
1671 return NULL;
1672
1673 if (regs[0]->unit == UNIT_RD)
1674 {
1675 if (regs[0]->no != 0)
1676 {
1677 as_bad (_("set can only use RD port as source"));
1678 return NULL;
1679 }
1680 reg_no = 16;
1681 }
1682 else
1683 reg_no = regs[0]->no;
1684
1685 if (addr.update)
1686 return NULL;
1687
1688 if (!(addr.immediate &&
1689 addr.exp.X_add_number == 0))
1690 return NULL;
1691
1692 insn->bits = (template->meta_opcode |
1693 (reg_no << 19) |
1694 (regs[0]->unit << 10));
1695
1696 if (!is_short_unit (addr.base_reg->unit))
1697 {
1698 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
1699 return NULL;
1700 }
1701
1702 insn->bits |= ((addr.base_reg->no << 14) |
1703 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
1704
1705 insn->len = 4;
1706 return l;
1707 }
1708
1709 /* Parse an XFR instruction. */
1710 static const char *
1711 parse_xfr (const char *line, metag_insn *insn,
1712 const insn_template *template)
1713 {
1714 const char *l = line;
1715 metag_addr dest_addr, src_addr;
1716 unsigned int size = 4;
1717
1718 memset(&dest_addr, 0, sizeof(dest_addr));
1719 memset(&src_addr, 0, sizeof(src_addr));
1720 dest_addr.reloc_type = BFD_RELOC_UNUSED;
1721 src_addr.reloc_type = BFD_RELOC_UNUSED;
1722
1723 l = parse_addr (l, &dest_addr, size);
1724
1725 if (l == NULL ||
1726 dest_addr.immediate == 1)
1727 {
1728 as_bad (_("invalid destination memory operand"));
1729 return NULL;
1730 }
1731
1732 l = skip_comma (l);
1733
1734 if (l == NULL ||
1735 *l == END_OF_INSN)
1736 return NULL;
1737
1738 l = parse_addr (l, &src_addr, size);
1739
1740 if (l == NULL ||
1741 src_addr.immediate == 1)
1742 {
1743 as_bad (_("invalid source memory operand"));
1744 return NULL;
1745 }
1746
1747 if (!is_short_unit (dest_addr.base_reg->unit) ||
1748 !is_short_unit (src_addr.base_reg->unit))
1749 {
1750 as_bad (_("address units must be one of %s"), SHORT_UNITS);
1751 return NULL;
1752 }
1753
1754 if ((dest_addr.base_reg->unit != dest_addr.offset_reg->unit) ||
1755 (src_addr.base_reg->unit != src_addr.offset_reg->unit))
1756 {
1757 as_bad (_("base and offset must be from the same unit"));
1758 return NULL;
1759 }
1760
1761 if (dest_addr.update == 1 &&
1762 src_addr.update == 1 &&
1763 dest_addr.post_increment != src_addr.post_increment)
1764 {
1765 as_bad (_("source and destination increment mode must agree"));
1766 return NULL;
1767 }
1768
1769 insn->bits = (template->meta_opcode |
1770 (src_addr.base_reg->no << 19) |
1771 (src_addr.offset_reg->no << 14) |
1772 ((src_addr.base_reg->unit & SHORT_UNIT_MASK) << 2));
1773
1774 insn->bits |= ((dest_addr.base_reg->no << 9) |
1775 (dest_addr.offset_reg->no << 4) |
1776 ((dest_addr.base_reg->unit & SHORT_UNIT_MASK)));
1777
1778 if (dest_addr.update == 1)
1779 insn->bits |= (1 << 26);
1780
1781 if (src_addr.update == 1)
1782 insn->bits |= (1 << 27);
1783
1784 if (dest_addr.post_increment == 1 ||
1785 src_addr.post_increment == 1)
1786 insn->bits |= (1 << 24);
1787
1788 insn->len = 4;
1789 return l;
1790 }
1791
1792 /* Parse an 8bit immediate value. */
1793 static const char *
1794 parse_imm8 (const char *line, metag_insn *insn, int *value)
1795 {
1796 const char *l = line;
1797 char *save_input_line_pointer;
1798 expressionS *exp = &insn->reloc_exp;
1799
1800 /* Skip #. */
1801 if (*l == '#')
1802 l++;
1803 else
1804 return NULL;
1805
1806 save_input_line_pointer = input_line_pointer;
1807 input_line_pointer = (char *) l;
1808
1809 expression (exp);
1810
1811 l = input_line_pointer;
1812 input_line_pointer = save_input_line_pointer;
1813
1814 if (exp->X_op == O_absent || exp->X_op == O_big)
1815 {
1816 return NULL;
1817 }
1818 else if (exp->X_op == O_constant)
1819 {
1820 *value = exp->X_add_number;
1821 }
1822 else
1823 {
1824 insn->reloc_type = BFD_RELOC_METAG_REL8;
1825 insn->reloc_pcrel = 0;
1826 }
1827
1828 return l;
1829 }
1830
1831 /* Parse a 16bit immediate value. */
1832 static const char *
1833 parse_imm16 (const char *line, metag_insn *insn, int *value)
1834 {
1835 const char *l = line;
1836 char *save_input_line_pointer;
1837 expressionS *exp = &insn->reloc_exp;
1838 bfd_boolean is_hi = FALSE;
1839 bfd_boolean is_lo = FALSE;
1840
1841 /* Skip #. */
1842 if (*l == '#')
1843 l++;
1844 else
1845 return NULL;
1846
1847 if (strncasecmp (l, "HI", 2) == 0)
1848 {
1849 is_hi = TRUE;
1850 l += 2;
1851 }
1852 else if (strncasecmp (l, "LO", 2) == 0)
1853 {
1854 is_lo = TRUE;
1855 l += 2;
1856 }
1857
1858 save_input_line_pointer = input_line_pointer;
1859 input_line_pointer = (char *) l;
1860
1861 expression (exp);
1862
1863 l = input_line_pointer;
1864 input_line_pointer = save_input_line_pointer;
1865
1866 if (exp->X_op == O_absent || exp->X_op == O_big)
1867 {
1868 return NULL;
1869 }
1870 else if (exp->X_op == O_constant)
1871 {
1872 if (is_hi)
1873 *value = (exp->X_add_number >> 16) & IMM16_MASK;
1874 else if (is_lo)
1875 *value = exp->X_add_number & IMM16_MASK;
1876 else
1877 *value = exp->X_add_number;
1878 }
1879 else
1880 {
1881 if (exp->X_op == O_PIC_reloc)
1882 {
1883 exp->X_op = O_symbol;
1884
1885 if (exp->X_md == BFD_RELOC_METAG_GOTOFF)
1886 {
1887 if (is_hi)
1888 insn->reloc_type = BFD_RELOC_METAG_HI16_GOTOFF;
1889 else if (is_lo)
1890 insn->reloc_type = BFD_RELOC_METAG_LO16_GOTOFF;
1891 else
1892 return NULL;
1893 }
1894 else if (exp->X_md == BFD_RELOC_METAG_PLT)
1895 {
1896 if (is_hi)
1897 insn->reloc_type = BFD_RELOC_METAG_HI16_PLT;
1898 else if (is_lo)
1899 insn->reloc_type = BFD_RELOC_METAG_LO16_PLT;
1900 else
1901 return NULL;
1902 }
1903 else if (exp->X_md == BFD_RELOC_METAG_TLS_LDO)
1904 {
1905 if (is_hi)
1906 insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_HI16;
1907 else if (is_lo)
1908 insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_LO16;
1909 else
1910 return NULL;
1911 }
1912 else if (exp->X_md == BFD_RELOC_METAG_TLS_IENONPIC)
1913 {
1914 if (is_hi)
1915 insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_HI16;
1916 else if (is_lo)
1917 insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_LO16;
1918 else
1919 return NULL;
1920 }
1921 else if (exp->X_md == BFD_RELOC_METAG_TLS_LE)
1922 {
1923 if (is_hi)
1924 insn->reloc_type = BFD_RELOC_METAG_TLS_LE_HI16;
1925 else if (is_lo)
1926 insn->reloc_type = BFD_RELOC_METAG_TLS_LE_LO16;
1927 else
1928 return NULL;
1929 }
1930 else if (exp->X_md == BFD_RELOC_METAG_TLS_GD ||
1931 exp->X_md == BFD_RELOC_METAG_TLS_LDM)
1932 insn->reloc_type = exp->X_md;
1933 }
1934 else
1935 {
1936 if (exp->X_op == O_symbol && exp->X_add_symbol == GOT_symbol)
1937 {
1938 if (is_hi)
1939 insn->reloc_type = BFD_RELOC_METAG_HI16_GOTPC;
1940 else if (is_lo)
1941 insn->reloc_type = BFD_RELOC_METAG_LO16_GOTPC;
1942 else
1943 return NULL;
1944 }
1945 else
1946 {
1947 if (is_hi)
1948 insn->reloc_type = BFD_RELOC_METAG_HIADDR16;
1949 else if (is_lo)
1950 insn->reloc_type = BFD_RELOC_METAG_LOADDR16;
1951 else
1952 insn->reloc_type = BFD_RELOC_METAG_REL16;
1953 }
1954 }
1955
1956 insn->reloc_pcrel = 0;
1957 }
1958
1959 return l;
1960 }
1961
1962 /* Parse a MOV to control unit instruction. */
1963 static const char *
1964 parse_mov_ct (const char *line, metag_insn *insn,
1965 const insn_template *template)
1966 {
1967 const char *l = line;
1968 const metag_reg *regs[1];
1969 unsigned int top = template->meta_opcode & 0x1;
1970 unsigned int is_trace = (template->meta_opcode >> 2) & 0x1;
1971 unsigned int sign_extend = 0;
1972 int value = 0;
1973
1974 l = parse_gp_regs (l, regs, 1);
1975
1976 if (l == NULL)
1977 return NULL;
1978
1979 if (is_trace)
1980 {
1981 if (regs[0]->unit != UNIT_TT)
1982 return NULL;
1983 }
1984 else
1985 {
1986 if (regs[0]->unit != UNIT_CT)
1987 return NULL;
1988 }
1989
1990 l = skip_comma (l);
1991
1992 if (l == NULL ||
1993 *l == END_OF_INSN)
1994 return NULL;
1995
1996 l = parse_imm16 (l, insn, &value);
1997
1998 if (l == NULL)
1999 return NULL;
2000
2001 if (value < 0)
2002 sign_extend = 1;
2003
2004 insn->bits = (template->meta_opcode |
2005 (regs[0]->no << 19) |
2006 ((value & IMM16_MASK) << 3));
2007
2008 if (sign_extend == 1 && top == 0)
2009 insn->bits |= (1 << 1);
2010
2011 insn->len = 4;
2012 return l;
2013 }
2014
2015 /* Parse a SWAP instruction. */
2016 static const char *
2017 parse_swap (const char *line, metag_insn *insn,
2018 const insn_template *template)
2019 {
2020 const char *l = line;
2021 const metag_reg *regs[2];
2022
2023 l = parse_gp_regs (l, regs, 2);
2024
2025 if (l == NULL)
2026 return NULL;
2027
2028 /* PC.r | CT.r | TR.r | TT.r are treated as if they are a single unit. */
2029 switch (regs[0]->unit)
2030 {
2031 case UNIT_PC:
2032 case UNIT_CT:
2033 case UNIT_TR:
2034 case UNIT_TT:
2035 if (regs[1]->unit == UNIT_PC
2036 || regs[1]->unit == UNIT_CT
2037 || regs[1]->unit == UNIT_TR
2038 || regs[1]->unit == UNIT_TT)
2039 {
2040 as_bad (_("PC, CT, TR and TT are treated as if they are a single unit but operands must be in different units"));
2041 return NULL;
2042 }
2043 break;
2044
2045 default:
2046 /* Registers must be in different units. */
2047 if (regs[0]->unit == regs[1]->unit)
2048 {
2049 as_bad (_("source and destination register must be in different units"));
2050 return NULL;
2051 }
2052 break;
2053 }
2054
2055 insn->bits = (template->meta_opcode
2056 | (regs[1]->no << 19)
2057 | (regs[0]->no << 14)
2058 | (regs[1]->unit << 10)
2059 | (regs[0]->unit << 5));
2060
2061 insn->len = 4;
2062 return l;
2063 }
2064
2065 /* Parse a JUMP instruction. */
2066 static const char *
2067 parse_jump (const char *line, metag_insn *insn,
2068 const insn_template *template)
2069 {
2070 const char *l = line;
2071 const metag_reg *regs[1];
2072 int value = 0;
2073
2074 l = parse_gp_regs (l, regs, 1);
2075
2076 if (l == NULL)
2077 return NULL;
2078
2079 if (!is_short_unit (regs[0]->unit))
2080 {
2081 as_bad (_("register unit must be one of %s"), SHORT_UNITS);
2082 return FALSE;
2083 }
2084
2085 l = skip_comma (l);
2086
2087 if (l == NULL ||
2088 *l == END_OF_INSN)
2089 return NULL;
2090
2091 l = parse_imm16 (l, insn, &value);
2092
2093 if (l == NULL)
2094 return NULL;
2095
2096 insn->bits = (template->meta_opcode |
2097 (regs[0]->no << 19) |
2098 (regs[0]->unit & SHORT_UNIT_MASK) |
2099 ((value & IMM16_MASK) << 3));
2100
2101 insn->len = 4;
2102 return l;
2103 }
2104
2105 /* Parse a 19bit immediate value. */
2106 static const char *
2107 parse_imm19 (const char *line, metag_insn *insn, int *value)
2108 {
2109 const char *l = line;
2110 char *save_input_line_pointer;
2111 expressionS *exp = &insn->reloc_exp;
2112
2113 /* Skip #. */
2114 if (*l == '#')
2115 l++;
2116
2117 save_input_line_pointer = input_line_pointer;
2118 input_line_pointer = (char *) l;
2119
2120 expression (exp);
2121
2122 l = input_line_pointer;
2123 input_line_pointer = save_input_line_pointer;
2124
2125 if (exp->X_op == O_absent || exp->X_op == O_big)
2126 {
2127 return NULL;
2128 }
2129 else if (exp->X_op == O_constant)
2130 {
2131 *value = exp->X_add_number;
2132 }
2133 else
2134 {
2135 if (exp->X_op == O_PIC_reloc)
2136 {
2137 exp->X_op = O_symbol;
2138
2139 if (exp->X_md == BFD_RELOC_METAG_PLT)
2140 insn->reloc_type = BFD_RELOC_METAG_RELBRANCH_PLT;
2141 else
2142 return NULL;
2143 }
2144 else
2145 insn->reloc_type = BFD_RELOC_METAG_RELBRANCH;
2146 insn->reloc_pcrel = 1;
2147 }
2148
2149 return l;
2150 }
2151
2152 /* Parse a CALLR instruction. */
2153 static const char *
2154 parse_callr (const char *line, metag_insn *insn,
2155 const insn_template *template)
2156 {
2157 const char *l = line;
2158 const metag_reg *regs[1];
2159 int value = 0;
2160
2161 l = parse_gp_regs (l, regs, 1);
2162
2163 if (l == NULL)
2164 return NULL;
2165
2166 if (!is_short_unit (regs[0]->unit))
2167 {
2168 as_bad (_("link register unit must be one of %s"), SHORT_UNITS);
2169 return NULL;
2170 }
2171
2172 if (regs[0]->no & ~CALLR_REG_MASK)
2173 {
2174 as_bad (_("link register must be in a low numbered register"));
2175 return NULL;
2176 }
2177
2178 l = skip_comma (l);
2179
2180 if (l == NULL ||
2181 *l == END_OF_INSN)
2182 return NULL;
2183
2184 l = parse_imm19 (l, insn, &value);
2185
2186 if (l == NULL)
2187 return NULL;
2188
2189 if (!within_signed_range (value / 4, IMM19_BITS))
2190 {
2191 as_bad (_("target out of range"));
2192 return NULL;
2193 }
2194
2195 insn->bits = (template->meta_opcode |
2196 (regs[0]->no & CALLR_REG_MASK) |
2197 ((regs[0]->unit & SHORT_UNIT_MASK) << 3) |
2198 ((value & IMM19_MASK) << 5));
2199
2200 insn->len = 4;
2201 return l;
2202 }
2203
2204 /* Return the value for the register field if we apply the O2R modifier
2205 to operand 2 REG, combined with UNIT_BIT derived from the destination
2206 register or source1. Uses address unit O2R if IS_ADDR is set. */
2207 static int
2208 lookup_o2r (unsigned int is_addr, unsigned int unit_bit, const metag_reg *reg)
2209 {
2210 if (reg->no & ~O2R_REG_MASK)
2211 return -1;
2212
2213 if (is_addr)
2214 {
2215 if (unit_bit)
2216 {
2217 switch (reg->unit)
2218 {
2219 case UNIT_D1:
2220 return reg->no;
2221 case UNIT_D0:
2222 return (1 << 3) | reg->no;
2223 case UNIT_RD:
2224 return (2 << 3) | reg->no;
2225 case UNIT_A0:
2226 return (3 << 3) | reg->no;
2227 default:
2228 return -1;
2229 }
2230 }
2231 else
2232 {
2233 switch (reg->unit)
2234 {
2235 case UNIT_A1:
2236 return reg->no;
2237 case UNIT_D0:
2238 return (1 << 3) | reg->no;
2239 case UNIT_RD:
2240 return (2 << 3) | reg->no;
2241 case UNIT_D1:
2242 return (3 << 3) | reg->no;
2243 default:
2244 return -1;
2245 }
2246 }
2247 }
2248 else
2249 {
2250 if (unit_bit)
2251 {
2252 switch (reg->unit)
2253 {
2254 case UNIT_A1:
2255 return reg->no;
2256 case UNIT_D0:
2257 return (1 << 3) | reg->no;
2258 case UNIT_RD:
2259 return (2 << 3) | reg->no;
2260 case UNIT_A0:
2261 return (3 << 3) | reg->no;
2262 default:
2263 return -1;
2264 }
2265 }
2266 else
2267 {
2268 switch (reg->unit)
2269 {
2270 case UNIT_A1:
2271 return reg->no;
2272 case UNIT_D1:
2273 return (1 << 3) | reg->no;
2274 case UNIT_RD:
2275 return (2 << 3) | reg->no;
2276 case UNIT_A0:
2277 return (3 << 3) | reg->no;
2278 default:
2279 return -1;
2280 }
2281 }
2282 }
2283 }
2284
2285 /* Parse GP ALU instruction. */
2286 static const char *
2287 parse_alu (const char *line, metag_insn *insn,
2288 const insn_template *template)
2289 {
2290 const char *l = line;
2291 const metag_reg *dest_regs[1];
2292 const metag_reg *src_regs[2];
2293 int value = 0;
2294 unsigned int o1z = 0;
2295 unsigned int imm = (template->meta_opcode >> 25) & 0x1;
2296 unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2297 unsigned int ca = (template->meta_opcode >> 5) & 0x1;
2298 unsigned int top = template->meta_opcode & 0x1;
2299 unsigned int sign_extend = 0;
2300 unsigned int is_addr_op = MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR;
2301 unsigned int is_mul = MAJOR_OPCODE (template->meta_opcode) == OPC_MUL;
2302 unsigned int unit_bit = 0;
2303 bfd_boolean is_quickrot = template->arg_type & GP_ARGS_QR;
2304
2305 l = parse_gp_regs (l, dest_regs, 1);
2306
2307 if (l == NULL)
2308 return NULL;
2309
2310 l = skip_comma (l);
2311
2312 if (l == NULL ||
2313 *l == END_OF_INSN)
2314 return NULL;
2315
2316 if (is_addr_op)
2317 {
2318 if (dest_regs[0]->unit == UNIT_A0)
2319 unit_bit = 0;
2320 else if (dest_regs[0]->unit == UNIT_A1)
2321 unit_bit = 1;
2322 }
2323 else
2324 {
2325 if (dest_regs[0]->unit == UNIT_D0)
2326 unit_bit = 0;
2327 else if (dest_regs[0]->unit == UNIT_D1)
2328 unit_bit = 1;
2329 }
2330
2331 if ((MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR ||
2332 MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
2333 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) &&
2334 ((template->meta_opcode >> 2) & 0x1))
2335 o1z = 1;
2336
2337 if (imm)
2338 {
2339 if (!cond)
2340 {
2341 if (is_addr_op)
2342 {
2343 if (dest_regs[0]->unit == UNIT_A0)
2344 unit_bit = 0;
2345 else if (dest_regs[0]->unit == UNIT_A1)
2346 unit_bit = 1;
2347 else
2348 return NULL;
2349 }
2350 else
2351 {
2352 if (dest_regs[0]->unit == UNIT_D0)
2353 unit_bit = 0;
2354 else if (dest_regs[0]->unit == UNIT_D1)
2355 unit_bit = 1;
2356 else
2357 return NULL;
2358 }
2359 }
2360
2361 if (cond)
2362 {
2363 l = parse_gp_regs (l, src_regs, 1);
2364
2365 if (l == NULL)
2366 return NULL;
2367
2368 l = skip_comma (l);
2369
2370 if (l == NULL ||
2371 *l == END_OF_INSN)
2372 return NULL;
2373
2374 if (is_addr_op)
2375 {
2376 if (src_regs[0]->unit == UNIT_A0)
2377 unit_bit = 0;
2378 else if (src_regs[0]->unit == UNIT_A1)
2379 unit_bit = 1;
2380 else
2381 return NULL;
2382 }
2383 else
2384 {
2385 if (src_regs[0]->unit == UNIT_D0)
2386 unit_bit = 0;
2387 else if (src_regs[0]->unit == UNIT_D1)
2388 unit_bit = 1;
2389 else
2390 return NULL;
2391 }
2392
2393 if (src_regs[0]->unit != dest_regs[0]->unit && !ca)
2394 return NULL;
2395
2396 l = parse_imm8 (l, insn, &value);
2397
2398 if (l == NULL)
2399 return NULL;
2400
2401 if (!within_unsigned_range (value, IMM8_BITS))
2402 return NULL;
2403
2404 insn->bits = (template->meta_opcode |
2405 (dest_regs[0]->no << 19) |
2406 (src_regs[0]->no << 14) |
2407 ((value & IMM8_MASK) << 6));
2408
2409 if (ca)
2410 {
2411 if (is_addr_op)
2412 {
2413 if (src_regs[0]->unit == UNIT_A0)
2414 unit_bit = 0;
2415 else if (src_regs[0]->unit == UNIT_A1)
2416 unit_bit = 1;
2417 else
2418 return NULL;
2419 }
2420 else
2421 {
2422 if (src_regs[0]->unit == UNIT_D0)
2423 unit_bit = 0;
2424 else if (src_regs[0]->unit == UNIT_D1)
2425 unit_bit = 1;
2426 else
2427 return NULL;
2428 }
2429
2430 insn->bits |= dest_regs[0]->unit << 1;
2431 }
2432 }
2433 else if (o1z)
2434 {
2435 l = parse_imm16 (l, insn, &value);
2436
2437 if (l == NULL)
2438 return NULL;
2439
2440 if (value < 0)
2441 {
2442 if (!within_signed_range (value, IMM16_BITS))
2443 {
2444 as_bad (_("immediate out of range"));
2445 return NULL;
2446 }
2447 sign_extend = 1;
2448 }
2449 else
2450 {
2451 if (!within_unsigned_range (value, IMM16_BITS))
2452 {
2453 as_bad (_("immediate out of range"));
2454 return NULL;
2455 }
2456 }
2457
2458 insn->bits = (template->meta_opcode |
2459 (dest_regs[0]->no << 19) |
2460 ((value & IMM16_MASK) << 3));
2461 }
2462 else
2463 {
2464 l = parse_gp_regs (l, src_regs, 1);
2465
2466 if (l == NULL)
2467 return NULL;
2468
2469 if (!(src_regs[0]->unit == dest_regs[0]->unit))
2470 return NULL;
2471
2472 /* CPC is valid for address ops. */
2473 if (src_regs[0]->no != dest_regs[0]->no &&
2474 !(is_addr_op && src_regs[0]->no == 0x10))
2475 return NULL;
2476
2477 l = skip_comma (l);
2478
2479 if (l == NULL ||
2480 *l == END_OF_INSN)
2481 return NULL;
2482
2483 l = parse_imm16 (l, insn, &value);
2484
2485 if (l == NULL)
2486 return NULL;
2487
2488 if (value < 0)
2489 {
2490 if (!within_signed_range (value, IMM16_BITS))
2491 {
2492 as_bad (_("immediate out of range"));
2493 return NULL;
2494 }
2495 sign_extend = 1;
2496 }
2497 else
2498 {
2499 if (!within_unsigned_range (value, IMM16_BITS))
2500 {
2501 as_bad (_("immediate out of range"));
2502 return NULL;
2503 }
2504 }
2505
2506 insn->bits = (template->meta_opcode |
2507 (dest_regs[0]->no << 19) |
2508 (src_regs[0]->no << 19) |
2509 ((value & IMM16_MASK) << 3));
2510 }
2511 }
2512 else
2513 {
2514 unsigned int o2r = 0;
2515 int rs2;
2516
2517 if (cond || !o1z)
2518 l = parse_gp_regs (l, src_regs, 2);
2519 else
2520 l = parse_gp_regs (l, src_regs, 1);
2521
2522 if (l == NULL)
2523 return NULL;
2524
2525 if (cond || !o1z)
2526 {
2527 if (is_addr_op)
2528 {
2529 if (src_regs[0]->unit == UNIT_A0)
2530 unit_bit = 0;
2531 else if (src_regs[0]->unit == UNIT_A1)
2532 unit_bit = 1;
2533 else
2534 return NULL;
2535 }
2536 else
2537 {
2538 if (src_regs[0]->unit == UNIT_D0)
2539 unit_bit = 0;
2540 else if (src_regs[0]->unit == UNIT_D1)
2541 unit_bit = 1;
2542 else
2543 return NULL;
2544 }
2545 }
2546 else
2547 {
2548 if (is_addr_op)
2549 {
2550 if (dest_regs[0]->unit == UNIT_A0)
2551 unit_bit = 0;
2552 else if (dest_regs[0]->unit == UNIT_A1)
2553 unit_bit = 1;
2554 else
2555 return NULL;
2556 }
2557 else
2558 {
2559 if (dest_regs[0]->unit == UNIT_D0)
2560 unit_bit = 0;
2561 else if (dest_regs[0]->unit == UNIT_D1)
2562 unit_bit = 1;
2563 else
2564 return NULL;
2565 }
2566 }
2567
2568 if (cond)
2569 {
2570 if (src_regs[0]->unit != src_regs[1]->unit)
2571 {
2572 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);
2573
2574 if (rs2 < 0)
2575 return NULL;
2576
2577 o2r = 1;
2578 }
2579 else
2580 {
2581 rs2 = src_regs[1]->no;
2582 }
2583
2584 insn->bits = (template->meta_opcode |
2585 (dest_regs[0]->no << 19) |
2586 (src_regs[0]->no << 14) |
2587 (rs2 << 9));
2588
2589 if (is_mul)
2590 {
2591 if (dest_regs[0]->unit != src_regs[0]->unit && is_mul)
2592 {
2593 if (ca)
2594 {
2595 insn->bits |= dest_regs[0]->unit << 1;
2596 }
2597 else
2598 return NULL;
2599 }
2600 }
2601 else
2602 insn->bits |= dest_regs[0]->unit << 5;
2603 }
2604 else if (o1z)
2605 {
2606 if (dest_regs[0]->unit != src_regs[0]->unit)
2607 {
2608 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[0]);
2609
2610 if (rs2 < 0)
2611 return NULL;
2612
2613 o2r = 1;
2614 }
2615 else
2616 {
2617 rs2 = src_regs[0]->no;
2618 }
2619
2620 insn->bits = (template->meta_opcode |
2621 (dest_regs[0]->no << 19) |
2622 (rs2 << 9));
2623 }
2624 else
2625 {
2626 if (dest_regs[0]->unit != src_regs[0]->unit)
2627 return NULL;
2628
2629 if (dest_regs[0]->unit != src_regs[1]->unit)
2630 {
2631 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);
2632
2633 if (rs2 < 0)
2634 return NULL;
2635
2636 o2r = 1;
2637 }
2638 else
2639 {
2640 rs2 = src_regs[1]->no;
2641 }
2642
2643 insn->bits = (template->meta_opcode |
2644 (dest_regs[0]->no << 19) |
2645 (src_regs[0]->no << 14) |
2646 (rs2 << 9));
2647 }
2648
2649 if (o2r)
2650 insn->bits |= 1;
2651 }
2652
2653 if (is_quickrot)
2654 {
2655 const metag_reg *qr_regs[1];
2656 bfd_boolean limit_regs = imm && cond;
2657
2658 l = skip_comma (l);
2659
2660 if (l == NULL ||
2661 *l == END_OF_INSN)
2662 return NULL;
2663
2664 l = parse_gp_regs (l, qr_regs, 1);
2665
2666 if (l == NULL)
2667 return NULL;
2668
2669 if (!((unit_bit == 0 && qr_regs[0]->unit != UNIT_A0) ||
2670 !(unit_bit == 1 && qr_regs[0]->unit != UNIT_A1)))
2671 {
2672 as_bad (_("invalid quickrot unit specified"));
2673 return NULL;
2674 }
2675
2676 switch (qr_regs[0]->no)
2677 {
2678 case 2:
2679 break;
2680 case 3:
2681 if (!limit_regs)
2682 {
2683 insn->bits |= (1 << 7);
2684 break;
2685 }
2686 /* Fall through. */
2687 default:
2688 as_bad (_("invalid quickrot register specified"));
2689 return NULL;
2690 }
2691 }
2692
2693 if (sign_extend == 1 && top == 0)
2694 insn->bits |= (1 << 1);
2695
2696 insn->bits |= unit_bit << 24;
2697 insn->len = 4;
2698 return l;
2699 }
2700
2701 /* Parse a B instruction. */
2702 static const char *
2703 parse_branch (const char *line, metag_insn *insn,
2704 const insn_template *template)
2705 {
2706 const char *l = line;
2707 int value = 0;
2708
2709 l = parse_imm19 (l, insn, &value);
2710
2711 if (l == NULL)
2712 return NULL;
2713
2714 if (!within_signed_range (value / 4, IMM19_BITS))
2715 {
2716 as_bad (_("target out of range"));
2717 return NULL;
2718 }
2719
2720 insn->bits = (template->meta_opcode |
2721 ((value & IMM19_MASK) << 5));
2722
2723 insn->len = 4;
2724 return l;
2725 }
2726
2727 /* Parse a KICK instruction. */
2728 static const char *
2729 parse_kick (const char *line, metag_insn *insn,
2730 const insn_template *template)
2731 {
2732 const char *l = line;
2733 const metag_reg *regs[2];
2734
2735 l = parse_gp_regs (l, regs, 2);
2736
2737 if (l == NULL)
2738 return NULL;
2739
2740 if (regs[1]->unit != UNIT_TR)
2741 {
2742 as_bad (_("source register must be in the trigger unit"));
2743 return NULL;
2744 }
2745
2746 insn->bits = (template->meta_opcode |
2747 (regs[1]->no << 19) |
2748 (regs[0]->no << 14) |
2749 (regs[0]->unit << 5));
2750
2751 insn->len = 4;
2752 return l;
2753 }
2754
2755 /* Parse a SWITCH instruction. */
2756 static const char *
2757 parse_switch (const char *line, metag_insn *insn,
2758 const insn_template *template)
2759 {
2760 const char *l = line;
2761 int value = 0;
2762
2763 l = parse_imm_constant (l, insn, &value);
2764
2765 if (l == NULL)
2766 return NULL;
2767
2768 if (!within_unsigned_range (value, IMM24_BITS))
2769 {
2770 as_bad (_("target out of range"));
2771 return NULL;
2772 }
2773
2774 insn->bits = (template->meta_opcode |
2775 (value & IMM24_MASK));
2776
2777 insn->len = 4;
2778 return l;
2779 }
2780
2781 /* Parse a shift instruction. */
2782 static const char *
2783 parse_shift (const char *line, metag_insn *insn,
2784 const insn_template *template)
2785 {
2786 const char *l = line;
2787 const metag_reg *regs[2];
2788 const metag_reg *src2_regs[1];
2789 int value = 0;
2790 unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2791 unsigned int ca = (template->meta_opcode >> 5) & 0x1;
2792 unsigned int unit_bit = 0;
2793
2794 l = parse_gp_regs (l, regs, 2);
2795
2796 if (l == NULL)
2797 return NULL;
2798
2799 l = skip_comma (l);
2800
2801 if (l == NULL ||
2802 *l == END_OF_INSN)
2803 return NULL;
2804
2805 if (regs[1]->unit == UNIT_D0)
2806 unit_bit = 0;
2807 else if (regs[1]->unit == UNIT_D1)
2808 unit_bit = 1;
2809 else
2810 return NULL;
2811
2812 if (regs[0]->unit != regs[1]->unit && !(cond && ca))
2813 return NULL;
2814
2815 if (*l == '#')
2816 {
2817 l = parse_imm_constant (l, insn, &value);
2818
2819 if (l == NULL)
2820 return NULL;
2821
2822 if (!within_unsigned_range (value, IMM5_BITS))
2823 return NULL;
2824
2825 insn->bits = (template->meta_opcode |
2826 (1 << 25) |
2827 (regs[0]->no << 19) |
2828 (regs[1]->no << 14) |
2829 ((value & IMM5_MASK) << 9));
2830 }
2831 else
2832 {
2833 l = parse_gp_regs (l, src2_regs, 1);
2834
2835 if (l == NULL)
2836 return NULL;
2837
2838 insn->bits = (template->meta_opcode |
2839 (regs[0]->no << 19) |
2840 (regs[1]->no << 14) |
2841 (src2_regs[0]->no << 9));
2842
2843 if (src2_regs[0]->unit != regs[1]->unit)
2844 {
2845 as_bad(_("Source registers must be in the same unit"));
2846 return NULL;
2847 }
2848 }
2849
2850 if (regs[0]->unit != regs[1]->unit)
2851 {
2852 if (cond && ca)
2853 {
2854 if (regs[1]->unit == UNIT_D0)
2855 unit_bit = 0;
2856 else if (regs[1]->unit == UNIT_D1)
2857 unit_bit = 1;
2858 else
2859 return NULL;
2860
2861 insn->bits |= ((1 << 5) |
2862 (regs[0]->unit << 1));
2863 }
2864 else
2865 return NULL;
2866 }
2867
2868 insn->bits |= unit_bit << 24;
2869 insn->len = 4;
2870 return l;
2871 }
2872
2873 /* Parse a MIN or MAX instruction. */
2874 static const char *
2875 parse_min_max (const char *line, metag_insn *insn,
2876 const insn_template *template)
2877 {
2878 const char *l = line;
2879 const metag_reg *regs[3];
2880
2881 l = parse_gp_regs (l, regs, 3);
2882
2883 if (l == NULL)
2884 return NULL;
2885
2886 if (!(regs[0]->unit == UNIT_D0 ||
2887 regs[0]->unit == UNIT_D1))
2888 return NULL;
2889
2890 if (!(regs[0]->unit == regs[1]->unit &&
2891 regs[1]->unit == regs[2]->unit))
2892 return NULL;
2893
2894 insn->bits = (template->meta_opcode |
2895 (regs[0]->no << 19) |
2896 (regs[1]->no << 14) |
2897 (regs[2]->no << 9));
2898
2899 if (regs[0]->unit == UNIT_D1)
2900 insn->bits |= (1 << 24);
2901
2902 insn->len = 4;
2903 return l;
2904 }
2905
2906 /* Parse a bit operation instruction. */
2907 static const char *
2908 parse_bitop (const char *line, metag_insn *insn,
2909 const insn_template *template)
2910 {
2911 const char *l = line;
2912 const metag_reg *regs[2];
2913 unsigned int swap_inst = MAJOR_OPCODE (template->meta_opcode) == OPC_MISC;
2914 unsigned int is_bexl = 0;
2915
2916 if (swap_inst &&
2917 ((template->meta_opcode >> 1) & 0xb) == 0xa)
2918 is_bexl = 1;
2919
2920 l = parse_gp_regs (l, regs, 2);
2921
2922 if (l == NULL)
2923 return NULL;
2924
2925 if (!(regs[0]->unit == UNIT_D0 ||
2926 regs[0]->unit == UNIT_D1))
2927 return NULL;
2928
2929 if (is_bexl)
2930 {
2931 if (regs[0]->unit == UNIT_D0 &&
2932 regs[1]->unit != UNIT_D1)
2933 return NULL;
2934 else if (regs[0]->unit == UNIT_D1 &&
2935 regs[1]->unit != UNIT_D0)
2936 return NULL;
2937 }
2938 else if (!(regs[0]->unit == regs[1]->unit))
2939 return NULL;
2940
2941 insn->bits = (template->meta_opcode |
2942 (regs[0]->no << 19) |
2943 (regs[1]->no << 14));
2944
2945 if (swap_inst)
2946 {
2947 if (regs[1]->unit == UNIT_D1)
2948 insn->bits |= 1;
2949 }
2950 else
2951 {
2952 if (regs[1]->unit == UNIT_D1)
2953 insn->bits |= (1 << 24);
2954 }
2955
2956 insn->len = 4;
2957 return l;
2958 }
2959
2960 /* Parse a CMP or TST instruction. */
2961 static const char *
2962 parse_cmp (const char *line, metag_insn *insn,
2963 const insn_template *template)
2964 {
2965 const char *l = line;
2966 const metag_reg *dest_regs[1];
2967 const metag_reg *src_regs[1];
2968 int value = 0;
2969 unsigned int imm = (template->meta_opcode >> 25) & 0x1;
2970 unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2971 unsigned int top = template->meta_opcode & 0x1;
2972 unsigned int sign_extend = 0;
2973 unsigned int unit_bit = 0;
2974
2975 l = parse_gp_regs (l, dest_regs, 1);
2976
2977 if (l == NULL)
2978 return NULL;
2979
2980 l = skip_comma (l);
2981
2982 if (l == NULL ||
2983 *l == END_OF_INSN)
2984 return NULL;
2985
2986 if (dest_regs[0]->unit == UNIT_D0)
2987 unit_bit = 0;
2988 else if (dest_regs[0]->unit == UNIT_D1)
2989 unit_bit = 1;
2990 else
2991 return NULL;
2992
2993 if (imm)
2994 {
2995 if (cond)
2996 {
2997 l = parse_imm_constant (l, insn, &value);
2998
2999 if (l == NULL)
3000 return NULL;
3001
3002 if (!within_unsigned_range (value, IMM8_BITS))
3003 return NULL;
3004
3005 insn->bits = (template->meta_opcode |
3006 (dest_regs[0]->no << 14) |
3007 ((value & IMM8_MASK) << 6));
3008
3009 }
3010 else
3011 {
3012 l = parse_imm16 (l, insn, &value);
3013
3014 if (l == NULL)
3015 return NULL;
3016
3017 if (value < 0)
3018 {
3019 if (!within_signed_range (value, IMM16_BITS))
3020 {
3021 as_bad (_("immediate out of range"));
3022 return NULL;
3023 }
3024 sign_extend = 1;
3025 }
3026 else
3027 {
3028 if (!within_unsigned_range (value, IMM16_BITS))
3029 {
3030 as_bad (_("immediate out of range"));
3031 return NULL;
3032 }
3033 }
3034
3035 insn->bits = (template->meta_opcode |
3036 (dest_regs[0]->no << 19) |
3037 ((value & IMM16_MASK) << 3));
3038 }
3039 }
3040 else
3041 {
3042 unsigned int o2r = 0;
3043 int rs2;
3044
3045 l = parse_gp_regs (l, src_regs, 1);
3046
3047 if (l == NULL)
3048 return NULL;
3049
3050 if (dest_regs[0]->unit != src_regs[0]->unit)
3051 {
3052 rs2 = lookup_o2r (0, unit_bit, src_regs[0]);
3053
3054 if (rs2 < 0)
3055 return NULL;
3056
3057 o2r = 1;
3058 }
3059 else
3060 {
3061 rs2 = src_regs[0]->no;
3062 }
3063
3064 insn->bits = (template->meta_opcode |
3065 (dest_regs[0]->no << 14) |
3066 (rs2 << 9));
3067
3068 if (o2r)
3069 insn->bits |= 1;
3070 }
3071
3072 if (sign_extend == 1 && top == 0)
3073 insn->bits |= (1 << 1);
3074
3075 insn->bits |= unit_bit << 24;
3076 insn->len = 4;
3077 return l;
3078 }
3079
3080 /* Parse a CACHEW instruction. */
3081 static const char *
3082 parse_cachew (const char *line, metag_insn *insn,
3083 const insn_template *template)
3084 {
3085 const char *l = line;
3086 const metag_reg *src_regs[2];
3087 unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
3088 metag_addr addr;
3089 int offset;
3090
3091 memset(&addr, 0, sizeof(addr));
3092 addr.reloc_type = BFD_RELOC_UNUSED;
3093
3094 l = parse_addr (l, &addr, size);
3095
3096 if (l == NULL ||
3097 !is_short_unit (addr.base_reg->unit) ||
3098 addr.update ||
3099 !addr.immediate)
3100 {
3101 as_bad (_("invalid memory operand"));
3102 return NULL;
3103 }
3104
3105 l = skip_comma (l);
3106
3107 if (l == NULL ||
3108 *l == END_OF_INSN)
3109 return NULL;
3110
3111 if (size == 4)
3112 l = parse_gp_regs (l, src_regs, 1);
3113 else
3114 l = parse_pair_gp_regs (l, src_regs);
3115
3116 if (l == NULL ||
3117 !is_short_unit (src_regs[0]->unit))
3118 {
3119 as_bad (_("invalid source register"));
3120 return NULL;
3121 }
3122
3123 offset = addr.exp.X_add_number;
3124
3125 if (addr.negate)
3126 offset = -offset;
3127
3128 offset = offset / 64;
3129
3130 if (!within_signed_range (offset, GET_SET_IMM_BITS))
3131 {
3132 as_bad (_("offset value out of range"));
3133 return NULL;
3134 }
3135
3136 insn->bits = (template->meta_opcode |
3137 (src_regs[0]->no << 19) |
3138 (addr.base_reg->no << 14) |
3139 ((offset & GET_SET_IMM_MASK) << 8) |
3140 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3141 ((src_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3142
3143 insn->len = 4;
3144 return l;
3145 }
3146
3147 /* Parse a CACHEW instruction. */
3148 static const char *
3149 parse_cacher (const char *line, metag_insn *insn,
3150 const insn_template *template)
3151 {
3152 const char *l = line;
3153 const metag_reg *dest_regs[2];
3154 unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
3155 metag_addr addr;
3156 int offset;
3157
3158 memset(&addr, 0, sizeof(addr));
3159 addr.reloc_type = BFD_RELOC_UNUSED;
3160
3161 if (size == 4)
3162 l = parse_gp_regs (l, dest_regs, 1);
3163 else
3164 l = parse_pair_gp_regs (l, dest_regs);
3165
3166 if (l == NULL ||
3167 !is_short_unit (dest_regs[0]->unit))
3168 {
3169 as_bad (_("invalid destination register"));
3170 return NULL;
3171 }
3172
3173 l = skip_comma (l);
3174
3175 if (l == NULL ||
3176 *l == END_OF_INSN)
3177 return NULL;
3178
3179 l = parse_addr (l, &addr, size);
3180
3181 if (l == NULL ||
3182 !is_short_unit (addr.base_reg->unit) ||
3183 addr.update ||
3184 !addr.immediate)
3185 {
3186 as_bad (_("invalid memory operand"));
3187 return NULL;
3188 }
3189
3190 offset = addr.exp.X_add_number;
3191
3192 if (addr.negate)
3193 offset = -offset;
3194
3195 offset = offset / (int)size;
3196
3197 if (!within_signed_range (offset, GET_SET_IMM_BITS))
3198 {
3199 as_bad (_("offset value out of range"));
3200 return NULL;
3201 }
3202
3203 insn->bits = (template->meta_opcode |
3204 (dest_regs[0]->no << 19) |
3205 (addr.base_reg->no << 14) |
3206 ((offset & GET_SET_IMM_MASK) << 8) |
3207 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3208 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3209
3210 insn->len = 4;
3211 return l;
3212 }
3213
3214 /* Parse an ICACHE instruction. */
3215 static const char *
3216 parse_icache (const char *line, metag_insn *insn,
3217 const insn_template *template)
3218 {
3219 const char *l = line;
3220 int offset;
3221 int pfcount;
3222
3223 l = parse_imm_constant (l, insn, &offset);
3224
3225 if (l == NULL)
3226 return NULL;
3227
3228 if (!within_signed_range (offset, IMM15_BITS))
3229 return NULL;
3230
3231 l = skip_comma (l);
3232
3233 l = parse_imm_constant (l, insn, &pfcount);
3234
3235 if (l == NULL)
3236 return NULL;
3237
3238 if (!within_unsigned_range (pfcount, IMM4_BITS))
3239 return NULL;
3240
3241 insn->bits = (template->meta_opcode |
3242 ((offset & IMM15_MASK) << 9) |
3243 ((pfcount & IMM4_MASK) << 1));
3244
3245 insn->len = 4;
3246 return l;
3247 }
3248
3249 /* Parse a LNKGET instruction. */
3250 static const char *
3251 parse_lnkget (const char *line, metag_insn *insn,
3252 const insn_template *template)
3253 {
3254 const char *l = line;
3255 const metag_reg *dest_regs[2];
3256 unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode);
3257 metag_addr addr;
3258 int offset;
3259
3260 memset(&addr, 0, sizeof(addr));
3261 addr.reloc_type = BFD_RELOC_UNUSED;
3262
3263 if (size == 8)
3264 l = parse_pair_gp_regs (l, dest_regs);
3265 else
3266 l = parse_gp_regs (l, dest_regs, 1);
3267
3268 if (l == NULL ||
3269 !is_short_unit (dest_regs[0]->unit))
3270 {
3271 as_bad (_("invalid destination register"));
3272 return NULL;
3273 }
3274
3275 l = skip_comma (l);
3276
3277 if (l == NULL ||
3278 *l == END_OF_INSN)
3279 return NULL;
3280
3281 l = parse_addr (l, &addr, size);
3282
3283 if (l == NULL ||
3284 !is_short_unit (addr.base_reg->unit) ||
3285 addr.update ||
3286 !addr.immediate)
3287 {
3288 as_bad (_("invalid memory operand"));
3289 return NULL;
3290 }
3291
3292 offset = addr.exp.X_add_number;
3293
3294 if (addr.negate)
3295 offset = -offset;
3296
3297 offset = offset / size;
3298
3299 if (!within_signed_range (offset, GET_SET_IMM_BITS))
3300 {
3301 as_bad (_("offset value out of range"));
3302 return NULL;
3303 }
3304
3305 insn->bits = (template->meta_opcode |
3306 (dest_regs[0]->no << 19) |
3307 (addr.base_reg->no << 14) |
3308 ((offset & GET_SET_IMM_MASK) << 8) |
3309 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3310 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3311
3312 insn->len = 4;
3313 return l;
3314 }
3315
3316 /* Parse an FPU MOV instruction. */
3317 static const char *
3318 parse_fmov (const char *line, metag_insn *insn,
3319 const insn_template *template)
3320 {
3321 const char *l = line;
3322 const metag_reg *regs[2];
3323
3324 l = parse_fpu_regs (l, regs, 2);
3325
3326 if (l == NULL)
3327 return NULL;
3328
3329 insn->bits = (template->meta_opcode |
3330 (regs[0]->no << 19) |
3331 (regs[1]->no << 14));
3332
3333 if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3334 insn->bits |= (1 << 5);
3335 else if (insn->fpu_width == FPU_WIDTH_PAIR)
3336 insn->bits |= (1 << 6);
3337
3338 insn->len = 4;
3339 return l;
3340 }
3341
3342 /* Parse an FPU MMOV instruction. */
3343 static const char *
3344 parse_fmmov (const char *line, metag_insn *insn,
3345 const insn_template *template)
3346 {
3347 const char *l = line;
3348 bfd_boolean to_fpu = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
3349 bfd_boolean is_mmovl = MINOR_OPCODE (template->meta_opcode) & 0x1;
3350 size_t regs_read = 0;
3351 const metag_reg *regs[16];
3352 unsigned int lowest_data_reg = 0xffffffff;
3353 unsigned int lowest_fpu_reg = 0xffffffff;
3354 unsigned int rmask = 0, data_unit;
3355 size_t i;
3356 int last_reg = -1;
3357
3358 if (insn->fpu_width != FPU_WIDTH_SINGLE)
3359 return NULL;
3360
3361 l = parse_gp_regs_list (l, regs, 16, &regs_read);
3362
3363 if (l == NULL)
3364 return NULL;
3365
3366 if (regs_read % 2)
3367 return NULL;
3368
3369 if (to_fpu)
3370 {
3371 for (i = 0; i < regs_read / 2; i++)
3372 {
3373 if (regs[i]->unit != UNIT_FX)
3374 return NULL;
3375
3376 if (last_reg == -1)
3377 {
3378 last_reg = regs[i]->no;
3379 lowest_fpu_reg = last_reg;
3380 }
3381 else
3382 {
3383 if (is_mmovl)
3384 {
3385 if (regs[i]->no != (unsigned int)(last_reg + 2))
3386 return NULL;
3387 }
3388 else if (regs[i]->no != (unsigned int)(last_reg + 1))
3389 return NULL;
3390
3391 last_reg = regs[i]->no;
3392 }
3393 }
3394
3395 if (regs[i]->unit == UNIT_D0)
3396 data_unit = 0;
3397 else if (regs[i]->unit == UNIT_D1)
3398 data_unit = 1;
3399 else
3400 return NULL;
3401
3402 if (!check_rmask (&regs[i], regs_read / 2, TRUE, FALSE, &lowest_data_reg,
3403 &rmask))
3404 return NULL;
3405 }
3406 else
3407 {
3408 if (regs[0]->unit == UNIT_D0)
3409 data_unit = 0;
3410 else if (regs[0]->unit == UNIT_D1)
3411 data_unit = 1;
3412 else
3413 return NULL;
3414
3415 if (!check_rmask (regs, regs_read / 2, TRUE, FALSE, &lowest_data_reg,
3416 &rmask))
3417 return NULL;
3418
3419 for (i = regs_read / 2; i < regs_read; i++)
3420 {
3421 if (regs[i]->unit != UNIT_FX)
3422 return NULL;
3423
3424 if (last_reg == -1)
3425 {
3426 last_reg = regs[i]->no;
3427 lowest_fpu_reg = last_reg;
3428 }
3429 else
3430 {
3431 if (is_mmovl)
3432 {
3433 if (regs[i]->no != (unsigned int)(last_reg + 2))
3434 return NULL;
3435 }
3436 else if (regs[i]->no != (unsigned int)(last_reg + 1))
3437 return NULL;
3438
3439 last_reg = regs[i]->no;
3440 }
3441 }
3442 }
3443
3444 insn->bits = (template->meta_opcode |
3445 ((lowest_data_reg & REG_MASK) << 19) |
3446 ((lowest_fpu_reg & REG_MASK) << 14) |
3447 ((rmask & RMASK_MASK) << 7) |
3448 data_unit);
3449
3450 insn->len = 4;
3451 return l;
3452 }
3453
3454 /* Parse an FPU data unit MOV instruction. */
3455 static const char *
3456 parse_fmov_data (const char *line, metag_insn *insn,
3457 const insn_template *template)
3458 {
3459 const char *l = line;
3460 unsigned int to_fpu = ((template->meta_opcode >> 7) & 0x1);
3461 const metag_reg *regs[2];
3462 unsigned int base_unit;
3463
3464 if (insn->fpu_width == FPU_WIDTH_PAIR)
3465 return NULL;
3466
3467 l = parse_gp_regs (l, regs, 2);
3468
3469 if (l == NULL)
3470 return NULL;
3471
3472 if (to_fpu)
3473 {
3474 if (regs[0]->unit != UNIT_FX)
3475 return NULL;
3476
3477 if (regs[1]->unit == UNIT_D0)
3478 base_unit = 0;
3479 else if (regs[1]->unit == UNIT_D1)
3480 base_unit = 1;
3481 else
3482 return NULL;
3483 }
3484 else
3485 {
3486 if (regs[0]->unit == UNIT_D0)
3487 base_unit = 0;
3488 else if (regs[0]->unit == UNIT_D1)
3489 base_unit = 1;
3490 else
3491 return NULL;
3492
3493 if (regs[1]->unit != UNIT_FX)
3494 return NULL;
3495 }
3496
3497 insn->bits = (template->meta_opcode |
3498 (base_unit << 24) |
3499 (regs[0]->no << 19) |
3500 (regs[1]->no << 9));
3501
3502 insn->len = 4;
3503 return l;
3504 }
3505
3506 /* Parse an FPU immediate MOV instruction. */
3507 static const char *
3508 parse_fmov_i (const char *line, metag_insn *insn,
3509 const insn_template *template)
3510 {
3511 const char *l = line;
3512 const metag_reg *regs[1];
3513 int value = 0;
3514
3515 l = parse_fpu_regs (l, regs, 1);
3516
3517 l = skip_comma (l);
3518
3519 if (l == NULL ||
3520 *l == END_OF_INSN)
3521 return NULL;
3522
3523 l = parse_imm16 (l, insn, &value);
3524
3525 if (l == NULL)
3526 return NULL;
3527
3528 insn->bits = (template->meta_opcode |
3529 (regs[0]->no << 19) |
3530 ((value & IMM16_MASK) << 3));
3531
3532 if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3533 insn->bits |= (1 << 1);
3534 else if (insn->fpu_width == FPU_WIDTH_PAIR)
3535 insn->bits |= (1 << 2);
3536
3537 insn->len = 4;
3538 return l;
3539 }
3540
3541 /* Parse an FPU PACK instruction. */
3542 static const char *
3543 parse_fpack (const char *line, metag_insn *insn,
3544 const insn_template *template)
3545 {
3546 const char *l = line;
3547 const metag_reg *regs[3];
3548
3549 l = parse_fpu_regs (l, regs, 3);
3550
3551 if (l == NULL)
3552 return NULL;
3553
3554 if (regs[0]->no % 2)
3555 {
3556 as_bad (_("destination register should be even numbered"));
3557 return NULL;
3558 }
3559
3560 insn->bits = (template->meta_opcode |
3561 (regs[0]->no << 19) |
3562 (regs[1]->no << 14) |
3563 (regs[2]->no << 9));
3564
3565 insn->len = 4;
3566 return l;
3567 }
3568
3569 /* Parse an FPU SWAP instruction. */
3570 static const char *
3571 parse_fswap (const char *line, metag_insn *insn,
3572 const insn_template *template)
3573 {
3574 const char *l = line;
3575 const metag_reg *regs[2];
3576
3577 if (insn->fpu_width != FPU_WIDTH_PAIR)
3578 return NULL;
3579
3580 l = parse_fpu_regs (l, regs, 2);
3581
3582 if (l == NULL)
3583 return NULL;
3584
3585 if (regs[0]->no % 2)
3586 return NULL;
3587
3588 if (regs[1]->no % 2)
3589 return NULL;
3590
3591 insn->bits = (template->meta_opcode |
3592 (regs[0]->no << 19) |
3593 (regs[1]->no << 14));
3594
3595 insn->len = 4;
3596 return l;
3597 }
3598
3599 /* Parse an FPU CMP instruction. */
3600 static const char *
3601 parse_fcmp (const char *line, metag_insn *insn,
3602 const insn_template *template)
3603 {
3604 const char *l = line, *l2;
3605 const metag_reg *regs1[1];
3606 const metag_reg *regs2[1];
3607
3608 l = parse_fpu_regs (l, regs1, 1);
3609
3610 l = skip_comma (l);
3611
3612 if (l == NULL ||
3613 *l == END_OF_INSN)
3614 return NULL;
3615
3616 l2 = parse_fpu_regs (l, regs2, 1);
3617
3618 if (l2 != NULL)
3619 {
3620 insn->bits = (regs2[0]->no << 9);
3621 }
3622 else
3623 {
3624 int constant = 0;
3625 l2 = parse_imm_constant (l, insn, &constant);
3626 if (!l2 || constant != 0)
3627 {
3628 as_bad (_("comparison must be with register or #0"));
3629 return NULL;
3630 }
3631 insn->bits = (1 << 8);
3632 }
3633
3634 insn->bits |= (template->meta_opcode |
3635 (regs1[0]->no << 14));
3636
3637 if (insn->fpu_action_flags & FPU_ACTION_ABS)
3638 insn->bits |= (1 << 19);
3639
3640 if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3641 insn->bits |= (1 << 7);
3642
3643 if (insn->fpu_width == FPU_WIDTH_PAIR)
3644 insn->bits |= (1 << 6);
3645 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3646 insn->bits |= (1 << 5);
3647
3648 insn->len = 4;
3649 return l2;
3650 }
3651
3652 /* Parse an FPU MIN or MAX instruction. */
3653 static const char *
3654 parse_fminmax (const char *line, metag_insn *insn,
3655 const insn_template *template)
3656 {
3657 const char *l = line;
3658 const metag_reg *regs[3];
3659
3660 l = parse_fpu_regs (l, regs, 3);
3661
3662 if (l == NULL)
3663 return NULL;
3664
3665 insn->bits = (template->meta_opcode |
3666 (regs[0]->no << 19) |
3667 (regs[1]->no << 14) |
3668 (regs[2]->no << 9));
3669
3670 if (insn->fpu_width == FPU_WIDTH_PAIR)
3671 insn->bits |= (1 << 6);
3672 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3673 insn->bits |= (1 << 5);
3674
3675 insn->len = 4;
3676 return l;
3677 }
3678
3679 /* Parse an FPU data conversion instruction. */
3680 static const char *
3681 parse_fconv (const char *line, metag_insn *insn,
3682 const insn_template *template)
3683 {
3684 const char *l = line;
3685 const metag_reg *regs[2];
3686
3687 if (insn->fpu_width == FPU_WIDTH_PAIR)
3688 {
3689 if (strncasecmp (template->name, "FTOH", 4) &&
3690 strncasecmp (template->name, "HTOF", 4) &&
3691 strncasecmp (template->name, "FTOI", 4) &&
3692 strncasecmp (template->name, "ITOF", 4))
3693 {
3694 as_bad (_("instruction cannot operate on pair values"));
3695 return NULL;
3696 }
3697 }
3698
3699 if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3700 {
3701 if (strncasecmp (template->name, "FTOI", 4) &&
3702 strncasecmp (template->name, "DTOI", 4) &&
3703 strncasecmp (template->name, "DTOL", 4))
3704 {
3705 as_bad (_("zero flag is not valid for this instruction"));
3706 return NULL;
3707 }
3708 }
3709
3710 l = parse_fpu_regs (l, regs, 2);
3711
3712 if (l == NULL)
3713 return NULL;
3714
3715 if (!strncasecmp (template->name, "DTOL", 4) ||
3716 !strncasecmp (template->name, "LTOD", 4))
3717 {
3718 if (regs[0]->no % 2)
3719 {
3720 as_bad (_("destination register should be even numbered"));
3721 return NULL;
3722 }
3723
3724 if (regs[1]->no % 2)
3725 {
3726 as_bad (_("source register should be even numbered"));
3727 return NULL;
3728 }
3729 }
3730
3731 insn->bits = (template->meta_opcode |
3732 (regs[0]->no << 19) |
3733 (regs[1]->no << 14));
3734
3735 if (insn->fpu_width == FPU_WIDTH_PAIR)
3736 insn->bits |= (1 << 6);
3737
3738 if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3739 insn->bits |= (1 << 12);
3740
3741 insn->len = 4;
3742 return l;
3743 }
3744
3745 /* Parse an FPU extended data conversion instruction. */
3746 static const char *
3747 parse_fconvx (const char *line, metag_insn *insn,
3748 const insn_template *template)
3749 {
3750 const char *l = line;
3751 const metag_reg *regs[2];
3752 int fraction_bits = 0;
3753
3754 if (insn->fpu_width == FPU_WIDTH_PAIR)
3755 {
3756 if (strncasecmp (template->name, "FTOX", 4) &&
3757 strncasecmp (template->name, "XTOF", 4))
3758 {
3759 as_bad (_("instruction cannot operate on pair values"));
3760 return NULL;
3761 }
3762 }
3763
3764 l = parse_fpu_regs (l, regs, 2);
3765
3766 l = skip_comma (l);
3767
3768 if (l == NULL ||
3769 *l == END_OF_INSN)
3770 return NULL;
3771
3772 l = parse_imm_constant (l, insn, &fraction_bits);
3773
3774 if (l == NULL)
3775 return NULL;
3776
3777 insn->bits = (template->meta_opcode |
3778 (regs[0]->no << 19) |
3779 (regs[1]->no << 14));
3780
3781 if (strncasecmp (template->name, "DTOXL", 5) &&
3782 strncasecmp (template->name, "XLTOD", 5))
3783 {
3784 if (!within_unsigned_range (fraction_bits, IMM5_BITS))
3785 {
3786 as_bad (_("fraction bits value out of range"));
3787 return NULL;
3788 }
3789 insn->bits |= ((fraction_bits & IMM5_MASK) << 9);
3790 }
3791 else
3792 {
3793 if (!within_unsigned_range (fraction_bits, IMM6_BITS))
3794 {
3795 as_bad (_("fraction bits value out of range"));
3796 return NULL;
3797 }
3798 insn->bits |= ((fraction_bits & IMM6_MASK) << 8);
3799 }
3800
3801 if (insn->fpu_width == FPU_WIDTH_PAIR)
3802 insn->bits |= (1 << 6);
3803
3804 insn->len = 4;
3805 return l;
3806 }
3807
3808 /* Parse an FPU basic arithmetic instruction. */
3809 static const char *
3810 parse_fbarith (const char *line, metag_insn *insn,
3811 const insn_template *template)
3812 {
3813 const char *l = line;
3814 const metag_reg *regs[3];
3815
3816 l = parse_fpu_regs (l, regs, 3);
3817
3818 if (l == NULL)
3819 return NULL;
3820
3821 insn->bits = (template->meta_opcode |
3822 (regs[0]->no << 19) |
3823 (regs[1]->no << 14) |
3824 (regs[2]->no << 9));
3825
3826 if (insn->fpu_width == FPU_WIDTH_PAIR)
3827 insn->bits |= (1 << 6);
3828 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3829 insn->bits |= (1 << 5);
3830
3831 if (insn->fpu_action_flags & FPU_ACTION_INV)
3832 insn->bits |= (1 << 7);
3833
3834 insn->len = 4;
3835 return l;
3836 }
3837
3838 /* Parse a floating point accumulator name. */
3839 static const char *
3840 parse_acf (const char *line, int *part)
3841 {
3842 const char *l = line;
3843 size_t i;
3844
3845 for (i = 0; i < sizeof(metag_acftab)/sizeof(metag_acftab[0]); i++)
3846 {
3847 const metag_acf *acf = &metag_acftab[i];
3848 size_t name_len = strlen (acf->name);
3849
3850 if (strncasecmp (l, acf->name, name_len) == 0)
3851 {
3852 l += name_len;
3853 *part = acf->part;
3854 return l;
3855 }
3856 }
3857 return NULL;
3858 }
3859
3860 /* Parse an FPU extended arithmetic instruction. */
3861 static const char *
3862 parse_fearith (const char *line, metag_insn *insn,
3863 const insn_template *template)
3864 {
3865 const char *l = line;
3866 const metag_reg *regs[3];
3867 bfd_boolean is_muz = (MINOR_OPCODE (template->meta_opcode) == 0x6 &&
3868 ((template->meta_opcode >> 4) & 0x1));
3869 unsigned int is_o3o = template->meta_opcode & 0x1;
3870 unsigned int is_mac = 0;
3871 unsigned int is_maw = 0;
3872
3873 if (!strncasecmp (template->name, "MAW", 3))
3874 is_maw = 1;
3875
3876 if (!strncasecmp (template->name, "MAC", 3))
3877 {
3878 int part;
3879 l = parse_acf (l, &part);
3880
3881 if (l == NULL || part != 0)
3882 return NULL;
3883
3884 l = skip_comma (l);
3885
3886 l = parse_fpu_regs (l, &regs[1], 2);
3887
3888 is_mac = 1;
3889 }
3890 else
3891 {
3892 if (is_o3o && is_maw)
3893 l = parse_fpu_regs (l, regs, 2);
3894 else
3895 l = parse_fpu_regs (l, regs, 3);
3896 }
3897
3898 if (l == NULL)
3899 return NULL;
3900
3901 if (is_o3o && is_maw)
3902 insn->bits = (template->meta_opcode |
3903 (regs[1]->no << 9));
3904 else
3905 insn->bits = (template->meta_opcode |
3906 (regs[1]->no << 14));
3907
3908 if (!(is_o3o && is_maw))
3909 insn->bits |= (regs[2]->no << 9);
3910
3911 if (is_o3o && is_maw)
3912 insn->bits |= (regs[0]->no << 14);
3913 else if (!is_mac)
3914 insn->bits |= (regs[0]->no << 19);
3915
3916 if (insn->fpu_width == FPU_WIDTH_PAIR)
3917 insn->bits |= (1 << 6);
3918 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3919 insn->bits |= (1 << 5);
3920
3921 if (!is_mac && !is_maw)
3922 if (insn->fpu_action_flags & FPU_ACTION_INV)
3923 insn->bits |= (1 << 7);
3924
3925 if (is_muz)
3926 if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3927 insn->bits |= (1 << 1);
3928
3929 insn->len = 4;
3930 return l;
3931 }
3932
3933 /* Parse an FPU RCP or RSQ instruction. */
3934 static const char *
3935 parse_frec (const char *line, metag_insn *insn,
3936 const insn_template *template)
3937 {
3938 const char *l = line;
3939 const metag_reg *regs[2];
3940
3941 l = parse_fpu_regs (l, regs, 2);
3942
3943 if (l == NULL)
3944 return NULL;
3945
3946 insn->bits = (template->meta_opcode |
3947 (regs[0]->no << 19) |
3948 (regs[1]->no << 14));
3949
3950 if (insn->fpu_width == FPU_WIDTH_PAIR)
3951 insn->bits |= (1 << 6);
3952 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3953 insn->bits |= (1 << 5);
3954
3955 if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3956 insn->bits |= (1 << 10);
3957 else if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3958 insn->bits |= (1 << 9);
3959
3960 if (insn->fpu_action_flags & FPU_ACTION_INV)
3961 insn->bits |= (1 << 7);
3962
3963 insn->len = 4;
3964 return l;
3965 }
3966
3967 /* Parse an FPU vector arithmetic instruction. */
3968 static const char *
3969 parse_fsimd (const char *line, metag_insn *insn,
3970 const insn_template *template)
3971 {
3972 const char *l = line;
3973 const metag_reg *regs[3];
3974
3975 if (insn->fpu_width != FPU_WIDTH_PAIR)
3976 {
3977 as_bad (_("simd instructions operate on pair values (L prefix)"));
3978 return NULL;
3979 }
3980
3981 l = parse_fpu_regs (l, regs, 3);
3982
3983 if (l == NULL)
3984 return NULL;
3985
3986 if (regs[0]->no % 2)
3987 {
3988 as_bad (_("destination register should be even numbered"));
3989 return NULL;
3990 }
3991
3992 if ((regs[1]->no % 2) ||
3993 (regs[2]->no % 2))
3994 {
3995 as_bad (_("source registers should be even numbered"));
3996 return NULL;
3997 }
3998
3999 insn->bits = (template->meta_opcode |
4000 (regs[0]->no << 19) |
4001 (regs[1]->no << 14) |
4002 (regs[2]->no << 9));
4003
4004 if (insn->fpu_action_flags & FPU_ACTION_INV)
4005 insn->bits |= (1 << 7);
4006
4007 insn->len = 4;
4008 return l;
4009 }
4010
4011 /* Parse an FPU accumulator GET or SET instruction. */
4012 static const char *
4013 parse_fget_set_acf (const char *line, metag_insn *insn,
4014 const insn_template *template)
4015 {
4016 const char *l = line;
4017 int part;
4018 metag_addr addr;
4019 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
4020
4021 memset(&addr, 0, sizeof(addr));
4022 addr.reloc_type = BFD_RELOC_UNUSED;
4023
4024 if (is_get)
4025 {
4026 l = parse_acf (l, &part);
4027
4028 l = skip_comma (l);
4029
4030 if (l == NULL)
4031 return NULL;
4032
4033 l = parse_mget_mset_addr (l, &addr);
4034 }
4035 else
4036 {
4037 l = parse_mget_mset_addr (l, &addr);
4038
4039 l = skip_comma (l);
4040
4041 if (l == NULL)
4042 return NULL;
4043
4044 l = parse_acf (l, &part);
4045 }
4046
4047 if (l == NULL)
4048 return NULL;
4049
4050 insn->bits = (template->meta_opcode |
4051 (part << 19));
4052
4053 if (!is_short_unit (addr.base_reg->unit))
4054 {
4055 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
4056 return NULL;
4057 }
4058
4059 insn->bits |= ((addr.base_reg->no << 14) |
4060 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
4061
4062 insn->len = 4;
4063 return l;
4064 }
4065
4066 /* Copy the name of the next register in LINE to REG_BUF. */
4067 static size_t
4068 strip_reg_name(const char *line, char *reg_buf)
4069 {
4070 const char *l = line;
4071 size_t len = 0;
4072
4073 while (is_register_char (*l))
4074 {
4075 reg_buf[len] = *l;
4076 l++;
4077 len++;
4078 if (!(len < MAX_REG_LEN))
4079 return 0;
4080 }
4081
4082 if (len)
4083 reg_buf[len] = '\0';
4084
4085 return len;
4086 }
4087
4088 /* Parse a DSP register from LINE into REG using only the registers
4089 from DSP_REGTAB. Return the next character or NULL. */
4090 static const char *
4091 __parse_dsp_reg (const char *line, const metag_reg **reg, htab_t dsp_regtab)
4092 {
4093 const char *l = line;
4094 char name[MAX_REG_LEN];
4095 size_t len = 0;
4096 metag_reg entry;
4097 const metag_reg *_reg;
4098
4099 /* We don't entirely strip the register name because we might
4100 actually want to match whole string in the register table,
4101 e.g. "D0AW.1++" not just "D0AW.1". The string length of the table
4102 entry limits our comaprison to a reasonable bound anyway. */
4103 while (is_register_char (*l) || *l == PLUS)
4104 {
4105 name[len] = *l;
4106 l++;
4107 len++;
4108 if (!(len < MAX_REG_LEN))
4109 return NULL;
4110 }
4111
4112 if (!len)
4113 return NULL;
4114
4115 name[len] = '\0';
4116 entry.name = name;
4117
4118 _reg = (const metag_reg *) htab_find (dsp_regtab, &entry);
4119 if (!_reg)
4120 return NULL;
4121
4122 *reg = _reg;
4123
4124 return l;
4125 }
4126
4127 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4128 member is suitable for encoding into a DSP insn register field. */
4129 static const char *
4130 parse_dsp_insn_reg (const char *line, const metag_reg **reg)
4131 {
4132 return __parse_dsp_reg (line, reg, dsp_reg_htab);
4133 }
4134
4135 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4136 member is suitable for encoding into a DSP template definition insn
4137 register field.
4138
4139 There is a separate table for whether we're doing a load or a store
4140 definition. "load" specifies which table to look at. */
4141 static const char *
4142 parse_dsp_template_reg (const char *line, const metag_reg **reg,
4143 bfd_boolean load)
4144 {
4145 return __parse_dsp_reg (line, reg, dsp_tmpl_reg_htab[load]);
4146 }
4147
4148 /* Parse a single DSP register from LINE. */
4149 static const char *
4150 parse_dsp_reg (const char *line, const metag_reg **reg,
4151 bfd_boolean tmpl, bfd_boolean load)
4152 {
4153 if (tmpl)
4154 return parse_dsp_template_reg (line, reg, load);
4155 else
4156 return parse_dsp_insn_reg (line, reg);
4157 }
4158
4159 /* Return TRUE if UNIT is an address unit. */
4160 static bfd_boolean
4161 is_addr_unit (enum metag_unit unit)
4162 {
4163 switch (unit)
4164 {
4165 case UNIT_A0:
4166 case UNIT_A1:
4167 return TRUE;
4168 default:
4169 return FALSE;
4170 }
4171 }
4172
4173 /* Return TRUE if UNIT1 and UNIT2 are equivalent units. */
4174 static bfd_boolean
4175 is_same_data_unit (enum metag_unit unit1, enum metag_unit unit2)
4176 {
4177 if (unit1 == unit2)
4178 return TRUE;
4179
4180 switch (unit1)
4181 {
4182 case UNIT_D0:
4183 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0)
4184 return TRUE;
4185 break;
4186 case UNIT_D1:
4187 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1)
4188 return TRUE;
4189 break;
4190 case UNIT_ACC_D0:
4191 if (unit2 == UNIT_D0 || unit2 == UNIT_RAM_D0)
4192 return TRUE;
4193 break;
4194 case UNIT_ACC_D1:
4195 if (unit2 == UNIT_D1 || unit2 == UNIT_RAM_D1)
4196 return TRUE;
4197 break;
4198 case UNIT_RAM_D0:
4199 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_D0)
4200 return TRUE;
4201 break;
4202 case UNIT_RAM_D1:
4203 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_D1)
4204 return TRUE;
4205 break;
4206 default:
4207 return FALSE;
4208 }
4209
4210 return FALSE;
4211 }
4212
4213 /* Return TRUE if the register NUM is a quickrot control register. */
4214 static bfd_boolean
4215 is_quickrot_reg (unsigned int num)
4216 {
4217 switch (num)
4218 {
4219 case 2:
4220 case 3:
4221 return TRUE;
4222 }
4223
4224 return FALSE;
4225 }
4226
4227 /* Return TRUE if REG is an accumulator register. */
4228 static bfd_boolean
4229 is_accumulator_reg (const metag_reg *reg)
4230 {
4231 if (reg->unit == UNIT_ACC_D0 || reg->unit == UNIT_ACC_D1)
4232 return TRUE;
4233
4234 return FALSE;
4235 }
4236
4237 /* Return TRUE if REG is a DSP RAM register. */
4238 static bfd_boolean
4239 is_dspram_reg (const metag_reg *reg)
4240 {
4241 if (reg->unit == UNIT_RAM_D0 || reg->unit == UNIT_RAM_D1)
4242 return TRUE;
4243
4244 return FALSE;
4245 }
4246
4247 static const char *
4248 __parse_gp_reg (const char *line, const metag_reg **reg, bfd_boolean load)
4249 {
4250 const char *l = line;
4251 char reg_buf[MAX_REG_LEN];
4252 size_t len = 0;
4253
4254 if (l == NULL)
4255 return NULL;
4256
4257 /* Parse [DSPRAM.x]. */
4258 if (*l == ADDR_BEGIN_CHAR)
4259 {
4260 l++;
4261
4262 if (l == NULL)
4263 return NULL;
4264
4265 l = parse_dsp_reg (l, reg, TRUE, load);
4266 if (l == NULL)
4267 return NULL;
4268
4269 if (*l == ADDR_END_CHAR)
4270 l++;
4271 else
4272 {
4273 as_bad (_("expected ']', not %c in %s"), *l, l);
4274 return NULL;
4275 }
4276
4277 return l;
4278 }
4279 else
4280 {
4281
4282 len = strip_reg_name (l, reg_buf);
4283 if (!len)
4284 return NULL;
4285
4286 l += len;
4287 *reg = parse_gp_reg (reg_buf);
4288 if (*reg == NULL)
4289 return NULL;
4290 }
4291
4292 return l;
4293 }
4294
4295 /* Parse a list of DSP/GP registers. TRY_GP indicates whether we
4296 should try to parse the register as a general-purpose register if
4297 we fail to parse it as a DSP one. TMPL indicates whether the
4298 registers are part of a template definition instruction. If this is
4299 a template definition instruction LOAD says whether it's a load
4300 template insn. FIRST_DST indicates whether the first register is
4301 a destination operand. */
4302 static const char *
4303 parse_dsp_regs_list (const char *line, const metag_reg **regs, size_t count,
4304 size_t *regs_read, bfd_boolean try_gp, bfd_boolean tmpl,
4305 bfd_boolean load, bfd_boolean first_dst)
4306 {
4307 const char *l = line;
4308 int seen_regs = 0;
4309 size_t i;
4310 const metag_reg *reg;
4311
4312 for (i = 0; i < count; i++)
4313 {
4314 const char *next, *ll;
4315
4316 next = l;
4317
4318 if (i > 0)
4319 {
4320 l = skip_comma (l);
4321 if (l == NULL)
4322 {
4323 *regs_read = seen_regs;
4324 return next;
4325 }
4326 }
4327
4328 ll = parse_dsp_reg (l, &reg, tmpl, load);
4329
4330 if (!ll)
4331 {
4332 if (try_gp)
4333 {
4334 l = __parse_gp_reg (l, &reg, !(first_dst && i == 0));
4335 if (l == NULL)
4336 {
4337 *regs_read = seen_regs;
4338 return next;
4339 }
4340 regs[i] = reg;
4341 seen_regs++;
4342 }
4343 else
4344 {
4345 *regs_read = seen_regs;
4346 return l;
4347 }
4348 }
4349 else
4350 {
4351 regs[i] = reg;
4352 seen_regs++;
4353 l = ll;
4354 }
4355 }
4356
4357 *regs_read = seen_regs;
4358 return l;
4359 }
4360
4361 /* Parse the following memory references:
4362
4363 - [Ax.r]
4364 - [Ax.r++]
4365 - [Ax.r--]
4366 - [Ax.r+Ax.r++]
4367 - [Ax.r-Ax.r--]
4368
4369 - [DSPRam]
4370 - [DSPRam++]
4371 - [DSPRam+DSPRam++]
4372 - [DSPRam-DSPRam--] */
4373 static const char *
4374 parse_dsp_addr (const char *line, metag_addr *addr, unsigned int size,
4375 bfd_boolean load)
4376 {
4377 const char *l = line, *ll;
4378 const metag_reg *regs[1];
4379 size_t regs_read;
4380
4381 /* Skip opening square bracket. */
4382 l++;
4383
4384 l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);
4385
4386 if (l == NULL)
4387 return NULL;
4388
4389 if (!is_addr_unit (regs[0]->unit) &&
4390 !is_dspram_reg (regs[0]))
4391 {
4392 as_bad (_("invalid register for memory access"));
4393 return NULL;
4394 }
4395
4396 addr->base_reg = regs[0];
4397
4398 if (*l == ADDR_END_CHAR)
4399 {
4400 addr->exp.X_op = O_constant;
4401 addr->exp.X_add_symbol = NULL;
4402 addr->exp.X_op_symbol = NULL;
4403
4404 /* Simple register with no offset (0 immediate). */
4405 addr->exp.X_add_number = 0;
4406
4407 addr->immediate = 1;
4408 l++;
4409
4410 return l;
4411 }
4412
4413 ll = parse_addr_post_incr_op (l, addr);
4414
4415 if (ll && *ll == ADDR_END_CHAR)
4416 {
4417 if (addr->update == 1)
4418 {
4419 /* We have a post increment/decrement. */
4420 addr->exp.X_op = O_constant;
4421 addr->exp.X_add_number = size;
4422 addr->exp.X_add_symbol = NULL;
4423 addr->exp.X_op_symbol = NULL;
4424 addr->post_increment = 1;
4425 }
4426 addr->immediate = 1;
4427 ll++;
4428 return ll;
4429 }
4430
4431 addr->post_increment = 0;
4432
4433 l = parse_addr_op (l, addr);
4434
4435 if (l == NULL)
4436 return NULL;
4437
4438 l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);
4439
4440 if (l == NULL)
4441 return NULL;
4442
4443 if (regs[0]->unit != addr->base_reg->unit)
4444 {
4445 as_bad (_("offset and base must be from the same unit"));
4446 return NULL;
4447 }
4448
4449 addr->offset_reg = regs[0];
4450
4451 if (*l == ADDR_END_CHAR)
4452 {
4453 l++;
4454 return l;
4455 }
4456
4457 l = parse_addr_post_incr_op (l, addr);
4458
4459 if (l == NULL)
4460 return NULL;
4461
4462 if (*l == ADDR_END_CHAR)
4463 {
4464 l++;
4465 return l;
4466 }
4467
4468 return NULL;
4469 }
4470
4471 /* Parse a DSP GET or SET instruction. */
4472 static const char *
4473 parse_dget_set (const char *line, metag_insn *insn,
4474 const insn_template *template)
4475 {
4476 const char *l = line;
4477 metag_addr addr;
4478 int unit = 0;
4479 int rd_reg = 0;
4480 bfd_boolean is_get = (template->meta_opcode & 0x100);
4481 bfd_boolean is_dual = (template->meta_opcode & 0x4);
4482 bfd_boolean is_template = FALSE;
4483 const metag_reg *regs[2];
4484 unsigned int size;
4485 size_t count, regs_read;
4486
4487 memset(&addr, 0, sizeof(addr));
4488 addr.reloc_type = BFD_RELOC_UNUSED;
4489
4490 size = is_dual ? 8 : 4;
4491 count = is_dual ? 2 : 1;
4492
4493 if (is_get)
4494 {
4495 /* GETL can be used on one template table entry. */
4496 if (*l == 'T')
4497 count = 1;
4498
4499 l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE,
4500 FALSE, FALSE, FALSE);
4501 l = skip_comma (l);
4502
4503 if (l == NULL)
4504 {
4505 as_bad (_("unexpected end of line"));
4506 return NULL;
4507 }
4508
4509 l = parse_addr (l, &addr, size);
4510 }
4511 else
4512 {
4513 l = parse_addr (l, &addr, size);
4514
4515 l = skip_comma (l);
4516
4517 if (l == NULL)
4518 return NULL;
4519
4520 /* GETL can be used on one template table entry. */
4521 if (*l == 'T')
4522 count = 1;
4523
4524 l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE, FALSE,
4525 FALSE, FALSE);
4526 }
4527
4528 if (l == NULL)
4529 return NULL;
4530
4531 /* The first register dictates the unit. */
4532 if (regs[0]->unit == UNIT_DT)
4533 is_template = TRUE;
4534 else
4535 {
4536 if (regs[0]->unit == UNIT_D0 || regs[0]->unit == UNIT_RAM_D0 ||
4537 regs[0]->unit == UNIT_ACC_D0)
4538 unit = 0;
4539 else
4540 unit = 1;
4541 }
4542
4543 rd_reg = regs[0]->no;
4544
4545 /* The 'H' modifier allows a DSP GET/SET instruction to target the
4546 upper 8-bits of an accumulator. It is _only_ valid for the
4547 accumulators. */
4548 if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH)
4549 {
4550 if (is_template || !(rd_reg >= 16 && rd_reg < 20))
4551 {
4552 as_bad (_("'H' modifier only valid for accumulator registers"));
4553 return NULL;
4554 }
4555
4556 /* Top 8-bits of the accumulator. */
4557 rd_reg |= 8;
4558 }
4559
4560 if (is_template)
4561 {
4562 insn->bits = (template->meta_opcode | (1 << 1));
4563 }
4564 else
4565 {
4566 insn->bits = (template->meta_opcode | unit);
4567 }
4568
4569 insn->bits |= (rd_reg << 19);
4570
4571 if (addr.immediate)
4572 {
4573 int offset = addr.exp.X_add_number;
4574
4575 if (addr.negate)
4576 offset = -offset;
4577
4578 offset = offset / (int)size;
4579
4580 if (!within_signed_range (offset, DGET_SET_IMM_BITS))
4581 {
4582 as_bad (_("offset value out of range"));
4583 return NULL;
4584 }
4585
4586 offset = offset & DGET_SET_IMM_MASK;
4587
4588 insn->bits |= (1 << 13);
4589 insn->bits |= (offset << 9);
4590 }
4591 else
4592 {
4593 int au = (addr.base_reg->unit == UNIT_A1);
4594
4595 insn->bits |= (au << 18);
4596 insn->bits |= ((addr.base_reg->no & REG_MASK) << 14);
4597 insn->bits |= ((addr.offset_reg->no & REG_MASK) << 9);
4598 }
4599
4600 if (is_dual)
4601 insn->bits |= (1 << 2);
4602
4603 if (!is_addr_unit (addr.base_reg->unit))
4604 {
4605 as_bad (_("base unit must be either A0 or A1"));
4606 return NULL;
4607 }
4608
4609 unit = (addr.base_reg->unit == UNIT_A0) ? 0 : 1;
4610 insn->bits |= ((addr.base_reg->no << 14) | (unit << 18));
4611
4612 insn->len = 4;
4613
4614 return l;
4615 }
4616
4617 /* Parse a DSP template instruction. */
4618 static const char *
4619 parse_dtemplate (const char *line, metag_insn *insn,
4620 const insn_template *template)
4621 {
4622 const char *l = line;
4623 const metag_reg *regs[TEMPLATE_NUM_REGS];
4624 bfd_boolean daop_only = FALSE;
4625 int regs_val[4];
4626 int regs_which[4] = { -1, -1, -1, -1}; /* Register or immediate? */
4627 int i;
4628
4629 for (i = 0; i < TEMPLATE_NUM_REGS; i++)
4630 {
4631 if (l == NULL)
4632 {
4633 as_bad (_("unexpected end of line"));
4634 return NULL;
4635 }
4636
4637 /* We may only have 3 register operands. */
4638 if (*l == END_OF_INSN && i == 3)
4639 {
4640 daop_only = TRUE;
4641 break;
4642 }
4643
4644 if (i != 0)
4645 {
4646 l = skip_comma (l);
4647 if (l == NULL)
4648 return NULL;
4649 }
4650
4651 if (*l == IMM_CHAR)
4652 {
4653 l = parse_imm_constant (l, insn, &regs_val[i]);
4654 if (l == NULL)
4655 {
4656 as_bad (_("invalid immediate"));
4657 return NULL;
4658 }
4659 regs_which[i] = 0;
4660 }
4661 else
4662 {
4663 /* We can't tell from the template instantiation whether
4664 this is a load or store. So we have to try looking up the
4665 register name in both the load and store tables. */
4666 const char *l2 = l;
4667 l = __parse_gp_reg (l, &regs[i], TRUE);
4668 if (l == NULL)
4669 {
4670 /* Try the store table too. */
4671 l = __parse_gp_reg (l2, &regs[i], FALSE);
4672 if (l == NULL)
4673 {
4674 /* Then try a DSP register. */
4675 l = parse_dsp_insn_reg (l2, &regs[i]);
4676 if (l == NULL || regs[i]->unit == UNIT_DT)
4677 {
4678 as_bad (_("invalid register"));
4679 return NULL;
4680 }
4681 }
4682 }
4683 regs_which[i] = 1;
4684 }
4685 }
4686
4687 insn->bits = template->meta_opcode;
4688
4689 if (regs_which[0] == 0)
4690 insn->bits |= (regs_val[0] << 19);
4691 else if (regs_which[0] == 1)
4692 insn->bits |= (regs[0]->no << 19);
4693
4694 if (regs_which[1] == 0)
4695 insn->bits |= (regs_val[1] << 14);
4696 else if (regs_which[1] == 1)
4697 insn->bits |= (regs[1]->no << 14);
4698
4699 if (regs_which[2] == 0)
4700 insn->bits |= (regs_val[2] << 9);
4701 else if (regs_which[2] == 1)
4702 insn->bits |= (regs[2]->no << 9);
4703
4704 if (regs_which[3] == 0)
4705 insn->bits |= (regs_val[3] << 4);
4706 else if (regs_which[3] == 1)
4707 insn->bits |= (regs[3]->no << 4);
4708
4709 /* DaOp only. */
4710 if (daop_only)
4711 insn->bits |= (0x3 << 24); /* Set the minor opcode. */
4712 else if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH) /* Half Load/Store. */
4713 insn->bits |= (0x5 << 24); /* Set the minor opcode. */
4714
4715 insn->len = 4;
4716
4717 return l;
4718 }
4719
4720 /* Parse a DSP Template definiton memory reference, e.g
4721 [A0.7+A0.5++]. DSPRAM is set to true by this function if this
4722 template definition is a DSP RAM template definition. */
4723 static const char *
4724 template_mem_ref(const char *line, metag_addr *addr,
4725 bfd_boolean *dspram, int size, bfd_boolean load)
4726 {
4727 const char *l = line;
4728
4729 l = parse_dsp_addr (l, addr, size, load);
4730
4731 if (l != NULL)
4732 {
4733 if (is_addr_unit(addr->base_reg->unit))
4734 *dspram = FALSE;
4735 else
4736 *dspram = TRUE;
4737 }
4738
4739 return l;
4740 }
4741
4742 /* Sets LOAD to TRUE if this is a Template load definiton (otherwise
4743 it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT. */
4744 static const char *
4745 parse_template_regs (const char *line, bfd_boolean *load,
4746 unsigned int *addr_unit,
4747 const metag_reg **template_reg, metag_addr *addr,
4748 bfd_boolean *dspram, int size)
4749 {
4750 const char *l = line;
4751
4752 if (l == NULL)
4753 return NULL;
4754
4755 /* DSP Template load definition (Tx, [Ax]) */
4756 if (*l == 'T')
4757 {
4758 *load = TRUE;
4759 l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
4760 if (l == NULL)
4761 return NULL;
4762
4763 l = skip_comma (l);
4764
4765 l = template_mem_ref (l, addr, dspram, size, *load);
4766
4767 if (addr->base_reg->unit == UNIT_A1)
4768 *addr_unit = 1;
4769
4770 }
4771 else if (*l == ADDR_BEGIN_CHAR) /* DSP Template store ([Ax], Tx) */
4772 {
4773 *load = FALSE;
4774 l = template_mem_ref (l, addr, dspram, size, *load);
4775 l = skip_comma(l);
4776
4777 if (l == NULL)
4778 return NULL;
4779
4780 l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
4781 if (l == NULL)
4782 return NULL;
4783
4784 if (addr->base_reg->unit == UNIT_A1)
4785 *addr_unit = 1;
4786 }
4787 else
4788 {
4789 as_bad (_("invalid register operand"));
4790 return NULL;
4791 }
4792
4793 return l;
4794 }
4795
4796 #define INVALID_SHIFT (-1)
4797
4798 static metag_reg _reg;
4799
4800 /* Parse a template instruction definition. */
4801 static const char *
4802 interpret_template_regs(const char *line, metag_insn *insn,
4803 const metag_reg **regs,
4804 int *regs_shift, bfd_boolean *load, bfd_boolean *dspram,
4805 int size, int *ls_shift, int *au_shift,
4806 unsigned int *au, int *imm, int *imm_shift,
4807 unsigned int *imm_mask)
4808 {
4809 const char *l = line;
4810 metag_addr addr;
4811 const metag_reg *template_reg[1];
4812
4813 memset (&addr, 0, sizeof(addr));
4814
4815 regs_shift[0] = 19;
4816 regs_shift[1] = INVALID_SHIFT;
4817
4818 insn->bits |= (1 << 1);
4819
4820 l = skip_whitespace (l);
4821
4822 l = parse_template_regs (l, load, au, template_reg,
4823 &addr, dspram, size);
4824 if (l == NULL)
4825 {
4826 as_bad (_("could not parse template definition"));
4827 return NULL;
4828 }
4829
4830 regs[2] = template_reg[0];
4831 regs_shift[2] = 9;
4832
4833 /* DSPRAM definition. */
4834 if (*dspram)
4835 {
4836
4837 _reg = *addr.base_reg;
4838
4839 if (addr.immediate)
4840 {
4841 /* Set the post-increment bit in the register field. */
4842 if (addr.update)
4843 _reg.no |= 0x1;
4844 }
4845 else
4846 {
4847 /* The bottom bit of the increment register tells us
4848 whether it's increment register 0 or 1. */
4849 if (addr.offset_reg->no & 0x1)
4850 _reg.no |= 0x3;
4851 else
4852 _reg.no |= 0x2;
4853 }
4854
4855 regs[0] = &_reg;
4856
4857 insn->bits |= (0x3 << 17); /* This signifies a DSPRAM definition. */
4858 }
4859 else /* DaOpPaMe definition. */
4860 {
4861 regs[0] = addr.base_reg;
4862 if (addr.immediate)
4863 {
4864 /* Set the I bit. */
4865 insn->bits |= (1 << 18);
4866
4867 if (addr.update == 1)
4868 {
4869 if (addr.negate == 1)
4870 *imm = 0x3;
4871 else
4872 *imm = 0x1;
4873 }
4874
4875 *imm_shift = 14;
4876 *imm_mask = 0x3;
4877 }
4878 else
4879 {
4880 /* Setup the offset register. */
4881 regs[1] = addr.offset_reg;
4882 regs_shift[1] = 14;
4883 }
4884 *au_shift = 23;
4885 }
4886
4887 *ls_shift = 13;
4888
4889 return l;
4890 }
4891
4892 /* Does this combination of units need the O2R bit and can it be encoded? */
4893 static bfd_boolean
4894 units_need_o2r (enum metag_unit unit1, enum metag_unit unit2)
4895 {
4896 if (unit1 == unit2)
4897 return FALSE;
4898
4899 if (unit1 == UNIT_D0 || unit1 == UNIT_ACC_D0 || unit1 == UNIT_RAM_D0)
4900 {
4901 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0 || unit2 == UNIT_D0)
4902 return FALSE;
4903
4904 switch (unit2)
4905 {
4906 case UNIT_A1:
4907 case UNIT_D1:
4908 case UNIT_RD:
4909 case UNIT_A0:
4910 return TRUE;
4911 default:
4912 return FALSE;
4913 }
4914 }
4915
4916 if (unit1 == UNIT_D1 || unit1 == UNIT_ACC_D1 || unit1 == UNIT_RAM_D1)
4917 {
4918 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1 || unit2 == UNIT_D1)
4919 return FALSE;
4920
4921 switch (unit2)
4922 {
4923 case UNIT_A1:
4924 case UNIT_D0:
4925 case UNIT_RD:
4926 case UNIT_A0:
4927 return TRUE;
4928 default:
4929 return FALSE;
4930 }
4931 }
4932
4933 return FALSE;
4934 }
4935
4936 /* Return TRUE if this is a DSP data unit. */
4937 static bfd_boolean
4938 is_dsp_data_unit (const metag_reg *reg)
4939 {
4940 switch (reg->unit)
4941 {
4942 case UNIT_D0:
4943 case UNIT_D1:
4944 case UNIT_ACC_D0:
4945 case UNIT_ACC_D1:
4946 case UNIT_RAM_D0:
4947 case UNIT_RAM_D1:
4948 return TRUE;
4949 default:
4950 return FALSE;
4951 }
4952 }
4953
4954 static metag_reg o2r_reg;
4955
4956 /* Parse a DaOpPaMe load template definition. */
4957 static const char *
4958 parse_dalu (const char *line, metag_insn *insn,
4959 const insn_template *template)
4960 {
4961 const char *l = line;
4962 const char *ll;
4963 const metag_reg *regs[4];
4964 metag_addr addr;
4965 size_t regs_read;
4966 bfd_boolean is_mov = MAJOR_OPCODE (template->meta_opcode) == OPC_ADD;
4967 bfd_boolean is_cmp = ((MAJOR_OPCODE (template->meta_opcode) == OPC_CMP) &&
4968 ((template->meta_opcode & 0xee) == 0));
4969 bfd_boolean is_dual = (insn->dsp_width == DSP_WIDTH_DUAL);
4970 bfd_boolean is_quickrot64 = ((insn->dsp_action_flags & DSP_ACTION_QR64) != 0);
4971 int l1_shift = INVALID_SHIFT;
4972 bfd_boolean load = FALSE;
4973 int ls_shift = INVALID_SHIFT;
4974 bfd_boolean ar = FALSE;
4975 int ar_shift = INVALID_SHIFT;
4976 int regs_shift[3] = { INVALID_SHIFT, INVALID_SHIFT, INVALID_SHIFT };
4977 int imm = 0;
4978 int imm_shift = INVALID_SHIFT;
4979 unsigned int imm_mask = 0;
4980 unsigned int au = 0;
4981 int au_shift = INVALID_SHIFT;
4982 unsigned int du = 0;
4983 int du_shift = INVALID_SHIFT;
4984 unsigned int sc = ((insn->dsp_action_flags & DSP_ACTION_OV) != 0);
4985 int sc_shift = INVALID_SHIFT;
4986 unsigned int om = ((insn->dsp_action_flags & DSP_ACTION_MOD) != 0);
4987 int om_shift = INVALID_SHIFT;
4988 unsigned int o2r = 0;
4989 int o2r_shift = INVALID_SHIFT;
4990 unsigned int qr = 0;
4991 int qr_shift = INVALID_SHIFT;
4992 int qd_shift = INVALID_SHIFT;
4993 unsigned int qn = 0;
4994 int qn_shift = INVALID_SHIFT;
4995 unsigned int a1 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ZERO)) != 0);
4996 int a1_shift = INVALID_SHIFT;
4997 unsigned int a2 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD)) != 0);
4998 int a2_shift = INVALID_SHIFT;
4999 unsigned su = ((insn->dsp_action_flags & DSP_ACTION_UMUL) != 0);
5000 int su_shift = INVALID_SHIFT;
5001 unsigned int ac;
5002 int ac_shift = INVALID_SHIFT;
5003 unsigned int mx = (((insn->dsp_daoppame_flags & DSP_DAOPPAME_8) != 0) ||
5004 (insn->dsp_daoppame_flags & DSP_DAOPPAME_16) != 0);
5005 int mx_shift = INVALID_SHIFT;
5006 int size = is_dual ? 8 : 4;
5007 bfd_boolean dspram;
5008 bfd_boolean conditional = (MINOR_OPCODE (template->meta_opcode) & 0x4);
5009
5010 /* XFIXME: check the flags are valid with the instruction. */
5011 if (is_quickrot64 && !(template->arg_type & DSP_ARGS_QR))
5012 {
5013 as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction"));
5014 return NULL;
5015 }
5016
5017 insn->bits = template->meta_opcode;
5018
5019 memset (regs, 0, sizeof (regs));
5020 memset (&addr, 0, sizeof (addr));
5021
5022 /* There are the following forms of DSP ALU instructions,
5023
5024 * Group 1:
5025 19. D[T] Op De.r,Dx.r,De.r
5026 1. D[T] Op De.r,Dx.r,De.r|ACe.r [Accumulator in src 2]
5027 3. D[T] Op De.r,Dx.r,De.r[,Ae.r] [QUICKRoT]
5028 2. D[T] Op ACe.e,ACx.r,ACo.e [cross-unit accumulator op]
5029 5. D[T] Op De.r|ACe.r,Dx.r,De.r
5030 20. D[T] Op De.r,Dx.r|ACx.r,De.r
5031 8. D Opcc De.r,Dx.r,Rx.r
5032 6. D Op De.r,Dx.r,Rx.r|RD
5033 17. D Op De.r|ACe.r,Dx.r,Rx.r|RD
5034 7. D Op De.e,Dx.r,#I16
5035
5036 * Group 2:
5037 4. D[T] Op Dx.r,De.r
5038 10. D Op Dx.r,Rx.r|RD
5039 13. D Op Dx.r,Rx.r
5040 11. D Op Dx.r,#I16
5041 12. D[T] Op De.r,Dx.r
5042 14. D Op DSPe.r,Dx.r
5043 15. D Op DSPx.r,#I16
5044 16. D Op De.r,DSPx.r
5045 18. D Op De.r,Dx.r|ACx.r
5046
5047 * Group 3:
5048 22. D Op De.r,Dx.r|ACx.r,De.r|#I5
5049 23. D Op Ux.r,Dx.r|ACx.r,De.r|#I5
5050 21. D Op De.r,Dx.r|ACx.r,#I5 */
5051
5052 /* Group 1. */
5053 if (template->arg_type & DSP_ARGS_1)
5054 {
5055 du_shift = 24;
5056
5057 /* Could this be a cross-unit accumulator op,
5058 e.g. ACe.e,ACx.r,ACo.e */
5059 if (template->arg_type & DSP_ARGS_XACC)
5060 {
5061 ll = parse_dsp_regs_list (l, regs, 3, &regs_read, FALSE, FALSE,
5062 FALSE, FALSE);
5063 if (ll != NULL && regs_read == 3
5064 && is_accumulator_reg (regs[0]))
5065 {
5066 if (regs[0]->unit != regs[1]->unit ||
5067 regs[2]->unit == regs[1]->unit)
5068 {
5069 as_bad (_("invalid operands for cross-unit op"));
5070 return NULL;
5071 }
5072
5073 du = (regs[1]->unit == UNIT_ACC_D1);
5074 regs_shift[1] = 19;
5075 l = ll;
5076
5077 /* All cross-unit accumulator ops have bits 8 and 6 set. */
5078 insn->bits |= (5 << 6);
5079
5080 goto check_for_template;
5081 }
5082
5083 /* If we reach here, this instruction is not a
5084 cross-unit accumulator op. */
5085 }
5086
5087 if (template->arg_type & DSP_ARGS_SPLIT8)
5088 om_shift = 7;
5089
5090 sc_shift = 5;
5091 l1_shift = 4;
5092 o2r_shift = 0;
5093
5094 /* De.r|ACe.r,Dx.r,De.r */
5095 if (template->arg_type & DSP_ARGS_DACC)
5096 {
5097 /* XFIXME: these need moving? */
5098 a2_shift = 7;
5099 su_shift = 6;
5100 a1_shift = 2;
5101 om_shift = 3;
5102
5103 ll = parse_dsp_reg (l, &regs[0], FALSE, FALSE);
5104 if (ll != NULL)
5105 {
5106 /* Using ACe.r as the dst requires one of the P,N or Z
5107 flags to be used. */
5108 if (!(insn->dsp_action_flags &
5109 (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
5110 {
5111 as_bad (_("missing flags: one of 'P', 'N' or 'Z' required"));
5112 return NULL;
5113 }
5114
5115 l = ll;
5116 l = skip_comma (l);
5117 l = parse_dsp_regs_list (l, &regs[1], 2, &regs_read,
5118 TRUE, FALSE, FALSE, FALSE);
5119 if (l == NULL || regs_read != 2)
5120 {
5121 as_bad (_("invalid register"));
5122 return NULL;
5123 }
5124
5125 if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
5126 du = 1;
5127
5128 regs_shift[0] = 19;
5129 regs_shift[1] = 14;
5130 regs_shift[2] = 9;
5131 goto check_for_template;
5132 }
5133
5134 /* If we reach here, this instruction does not use the
5135 accumulator as the destination register. */
5136 if ((insn->dsp_action_flags &
5137 (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
5138 {
5139 as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating"));
5140 return NULL;
5141 }
5142 }
5143
5144 regs_shift[0] = 19;
5145
5146
5147 l = parse_dsp_regs_list (l, regs, 2, &regs_read, TRUE, FALSE, FALSE, TRUE);
5148 if (l == NULL || regs_read != 2)
5149 return NULL;
5150
5151 l = skip_comma (l);
5152 if (l == NULL)
5153 return NULL;
5154
5155 if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
5156 du = 1;
5157
5158 if (is_accumulator_reg(regs[0]) && !(template->arg_type & DSP_ARGS_DACC))
5159 {
5160 as_bad (_("accumulator not a valid destination"));
5161 return NULL;
5162 }
5163
5164 /* Check for immediate, e.g. De.r,Dx.r,#I16 */
5165 if (*l == IMM_CHAR)
5166 {
5167 l = parse_imm16 (l, insn, &imm);
5168 if (l == NULL)
5169 {
5170 as_bad (_("invalid immediate value"));
5171 return NULL;
5172 }
5173
5174 if (!within_signed_range (imm, IMM16_BITS))
5175 {
5176 as_bad (_("immediate value out of range"));
5177 return NULL;
5178 }
5179
5180 if (regs[0]->unit != regs[1]->unit || regs[0]->no != regs[1]->no)
5181 {
5182 as_bad (_("immediate value not allowed when source & dest differ"));
5183 return NULL;
5184 }
5185
5186 imm_mask = 0xffff;
5187 imm_shift = 3;
5188
5189 /* Set the I-bit */
5190 insn->bits |= (1 << 25);
5191
5192 insn->bits |= (0x3 << 0);
5193
5194 l1_shift = 2;
5195
5196 /* Remove any bits that have been set in the immediate
5197 field. */
5198 insn->bits &= ~(imm_mask << imm_shift);
5199 }
5200 else
5201 {
5202
5203 regs_shift[1] = 14;
5204 regs_shift[2] = 9;
5205
5206 /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */
5207 ll = parse_dsp_reg (l, &regs[2], FALSE, FALSE);
5208 if (ll != NULL)
5209 {
5210 l = ll;
5211
5212 if (!(template->arg_type & DSP_ARGS_ACC2))
5213 {
5214 as_bad (_("invalid register operand: %s"), regs[2]->name);
5215 return NULL;
5216 }
5217
5218 om_shift = 3;
5219 ar_shift = 7;
5220 ar = TRUE;
5221 }
5222 else
5223 {
5224 /* De.r,Dx.r,De.r */
5225 l = __parse_gp_reg (l, &regs[2], TRUE);
5226 if (l == NULL)
5227 return NULL;
5228 }
5229
5230 if (template->arg_type & DSP_ARGS_ACC2)
5231 om_shift = 3;
5232
5233 /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */
5234 if (template->arg_type & DSP_ARGS_QR)
5235 {
5236 if (conditional)
5237 qn_shift = 5;
5238 else
5239 {
5240 qn_shift = 7;
5241 qr_shift = 6;
5242 qd_shift = 5;
5243 }
5244
5245 l = skip_comma (l);
5246 if (l == NULL)
5247 {
5248 as_bad (_("QUICKRoT extension requires 4 registers"));
5249 return NULL;
5250 }
5251
5252 l = __parse_gp_reg (l, &regs[3], TRUE);
5253 if (l == NULL)
5254 {
5255 as_bad (_("invalid fourth register"));
5256 return NULL;
5257 }
5258
5259 if (!is_addr_unit (regs[3]->unit) ||
5260 !is_quickrot_reg (regs[3]->no))
5261 {
5262 as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register"));
5263 return NULL;
5264 }
5265
5266 qn = (regs[3]->no == 3);
5267 }
5268 }
5269
5270 check_for_template:
5271 /* This is the common exit path. Check for o2r. */
5272 if (regs[2] != NULL)
5273 {
5274 o2r = units_need_o2r (regs[1]->unit, regs[2]->unit);
5275 if (o2r)
5276 {
5277 o2r_reg.no = lookup_o2r (0, du, regs[2]);
5278 o2r_reg.unit = regs[2]->unit;
5279 regs[2] = &o2r_reg;
5280 }
5281 }
5282
5283 /* Check any DSP RAM pointers are valid for this unit. */
5284 if ((du && (regs[0]->unit == UNIT_RAM_D0)) ||
5285 (!du && (regs[0]->unit == UNIT_RAM_D1)) ||
5286 (du && (regs[1]->unit == UNIT_RAM_D0)) ||
5287 (!du && (regs[1]->unit == UNIT_RAM_D1)) ||
5288 (du && regs[2] && (regs[2]->unit == UNIT_RAM_D0)) ||
5289 (!du && regs[2] && (regs[2]->unit == UNIT_RAM_D1))) {
5290 as_bad (_("DSP RAM pointer in incorrect unit"));
5291 return NULL;
5292 }
5293
5294 /* Is this a template definition? */
5295 if (IS_TEMPLATE_DEF (insn))
5296 {
5297 l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5298 &dspram, size, &ls_shift, &au_shift,
5299 &au, &imm, &imm_shift, &imm_mask);
5300
5301 if (l == NULL)
5302 return NULL;
5303
5304 if (!dspram)
5305 mx_shift = 0;
5306 }
5307
5308 goto matched;
5309 }
5310
5311 /* Group 2. */
5312 if (template->arg_type & DSP_ARGS_2)
5313 {
5314 bfd_boolean is_xsd = ((MAJOR_OPCODE (template->meta_opcode) == OPC_MISC) &&
5315 (MINOR_OPCODE (template->meta_opcode) == 0xa));
5316 bfd_boolean is_fpu_mov = template->insn_type == INSN_DSP_FPU;
5317 bfd_boolean to_fpu = (template->meta_opcode >> 7) & 0x1;
5318
5319 if (is_xsd)
5320 du_shift = 0;
5321 else
5322 du_shift = 24;
5323
5324 l1_shift = 4;
5325
5326 /* CMPs and TSTs don't store to their destination operand. */
5327 ll = __parse_gp_reg (l, regs, is_cmp);
5328 if (ll == NULL)
5329 {
5330 /* DSPe.r,Dx.r or DSPx.r,#I16 */
5331 if (template->arg_type & DSP_ARGS_DSP_SRC1)
5332 {
5333 l = parse_dsp_reg (l, regs, FALSE, FALSE);
5334 if (l == NULL)
5335 {
5336 as_bad (_("invalid register operand #1"));
5337 return NULL;
5338 }
5339
5340 /* Only MOV instructions have a DSP register as a
5341 destination. Set the MOV DSPe.r opcode. The simple
5342 OR'ing is OK because the usual MOV opcode is 0x00. */
5343 insn->bits = (0x91 << 24);
5344 du_shift = 0;
5345 l1_shift = 2;
5346 regs_shift[0] = 19;
5347 }
5348 else
5349 {
5350 as_bad (_("invalid register operand #2"));
5351 return NULL;
5352 }
5353 }
5354 else
5355 {
5356 l = ll;
5357
5358 /* Everything but CMP and TST. */
5359 if (MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
5360 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
5361 MAJOR_OPCODE (insn->bits) == OPC_9 ||
5362 MAJOR_OPCODE (template->meta_opcode) == OPC_MISC ||
5363 ((template->meta_opcode & 0x0000002c) != 0))
5364 regs_shift[0] = 19;
5365 else
5366 regs_shift[0] = 14;
5367 }
5368
5369 if (!is_dsp_data_unit (regs[0]) && !(regs[0]->unit == UNIT_FX &&
5370 is_fpu_mov && to_fpu))
5371 return NULL;
5372
5373 du = (regs[0]->unit == UNIT_D1 || regs[0]->unit == UNIT_RAM_D1 ||
5374 regs[0]->unit == UNIT_ACC_D1);
5375
5376 l = skip_comma (l);
5377
5378 if (*l == IMM_CHAR)
5379 {
5380 if (template->arg_type & DSP_ARGS_IMM &&
5381 !(is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)))
5382 {
5383 l = parse_imm16 (l, insn, &imm);
5384 if (l == NULL)
5385 {
5386 as_bad (_("invalid immediate value"));
5387 return NULL;
5388 }
5389
5390 if (!within_signed_range (imm, IMM16_BITS))
5391 return NULL;
5392
5393 l1_shift = 2;
5394 regs_shift[0] = 19;
5395
5396 imm_mask = 0xffff;
5397 imm_shift = 3;
5398
5399 /* Set the I-bit unless it's a MOV because they're
5400 different. */
5401 if (!(is_mov && MAJOR_OPCODE (insn->bits) == OPC_9))
5402 insn->bits |= (1 << 25);
5403
5404 /* All instructions that takes immediates also have bit 1 set. */
5405 insn->bits |= (1 << 1);
5406
5407 if (MAJOR_OPCODE (insn->bits) != OPC_9)
5408 insn->bits |= (1 << 0);
5409
5410 insn->bits &= ~(1 << 8);
5411 }
5412 else
5413 {
5414 as_bad (_("this instruction does not accept an immediate"));
5415 return NULL;
5416 }
5417 }
5418 else
5419 {
5420 if (MAJOR_OPCODE (insn->bits) != OPC_9)
5421 {
5422 insn->bits |= (1 << 8);
5423 l1_shift = 4;
5424 }
5425
5426 ll = __parse_gp_reg (l, &regs[1], TRUE);
5427 if (ll == NULL)
5428 {
5429 if (template->arg_type & DSP_ARGS_DSP_SRC2)
5430 {
5431 l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
5432 if (l == NULL)
5433 {
5434 as_bad (_("invalid register operand #3"));
5435 return NULL;
5436 }
5437
5438 /* MOV and NEG. */
5439 if ((is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)) ||
5440 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB)
5441 {
5442 if (is_accumulator_reg (regs[1]))
5443 {
5444 if (is_fpu_mov)
5445 {
5446 as_bad (_("this instruction does not accept an accumulator"));
5447 return NULL;
5448 }
5449 ar_shift = 7;
5450 ar = 1;
5451 regs_shift[1] = 9;
5452 }
5453 else
5454 {
5455 du_shift = 0;
5456 l1_shift = 2;
5457 regs_shift[1] = 14;
5458 insn->bits = (0x92 << 24); /* Set opcode. */
5459 }
5460 }
5461 }
5462 else
5463 {
5464 as_bad (_("invalid register operand #4"));
5465 return NULL;
5466 }
5467 }
5468 else
5469 {
5470 /* Set the o2r bit if required. */
5471 if (!is_fpu_mov && units_need_o2r (regs[0]->unit, regs[1]->unit))
5472 {
5473 o2r_reg = *regs[1];
5474 o2r_reg.no = lookup_o2r (0, du, regs[1]);
5475 regs[1] = &o2r_reg;
5476 o2r_shift = 0;
5477 o2r = 1;
5478 }
5479 else if (!is_dsp_data_unit (regs[1]) &&
5480 !(is_fpu_mov && !to_fpu && regs[1]->unit == UNIT_FX))
5481 return NULL;
5482
5483 if (is_fpu_mov && to_fpu)
5484 du = (regs[1]->unit == UNIT_D1 ||
5485 regs[1]->unit == UNIT_RAM_D1 ||
5486 regs[1]->unit == UNIT_ACC_D1);
5487
5488 l = ll;
5489
5490 if (MAJOR_OPCODE (insn->bits) == OPC_ADD ||
5491 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
5492 (((template->meta_opcode & 0x0000002c) == 0) &&
5493 MAJOR_OPCODE (template->meta_opcode) != OPC_MISC))
5494 regs_shift[1] = 9;
5495 else
5496 regs_shift[1] = 14;
5497 }
5498 }
5499
5500 /* If it's an 0x0 MOV or NEG set some lower bits. */
5501 if ((MAJOR_OPCODE (insn->bits) == OPC_ADD ||
5502 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) && !is_fpu_mov)
5503 {
5504 om_shift = 3;
5505 sc_shift = 5;
5506 insn->bits |= (1 << 2);
5507 }
5508
5509 /* Check for template definitons. */
5510 if (IS_TEMPLATE_DEF (insn))
5511 {
5512 l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5513 &dspram, size, &ls_shift, &au_shift,
5514 &au, &imm, &imm_shift, &imm_mask);
5515 mx_shift = 0;
5516
5517 if (l == NULL)
5518 return NULL;
5519 }
5520 goto matched;
5521 }
5522
5523 /* Group 3. */
5524 du_shift = 24;
5525 l1_shift = 4;
5526
5527 l = __parse_gp_reg (l, regs, FALSE);
5528 if (l == NULL)
5529 {
5530 as_bad (_("invalid register operand"));
5531 return NULL;
5532 }
5533
5534 l = skip_comma (l);
5535
5536 if (*l == 'A')
5537 {
5538 l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
5539 if (l == NULL)
5540 {
5541 as_bad (_("invalid accumulator register"));
5542 return NULL;
5543 }
5544 ac = 1;
5545 ac_shift = 0;
5546 }
5547 else
5548 {
5549 l = __parse_gp_reg (l, &regs[1], TRUE);
5550 if (l == NULL)
5551 {
5552 as_bad (_("invalid register operand"));
5553 return NULL;
5554 }
5555 }
5556
5557 regs_shift[0] = 19;
5558 regs_shift[1] = 14;
5559
5560 du = (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_ACC_D1
5561 || regs[1]->unit == UNIT_RAM_D1);
5562
5563 l = skip_comma (l);
5564
5565 if (*l == IMM_CHAR)
5566 {
5567 l = parse_imm_constant (l, insn, &imm);
5568 if (l == NULL)
5569 {
5570 as_bad (_("invalid immediate value"));
5571 return NULL;
5572 }
5573
5574 if (!within_unsigned_range (imm, IMM5_BITS))
5575 return NULL;
5576
5577 imm_mask = 0x1f;
5578 imm_shift = 9;
5579
5580 /* Set the I-bit */
5581 insn->bits |= (1 << 25);
5582 }
5583 else
5584 {
5585 regs_shift[2] = 9;
5586 l = __parse_gp_reg (l, &regs[2], TRUE);
5587 if (l == NULL)
5588 return NULL;
5589 }
5590
5591 /* Check for post-processing R,G,B flags. Conditional instructions
5592 do not have these bits. */
5593 if (insn->dsp_action_flags & DSP_ACTION_CLAMP9)
5594 {
5595 if ((template->meta_opcode >> 26) & 0x1)
5596 {
5597 as_bad (_("conditional instruction cannot use G flag"));
5598 return NULL;
5599 }
5600
5601 insn->bits |= (1 << 3);
5602 }
5603
5604 if (insn->dsp_action_flags & DSP_ACTION_CLAMP8)
5605 {
5606 if ((template->meta_opcode >> 26) & 0x1)
5607 {
5608 as_bad (_("conditional instruction cannot use B flag"));
5609 return NULL;
5610 }
5611
5612 insn->bits |= (0x3 << 2);
5613 }
5614
5615 if (insn->dsp_action_flags & DSP_ACTION_ROUND)
5616 {
5617 if ((template->meta_opcode >> 26) & 0x1)
5618 {
5619 as_bad (_("conditional instruction cannot use R flag"));
5620 return NULL;
5621 }
5622 insn->bits |= (1 << 2);
5623 }
5624
5625 /* Conditional Data Unit Shift instructions cannot be dual unit. */
5626 if ((template->meta_opcode >> 26) & 0x1)
5627 ls_shift = INVALID_SHIFT;
5628
5629 /* The Condition Is Always (CA) bit must be set if we're targetting a
5630 Ux.r register as the destination. This means that we can't have
5631 any other condition bits set. */
5632 if (!is_same_data_unit (regs[1]->unit, regs[0]->unit))
5633 {
5634 /* Set both the Conditional bit and the Condition is Always bit. */
5635 insn->bits |= (1 << 26);
5636 insn->bits |= (1 << 5);
5637
5638 /* Fill out the Ud field. */
5639 insn->bits |= (regs[0]->unit << 1);
5640 }
5641
5642 if (IS_TEMPLATE_DEF (insn))
5643 {
5644 l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5645 &dspram, size, &ls_shift, &au_shift,
5646 &au, &imm, &imm_shift, &imm_mask);
5647
5648 if (l == NULL)
5649 return NULL;
5650
5651 if (!dspram)
5652 mx_shift = 5;
5653 }
5654
5655 /* Fall through. */
5656 matched:
5657
5658 /* Set the registers and immediate values. */
5659 if (regs_shift[0] != INVALID_SHIFT)
5660 insn->bits |= (regs[0]->no << regs_shift[0]);
5661
5662 if (regs_shift[1] != INVALID_SHIFT)
5663 insn->bits |= (regs[1]->no << regs_shift[1]);
5664
5665 if (regs_shift[2] != INVALID_SHIFT)
5666 insn->bits |= (regs[2]->no << regs_shift[2]);
5667
5668 /* Does this insn have an 'IMM' bit? The immediate value should
5669 already have been masked. */
5670 if (imm_shift != INVALID_SHIFT)
5671 insn->bits |= ((imm & imm_mask) << imm_shift);
5672
5673 /* Does this insn have an 'AU' bit? */
5674 if (au_shift != INVALID_SHIFT)
5675 insn->bits |= (au << au_shift);
5676
5677 /* Does this instruction have an 'LS' bit? */
5678 if (ls_shift != INVALID_SHIFT)
5679 insn->bits |= (load << ls_shift);
5680
5681 /* Does this instruction have an 'AR' bit? */
5682 if (ar)
5683 insn->bits |= (1 << ar_shift);
5684
5685 if (du_shift != INVALID_SHIFT)
5686 insn->bits |= (du << du_shift);
5687
5688 if (sc_shift != INVALID_SHIFT)
5689 insn->bits |= (sc << sc_shift);
5690
5691 if (om_shift != INVALID_SHIFT)
5692 insn->bits |= (om << om_shift);
5693
5694 if (o2r_shift != INVALID_SHIFT)
5695 insn->bits |= (o2r << o2r_shift);
5696
5697 if (qn_shift != INVALID_SHIFT)
5698 insn->bits |= (qn << qn_shift);
5699
5700 if (qr_shift != INVALID_SHIFT)
5701 insn->bits |= (qr << qr_shift);
5702
5703 if (qd_shift != INVALID_SHIFT)
5704 insn->bits |= (is_quickrot64 << qd_shift);
5705
5706 if (a1_shift != INVALID_SHIFT)
5707 insn->bits |= (a1 << a1_shift);
5708
5709 if (a2_shift != INVALID_SHIFT)
5710 insn->bits |= (a2 << a2_shift);
5711
5712 if (su_shift != INVALID_SHIFT)
5713 insn->bits |= (su << su_shift);
5714
5715 if (imm_shift != INVALID_SHIFT)
5716 insn->bits |= ((imm & imm_mask) << imm_shift);
5717
5718 if (ac_shift != INVALID_SHIFT)
5719 insn->bits |= (ac << ac_shift);
5720
5721 if (mx_shift != INVALID_SHIFT)
5722 insn->bits |= (mx << mx_shift);
5723
5724 if (is_dual)
5725 {
5726 if (l1_shift == INVALID_SHIFT)
5727 {
5728 as_bad (_("'L' modifier not valid for this instruction"));
5729 return NULL;
5730 }
5731
5732 insn->bits |= (1 << l1_shift);
5733 }
5734
5735 insn->len = 4;
5736
5737 return l;
5738 }
5739
5740 typedef const char *(*insn_parser)(const char *, metag_insn *,
5741 const insn_template *);
5742
5743 /* Parser table. */
5744 static const insn_parser insn_parsers[ENC_MAX] =
5745 {
5746 [ENC_NONE] = parse_none,
5747 [ENC_MOV_U2U] = parse_mov_u2u,
5748 [ENC_MOV_PORT] = parse_mov_port,
5749 [ENC_MMOV] = parse_mmov,
5750 [ENC_MDRD] = parse_mdrd,
5751 [ENC_MOVL_TTREC] = parse_movl_ttrec,
5752 [ENC_GET_SET] = parse_get_set,
5753 [ENC_GET_SET_EXT] = parse_get_set_ext,
5754 [ENC_MGET_MSET] = parse_mget_mset,
5755 [ENC_COND_SET] = parse_cond_set,
5756 [ENC_XFR] = parse_xfr,
5757 [ENC_MOV_CT] = parse_mov_ct,
5758 [ENC_SWAP] = parse_swap,
5759 [ENC_JUMP] = parse_jump,
5760 [ENC_CALLR] = parse_callr,
5761 [ENC_ALU] = parse_alu,
5762 [ENC_SHIFT] = parse_shift,
5763 [ENC_MIN_MAX] = parse_min_max,
5764 [ENC_BITOP] = parse_bitop,
5765 [ENC_CMP] = parse_cmp,
5766 [ENC_BRANCH] = parse_branch,
5767 [ENC_KICK] = parse_kick,
5768 [ENC_SWITCH] = parse_switch,
5769 [ENC_CACHER] = parse_cacher,
5770 [ENC_CACHEW] = parse_cachew,
5771 [ENC_ICACHE] = parse_icache,
5772 [ENC_LNKGET] = parse_lnkget,
5773 [ENC_FMOV] = parse_fmov,
5774 [ENC_FMMOV] = parse_fmmov,
5775 [ENC_FMOV_DATA] = parse_fmov_data,
5776 [ENC_FMOV_I] = parse_fmov_i,
5777 [ENC_FPACK] = parse_fpack,
5778 [ENC_FSWAP] = parse_fswap,
5779 [ENC_FCMP] = parse_fcmp,
5780 [ENC_FMINMAX] = parse_fminmax,
5781 [ENC_FCONV] = parse_fconv,
5782 [ENC_FCONVX] = parse_fconvx,
5783 [ENC_FBARITH] = parse_fbarith,
5784 [ENC_FEARITH] = parse_fearith,
5785 [ENC_FREC] = parse_frec,
5786 [ENC_FSIMD] = parse_fsimd,
5787 [ENC_FGET_SET_ACF] = parse_fget_set_acf,
5788 [ENC_DGET_SET] = parse_dget_set,
5789 [ENC_DTEMPLATE] = parse_dtemplate,
5790 [ENC_DALU] = parse_dalu,
5791 };
5792
5793 struct metag_core_option
5794 {
5795 const char *name;
5796 unsigned int value;
5797 };
5798
5799 /* CPU type options. */
5800 static const struct metag_core_option metag_cpus[] =
5801 {
5802 {"all", CoreMeta11|CoreMeta12|CoreMeta21},
5803 {"metac11", CoreMeta11},
5804 {"metac12", CoreMeta12},
5805 {"metac21", CoreMeta21},
5806 {NULL, 0},
5807 };
5808
5809 /* FPU type options. */
5810 static const struct metag_core_option metag_fpus[] =
5811 {
5812 {"metac21", FpuMeta21},
5813 {NULL, 0},
5814 };
5815
5816 /* DSP type options. */
5817 static const struct metag_core_option metag_dsps[] =
5818 {
5819 {"metac21", DspMeta21},
5820 {NULL, 0},
5821 };
5822
5823 /* Parse a CPU command line option. */
5824 static int
5825 metag_parse_cpu (const char * str)
5826 {
5827 const struct metag_core_option * opt;
5828 int optlen;
5829
5830 optlen = strlen (str);
5831
5832 if (optlen == 0)
5833 {
5834 as_bad (_("missing cpu name `%s'"), str);
5835 return 0;
5836 }
5837
5838 for (opt = metag_cpus; opt->name != NULL; opt++)
5839 if (strncmp (opt->name, str, optlen) == 0)
5840 {
5841 mcpu_opt = opt->value;
5842 return 1;
5843 }
5844
5845 as_bad (_("unknown cpu `%s'"), str);
5846 return 0;
5847 }
5848
5849 /* Parse an FPU command line option. */
5850 static int
5851 metag_parse_fpu (const char * str)
5852 {
5853 const struct metag_core_option * opt;
5854 int optlen;
5855
5856 optlen = strlen (str);
5857
5858 if (optlen == 0)
5859 {
5860 as_bad (_("missing fpu name `%s'"), str);
5861 return 0;
5862 }
5863
5864 for (opt = metag_fpus; opt->name != NULL; opt++)
5865 if (strncmp (opt->name, str, optlen) == 0)
5866 {
5867 mfpu_opt = opt->value;
5868 return 1;
5869 }
5870
5871 as_bad (_("unknown fpu `%s'"), str);
5872 return 0;
5873 }
5874
5875 /* Parse a DSP command line option. */
5876 static int
5877 metag_parse_dsp (const char * str)
5878 {
5879 const struct metag_core_option * opt;
5880 int optlen;
5881
5882 optlen = strlen (str);
5883
5884 if (optlen == 0)
5885 {
5886 as_bad (_("missing DSP name `%s'"), str);
5887 return 0;
5888 }
5889
5890 for (opt = metag_dsps; opt->name != NULL; opt++)
5891 if (strncmp (opt->name, str, optlen) == 0)
5892 {
5893 mdsp_opt = opt->value;
5894 return 1;
5895 }
5896
5897 as_bad (_("unknown DSP `%s'"), str);
5898 return 0;
5899 }
5900
5901 struct metag_long_option
5902 {
5903 const char * option; /* Substring to match. */
5904 const char * help; /* Help information. */
5905 int (* func) (const char * subopt); /* Function to decode sub-option. */
5906 const char * deprecated; /* If non-null, print this message. */
5907 };
5908
5909 struct metag_long_option metag_long_opts[] =
5910 {
5911 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
5912 metag_parse_cpu, NULL},
5913 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
5914 metag_parse_fpu, NULL},
5915 {"mdsp=", N_("<dsp name>\t assemble for DSP architecture <dsp name>"),
5916 metag_parse_dsp, NULL},
5917 {NULL, NULL, 0, NULL}
5918 };
5919
5920 int
5921 md_parse_option (int c, const char * arg)
5922 {
5923 struct metag_long_option *lopt;
5924
5925 for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
5926 {
5927 /* These options are expected to have an argument. */
5928 if (c == lopt->option[0]
5929 && arg != NULL
5930 && strncmp (arg, lopt->option + 1,
5931 strlen (lopt->option + 1)) == 0)
5932 {
5933 #if WARN_DEPRECATED
5934 /* If the option is deprecated, tell the user. */
5935 if (lopt->deprecated != NULL)
5936 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
5937 _(lopt->deprecated));
5938 #endif
5939
5940 /* Call the sup-option parser. */
5941 return lopt->func (arg + strlen (lopt->option) - 1);
5942 }
5943 }
5944
5945 return 0;
5946 }
5947
5948 void
5949 md_show_usage (FILE * stream)
5950 {
5951 struct metag_long_option *lopt;
5952
5953 fprintf (stream, _(" Meta specific command line options:\n"));
5954
5955 for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
5956 if (lopt->help != NULL)
5957 fprintf (stream, " -%s%s\n", lopt->option, _(lopt->help));
5958 }
5959
5960 /* The target specific pseudo-ops which we support. */
5961 const pseudo_typeS md_pseudo_table[] =
5962 {
5963 { "word", cons, 2 },
5964 { NULL, NULL, 0 }
5965 };
5966
5967 void
5968 md_begin (void)
5969 {
5970 int c;
5971
5972 for (c = 0; c < 256; c++)
5973 {
5974 if (ISDIGIT (c))
5975 {
5976 register_chars[c] = c;
5977 /* LOCK0, LOCK1, LOCK2. */
5978 mnemonic_chars[c] = c;
5979 }
5980 else if (ISLOWER (c))
5981 {
5982 register_chars[c] = c;
5983 mnemonic_chars[c] = c;
5984 }
5985 else if (ISUPPER (c))
5986 {
5987 register_chars[c] = c;
5988 mnemonic_chars[c] = c;
5989 }
5990 else if (c == '.')
5991 {
5992 register_chars[c] = c;
5993 }
5994 }
5995 }
5996
5997 /* Parse a split condition code prefix. */
5998 static const char *
5999 parse_split_condition (const char *line, metag_insn *insn)
6000 {
6001 const char *l = line;
6002 const split_condition *scond;
6003 split_condition entry;
6004 char buf[4];
6005
6006 memcpy (buf, l, 4);
6007 buf[3] = '\0';
6008
6009 entry.name = buf;
6010
6011 scond = (const split_condition *) htab_find (scond_htab, &entry);
6012
6013 if (!scond)
6014 return NULL;
6015
6016 insn->scond = scond->code;
6017
6018 return l + strlen (scond->name);
6019 }
6020
6021 /* Parse an instruction prefix - F for float, D for DSP - and associated
6022 flags and condition codes. */
6023 static const char *
6024 parse_prefix (const char *line, metag_insn *insn)
6025 {
6026 const char *l = line;
6027
6028 l = skip_whitespace (l);
6029
6030 insn->type = INSN_GP;
6031
6032 if (TOLOWER (*l) == FPU_PREFIX_CHAR)
6033 {
6034 if (strncasecmp (l, FFB_INSN, strlen(FFB_INSN)))
6035 {
6036 insn->type = INSN_FPU;
6037
6038 l++;
6039
6040 if (*l == END_OF_INSN)
6041 {
6042 as_bad (_("premature end of floating point prefix"));
6043 return NULL;
6044 }
6045
6046 if (TOLOWER (*l) == FPU_DOUBLE_CHAR)
6047 {
6048 insn->fpu_width = FPU_WIDTH_DOUBLE;
6049 l++;
6050 }
6051 else if (TOLOWER (*l) == FPU_PAIR_CHAR)
6052 {
6053 const char *l2 = l;
6054
6055 /* Check this isn't a split condition beginning with L. */
6056 l2 = parse_split_condition (l2, insn);
6057
6058 if (l2 && is_whitespace_char (*l2))
6059 {
6060 l = l2;
6061 }
6062 else
6063 {
6064 insn->fpu_width = FPU_WIDTH_PAIR;
6065 l++;
6066 }
6067 }
6068 else
6069 {
6070 insn->fpu_width = FPU_WIDTH_SINGLE;
6071 }
6072
6073 if (TOLOWER (*l) == FPU_ACTION_ABS_CHAR)
6074 {
6075 insn->fpu_action_flags |= FPU_ACTION_ABS;
6076 l++;
6077 }
6078 else if (TOLOWER (*l) == FPU_ACTION_INV_CHAR)
6079 {
6080 insn->fpu_action_flags |= FPU_ACTION_INV;
6081 l++;
6082 }
6083
6084 if (TOLOWER (*l) == FPU_ACTION_QUIET_CHAR)
6085 {
6086 insn->fpu_action_flags |= FPU_ACTION_QUIET;
6087 l++;
6088 }
6089
6090 if (TOLOWER (*l) == FPU_ACTION_ZERO_CHAR)
6091 {
6092 insn->fpu_action_flags |= FPU_ACTION_ZERO;
6093 l++;
6094 }
6095
6096 if (! is_whitespace_char (*l))
6097 {
6098 l = parse_split_condition (l, insn);
6099
6100 if (!l)
6101 {
6102 as_bad (_("unknown floating point prefix character"));
6103 return NULL;
6104 }
6105 }
6106
6107 l = skip_space (l);
6108 }
6109 }
6110 else if (TOLOWER (*l) == DSP_PREFIX_CHAR)
6111 {
6112 if (strncasecmp (l, DCACHE_INSN, strlen (DCACHE_INSN)) &&
6113 strncasecmp (l, DEFR_INSN, strlen (DEFR_INSN)))
6114 {
6115 const char *ll = l;
6116 insn->type = INSN_DSP;
6117
6118 l++;
6119
6120 insn->dsp_width = DSP_WIDTH_SINGLE;
6121
6122 while (!is_whitespace_char (*l))
6123 {
6124 /* We have to check for split condition codes first
6125 because they are the longest strings to match,
6126 e.g. if the string contains "LLS" we want it to match
6127 the split condition code "LLS", not the dual unit
6128 character "L". */
6129 ll = l;
6130 l = parse_split_condition (l, insn);
6131
6132 if (l == NULL)
6133 l = ll;
6134 else
6135 continue;
6136
6137 /* Accept an FPU prefix char which may be used when doing
6138 template MOV with FPU registers. */
6139 if (TOLOWER(*l) == FPU_PREFIX_CHAR)
6140 {
6141 insn->type = INSN_DSP_FPU;
6142 l++;
6143 continue;
6144 }
6145
6146 if (TOLOWER(*l) == DSP_DUAL_CHAR)
6147 {
6148 insn->dsp_width = DSP_WIDTH_DUAL;
6149 l++;
6150 continue;
6151 }
6152
6153 if (TOLOWER(*l) == DSP_ACTION_QR64_CHAR)
6154 {
6155 insn->dsp_action_flags |= DSP_ACTION_QR64;
6156 l++;
6157 continue;
6158 }
6159
6160 if (TOLOWER(*l) == DSP_ACTION_UMUL_CHAR)
6161 {
6162 insn->dsp_action_flags |= DSP_ACTION_UMUL;
6163 l++;
6164 continue;
6165 }
6166
6167 if (TOLOWER(*l) == DSP_ACTION_ROUND_CHAR)
6168 {
6169 insn->dsp_action_flags |= DSP_ACTION_ROUND;
6170 l++;
6171 continue;
6172 }
6173
6174 if (TOLOWER(*l) == DSP_ACTION_CLAMP9_CHAR)
6175 {
6176 insn->dsp_action_flags |= DSP_ACTION_CLAMP9;
6177 l++;
6178 continue;
6179 }
6180
6181 if (TOLOWER(*l) == DSP_ACTION_CLAMP8_CHAR)
6182 {
6183 insn->dsp_action_flags |= DSP_ACTION_CLAMP8;
6184 l++;
6185 continue;
6186 }
6187
6188 if (TOLOWER(*l) == DSP_ACTION_MOD_CHAR)
6189 {
6190 insn->dsp_action_flags |= DSP_ACTION_MOD;
6191 l++;
6192 continue;
6193 }
6194
6195 if (TOLOWER(*l) == DSP_ACTION_ACC_ZERO_CHAR)
6196 {
6197 insn->dsp_action_flags |= DSP_ACTION_ACC_ZERO;
6198 l++;
6199 continue;
6200 }
6201
6202 if (TOLOWER(*l) == DSP_ACTION_ACC_ADD_CHAR)
6203 {
6204 insn->dsp_action_flags |= DSP_ACTION_ACC_ADD;
6205 l++;
6206 continue;
6207 }
6208
6209 if (TOLOWER(*l) == DSP_ACTION_ACC_SUB_CHAR)
6210 {
6211 insn->dsp_action_flags |= DSP_ACTION_ACC_SUB;
6212 l++;
6213 continue;
6214 }
6215
6216 if (TOLOWER(*l) == DSP_ACTION_OV_CHAR)
6217 {
6218 insn->dsp_action_flags |= DSP_ACTION_OV;
6219 l++;
6220 continue;
6221 }
6222
6223 if (TOLOWER(*l) == DSP_DAOPPAME_8_CHAR)
6224 {
6225 insn->dsp_daoppame_flags |= DSP_DAOPPAME_8;
6226 l++;
6227 continue;
6228 }
6229
6230 if (TOLOWER(*l) == DSP_DAOPPAME_16_CHAR)
6231 {
6232 insn->dsp_daoppame_flags |= DSP_DAOPPAME_16;
6233 l++;
6234 continue;
6235 }
6236
6237 if (TOLOWER(*l) == DSP_DAOPPAME_TEMP_CHAR)
6238 {
6239 insn->dsp_daoppame_flags |= DSP_DAOPPAME_TEMP;
6240 l++;
6241 continue;
6242 }
6243
6244 if (TOLOWER(*l) == DSP_DAOPPAME_HIGH_CHAR)
6245 {
6246 insn->dsp_daoppame_flags |= DSP_DAOPPAME_HIGH;
6247 l++;
6248 continue;
6249 }
6250
6251 as_bad (_("unknown DSP prefix character %c %s"), *l, l);
6252 return NULL;
6253 }
6254
6255 l = skip_space (l);
6256 }
6257 }
6258
6259 return l;
6260 }
6261
6262 /* Return a list of appropriate instruction parsers for MNEMONIC. */
6263 static insn_templates *
6264 find_insn_templates (const char *mnemonic)
6265 {
6266 insn_template template;
6267 insn_templates entry;
6268 insn_templates *slot;
6269
6270 entry.template = &template;
6271
6272 memcpy ((void *)&entry.template->name, &mnemonic, sizeof (char *));
6273
6274 slot = (insn_templates *) htab_find (mnemonic_htab, &entry);
6275
6276 if (slot)
6277 return slot;
6278
6279 return NULL;
6280 }
6281
6282 /* Make an uppercase copy of SRC into DST and return DST. */
6283 static char *
6284 strupper (char * dst, const char *src)
6285 {
6286 size_t i = 0;
6287
6288 while (src[i])
6289 {
6290 dst[i] = TOUPPER (src[i]);
6291 i++;
6292 }
6293
6294 dst[i] = 0;
6295
6296 return dst;
6297 }
6298
6299 /* Calculate a hash value for a template. */
6300 static hashval_t
6301 hash_templates (const void *p)
6302 {
6303 insn_templates *tp = (insn_templates *)p;
6304 char buf[MAX_MNEMONIC_LEN];
6305
6306 strupper (buf, tp->template->name);
6307
6308 return htab_hash_string (buf);
6309 }
6310
6311 /* Check if two templates are equal. */
6312 static int
6313 eq_templates (const void *a, const void *b)
6314 {
6315 insn_templates *ta = (insn_templates *)a;
6316 insn_templates *tb = (insn_templates *)b;
6317 return strcasecmp (ta->template->name, tb->template->name) == 0;
6318 }
6319
6320 /* Create the hash table required for parsing instructions. */
6321 static void
6322 create_mnemonic_htab (void)
6323 {
6324 size_t i, num_templates = sizeof(metag_optab)/sizeof(metag_optab[0]);
6325
6326 mnemonic_htab = htab_create_alloc (num_templates, hash_templates,
6327 eq_templates, NULL, xcalloc, free);
6328
6329 for (i = 0; i < num_templates; i++)
6330 {
6331 const insn_template *template = &metag_optab[i];
6332 insn_templates **slot = NULL;
6333 insn_templates *new_entry;
6334
6335 new_entry = XNEW (insn_templates);
6336
6337 new_entry->template = template;
6338 new_entry->next = NULL;
6339
6340 slot = (insn_templates **) htab_find_slot (mnemonic_htab, new_entry,
6341 INSERT);
6342
6343 if (*slot)
6344 {
6345 insn_templates *last_entry = *slot;
6346
6347 while (last_entry->next)
6348 last_entry = last_entry->next;
6349
6350 last_entry->next = new_entry;
6351 }
6352 else
6353 {
6354 *slot = new_entry;
6355 }
6356 }
6357 }
6358
6359 /* Calculate a hash value for a register. */
6360 static hashval_t
6361 hash_regs (const void *p)
6362 {
6363 metag_reg *rp = (metag_reg *)p;
6364 char buf[MAX_REG_LEN];
6365
6366 strupper (buf, rp->name);
6367
6368 return htab_hash_string (buf);
6369 }
6370
6371 /* Check if two registers are equal. */
6372 static int
6373 eq_regs (const void *a, const void *b)
6374 {
6375 metag_reg *ra = (metag_reg *)a;
6376 metag_reg *rb = (metag_reg *)b;
6377 return strcasecmp (ra->name, rb->name) == 0;
6378 }
6379
6380 /* Create the hash table required for parsing registers. */
6381 static void
6382 create_reg_htab (void)
6383 {
6384 size_t i, num_regs = sizeof(metag_regtab)/sizeof(metag_regtab[0]);
6385
6386 reg_htab = htab_create_alloc (num_regs, hash_regs,
6387 eq_regs, NULL, xcalloc, free);
6388
6389 for (i = 0; i < num_regs; i++)
6390 {
6391 const metag_reg *reg = &metag_regtab[i];
6392 const metag_reg **slot;
6393
6394 slot = (const metag_reg **) htab_find_slot (reg_htab, reg, INSERT);
6395
6396 if (!*slot)
6397 *slot = reg;
6398 }
6399 }
6400
6401 /* Create the hash table required for parsing DSP registers. */
6402 static void
6403 create_dspreg_htabs (void)
6404 {
6405 size_t i, num_regs = sizeof(metag_dsp_regtab)/sizeof(metag_dsp_regtab[0]);
6406 size_t h;
6407
6408 dsp_reg_htab = htab_create_alloc (num_regs, hash_regs,
6409 eq_regs, NULL, xcalloc, free);
6410
6411 for (i = 0; i < num_regs; i++)
6412 {
6413 const metag_reg *reg = &metag_dsp_regtab[i];
6414 const metag_reg **slot;
6415
6416 slot = (const metag_reg **) htab_find_slot (dsp_reg_htab, reg, INSERT);
6417
6418 /* Make sure there are no hash table collisions, which would
6419 require chaining entries. */
6420 gas_assert (*slot == NULL);
6421 *slot = reg;
6422 }
6423
6424 num_regs = sizeof(metag_dsp_tmpl_regtab[0])/sizeof(metag_dsp_tmpl_regtab[0][0]);
6425
6426 for (h = 0; h < 2; h++)
6427 {
6428 dsp_tmpl_reg_htab[h] = htab_create_alloc (num_regs, hash_regs,
6429 eq_regs, NULL, xcalloc, free);
6430 }
6431
6432 for (h = 0; h < 2; h++)
6433 {
6434 for (i = 0; i < num_regs; i++)
6435 {
6436 const metag_reg *reg = &metag_dsp_tmpl_regtab[h][i];
6437 const metag_reg **slot;
6438 slot = (const metag_reg **) htab_find_slot (dsp_tmpl_reg_htab[h],
6439 reg, INSERT);
6440
6441 /* Make sure there are no hash table collisions, which would
6442 require chaining entries. */
6443 gas_assert (*slot == NULL);
6444 *slot = reg;
6445 }
6446 }
6447 }
6448
6449 /* Calculate a hash value for a split condition code. */
6450 static hashval_t
6451 hash_scond (const void *p)
6452 {
6453 split_condition *cp = (split_condition *)p;
6454 char buf[4];
6455
6456 strupper (buf, cp->name);
6457
6458 return htab_hash_string (buf);
6459 }
6460
6461 /* Check if two split condition codes are equal. */
6462 static int
6463 eq_scond (const void *a, const void *b)
6464 {
6465 split_condition *ra = (split_condition *)a;
6466 split_condition *rb = (split_condition *)b;
6467
6468 return strcasecmp (ra->name, rb->name) == 0;
6469 }
6470
6471 /* Create the hash table required for parsing split condition codes. */
6472 static void
6473 create_scond_htab (void)
6474 {
6475 size_t i, nentries;
6476
6477 nentries = sizeof (metag_scondtab) / sizeof (metag_scondtab[0]);
6478
6479 scond_htab = htab_create_alloc (nentries, hash_scond, eq_scond,
6480 NULL, xcalloc, free);
6481 for (i = 0; i < nentries; i++)
6482 {
6483 const split_condition *scond = &metag_scondtab[i];
6484 const split_condition **slot;
6485
6486 slot = (const split_condition **) htab_find_slot (scond_htab,
6487 scond, INSERT);
6488 /* Make sure there are no hash table collisions, which would
6489 require chaining entries. */
6490 gas_assert (*slot == NULL);
6491 *slot = scond;
6492 }
6493 }
6494
6495 /* Entry point for instruction parsing. */
6496 static bfd_boolean
6497 parse_insn (const char *line, metag_insn *insn)
6498 {
6499 char mnemonic[MAX_MNEMONIC_LEN];
6500 const char *l = line;
6501 size_t mnemonic_len = 0;
6502 insn_templates *templates;
6503
6504 l = skip_space (l);
6505
6506 while (is_mnemonic_char(*l))
6507 {
6508 l++;
6509 mnemonic_len++;
6510 }
6511
6512 if (mnemonic_len >= MAX_MNEMONIC_LEN)
6513 {
6514 as_bad (_("instruction mnemonic too long: %s"), line);
6515 return FALSE;
6516 }
6517
6518 strncpy(mnemonic, line, mnemonic_len);
6519
6520 mnemonic[mnemonic_len] = '\0';
6521
6522 templates = find_insn_templates (mnemonic);
6523
6524 if (templates)
6525 {
6526 insn_templates *current_template = templates;
6527
6528 l = skip_space (l);
6529
6530 while (current_template)
6531 {
6532 const insn_template *template = current_template->template;
6533 enum insn_encoding encoding = template->encoding;
6534 insn_parser parser = insn_parsers[encoding];
6535
6536 current_template = current_template->next;
6537
6538 if (template->insn_type == INSN_GP &&
6539 !(template->core_flags & mcpu_opt))
6540 continue;
6541
6542 if (template->insn_type == INSN_FPU &&
6543 !(template->core_flags & mfpu_opt))
6544 continue;
6545
6546 if (template->insn_type == INSN_DSP &&
6547 !(template->core_flags & mdsp_opt))
6548 continue;
6549
6550 if (template->insn_type == INSN_DSP_FPU &&
6551 !((template->core_flags & mdsp_opt) &&
6552 (template->core_flags & mfpu_opt)))
6553 continue;
6554
6555 /* DSP instructions always require special decoding */
6556 if ((insn->type == INSN_DSP && (template->insn_type != INSN_DSP)) ||
6557 ((template->insn_type == INSN_DSP) && insn->type != INSN_DSP) ||
6558 (insn->type == INSN_DSP_FPU && (template->insn_type != INSN_DSP_FPU)) ||
6559 ((template->insn_type == INSN_DSP_FPU) && insn->type != INSN_DSP_FPU))
6560 continue;
6561
6562 if (parser)
6563 {
6564 const char *end = parser(l, insn, template);
6565
6566 if (end != NULL)
6567 {
6568 if (*end != END_OF_INSN)
6569 as_bad (_("junk at end of line: \"%s\""), line);
6570 else
6571 return TRUE;
6572 }
6573 }
6574 }
6575
6576 as_bad (_("failed to assemble instruction: \"%s\""), line);
6577 }
6578 else
6579 {
6580 if (insn->type == INSN_FPU)
6581 as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic);
6582 else
6583 as_bad (_("unknown mnemonic: \"%s\""), mnemonic);
6584 }
6585 return FALSE;
6586 }
6587
6588 static void
6589 output_insn (metag_insn *insn)
6590 {
6591 char *output;
6592
6593 output = frag_more (insn->len);
6594 dwarf2_emit_insn (insn->len);
6595
6596 if (insn->reloc_type != BFD_RELOC_UNUSED)
6597 {
6598 fix_new_exp (frag_now, output - frag_now->fr_literal,
6599 insn->reloc_size, &insn->reloc_exp,
6600 insn->reloc_pcrel, insn->reloc_type);
6601 }
6602
6603 md_number_to_chars (output, insn->bits, insn->len);
6604 }
6605
6606 void
6607 md_assemble (char *line)
6608 {
6609 const char *l = line;
6610 metag_insn insn;
6611
6612 memset (&insn, 0, sizeof(insn));
6613
6614 insn.reloc_type = BFD_RELOC_UNUSED;
6615 insn.reloc_pcrel = 0;
6616 insn.reloc_size = 4;
6617
6618 if (!mnemonic_htab)
6619 {
6620 create_mnemonic_htab ();
6621 create_reg_htab ();
6622 create_dspreg_htabs ();
6623 create_scond_htab ();
6624 }
6625
6626 l = parse_prefix (l, &insn);
6627
6628 if (l == NULL)
6629 return;
6630
6631 if (insn.type == INSN_DSP &&
6632 !mdsp_opt)
6633 {
6634 as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"),
6635 line);
6636 return;
6637 }
6638 else if (insn.type == INSN_FPU &&
6639 !mfpu_opt)
6640 {
6641 as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"),
6642 line);
6643 return;
6644 }
6645
6646 if (!parse_insn (l, &insn))
6647 return;
6648
6649 output_insn (&insn);
6650 }
6651
6652 void
6653 md_operand (expressionS * expressionP)
6654 {
6655 if (* input_line_pointer == IMM_CHAR)
6656 {
6657 input_line_pointer ++;
6658 expression (expressionP);
6659 }
6660 }
6661
6662 valueT
6663 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
6664 {
6665 return size;
6666 }
6667
6668 symbolS *
6669 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
6670 {
6671 return NULL;
6672 }
6673
6674 /* Functions concerning relocs. */
6675
6676 /* The location from which a PC relative jump should be calculated,
6677 given a PC relative reloc. */
6678
6679 long
6680 md_pcrel_from_section (fixS * fixP, segT sec)
6681 {
6682 if ((fixP->fx_addsy != (symbolS *) NULL
6683 && (! S_IS_DEFINED (fixP->fx_addsy)
6684 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
6685 || metag_force_relocation (fixP))
6686 {
6687 /* The symbol is undefined (or is defined but not in this section).
6688 Let the linker figure it out. */
6689 return 0;
6690 }
6691
6692 return fixP->fx_frag->fr_address + fixP->fx_where;
6693 }
6694
6695 /* Write a value out to the object file, using the appropriate endianness. */
6696
6697 void
6698 md_number_to_chars (char * buf, valueT val, int n)
6699 {
6700 number_to_chars_littleendian (buf, val, n);
6701 }
6702
6703 /* Turn a string in input_line_pointer into a floating point constant of type
6704 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
6705 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
6706 */
6707
6708 /* Equal to MAX_PRECISION in atof-ieee.c */
6709 #define MAX_LITTLENUMS 6
6710
6711 const char *
6712 md_atof (int type, char * litP, int * sizeP)
6713 {
6714 int i;
6715 int prec;
6716 LITTLENUM_TYPE words [MAX_LITTLENUMS];
6717 char * t;
6718
6719 switch (type)
6720 {
6721 case 'f':
6722 case 'F':
6723 case 's':
6724 case 'S':
6725 prec = 2;
6726 break;
6727
6728 case 'd':
6729 case 'D':
6730 case 'r':
6731 case 'R':
6732 prec = 4;
6733 break;
6734
6735 /* FIXME: Some targets allow other format chars for bigger sizes here. */
6736
6737 default:
6738 * sizeP = 0;
6739 return _("Bad call to md_atof()");
6740 }
6741
6742 t = atof_ieee (input_line_pointer, type, words);
6743 if (t)
6744 input_line_pointer = t;
6745 * sizeP = prec * sizeof (LITTLENUM_TYPE);
6746
6747 for (i = 0; i < prec; i++)
6748 {
6749 md_number_to_chars (litP, (valueT) words[i],
6750 sizeof (LITTLENUM_TYPE));
6751 litP += sizeof (LITTLENUM_TYPE);
6752 }
6753
6754 return 0;
6755 }
6756
6757 /* If this function returns non-zero, it prevents the relocation
6758 against symbol(s) in the FIXP from being replaced with relocations
6759 against section symbols, and guarantees that a relocation will be
6760 emitted even when the value can be resolved locally. */
6761
6762 int
6763 metag_force_relocation (fixS * fix)
6764 {
6765 switch (fix->fx_r_type)
6766 {
6767 case BFD_RELOC_METAG_RELBRANCH_PLT:
6768 case BFD_RELOC_METAG_TLS_LE:
6769 case BFD_RELOC_METAG_TLS_IE:
6770 case BFD_RELOC_METAG_TLS_LDO:
6771 case BFD_RELOC_METAG_TLS_LDM:
6772 case BFD_RELOC_METAG_TLS_GD:
6773 return 1;
6774 default:
6775 ;
6776 }
6777
6778 return generic_force_reloc (fix);
6779 }
6780
6781 bfd_boolean
6782 metag_fix_adjustable (fixS * fixP)
6783 {
6784 if (fixP->fx_addsy == NULL)
6785 return 1;
6786
6787 /* Prevent all adjustments to global symbols. */
6788 if (S_IS_EXTERNAL (fixP->fx_addsy))
6789 return 0;
6790 if (S_IS_WEAK (fixP->fx_addsy))
6791 return 0;
6792
6793 if (fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTOFF ||
6794 fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTOFF ||
6795 fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOTOFF ||
6796 fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOT ||
6797 fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTPC ||
6798 fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTPC ||
6799 fixP->fx_r_type == BFD_RELOC_METAG_HI16_PLT ||
6800 fixP->fx_r_type == BFD_RELOC_METAG_LO16_PLT ||
6801 fixP->fx_r_type == BFD_RELOC_METAG_RELBRANCH_PLT)
6802 return 0;
6803
6804 /* We need the symbol name for the VTABLE entries. */
6805 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6806 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6807 return 0;
6808
6809 return 1;
6810 }
6811
6812 /* Return an initial guess of the length by which a fragment must grow to
6813 hold a branch to reach its destination.
6814 Also updates fr_type/fr_subtype as necessary.
6815
6816 Called just before doing relaxation.
6817 Any symbol that is now undefined will not become defined.
6818 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
6819 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
6820 Although it may not be explicit in the frag, pretend fr_var starts with a
6821 0 value. */
6822
6823 int
6824 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
6825 segT segment ATTRIBUTE_UNUSED)
6826 {
6827 /* No assembler relaxation is defined (or necessary) for this port. */
6828 abort ();
6829 }
6830
6831 /* *fragP has been relaxed to its final size, and now needs to have
6832 the bytes inside it modified to conform to the new size.
6833
6834 Called after relaxation is finished.
6835 fragP->fr_type == rs_machine_dependent.
6836 fragP->fr_subtype is the subtype of what the address relaxed to. */
6837
6838 void
6839 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
6840 fragS * fragP ATTRIBUTE_UNUSED)
6841 {
6842 /* No assembler relaxation is defined (or necessary) for this port. */
6843 abort ();
6844 }
6845
6846 /* This is called from HANDLE_ALIGN in tc-metag.h. */
6847
6848 void
6849 metag_handle_align (fragS * fragP)
6850 {
6851 static unsigned char const noop[4] = { 0xfe, 0xff, 0xff, 0xa0 };
6852 int bytes, fix;
6853 char *p;
6854
6855 if (fragP->fr_type != rs_align_code)
6856 return;
6857
6858 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
6859 p = fragP->fr_literal + fragP->fr_fix;
6860 fix = 0;
6861
6862 if (bytes & 3)
6863 {
6864 fix = bytes & 3;
6865 memset (p, 0, fix);
6866 p += fix;
6867 bytes -= fix;
6868 }
6869
6870 while (bytes >= 4)
6871 {
6872 memcpy (p, noop, 4);
6873 p += 4;
6874 bytes -= 4;
6875 fix += 4;
6876 }
6877
6878 fragP->fr_fix += fix;
6879 fragP->fr_var = 4;
6880 }
6881
6882 static char *
6883 metag_end_of_match (char * cont, const char * what)
6884 {
6885 int len = strlen (what);
6886
6887 if (strncasecmp (cont, what, strlen (what)) == 0
6888 && ! is_part_of_name (cont[len]))
6889 return cont + len;
6890
6891 return NULL;
6892 }
6893
6894 int
6895 metag_parse_name (char const * name, expressionS * exprP, enum expr_mode mode,
6896 char * nextcharP)
6897 {
6898 char *next = input_line_pointer;
6899 char *next_end;
6900 int reloc_type;
6901 operatorT op_type;
6902 segT segment;
6903
6904 exprP->X_op_symbol = NULL;
6905 exprP->X_md = BFD_RELOC_UNUSED;
6906
6907 if (strcmp (name, GOT_NAME) == 0)
6908 {
6909 if (! GOT_symbol)
6910 GOT_symbol = symbol_find_or_make (name);
6911
6912 exprP->X_add_symbol = GOT_symbol;
6913 no_suffix:
6914 /* If we have an absolute symbol or a
6915 reg, then we know its value now. */
6916 segment = S_GET_SEGMENT (exprP->X_add_symbol);
6917 if (mode != expr_defer && segment == absolute_section)
6918 {
6919 exprP->X_op = O_constant;
6920 exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
6921 exprP->X_add_symbol = NULL;
6922 }
6923 else if (mode != expr_defer && segment == reg_section)
6924 {
6925 exprP->X_op = O_register;
6926 exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
6927 exprP->X_add_symbol = NULL;
6928 }
6929 else
6930 {
6931 exprP->X_op = O_symbol;
6932 exprP->X_add_number = 0;
6933 }
6934
6935 return 1;
6936 }
6937
6938 exprP->X_add_symbol = symbol_find_or_make (name);
6939
6940 if (*nextcharP != '@')
6941 goto no_suffix;
6942 else if ((next_end = metag_end_of_match (next + 1, "GOTOFF")))
6943 {
6944 reloc_type = BFD_RELOC_METAG_GOTOFF;
6945 op_type = O_PIC_reloc;
6946 }
6947 else if ((next_end = metag_end_of_match (next + 1, "GOT")))
6948 {
6949 reloc_type = BFD_RELOC_METAG_GETSET_GOT;
6950 op_type = O_PIC_reloc;
6951 }
6952 else if ((next_end = metag_end_of_match (next + 1, "PLT")))
6953 {
6954 reloc_type = BFD_RELOC_METAG_PLT;
6955 op_type = O_PIC_reloc;
6956 }
6957 else if ((next_end = metag_end_of_match (next + 1, "TLSGD")))
6958 {
6959 reloc_type = BFD_RELOC_METAG_TLS_GD;
6960 op_type = O_PIC_reloc;
6961 }
6962 else if ((next_end = metag_end_of_match (next + 1, "TLSLDM")))
6963 {
6964 reloc_type = BFD_RELOC_METAG_TLS_LDM;
6965 op_type = O_PIC_reloc;
6966 }
6967 else if ((next_end = metag_end_of_match (next + 1, "TLSLDO")))
6968 {
6969 reloc_type = BFD_RELOC_METAG_TLS_LDO;
6970 op_type = O_PIC_reloc;
6971 }
6972 else if ((next_end = metag_end_of_match (next + 1, "TLSIE")))
6973 {
6974 reloc_type = BFD_RELOC_METAG_TLS_IE;
6975 op_type = O_PIC_reloc;
6976 }
6977 else if ((next_end = metag_end_of_match (next + 1, "TLSIENONPIC")))
6978 {
6979 reloc_type = BFD_RELOC_METAG_TLS_IENONPIC;
6980 op_type = O_PIC_reloc; /* FIXME: is this correct? */
6981 }
6982 else if ((next_end = metag_end_of_match (next + 1, "TLSLE")))
6983 {
6984 reloc_type = BFD_RELOC_METAG_TLS_LE;
6985 op_type = O_PIC_reloc;
6986 }
6987 else
6988 goto no_suffix;
6989
6990 *input_line_pointer = *nextcharP;
6991 input_line_pointer = next_end;
6992 *nextcharP = *input_line_pointer;
6993 *input_line_pointer = '\0';
6994
6995 exprP->X_op = op_type;
6996 exprP->X_add_number = 0;
6997 exprP->X_md = reloc_type;
6998
6999 return 1;
7000 }
7001
7002 /* If while processing a fixup, a reloc really needs to be created
7003 then it is done here. */
7004
7005 arelent *
7006 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
7007 {
7008 arelent *reloc;
7009
7010 reloc = XNEW (arelent);
7011 reloc->sym_ptr_ptr = XNEW (asymbol *);
7012 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
7013 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
7014
7015 reloc->addend = fixp->fx_offset;
7016 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
7017
7018 if (reloc->howto == (reloc_howto_type *) NULL)
7019 {
7020 as_bad_where (fixp->fx_file, fixp->fx_line,
7021 /* xgettext:c-format. */
7022 _("reloc %d not supported by object file format"),
7023 (int) fixp->fx_r_type);
7024
7025 xfree (reloc);
7026
7027 return NULL;
7028 }
7029
7030 return reloc;
7031 }
7032
7033 static unsigned int
7034 md_chars_to_number (char *val, int n)
7035 {
7036 int retval;
7037 unsigned char * where = (unsigned char *) val;
7038
7039 for (retval = 0; n--;)
7040 {
7041 retval <<= 8;
7042 retval |= where[n];
7043 }
7044 return retval;
7045 }
7046
7047 void
7048 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
7049 {
7050 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
7051 int value = (int)*valP;
7052
7053 switch (fixP->fx_r_type)
7054 {
7055 case BFD_RELOC_METAG_TLS_GD:
7056 case BFD_RELOC_METAG_TLS_LE_HI16:
7057 case BFD_RELOC_METAG_TLS_LE_LO16:
7058 case BFD_RELOC_METAG_TLS_IE:
7059 case BFD_RELOC_METAG_TLS_IENONPIC_HI16:
7060 case BFD_RELOC_METAG_TLS_IENONPIC_LO16:
7061 case BFD_RELOC_METAG_TLS_LDM:
7062 case BFD_RELOC_METAG_TLS_LDO_HI16:
7063 case BFD_RELOC_METAG_TLS_LDO_LO16:
7064 S_SET_THREAD_LOCAL (fixP->fx_addsy);
7065 /* Fall through */
7066
7067 case BFD_RELOC_METAG_HIADDR16:
7068 case BFD_RELOC_METAG_LOADDR16:
7069 case BFD_RELOC_VTABLE_INHERIT:
7070 case BFD_RELOC_VTABLE_ENTRY:
7071 fixP->fx_done = FALSE;
7072 break;
7073
7074 case BFD_RELOC_METAG_REL8:
7075 if (!within_unsigned_range (value, IMM8_BITS))
7076 {
7077 as_bad_where (fixP->fx_file, fixP->fx_line,
7078 "rel8 out of range %d", value);
7079 }
7080 else
7081 {
7082 unsigned int newval;
7083 newval = md_chars_to_number (buf, 4);
7084 newval = (newval & 0xffffc03f) | ((value & IMM8_MASK) << 6);
7085 md_number_to_chars (buf, newval, 4);
7086 }
7087 break;
7088 case BFD_RELOC_METAG_REL16:
7089 if (!within_unsigned_range (value, IMM16_BITS))
7090 {
7091 as_bad_where (fixP->fx_file, fixP->fx_line,
7092 "rel16 out of range %d", value);
7093 }
7094 else
7095 {
7096 unsigned int newval;
7097 newval = md_chars_to_number (buf, 4);
7098 newval = (newval & 0xfff80007) | ((value & IMM16_MASK) << 3);
7099 md_number_to_chars (buf, newval, 4);
7100 }
7101 break;
7102
7103 case BFD_RELOC_8:
7104 md_number_to_chars (buf, value, 1);
7105 break;
7106 case BFD_RELOC_16:
7107 md_number_to_chars (buf, value, 2);
7108 break;
7109 case BFD_RELOC_32:
7110 md_number_to_chars (buf, value, 4);
7111 break;
7112 case BFD_RELOC_64:
7113 md_number_to_chars (buf, value, 8);
7114 break;
7115
7116 case BFD_RELOC_METAG_RELBRANCH:
7117 if (!value)
7118 break;
7119
7120 value = value / 4;
7121
7122 if (!within_signed_range (value, IMM19_BITS))
7123 {
7124 as_bad_where (fixP->fx_file, fixP->fx_line,
7125 "relbranch out of range %d", value);
7126 }
7127 else
7128 {
7129 unsigned int newval;
7130 newval = md_chars_to_number (buf, 4);
7131 newval = (newval & 0xff00001f) | ((value & IMM19_MASK) << 5);
7132 md_number_to_chars (buf, newval, 4);
7133 }
7134 break;
7135 default:
7136 break;
7137 }
7138
7139 if (fixP->fx_addsy == NULL)
7140 fixP->fx_done = TRUE;
7141 }
This page took 0.189739 seconds and 4 git commands to generate.