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