]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-metag.c
* common.h: Fix case of "Meta".
[thirdparty/binutils-gdb.git] / gas / config / tc-metag.c
1 /* tc-metag.c -- Assembler for the Imagination Technologies Meta.
2 Copyright (C) 2013 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 insn->bits = (template->meta_opcode |
2030 (regs[1]->no << 19) |
2031 (regs[0]->no << 14) |
2032 (regs[1]->unit << 10) |
2033 (regs[0]->unit << 5));
2034
2035 insn->len = 4;
2036 return l;
2037 }
2038
2039 /* Parse a JUMP instruction. */
2040 static const char *
2041 parse_jump (const char *line, metag_insn *insn,
2042 const insn_template *template)
2043 {
2044 const char *l = line;
2045 const metag_reg *regs[1];
2046 int value = 0;
2047
2048 l = parse_gp_regs (l, regs, 1);
2049
2050 if (l == NULL)
2051 return NULL;
2052
2053 if (!is_short_unit (regs[0]->unit))
2054 {
2055 as_bad (_("register unit must be one of %s"), SHORT_UNITS);
2056 return FALSE;
2057 }
2058
2059 l = skip_comma (l);
2060
2061 if (l == NULL ||
2062 *l == END_OF_INSN)
2063 return NULL;
2064
2065 l = parse_imm16 (l, insn, &value);
2066
2067 if (l == NULL)
2068 return NULL;
2069
2070 insn->bits = (template->meta_opcode |
2071 (regs[0]->no << 19) |
2072 (regs[0]->unit & SHORT_UNIT_MASK) |
2073 ((value & IMM16_MASK) << 3));
2074
2075 insn->len = 4;
2076 return l;
2077 }
2078
2079 /* Parse a 19bit immediate value. */
2080 static const char *
2081 parse_imm19 (const char *line, metag_insn *insn, int *value)
2082 {
2083 const char *l = line;
2084 char *save_input_line_pointer;
2085 expressionS *exp = &insn->reloc_exp;
2086
2087 /* Skip #. */
2088 if (*l == '#')
2089 l++;
2090
2091 save_input_line_pointer = input_line_pointer;
2092 input_line_pointer = (char *) l;
2093
2094 expression (exp);
2095
2096 l = input_line_pointer;
2097 input_line_pointer = save_input_line_pointer;
2098
2099 if (exp->X_op == O_absent || exp->X_op == O_big)
2100 {
2101 return NULL;
2102 }
2103 else if (exp->X_op == O_constant)
2104 {
2105 *value = exp->X_add_number;
2106 }
2107 else
2108 {
2109 if (exp->X_op == O_PIC_reloc)
2110 {
2111 exp->X_op = O_symbol;
2112
2113 if (exp->X_md == BFD_RELOC_METAG_PLT)
2114 insn->reloc_type = BFD_RELOC_METAG_RELBRANCH_PLT;
2115 else
2116 return NULL;
2117 }
2118 else
2119 insn->reloc_type = BFD_RELOC_METAG_RELBRANCH;
2120 insn->reloc_pcrel = 1;
2121 }
2122
2123 return l;
2124 }
2125
2126 /* Parse a CALLR instruction. */
2127 static const char *
2128 parse_callr (const char *line, metag_insn *insn,
2129 const insn_template *template)
2130 {
2131 const char *l = line;
2132 const metag_reg *regs[1];
2133 int value = 0;
2134
2135 l = parse_gp_regs (l, regs, 1);
2136
2137 if (l == NULL)
2138 return NULL;
2139
2140 if (!is_short_unit (regs[0]->unit))
2141 {
2142 as_bad (_("link register unit must be one of %s"), SHORT_UNITS);
2143 return NULL;
2144 }
2145
2146 if (regs[0]->no & ~CALLR_REG_MASK)
2147 {
2148 as_bad (_("link register must be in a low numbered register"));
2149 return NULL;
2150 }
2151
2152 l = skip_comma (l);
2153
2154 if (l == NULL ||
2155 *l == END_OF_INSN)
2156 return NULL;
2157
2158 l = parse_imm19 (l, insn, &value);
2159
2160 if (l == NULL)
2161 return NULL;
2162
2163 if (!within_signed_range (value / 4, IMM19_BITS))
2164 {
2165 as_bad (_("target out of range"));
2166 return NULL;
2167 }
2168
2169 insn->bits = (template->meta_opcode |
2170 (regs[0]->no & CALLR_REG_MASK) |
2171 ((regs[0]->unit & SHORT_UNIT_MASK) << 3) |
2172 ((value & IMM19_MASK) << 5));
2173
2174 insn->len = 4;
2175 return l;
2176 }
2177
2178 /* Return the value for the register field if we apply the O2R modifier
2179 to operand 2 REG, combined with UNIT_BIT derived from the destination
2180 register or source1. Uses address unit O2R if IS_ADDR is set. */
2181 static int
2182 lookup_o2r (unsigned int is_addr, unsigned int unit_bit, const metag_reg *reg)
2183 {
2184 if (reg->no & ~O2R_REG_MASK)
2185 return -1;
2186
2187 if (is_addr)
2188 {
2189 if (unit_bit)
2190 {
2191 switch (reg->unit)
2192 {
2193 case UNIT_D1:
2194 return reg->no;
2195 case UNIT_D0:
2196 return (1 << 3) | reg->no;
2197 case UNIT_RD:
2198 return (2 << 3) | reg->no;
2199 case UNIT_A0:
2200 return (3 << 3) | reg->no;
2201 default:
2202 return -1;
2203 }
2204 }
2205 else
2206 {
2207 switch (reg->unit)
2208 {
2209 case UNIT_A1:
2210 return reg->no;
2211 case UNIT_D0:
2212 return (1 << 3) | reg->no;
2213 case UNIT_RD:
2214 return (2 << 3) | reg->no;
2215 case UNIT_D1:
2216 return (3 << 3) | reg->no;
2217 default:
2218 return -1;
2219 }
2220 }
2221 }
2222 else
2223 {
2224 if (unit_bit)
2225 {
2226 switch (reg->unit)
2227 {
2228 case UNIT_A1:
2229 return reg->no;
2230 case UNIT_D0:
2231 return (1 << 3) | reg->no;
2232 case UNIT_RD:
2233 return (2 << 3) | reg->no;
2234 case UNIT_A0:
2235 return (3 << 3) | reg->no;
2236 default:
2237 return -1;
2238 }
2239 }
2240 else
2241 {
2242 switch (reg->unit)
2243 {
2244 case UNIT_A1:
2245 return reg->no;
2246 case UNIT_D1:
2247 return (1 << 3) | reg->no;
2248 case UNIT_RD:
2249 return (2 << 3) | reg->no;
2250 case UNIT_A0:
2251 return (3 << 3) | reg->no;
2252 default:
2253 return -1;
2254 }
2255 }
2256 }
2257 }
2258
2259 /* Parse GP ALU instruction. */
2260 static const char *
2261 parse_alu (const char *line, metag_insn *insn,
2262 const insn_template *template)
2263 {
2264 const char *l = line;
2265 const metag_reg *dest_regs[1];
2266 const metag_reg *src_regs[2];
2267 int value = 0;
2268 unsigned int o1z = 0;
2269 unsigned int imm = (template->meta_opcode >> 25) & 0x1;
2270 unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2271 unsigned int ca = (template->meta_opcode >> 5) & 0x1;
2272 unsigned int top = template->meta_opcode & 0x1;
2273 unsigned int sign_extend = 0;
2274 unsigned int is_addr_op = MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR;
2275 unsigned int is_mul = MAJOR_OPCODE (template->meta_opcode) == OPC_MUL;
2276 unsigned int unit_bit = 0;
2277 bfd_boolean is_quickrot = template->arg_type & GP_ARGS_QR;
2278
2279 l = parse_gp_regs (l, dest_regs, 1);
2280
2281 if (l == NULL)
2282 return NULL;
2283
2284 l = skip_comma (l);
2285
2286 if (l == NULL ||
2287 *l == END_OF_INSN)
2288 return NULL;
2289
2290 if (is_addr_op)
2291 {
2292 if (dest_regs[0]->unit == UNIT_A0)
2293 unit_bit = 0;
2294 else if (dest_regs[0]->unit == UNIT_A1)
2295 unit_bit = 1;
2296 }
2297 else
2298 {
2299 if (dest_regs[0]->unit == UNIT_D0)
2300 unit_bit = 0;
2301 else if (dest_regs[0]->unit == UNIT_D1)
2302 unit_bit = 1;
2303 }
2304
2305 if ((MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR ||
2306 MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
2307 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) &&
2308 ((template->meta_opcode >> 2) & 0x1))
2309 o1z = 1;
2310
2311 if (imm)
2312 {
2313 if (!cond)
2314 {
2315 if (is_addr_op)
2316 {
2317 if (dest_regs[0]->unit == UNIT_A0)
2318 unit_bit = 0;
2319 else if (dest_regs[0]->unit == UNIT_A1)
2320 unit_bit = 1;
2321 else
2322 return NULL;
2323 }
2324 else
2325 {
2326 if (dest_regs[0]->unit == UNIT_D0)
2327 unit_bit = 0;
2328 else if (dest_regs[0]->unit == UNIT_D1)
2329 unit_bit = 1;
2330 else
2331 return NULL;
2332 }
2333 }
2334
2335 if (cond)
2336 {
2337 l = parse_gp_regs (l, src_regs, 1);
2338
2339 if (l == NULL)
2340 return NULL;
2341
2342 l = skip_comma (l);
2343
2344 if (l == NULL ||
2345 *l == END_OF_INSN)
2346 return NULL;
2347
2348 if (is_addr_op)
2349 {
2350 if (src_regs[0]->unit == UNIT_A0)
2351 unit_bit = 0;
2352 else if (src_regs[0]->unit == UNIT_A1)
2353 unit_bit = 1;
2354 else
2355 return NULL;
2356 }
2357 else
2358 {
2359 if (src_regs[0]->unit == UNIT_D0)
2360 unit_bit = 0;
2361 else if (src_regs[0]->unit == UNIT_D1)
2362 unit_bit = 1;
2363 else
2364 return NULL;
2365 }
2366
2367 if (src_regs[0]->unit != dest_regs[0]->unit && !ca)
2368 return NULL;
2369
2370 l = parse_imm8 (l, insn, &value);
2371
2372 if (l == NULL)
2373 return NULL;
2374
2375 if (!within_unsigned_range (value, IMM8_BITS))
2376 return NULL;
2377
2378 insn->bits = (template->meta_opcode |
2379 (dest_regs[0]->no << 19) |
2380 (src_regs[0]->no << 14) |
2381 ((value & IMM8_MASK) << 6));
2382
2383 if (ca)
2384 {
2385 if (is_addr_op)
2386 {
2387 if (src_regs[0]->unit == UNIT_A0)
2388 unit_bit = 0;
2389 else if (src_regs[0]->unit == UNIT_A1)
2390 unit_bit = 1;
2391 else
2392 return NULL;
2393 }
2394 else
2395 {
2396 if (src_regs[0]->unit == UNIT_D0)
2397 unit_bit = 0;
2398 else if (src_regs[0]->unit == UNIT_D1)
2399 unit_bit = 1;
2400 else
2401 return NULL;
2402 }
2403
2404 insn->bits |= dest_regs[0]->unit << 1;
2405 }
2406 }
2407 else if (o1z)
2408 {
2409 l = parse_imm16 (l, insn, &value);
2410
2411 if (l == NULL)
2412 return NULL;
2413
2414 if (value < 0)
2415 {
2416 if (!within_signed_range (value, IMM16_BITS))
2417 {
2418 as_bad (_("immediate out of range"));
2419 return NULL;
2420 }
2421 sign_extend = 1;
2422 }
2423 else
2424 {
2425 if (!within_unsigned_range (value, IMM16_BITS))
2426 {
2427 as_bad (_("immediate out of range"));
2428 return NULL;
2429 }
2430 }
2431
2432 insn->bits = (template->meta_opcode |
2433 (dest_regs[0]->no << 19) |
2434 ((value & IMM16_MASK) << 3));
2435 }
2436 else
2437 {
2438 l = parse_gp_regs (l, src_regs, 1);
2439
2440 if (l == NULL)
2441 return NULL;
2442
2443 if (!(src_regs[0]->unit == dest_regs[0]->unit))
2444 return NULL;
2445
2446 /* CPC is valid for address ops. */
2447 if (src_regs[0]->no != dest_regs[0]->no &&
2448 !(is_addr_op && src_regs[0]->no == 0x10))
2449 return NULL;
2450
2451 l = skip_comma (l);
2452
2453 if (l == NULL ||
2454 *l == END_OF_INSN)
2455 return NULL;
2456
2457 l = parse_imm16 (l, insn, &value);
2458
2459 if (l == NULL)
2460 return NULL;
2461
2462 if (value < 0)
2463 {
2464 if (!within_signed_range (value, IMM16_BITS))
2465 {
2466 as_bad (_("immediate out of range"));
2467 return NULL;
2468 }
2469 sign_extend = 1;
2470 }
2471 else
2472 {
2473 if (!within_unsigned_range (value, IMM16_BITS))
2474 {
2475 as_bad (_("immediate out of range"));
2476 return NULL;
2477 }
2478 }
2479
2480 insn->bits = (template->meta_opcode |
2481 (dest_regs[0]->no << 19) |
2482 (src_regs[0]->no << 19) |
2483 ((value & IMM16_MASK) << 3));
2484 }
2485 }
2486 else
2487 {
2488 unsigned int o2r = 0;
2489 int rs2;
2490
2491 if (cond || !o1z)
2492 l = parse_gp_regs (l, src_regs, 2);
2493 else
2494 l = parse_gp_regs (l, src_regs, 1);
2495
2496 if (l == NULL)
2497 return NULL;
2498
2499 if (cond || !o1z)
2500 {
2501 if (is_addr_op)
2502 {
2503 if (src_regs[0]->unit == UNIT_A0)
2504 unit_bit = 0;
2505 else if (src_regs[0]->unit == UNIT_A1)
2506 unit_bit = 1;
2507 else
2508 return NULL;
2509 }
2510 else
2511 {
2512 if (src_regs[0]->unit == UNIT_D0)
2513 unit_bit = 0;
2514 else if (src_regs[0]->unit == UNIT_D1)
2515 unit_bit = 1;
2516 else
2517 return NULL;
2518 }
2519 }
2520 else
2521 {
2522 if (is_addr_op)
2523 {
2524 if (dest_regs[0]->unit == UNIT_A0)
2525 unit_bit = 0;
2526 else if (dest_regs[0]->unit == UNIT_A1)
2527 unit_bit = 1;
2528 else
2529 return NULL;
2530 }
2531 else
2532 {
2533 if (dest_regs[0]->unit == UNIT_D0)
2534 unit_bit = 0;
2535 else if (dest_regs[0]->unit == UNIT_D1)
2536 unit_bit = 1;
2537 else
2538 return NULL;
2539 }
2540 }
2541
2542 if (cond)
2543 {
2544 if (src_regs[0]->unit != src_regs[1]->unit)
2545 {
2546 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);
2547
2548 if (rs2 < 0)
2549 return NULL;
2550
2551 o2r = 1;
2552 }
2553 else
2554 {
2555 rs2 = src_regs[1]->no;
2556 }
2557
2558 insn->bits = (template->meta_opcode |
2559 (dest_regs[0]->no << 19) |
2560 (src_regs[0]->no << 14) |
2561 (rs2 << 9));
2562
2563 if (is_mul)
2564 {
2565 if (dest_regs[0]->unit != src_regs[0]->unit && is_mul)
2566 {
2567 if (ca)
2568 {
2569 insn->bits |= dest_regs[0]->unit << 1;
2570 }
2571 else
2572 return NULL;
2573 }
2574 }
2575 else
2576 insn->bits |= dest_regs[0]->unit << 5;
2577 }
2578 else if (o1z)
2579 {
2580 if (dest_regs[0]->unit != src_regs[0]->unit)
2581 {
2582 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[0]);
2583
2584 if (rs2 < 0)
2585 return NULL;
2586
2587 o2r = 1;
2588 }
2589 else
2590 {
2591 rs2 = src_regs[0]->no;
2592 }
2593
2594 insn->bits = (template->meta_opcode |
2595 (dest_regs[0]->no << 19) |
2596 (rs2 << 9));
2597 }
2598 else
2599 {
2600 if (dest_regs[0]->unit != src_regs[0]->unit)
2601 return NULL;
2602
2603 if (dest_regs[0]->unit != src_regs[1]->unit)
2604 {
2605 rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);
2606
2607 if (rs2 < 0)
2608 return NULL;
2609
2610 o2r = 1;
2611 }
2612 else
2613 {
2614 rs2 = src_regs[1]->no;
2615 }
2616
2617 insn->bits = (template->meta_opcode |
2618 (dest_regs[0]->no << 19) |
2619 (src_regs[0]->no << 14) |
2620 (rs2 << 9));
2621 }
2622
2623 if (o2r)
2624 insn->bits |= 1;
2625 }
2626
2627 if (is_quickrot)
2628 {
2629 const metag_reg *qr_regs[1];
2630 bfd_boolean limit_regs = imm && cond;
2631
2632 l = skip_comma (l);
2633
2634 if (l == NULL ||
2635 *l == END_OF_INSN)
2636 return NULL;
2637
2638 l = parse_gp_regs (l, qr_regs, 1);
2639
2640 if (l == NULL)
2641 return NULL;
2642
2643 if (!((unit_bit == 0 && qr_regs[0]->unit != UNIT_A0) ||
2644 !(unit_bit == 1 && qr_regs[0]->unit != UNIT_A1)))
2645 {
2646 as_bad (_("invalid quickrot unit specified"));
2647 return NULL;
2648 }
2649
2650 switch (qr_regs[0]->no)
2651 {
2652 case 2:
2653 break;
2654 case 3:
2655 if (!limit_regs)
2656 {
2657 insn->bits |= (1 << 7);
2658 break;
2659 }
2660 default:
2661 as_bad (_("invalid quickrot register specified"));
2662 return NULL;
2663 }
2664 }
2665
2666 if (sign_extend == 1 && top == 0)
2667 insn->bits |= (1 << 1);
2668
2669 insn->bits |= unit_bit << 24;
2670 insn->len = 4;
2671 return l;
2672 }
2673
2674 /* Parse a B instruction. */
2675 static const char *
2676 parse_branch (const char *line, metag_insn *insn,
2677 const insn_template *template)
2678 {
2679 const char *l = line;
2680 int value = 0;
2681
2682 l = parse_imm19 (l, insn, &value);
2683
2684 if (l == NULL)
2685 return NULL;
2686
2687 if (!within_signed_range (value / 4, IMM19_BITS))
2688 {
2689 as_bad (_("target out of range"));
2690 return NULL;
2691 }
2692
2693 insn->bits = (template->meta_opcode |
2694 ((value & IMM19_MASK) << 5));
2695
2696 insn->len = 4;
2697 return l;
2698 }
2699
2700 /* Parse a KICK instruction. */
2701 static const char *
2702 parse_kick (const char *line, metag_insn *insn,
2703 const insn_template *template)
2704 {
2705 const char *l = line;
2706 const metag_reg *regs[2];
2707
2708 l = parse_gp_regs (l, regs, 2);
2709
2710 if (l == NULL)
2711 return NULL;
2712
2713 if (regs[1]->unit != UNIT_TR)
2714 {
2715 as_bad (_("source register must be in the trigger unit"));
2716 return NULL;
2717 }
2718
2719 insn->bits = (template->meta_opcode |
2720 (regs[1]->no << 19) |
2721 (regs[0]->no << 14) |
2722 (regs[0]->unit << 5));
2723
2724 insn->len = 4;
2725 return l;
2726 }
2727
2728 /* Parse a SWITCH instruction. */
2729 static const char *
2730 parse_switch (const char *line, metag_insn *insn,
2731 const insn_template *template)
2732 {
2733 const char *l = line;
2734 int value = 0;
2735
2736 l = parse_imm_constant (l, insn, &value);
2737
2738 if (l == NULL)
2739 return NULL;
2740
2741 if (!within_unsigned_range (value, IMM24_BITS))
2742 {
2743 as_bad (_("target out of range"));
2744 return NULL;
2745 }
2746
2747 insn->bits = (template->meta_opcode |
2748 (value & IMM24_MASK));
2749
2750 insn->len = 4;
2751 return l;
2752 }
2753
2754 /* Parse a shift instruction. */
2755 static const char *
2756 parse_shift (const char *line, metag_insn *insn,
2757 const insn_template *template)
2758 {
2759 const char *l = line;
2760 const metag_reg *regs[2];
2761 const metag_reg *src2_regs[1];
2762 int value = 0;
2763 unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2764 unsigned int ca = (template->meta_opcode >> 5) & 0x1;
2765 unsigned int unit_bit = 0;
2766
2767 l = parse_gp_regs (l, regs, 2);
2768
2769 if (l == NULL)
2770 return NULL;
2771
2772 l = skip_comma (l);
2773
2774 if (l == NULL ||
2775 *l == END_OF_INSN)
2776 return NULL;
2777
2778 if (regs[1]->unit == UNIT_D0)
2779 unit_bit = 0;
2780 else if (regs[1]->unit == UNIT_D1)
2781 unit_bit = 1;
2782 else
2783 return NULL;
2784
2785 if (regs[0]->unit != regs[1]->unit && !(cond && ca))
2786 return NULL;
2787
2788 if (*l == '#')
2789 {
2790 l = parse_imm_constant (l, insn, &value);
2791
2792 if (l == NULL)
2793 return NULL;
2794
2795 if (!within_unsigned_range (value, IMM5_BITS))
2796 return NULL;
2797
2798 insn->bits = (template->meta_opcode |
2799 (1 << 25) |
2800 (regs[0]->no << 19) |
2801 (regs[1]->no << 14) |
2802 ((value & IMM5_MASK) << 9));
2803 }
2804 else
2805 {
2806 l = parse_gp_regs (l, src2_regs, 1);
2807
2808 if (l == NULL)
2809 return NULL;
2810
2811 insn->bits = (template->meta_opcode |
2812 (regs[0]->no << 19) |
2813 (regs[1]->no << 14) |
2814 (src2_regs[0]->no << 9));
2815
2816 if (src2_regs[0]->unit != regs[1]->unit)
2817 {
2818 as_bad(_("Source registers must be in the same unit"));
2819 return NULL;
2820 }
2821 }
2822
2823 if (regs[0]->unit != regs[1]->unit)
2824 {
2825 if (cond && ca)
2826 {
2827 if (regs[1]->unit == UNIT_D0)
2828 unit_bit = 0;
2829 else if (regs[1]->unit == UNIT_D1)
2830 unit_bit = 1;
2831 else
2832 return NULL;
2833
2834 insn->bits |= ((1 << 5) |
2835 (regs[0]->unit << 1));
2836 }
2837 else
2838 return NULL;
2839 }
2840
2841 insn->bits |= unit_bit << 24;
2842 insn->len = 4;
2843 return l;
2844 }
2845
2846 /* Parse a MIN or MAX instruction. */
2847 static const char *
2848 parse_min_max (const char *line, metag_insn *insn,
2849 const insn_template *template)
2850 {
2851 const char *l = line;
2852 const metag_reg *regs[3];
2853
2854 l = parse_gp_regs (l, regs, 3);
2855
2856 if (l == NULL)
2857 return NULL;
2858
2859 if (!(regs[0]->unit == UNIT_D0 ||
2860 regs[0]->unit == UNIT_D1))
2861 return NULL;
2862
2863 if (!(regs[0]->unit == regs[1]->unit &&
2864 regs[1]->unit == regs[2]->unit))
2865 return NULL;
2866
2867 insn->bits = (template->meta_opcode |
2868 (regs[0]->no << 19) |
2869 (regs[1]->no << 14) |
2870 (regs[2]->no << 9));
2871
2872 if (regs[0]->unit == UNIT_D1)
2873 insn->bits |= (1 << 24);
2874
2875 insn->len = 4;
2876 return l;
2877 }
2878
2879 /* Parse a bit operation instruction. */
2880 static const char *
2881 parse_bitop (const char *line, metag_insn *insn,
2882 const insn_template *template)
2883 {
2884 const char *l = line;
2885 const metag_reg *regs[2];
2886 unsigned int swap_inst = MAJOR_OPCODE (template->meta_opcode) == OPC_MISC;
2887 unsigned int is_bexl = 0;
2888
2889 if (swap_inst &&
2890 ((template->meta_opcode >> 1) & 0xb) == 0xa)
2891 is_bexl = 1;
2892
2893 l = parse_gp_regs (l, regs, 2);
2894
2895 if (l == NULL)
2896 return NULL;
2897
2898 if (!(regs[0]->unit == UNIT_D0 ||
2899 regs[0]->unit == UNIT_D1))
2900 return NULL;
2901
2902 if (is_bexl)
2903 {
2904 if (regs[0]->unit == UNIT_D0 &&
2905 regs[1]->unit != UNIT_D1)
2906 return NULL;
2907 else if (regs[0]->unit == UNIT_D1 &&
2908 regs[1]->unit != UNIT_D0)
2909 return NULL;
2910 }
2911 else if (!(regs[0]->unit == regs[1]->unit))
2912 return NULL;
2913
2914 insn->bits = (template->meta_opcode |
2915 (regs[0]->no << 19) |
2916 (regs[1]->no << 14));
2917
2918 if (swap_inst)
2919 {
2920 if (regs[1]->unit == UNIT_D1)
2921 insn->bits |= 1;
2922 }
2923 else
2924 {
2925 if (regs[1]->unit == UNIT_D1)
2926 insn->bits |= (1 << 24);
2927 }
2928
2929 insn->len = 4;
2930 return l;
2931 }
2932
2933 /* Parse a CMP or TST instruction. */
2934 static const char *
2935 parse_cmp (const char *line, metag_insn *insn,
2936 const insn_template *template)
2937 {
2938 const char *l = line;
2939 const metag_reg *dest_regs[1];
2940 const metag_reg *src_regs[1];
2941 int value = 0;
2942 unsigned int imm = (template->meta_opcode >> 25) & 0x1;
2943 unsigned int cond = (template->meta_opcode >> 26) & 0x1;
2944 unsigned int top = template->meta_opcode & 0x1;
2945 unsigned int sign_extend = 0;
2946 unsigned int unit_bit = 0;
2947
2948 l = parse_gp_regs (l, dest_regs, 1);
2949
2950 if (l == NULL)
2951 return NULL;
2952
2953 l = skip_comma (l);
2954
2955 if (l == NULL ||
2956 *l == END_OF_INSN)
2957 return NULL;
2958
2959 if (dest_regs[0]->unit == UNIT_D0)
2960 unit_bit = 0;
2961 else if (dest_regs[0]->unit == UNIT_D1)
2962 unit_bit = 1;
2963 else
2964 return NULL;
2965
2966 if (imm)
2967 {
2968 if (cond)
2969 {
2970 l = parse_imm_constant (l, insn, &value);
2971
2972 if (l == NULL)
2973 return NULL;
2974
2975 if (!within_unsigned_range (value, IMM8_BITS))
2976 return NULL;
2977
2978 insn->bits = (template->meta_opcode |
2979 (dest_regs[0]->no << 14) |
2980 ((value & IMM8_MASK) << 6));
2981
2982 }
2983 else
2984 {
2985 l = parse_imm16 (l, insn, &value);
2986
2987 if (l == NULL)
2988 return NULL;
2989
2990 if (value < 0)
2991 {
2992 if (!within_signed_range (value, IMM16_BITS))
2993 {
2994 as_bad (_("immediate out of range"));
2995 return NULL;
2996 }
2997 sign_extend = 1;
2998 }
2999 else
3000 {
3001 if (!within_unsigned_range (value, IMM16_BITS))
3002 {
3003 as_bad (_("immediate out of range"));
3004 return NULL;
3005 }
3006 }
3007
3008 insn->bits = (template->meta_opcode |
3009 (dest_regs[0]->no << 19) |
3010 ((value & IMM16_MASK) << 3));
3011 }
3012 }
3013 else
3014 {
3015 unsigned int o2r = 0;
3016 int rs2;
3017
3018 l = parse_gp_regs (l, src_regs, 1);
3019
3020 if (l == NULL)
3021 return NULL;
3022
3023 if (dest_regs[0]->unit != src_regs[0]->unit)
3024 {
3025 rs2 = lookup_o2r (0, unit_bit, src_regs[0]);
3026
3027 if (rs2 < 0)
3028 return NULL;
3029
3030 o2r = 1;
3031 }
3032 else
3033 {
3034 rs2 = src_regs[0]->no;
3035 }
3036
3037 insn->bits = (template->meta_opcode |
3038 (dest_regs[0]->no << 14) |
3039 (rs2 << 9));
3040
3041 if (o2r)
3042 insn->bits |= 1;
3043 }
3044
3045 if (sign_extend == 1 && top == 0)
3046 insn->bits |= (1 << 1);
3047
3048 insn->bits |= unit_bit << 24;
3049 insn->len = 4;
3050 return l;
3051 }
3052
3053 /* Parse a CACHEW instruction. */
3054 static const char *
3055 parse_cachew (const char *line, metag_insn *insn,
3056 const insn_template *template)
3057 {
3058 const char *l = line;
3059 const metag_reg *src_regs[2];
3060 unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
3061 metag_addr addr;
3062 int offset;
3063
3064 memset(&addr, 0, sizeof(addr));
3065 addr.reloc_type = BFD_RELOC_UNUSED;
3066
3067 l = parse_addr (l, &addr, size);
3068
3069 if (l == NULL ||
3070 !is_short_unit (addr.base_reg->unit) ||
3071 addr.update ||
3072 !addr.immediate)
3073 {
3074 as_bad (_("invalid memory operand"));
3075 return NULL;
3076 }
3077
3078 l = skip_comma (l);
3079
3080 if (l == NULL ||
3081 *l == END_OF_INSN)
3082 return NULL;
3083
3084 if (size == 4)
3085 l = parse_gp_regs (l, src_regs, 1);
3086 else
3087 l = parse_pair_gp_regs (l, src_regs);
3088
3089 if (l == NULL ||
3090 !is_short_unit (src_regs[0]->unit))
3091 {
3092 as_bad (_("invalid source register"));
3093 return NULL;
3094 }
3095
3096 offset = addr.exp.X_add_number;
3097
3098 if (addr.negate)
3099 offset = -offset;
3100
3101 offset = offset / 64;
3102
3103 if (!within_signed_range (offset, GET_SET_IMM_BITS))
3104 {
3105 as_bad (_("offset value out of range"));
3106 return NULL;
3107 }
3108
3109 insn->bits = (template->meta_opcode |
3110 (src_regs[0]->no << 19) |
3111 (addr.base_reg->no << 14) |
3112 ((offset & GET_SET_IMM_MASK) << 8) |
3113 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3114 ((src_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3115
3116 insn->len = 4;
3117 return l;
3118 }
3119
3120 /* Parse a CACHEW instruction. */
3121 static const char *
3122 parse_cacher (const char *line, metag_insn *insn,
3123 const insn_template *template)
3124 {
3125 const char *l = line;
3126 const metag_reg *dest_regs[2];
3127 unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
3128 metag_addr addr;
3129 int offset;
3130
3131 memset(&addr, 0, sizeof(addr));
3132 addr.reloc_type = BFD_RELOC_UNUSED;
3133
3134 if (size == 4)
3135 l = parse_gp_regs (l, dest_regs, 1);
3136 else
3137 l = parse_pair_gp_regs (l, dest_regs);
3138
3139 if (l == NULL ||
3140 !is_short_unit (dest_regs[0]->unit))
3141 {
3142 as_bad (_("invalid destination register"));
3143 return NULL;
3144 }
3145
3146 l = skip_comma (l);
3147
3148 if (l == NULL ||
3149 *l == END_OF_INSN)
3150 return NULL;
3151
3152 l = parse_addr (l, &addr, size);
3153
3154 if (l == NULL ||
3155 !is_short_unit (addr.base_reg->unit) ||
3156 addr.update ||
3157 !addr.immediate)
3158 {
3159 as_bad (_("invalid memory operand"));
3160 return NULL;
3161 }
3162
3163 offset = addr.exp.X_add_number;
3164
3165 if (addr.negate)
3166 offset = -offset;
3167
3168 offset = offset / (int)size;
3169
3170 if (!within_signed_range (offset, GET_SET_IMM_BITS))
3171 {
3172 as_bad (_("offset value out of range"));
3173 return NULL;
3174 }
3175
3176 insn->bits = (template->meta_opcode |
3177 (dest_regs[0]->no << 19) |
3178 (addr.base_reg->no << 14) |
3179 ((offset & GET_SET_IMM_MASK) << 8) |
3180 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3181 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3182
3183 insn->len = 4;
3184 return l;
3185 }
3186
3187 /* Parse an ICACHE instruction. */
3188 static const char *
3189 parse_icache (const char *line, metag_insn *insn,
3190 const insn_template *template)
3191 {
3192 const char *l = line;
3193 int offset;
3194 int pfcount;
3195
3196 l = parse_imm_constant (l, insn, &offset);
3197
3198 if (l == NULL)
3199 return NULL;
3200
3201 if (!within_signed_range (offset, IMM15_BITS))
3202 return NULL;
3203
3204 l = skip_comma (l);
3205
3206 l = parse_imm_constant (l, insn, &pfcount);
3207
3208 if (l == NULL)
3209 return NULL;
3210
3211 if (!within_unsigned_range (pfcount, IMM4_BITS))
3212 return NULL;
3213
3214 insn->bits = (template->meta_opcode |
3215 ((offset & IMM15_MASK) << 9) |
3216 ((pfcount & IMM4_MASK) << 1));
3217
3218 insn->len = 4;
3219 return l;
3220 }
3221
3222 /* Parse a LNKGET instruction. */
3223 static const char *
3224 parse_lnkget (const char *line, metag_insn *insn,
3225 const insn_template *template)
3226 {
3227 const char *l = line;
3228 const metag_reg *dest_regs[2];
3229 unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode);
3230 metag_addr addr;
3231 int offset;
3232
3233 memset(&addr, 0, sizeof(addr));
3234 addr.reloc_type = BFD_RELOC_UNUSED;
3235
3236 if (size == 8)
3237 l = parse_pair_gp_regs (l, dest_regs);
3238 else
3239 l = parse_gp_regs (l, dest_regs, 1);
3240
3241 if (l == NULL ||
3242 !is_short_unit (dest_regs[0]->unit))
3243 {
3244 as_bad (_("invalid destination register"));
3245 return NULL;
3246 }
3247
3248 l = skip_comma (l);
3249
3250 if (l == NULL ||
3251 *l == END_OF_INSN)
3252 return NULL;
3253
3254 l = parse_addr (l, &addr, size);
3255
3256 if (l == NULL ||
3257 !is_short_unit (addr.base_reg->unit) ||
3258 addr.update ||
3259 !addr.immediate)
3260 {
3261 as_bad (_("invalid memory operand"));
3262 return NULL;
3263 }
3264
3265 offset = addr.exp.X_add_number;
3266
3267 if (addr.negate)
3268 offset = -offset;
3269
3270 offset = offset / size;
3271
3272 if (!within_signed_range (offset, GET_SET_IMM_BITS))
3273 {
3274 as_bad (_("offset value out of range"));
3275 return NULL;
3276 }
3277
3278 insn->bits = (template->meta_opcode |
3279 (dest_regs[0]->no << 19) |
3280 (addr.base_reg->no << 14) |
3281 ((offset & GET_SET_IMM_MASK) << 8) |
3282 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
3283 ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));
3284
3285 insn->len = 4;
3286 return l;
3287 }
3288
3289 /* Parse an FPU MOV instruction. */
3290 static const char *
3291 parse_fmov (const char *line, metag_insn *insn,
3292 const insn_template *template)
3293 {
3294 const char *l = line;
3295 const metag_reg *regs[2];
3296
3297 l = parse_fpu_regs (l, regs, 2);
3298
3299 if (l == NULL)
3300 return NULL;
3301
3302 insn->bits = (template->meta_opcode |
3303 (regs[0]->no << 19) |
3304 (regs[1]->no << 14));
3305
3306 if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3307 insn->bits |= (1 << 5);
3308 else if (insn->fpu_width == FPU_WIDTH_PAIR)
3309 insn->bits |= (1 << 6);
3310
3311 insn->len = 4;
3312 return l;
3313 }
3314
3315 /* Parse an FPU MMOV instruction. */
3316 static const char *
3317 parse_fmmov (const char *line, metag_insn *insn,
3318 const insn_template *template)
3319 {
3320 const char *l = line;
3321 bfd_boolean to_fpu = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
3322 bfd_boolean is_mmovl = MINOR_OPCODE (template->meta_opcode) & 0x1;
3323 size_t regs_read = 0;
3324 const metag_reg *regs[16];
3325 unsigned int lowest_data_reg = 0xffffffff;
3326 unsigned int lowest_fpu_reg = 0xffffffff;
3327 unsigned int rmask = 0, data_unit;
3328 size_t i;
3329 int last_reg = -1;
3330
3331 if (insn->fpu_width != FPU_WIDTH_SINGLE)
3332 return NULL;
3333
3334 l = parse_gp_regs_list (l, regs, 16, &regs_read);
3335
3336 if (l == NULL)
3337 return NULL;
3338
3339 if (regs_read % 2)
3340 return NULL;
3341
3342 if (to_fpu)
3343 {
3344 for (i = 0; i < regs_read / 2; i++)
3345 {
3346 if (regs[i]->unit != UNIT_FX)
3347 return NULL;
3348
3349 if (last_reg == -1)
3350 {
3351 last_reg = regs[i]->no;
3352 lowest_fpu_reg = last_reg;
3353 }
3354 else
3355 {
3356 if (is_mmovl)
3357 {
3358 if (regs[i]->no != (unsigned int)(last_reg + 2))
3359 return NULL;
3360 }
3361 else if (regs[i]->no != (unsigned int)(last_reg + 1))
3362 return NULL;
3363
3364 last_reg = regs[i]->no;
3365 }
3366 }
3367
3368 if (regs[i]->unit == UNIT_D0)
3369 data_unit = 0;
3370 else if (regs[i]->unit == UNIT_D1)
3371 data_unit = 1;
3372 else
3373 return NULL;
3374
3375 if (!check_rmask (&regs[i], regs_read / 2, TRUE, FALSE, &lowest_data_reg,
3376 &rmask))
3377 return NULL;
3378 }
3379 else
3380 {
3381 if (regs[0]->unit == UNIT_D0)
3382 data_unit = 0;
3383 else if (regs[0]->unit == UNIT_D1)
3384 data_unit = 1;
3385 else
3386 return NULL;
3387
3388 if (!check_rmask (regs, regs_read / 2, TRUE, FALSE, &lowest_data_reg,
3389 &rmask))
3390 return NULL;
3391
3392 for (i = regs_read / 2; i < regs_read; i++)
3393 {
3394 if (regs[i]->unit != UNIT_FX)
3395 return NULL;
3396
3397 if (last_reg == -1)
3398 {
3399 last_reg = regs[i]->no;
3400 lowest_fpu_reg = last_reg;
3401 }
3402 else
3403 {
3404 if (is_mmovl)
3405 {
3406 if (regs[i]->no != (unsigned int)(last_reg + 2))
3407 return NULL;
3408 }
3409 else if (regs[i]->no != (unsigned int)(last_reg + 1))
3410 return NULL;
3411
3412 last_reg = regs[i]->no;
3413 }
3414 }
3415 }
3416
3417 insn->bits = (template->meta_opcode |
3418 ((lowest_data_reg & REG_MASK) << 19) |
3419 ((lowest_fpu_reg & REG_MASK) << 14) |
3420 ((rmask & RMASK_MASK) << 7) |
3421 data_unit);
3422
3423 insn->len = 4;
3424 return l;
3425 }
3426
3427 /* Parse an FPU data unit MOV instruction. */
3428 static const char *
3429 parse_fmov_data (const char *line, metag_insn *insn,
3430 const insn_template *template)
3431 {
3432 const char *l = line;
3433 unsigned int to_fpu = ((template->meta_opcode >> 7) & 0x1);
3434 const metag_reg *regs[2];
3435 unsigned int base_unit;
3436
3437 if (insn->fpu_width == FPU_WIDTH_PAIR)
3438 return NULL;
3439
3440 l = parse_gp_regs (l, regs, 2);
3441
3442 if (l == NULL)
3443 return NULL;
3444
3445 if (to_fpu)
3446 {
3447 if (regs[0]->unit != UNIT_FX)
3448 return NULL;
3449
3450 if (regs[1]->unit == UNIT_D0)
3451 base_unit = 0;
3452 else if (regs[1]->unit == UNIT_D1)
3453 base_unit = 1;
3454 else
3455 return NULL;
3456 }
3457 else
3458 {
3459 if (regs[0]->unit == UNIT_D0)
3460 base_unit = 0;
3461 else if (regs[0]->unit == UNIT_D1)
3462 base_unit = 1;
3463 else
3464 return NULL;
3465
3466 if (regs[1]->unit != UNIT_FX)
3467 return NULL;
3468 }
3469
3470 insn->bits = (template->meta_opcode |
3471 (base_unit << 24) |
3472 (regs[0]->no << 19) |
3473 (regs[1]->no << 9));
3474
3475 insn->len = 4;
3476 return l;
3477 }
3478
3479 /* Parse an FPU immediate MOV instruction. */
3480 static const char *
3481 parse_fmov_i (const char *line, metag_insn *insn,
3482 const insn_template *template)
3483 {
3484 const char *l = line;
3485 const metag_reg *regs[1];
3486 int value = 0;
3487
3488 l = parse_fpu_regs (l, regs, 1);
3489
3490 l = skip_comma (l);
3491
3492 if (l == NULL ||
3493 *l == END_OF_INSN)
3494 return NULL;
3495
3496 l = parse_imm16 (l, insn, &value);
3497
3498 if (l == NULL)
3499 return NULL;
3500
3501 insn->bits = (template->meta_opcode |
3502 (regs[0]->no << 19) |
3503 ((value & IMM16_MASK) << 3));
3504
3505 if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3506 insn->bits |= (1 << 1);
3507 else if (insn->fpu_width == FPU_WIDTH_PAIR)
3508 insn->bits |= (1 << 2);
3509
3510 insn->len = 4;
3511 return l;
3512 }
3513
3514 /* Parse an FPU PACK instruction. */
3515 static const char *
3516 parse_fpack (const char *line, metag_insn *insn,
3517 const insn_template *template)
3518 {
3519 const char *l = line;
3520 const metag_reg *regs[3];
3521
3522 l = parse_fpu_regs (l, regs, 3);
3523
3524 if (l == NULL)
3525 return NULL;
3526
3527 if (regs[0]->no % 2)
3528 {
3529 as_bad (_("destination register should be even numbered"));
3530 return NULL;
3531 }
3532
3533 insn->bits = (template->meta_opcode |
3534 (regs[0]->no << 19) |
3535 (regs[1]->no << 14) |
3536 (regs[2]->no << 9));
3537
3538 insn->len = 4;
3539 return l;
3540 }
3541
3542 /* Parse an FPU SWAP instruction. */
3543 static const char *
3544 parse_fswap (const char *line, metag_insn *insn,
3545 const insn_template *template)
3546 {
3547 const char *l = line;
3548 const metag_reg *regs[2];
3549
3550 if (insn->fpu_width != FPU_WIDTH_PAIR)
3551 return NULL;
3552
3553 l = parse_fpu_regs (l, regs, 2);
3554
3555 if (l == NULL)
3556 return NULL;
3557
3558 if (regs[0]->no % 2)
3559 return NULL;
3560
3561 if (regs[1]->no % 2)
3562 return NULL;
3563
3564 insn->bits = (template->meta_opcode |
3565 (regs[0]->no << 19) |
3566 (regs[1]->no << 14));
3567
3568 insn->len = 4;
3569 return l;
3570 }
3571
3572 /* Parse an FPU CMP instruction. */
3573 static const char *
3574 parse_fcmp (const char *line, metag_insn *insn,
3575 const insn_template *template)
3576 {
3577 const char *l = line, *l2;
3578 const metag_reg *regs1[1];
3579 const metag_reg *regs2[1];
3580
3581 l = parse_fpu_regs (l, regs1, 1);
3582
3583 l = skip_comma (l);
3584
3585 if (l == NULL ||
3586 *l == END_OF_INSN)
3587 return NULL;
3588
3589 l2 = parse_fpu_regs (l, regs2, 1);
3590
3591 if (l2 != NULL)
3592 {
3593 insn->bits = (regs2[0]->no << 9);
3594 }
3595 else
3596 {
3597 int constant = 0;
3598 l2 = parse_imm_constant (l, insn, &constant);
3599 if (!l2 || constant != 0)
3600 {
3601 as_bad (_("comparison must be with register or #0"));
3602 return NULL;
3603 }
3604 insn->bits = (1 << 8);
3605 }
3606
3607 insn->bits |= (template->meta_opcode |
3608 (regs1[0]->no << 14));
3609
3610 if (insn->fpu_action_flags & FPU_ACTION_ABS)
3611 insn->bits |= (1 << 19);
3612
3613 if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3614 insn->bits |= (1 << 7);
3615
3616 if (insn->fpu_width == FPU_WIDTH_PAIR)
3617 insn->bits |= (1 << 6);
3618 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3619 insn->bits |= (1 << 5);
3620
3621 insn->len = 4;
3622 return l2;
3623 }
3624
3625 /* Parse an FPU MIN or MAX instruction. */
3626 static const char *
3627 parse_fminmax (const char *line, metag_insn *insn,
3628 const insn_template *template)
3629 {
3630 const char *l = line;
3631 const metag_reg *regs[3];
3632
3633 l = parse_fpu_regs (l, regs, 3);
3634
3635 if (l == NULL)
3636 return NULL;
3637
3638 insn->bits = (template->meta_opcode |
3639 (regs[0]->no << 19) |
3640 (regs[1]->no << 14) |
3641 (regs[2]->no << 9));
3642
3643 if (insn->fpu_width == FPU_WIDTH_PAIR)
3644 insn->bits |= (1 << 6);
3645 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3646 insn->bits |= (1 << 5);
3647
3648 insn->len = 4;
3649 return l;
3650 }
3651
3652 /* Parse an FPU data conversion instruction. */
3653 static const char *
3654 parse_fconv (const char *line, metag_insn *insn,
3655 const insn_template *template)
3656 {
3657 const char *l = line;
3658 const metag_reg *regs[2];
3659
3660 if (insn->fpu_width == FPU_WIDTH_PAIR)
3661 {
3662 if (strncasecmp (template->name, "FTOH", 4) &&
3663 strncasecmp (template->name, "HTOF", 4) &&
3664 strncasecmp (template->name, "FTOI", 4) &&
3665 strncasecmp (template->name, "ITOF", 4))
3666 {
3667 as_bad (_("instruction cannot operate on pair values"));
3668 return NULL;
3669 }
3670 }
3671
3672 if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3673 {
3674 if (strncasecmp (template->name, "FTOI", 4) &&
3675 strncasecmp (template->name, "DTOI", 4) &&
3676 strncasecmp (template->name, "DTOL", 4))
3677 {
3678 as_bad (_("zero flag is not valid for this instruction"));
3679 return NULL;
3680 }
3681 }
3682
3683 l = parse_fpu_regs (l, regs, 2);
3684
3685 if (l == NULL)
3686 return NULL;
3687
3688 if (!strncasecmp (template->name, "DTOL", 4) ||
3689 !strncasecmp (template->name, "LTOD", 4))
3690 {
3691 if (regs[0]->no % 2)
3692 {
3693 as_bad (_("destination register should be even numbered"));
3694 return NULL;
3695 }
3696
3697 if (regs[1]->no % 2)
3698 {
3699 as_bad (_("source register should be even numbered"));
3700 return NULL;
3701 }
3702 }
3703
3704 insn->bits = (template->meta_opcode |
3705 (regs[0]->no << 19) |
3706 (regs[1]->no << 14));
3707
3708 if (insn->fpu_width == FPU_WIDTH_PAIR)
3709 insn->bits |= (1 << 6);
3710
3711 if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3712 insn->bits |= (1 << 12);
3713
3714 insn->len = 4;
3715 return l;
3716 }
3717
3718 /* Parse an FPU extended data conversion instruction. */
3719 static const char *
3720 parse_fconvx (const char *line, metag_insn *insn,
3721 const insn_template *template)
3722 {
3723 const char *l = line;
3724 const metag_reg *regs[2];
3725 int fraction_bits = 0;
3726
3727 if (insn->fpu_width == FPU_WIDTH_PAIR)
3728 {
3729 if (strncasecmp (template->name, "FTOX", 4) &&
3730 strncasecmp (template->name, "XTOF", 4))
3731 {
3732 as_bad (_("instruction cannot operate on pair values"));
3733 return NULL;
3734 }
3735 }
3736
3737 l = parse_fpu_regs (l, regs, 2);
3738
3739 l = skip_comma (l);
3740
3741 if (l == NULL ||
3742 *l == END_OF_INSN)
3743 return NULL;
3744
3745 l = parse_imm_constant (l, insn, &fraction_bits);
3746
3747 if (l == NULL)
3748 return NULL;
3749
3750 insn->bits = (template->meta_opcode |
3751 (regs[0]->no << 19) |
3752 (regs[1]->no << 14));
3753
3754 if (strncasecmp (template->name, "DTOXL", 5) &&
3755 strncasecmp (template->name, "XLTOD", 5))
3756 {
3757 if (!within_unsigned_range (fraction_bits, IMM5_BITS))
3758 {
3759 as_bad (_("fraction bits value out of range"));
3760 return NULL;
3761 }
3762 insn->bits |= ((fraction_bits & IMM5_MASK) << 9);
3763 }
3764 else
3765 {
3766 if (!within_unsigned_range (fraction_bits, IMM6_BITS))
3767 {
3768 as_bad (_("fraction bits value out of range"));
3769 return NULL;
3770 }
3771 insn->bits |= ((fraction_bits & IMM6_MASK) << 8);
3772 }
3773
3774 if (insn->fpu_width == FPU_WIDTH_PAIR)
3775 insn->bits |= (1 << 6);
3776
3777 insn->len = 4;
3778 return l;
3779 }
3780
3781 /* Parse an FPU basic arithmetic instruction. */
3782 static const char *
3783 parse_fbarith (const char *line, metag_insn *insn,
3784 const insn_template *template)
3785 {
3786 const char *l = line;
3787 const metag_reg *regs[3];
3788
3789 l = parse_fpu_regs (l, regs, 3);
3790
3791 if (l == NULL)
3792 return NULL;
3793
3794 insn->bits = (template->meta_opcode |
3795 (regs[0]->no << 19) |
3796 (regs[1]->no << 14) |
3797 (regs[2]->no << 9));
3798
3799 if (insn->fpu_width == FPU_WIDTH_PAIR)
3800 insn->bits |= (1 << 6);
3801 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3802 insn->bits |= (1 << 5);
3803
3804 if (insn->fpu_action_flags & FPU_ACTION_INV)
3805 insn->bits |= (1 << 7);
3806
3807 insn->len = 4;
3808 return l;
3809 }
3810
3811 /* Parse a floating point accumulator name. */
3812 static const char *
3813 parse_acf (const char *line, int *part)
3814 {
3815 const char *l = line;
3816 size_t i;
3817
3818 for (i = 0; i < sizeof(metag_acftab)/sizeof(metag_acftab[0]); i++)
3819 {
3820 const metag_acf *acf = &metag_acftab[i];
3821 size_t name_len = strlen (acf->name);
3822
3823 if (strncasecmp (l, acf->name, name_len) == 0)
3824 {
3825 l += name_len;
3826 *part = acf->part;
3827 return l;
3828 }
3829 }
3830 return NULL;
3831 }
3832
3833 /* Parse an FPU extended arithmetic instruction. */
3834 static const char *
3835 parse_fearith (const char *line, metag_insn *insn,
3836 const insn_template *template)
3837 {
3838 const char *l = line;
3839 const metag_reg *regs[3];
3840 bfd_boolean is_muz = (MINOR_OPCODE (template->meta_opcode) == 0x6 &&
3841 ((template->meta_opcode >> 4) & 0x1));
3842 unsigned int is_o3o = template->meta_opcode & 0x1;
3843 unsigned int is_mac = 0;
3844 unsigned int is_maw = 0;
3845
3846 if (!strncasecmp (template->name, "MAW", 3))
3847 is_maw = 1;
3848
3849 if (!strncasecmp (template->name, "MAC", 3))
3850 {
3851 int part;
3852 l = parse_acf (l, &part);
3853
3854 if (l == NULL || part != 0)
3855 return NULL;
3856
3857 l = skip_comma (l);
3858
3859 l = parse_fpu_regs (l, &regs[1], 2);
3860
3861 is_mac = 1;
3862 }
3863 else
3864 {
3865 if (is_o3o && is_maw)
3866 l = parse_fpu_regs (l, regs, 2);
3867 else
3868 l = parse_fpu_regs (l, regs, 3);
3869 }
3870
3871 if (l == NULL)
3872 return NULL;
3873
3874 if (is_o3o && is_maw)
3875 insn->bits = (template->meta_opcode |
3876 (regs[1]->no << 9));
3877 else
3878 insn->bits = (template->meta_opcode |
3879 (regs[1]->no << 14));
3880
3881 if (!(is_o3o && is_maw))
3882 insn->bits |= (regs[2]->no << 9);
3883
3884 if (is_o3o && is_maw)
3885 insn->bits |= (regs[0]->no << 14);
3886 else if (!is_mac)
3887 insn->bits |= (regs[0]->no << 19);
3888
3889 if (insn->fpu_width == FPU_WIDTH_PAIR)
3890 insn->bits |= (1 << 6);
3891 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3892 insn->bits |= (1 << 5);
3893
3894 if (!is_mac && !is_maw)
3895 if (insn->fpu_action_flags & FPU_ACTION_INV)
3896 insn->bits |= (1 << 7);
3897
3898 if (is_muz)
3899 if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3900 insn->bits |= (1 << 1);
3901
3902 insn->len = 4;
3903 return l;
3904 }
3905
3906 /* Parse an FPU RCP or RSQ instruction. */
3907 static const char *
3908 parse_frec (const char *line, metag_insn *insn,
3909 const insn_template *template)
3910 {
3911 const char *l = line;
3912 const metag_reg *regs[2];
3913
3914 l = parse_fpu_regs (l, regs, 2);
3915
3916 if (l == NULL)
3917 return NULL;
3918
3919 insn->bits = (template->meta_opcode |
3920 (regs[0]->no << 19) |
3921 (regs[1]->no << 14));
3922
3923 if (insn->fpu_width == FPU_WIDTH_PAIR)
3924 insn->bits |= (1 << 6);
3925 else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
3926 insn->bits |= (1 << 5);
3927
3928 if (insn->fpu_action_flags & FPU_ACTION_ZERO)
3929 insn->bits |= (1 << 10);
3930 else if (insn->fpu_action_flags & FPU_ACTION_QUIET)
3931 insn->bits |= (1 << 9);
3932
3933 if (insn->fpu_action_flags & FPU_ACTION_INV)
3934 insn->bits |= (1 << 7);
3935
3936 insn->len = 4;
3937 return l;
3938 }
3939
3940 /* Parse an FPU vector arithmetic instruction. */
3941 static const char *
3942 parse_fsimd (const char *line, metag_insn *insn,
3943 const insn_template *template)
3944 {
3945 const char *l = line;
3946 const metag_reg *regs[3];
3947
3948 if (insn->fpu_width != FPU_WIDTH_PAIR)
3949 {
3950 as_bad (_("simd instructions operate on pair values (L prefix)"));
3951 return NULL;
3952 }
3953
3954 l = parse_fpu_regs (l, regs, 3);
3955
3956 if (l == NULL)
3957 return NULL;
3958
3959 if (regs[0]->no % 2)
3960 {
3961 as_bad (_("destination register should be even numbered"));
3962 return NULL;
3963 }
3964
3965 if ((regs[1]->no % 2) ||
3966 (regs[2]->no % 2))
3967 {
3968 as_bad (_("source registers should be even numbered"));
3969 return NULL;
3970 }
3971
3972 insn->bits = (template->meta_opcode |
3973 (regs[0]->no << 19) |
3974 (regs[1]->no << 14) |
3975 (regs[2]->no << 9));
3976
3977 if (insn->fpu_action_flags & FPU_ACTION_INV)
3978 insn->bits |= (1 << 7);
3979
3980 insn->len = 4;
3981 return l;
3982 }
3983
3984 /* Parse an FPU accumulator GET or SET instruction. */
3985 static const char *
3986 parse_fget_set_acf (const char *line, metag_insn *insn,
3987 const insn_template *template)
3988 {
3989 const char *l = line;
3990 int part;
3991 metag_addr addr;
3992 bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
3993
3994 memset(&addr, 0, sizeof(addr));
3995 addr.reloc_type = BFD_RELOC_UNUSED;
3996
3997 if (is_get)
3998 {
3999 l = parse_acf (l, &part);
4000
4001 l = skip_comma (l);
4002
4003 if (l == NULL)
4004 return NULL;
4005
4006 l = parse_mget_mset_addr (l, &addr);
4007 }
4008 else
4009 {
4010 l = parse_mget_mset_addr (l, &addr);
4011
4012 l = skip_comma (l);
4013
4014 if (l == NULL)
4015 return NULL;
4016
4017 l = parse_acf (l, &part);
4018 }
4019
4020 if (l == NULL)
4021 return NULL;
4022
4023 insn->bits = (template->meta_opcode |
4024 (part << 19));
4025
4026 if (!is_short_unit (addr.base_reg->unit))
4027 {
4028 as_bad (_("base unit must be one of %s"), SHORT_UNITS);
4029 return NULL;
4030 }
4031
4032 insn->bits |= ((addr.base_reg->no << 14) |
4033 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
4034
4035 insn->len = 4;
4036 return l;
4037 }
4038
4039 /* Copy the name of the next register in LINE to REG_BUF. */
4040 static size_t
4041 strip_reg_name(const char *line, char *reg_buf)
4042 {
4043 const char *l = line;
4044 size_t len = 0;
4045
4046 while (is_register_char (*l))
4047 {
4048 reg_buf[len] = *l;
4049 l++;
4050 len++;
4051 if (!(len < MAX_REG_LEN))
4052 return 0;
4053 }
4054
4055 if (len)
4056 reg_buf[len] = '\0';
4057
4058 return len;
4059 }
4060
4061 /* Parse a DSP register from LINE into REG using only the registers
4062 from DSP_REGTAB. Return the next character or NULL. */
4063 static const char *
4064 __parse_dsp_reg (const char *line, const metag_reg **reg, htab_t dsp_regtab)
4065 {
4066 const char *l = line;
4067 char name[MAX_REG_LEN];
4068 size_t len = 0;
4069 metag_reg entry;
4070 const metag_reg *_reg;
4071
4072 /* We don't entirely strip the register name because we might
4073 actually want to match whole string in the register table,
4074 e.g. "D0AW.1++" not just "D0AW.1". The string length of the table
4075 entry limits our comaprison to a reasonable bound anyway. */
4076 while (is_register_char (*l) || *l == PLUS)
4077 {
4078 name[len] = *l;
4079 l++;
4080 len++;
4081 if (!(len < MAX_REG_LEN))
4082 return NULL;
4083 }
4084
4085 if (!len)
4086 return NULL;
4087
4088 name[len] = '\0';
4089 entry.name = name;
4090
4091 _reg = (const metag_reg *) htab_find (dsp_regtab, &entry);
4092 if (!_reg)
4093 return NULL;
4094
4095 *reg = _reg;
4096
4097 return l;
4098 }
4099
4100 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4101 member is suitable for encoding into a DSP insn register field. */
4102 static const char *
4103 parse_dsp_insn_reg (const char *line, const metag_reg **reg)
4104 {
4105 return __parse_dsp_reg (line, reg, dsp_reg_htab);
4106 }
4107
4108 /* Parse a DSP register and setup "reg" with a metag_reg whose "no"
4109 member is suitable for encoding into a DSP template definition insn
4110 register field.
4111
4112 There is a separate table for whether we're doing a load or a store
4113 definition. "load" specifies which table to look at. */
4114 static const char *
4115 parse_dsp_template_reg (const char *line, const metag_reg **reg,
4116 bfd_boolean load)
4117 {
4118 return __parse_dsp_reg (line, reg, dsp_tmpl_reg_htab[load]);
4119 }
4120
4121 /* Parse a single DSP register from LINE. */
4122 static const char *
4123 parse_dsp_reg (const char *line, const metag_reg **reg,
4124 bfd_boolean tmpl, bfd_boolean load)
4125 {
4126 if (tmpl)
4127 return parse_dsp_template_reg (line, reg, load);
4128 else
4129 return parse_dsp_insn_reg (line, reg);
4130 }
4131
4132 /* Return TRUE if UNIT is an address unit. */
4133 static bfd_boolean
4134 is_addr_unit (enum metag_unit unit)
4135 {
4136 switch (unit)
4137 {
4138 case UNIT_A0:
4139 case UNIT_A1:
4140 return TRUE;
4141 default:
4142 return FALSE;
4143 }
4144 }
4145
4146 /* Return TRUE if UNIT1 and UNIT2 are equivalent units. */
4147 static bfd_boolean
4148 is_same_data_unit (enum metag_unit unit1, enum metag_unit unit2)
4149 {
4150 if (unit1 == unit2)
4151 return TRUE;
4152
4153 switch (unit1)
4154 {
4155 case UNIT_D0:
4156 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0)
4157 return TRUE;
4158 break;
4159 case UNIT_D1:
4160 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1)
4161 return TRUE;
4162 break;
4163 case UNIT_ACC_D0:
4164 if (unit2 == UNIT_D0 || unit2 == UNIT_RAM_D0)
4165 return TRUE;
4166 break;
4167 case UNIT_ACC_D1:
4168 if (unit2 == UNIT_D1 || unit2 == UNIT_RAM_D1)
4169 return TRUE;
4170 break;
4171 case UNIT_RAM_D0:
4172 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_D0)
4173 return TRUE;
4174 break;
4175 case UNIT_RAM_D1:
4176 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_D1)
4177 return TRUE;
4178 break;
4179 default:
4180 return FALSE;
4181 }
4182
4183 return FALSE;
4184 }
4185
4186 /* Return TRUE if the register NUM is a quickrot control register. */
4187 static bfd_boolean
4188 is_quickrot_reg (unsigned int num)
4189 {
4190 switch (num)
4191 {
4192 case 2:
4193 case 3:
4194 return TRUE;
4195 }
4196
4197 return FALSE;
4198 }
4199
4200 /* Return TRUE if REG is an accumulator register. */
4201 static bfd_boolean
4202 is_accumulator_reg (const metag_reg *reg)
4203 {
4204 if (reg->unit == UNIT_ACC_D0 || reg->unit == UNIT_ACC_D1)
4205 return TRUE;
4206
4207 return FALSE;
4208 }
4209
4210 /* Return TRUE if REG is a DSP RAM register. */
4211 static bfd_boolean
4212 is_dspram_reg (const metag_reg *reg)
4213 {
4214 if (reg->unit == UNIT_RAM_D0 || reg->unit == UNIT_RAM_D1)
4215 return TRUE;
4216
4217 return FALSE;
4218 }
4219
4220 static const char *
4221 __parse_gp_reg (const char *line, const metag_reg **reg, bfd_boolean load)
4222 {
4223 const char *l = line;
4224 char reg_buf[MAX_REG_LEN];
4225 size_t len = 0;
4226
4227 if (l == NULL)
4228 return NULL;
4229
4230 /* Parse [DSPRAM.x]. */
4231 if (*l == ADDR_BEGIN_CHAR)
4232 {
4233 l++;
4234
4235 if (l == NULL)
4236 return NULL;
4237
4238 l = parse_dsp_reg (l, reg, TRUE, load);
4239 if (l == NULL)
4240 return NULL;
4241
4242 if (*l == ADDR_END_CHAR)
4243 l++;
4244 else
4245 {
4246 as_bad (_("expected ']', not %c in %s"), *l, l);
4247 return NULL;
4248 }
4249
4250 return l;
4251 }
4252 else
4253 {
4254
4255 len = strip_reg_name (l, reg_buf);
4256 if (!len)
4257 return NULL;
4258
4259 l += len;
4260 *reg = parse_gp_reg (reg_buf);
4261 if (*reg == NULL)
4262 return NULL;
4263 }
4264
4265 return l;
4266 }
4267
4268 /* Parse a list of DSP/GP registers. TRY_GP indicates whether we
4269 should try to parse the register as a general-purpose register if
4270 we fail to parse it as a DSP one. TMPL indicates whether the
4271 registers are part of a template definition instruction. If this is
4272 a template definition instruction LOAD says whether it's a load
4273 template insn. FIRST_DST indicates whether the first register is
4274 a destination operand. */
4275 static const char *
4276 parse_dsp_regs_list (const char *line, const metag_reg **regs, size_t count,
4277 size_t *regs_read, bfd_boolean try_gp, bfd_boolean tmpl,
4278 bfd_boolean load, bfd_boolean first_dst)
4279 {
4280 const char *l = line;
4281 int seen_regs = 0;
4282 size_t i;
4283 const metag_reg *reg;
4284
4285 for (i = 0; i < count; i++)
4286 {
4287 const char *next, *ll;
4288
4289 next = l;
4290
4291 if (i > 0)
4292 {
4293 l = skip_comma (l);
4294 if (l == NULL)
4295 {
4296 *regs_read = seen_regs;
4297 return next;
4298 }
4299 }
4300
4301 ll = parse_dsp_reg (l, &reg, tmpl, load);
4302
4303 if (!ll)
4304 {
4305 if (try_gp)
4306 {
4307 l = __parse_gp_reg (l, &reg, !(first_dst && i == 0));
4308 if (l == NULL)
4309 {
4310 *regs_read = seen_regs;
4311 return next;
4312 }
4313 regs[i] = reg;
4314 seen_regs++;
4315 }
4316 else
4317 {
4318 *regs_read = seen_regs;
4319 return l;
4320 }
4321 }
4322 else
4323 {
4324 regs[i] = reg;
4325 seen_regs++;
4326 l = ll;
4327 }
4328 }
4329
4330 *regs_read = seen_regs;
4331 return l;
4332 }
4333
4334 /* Parse the following memory references:
4335
4336 - [Ax.r]
4337 - [Ax.r++]
4338 - [Ax.r--]
4339 - [Ax.r+Ax.r++]
4340 - [Ax.r-Ax.r--]
4341
4342 - [DSPRam]
4343 - [DSPRam++]
4344 - [DSPRam+DSPRam++]
4345 - [DSPRam-DSPRam--] */
4346 static const char *
4347 parse_dsp_addr (const char *line, metag_addr *addr, unsigned int size,
4348 bfd_boolean load)
4349 {
4350 const char *l = line, *ll;
4351 const metag_reg *regs[1];
4352 size_t regs_read;
4353
4354 /* Skip opening square bracket. */
4355 l++;
4356
4357 l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);
4358
4359 if (l == NULL)
4360 return NULL;
4361
4362 if (!is_addr_unit (regs[0]->unit) &&
4363 !is_dspram_reg (regs[0]))
4364 {
4365 as_bad (_("invalid register for memory access"));
4366 return NULL;
4367 }
4368
4369 addr->base_reg = regs[0];
4370
4371 if (*l == ADDR_END_CHAR)
4372 {
4373 addr->exp.X_op = O_constant;
4374 addr->exp.X_add_symbol = NULL;
4375 addr->exp.X_op_symbol = NULL;
4376
4377 /* Simple register with no offset (0 immediate). */
4378 addr->exp.X_add_number = 0;
4379
4380 addr->immediate = 1;
4381 l++;
4382
4383 return l;
4384 }
4385
4386 ll = parse_addr_post_incr_op (l, addr);
4387
4388 if (ll && *ll == ADDR_END_CHAR)
4389 {
4390 if (addr->update == 1)
4391 {
4392 /* We have a post increment/decrement. */
4393 addr->exp.X_op = O_constant;
4394 addr->exp.X_add_number = size;
4395 addr->exp.X_add_symbol = NULL;
4396 addr->exp.X_op_symbol = NULL;
4397 addr->post_increment = 1;
4398 }
4399 addr->immediate = 1;
4400 ll++;
4401 return ll;
4402 }
4403
4404 addr->post_increment = 0;
4405
4406 l = parse_addr_op (l, addr);
4407
4408 if (l == NULL)
4409 return NULL;
4410
4411 l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);
4412
4413 if (l == NULL)
4414 return NULL;
4415
4416 if (regs[0]->unit != addr->base_reg->unit)
4417 {
4418 as_bad (_("offset and base must be from the same unit"));
4419 return NULL;
4420 }
4421
4422 addr->offset_reg = regs[0];
4423
4424 if (*l == ADDR_END_CHAR)
4425 {
4426 l++;
4427 return l;
4428 }
4429
4430 l = parse_addr_post_incr_op (l, addr);
4431
4432 if (l == NULL)
4433 return NULL;
4434
4435 if (*l == ADDR_END_CHAR)
4436 {
4437 l++;
4438 return l;
4439 }
4440
4441 return NULL;
4442 }
4443
4444 /* Parse a DSP GET or SET instruction. */
4445 static const char *
4446 parse_dget_set (const char *line, metag_insn *insn,
4447 const insn_template *template)
4448 {
4449 const char *l = line;
4450 metag_addr addr;
4451 int unit = 0;
4452 int rd_reg = 0;
4453 bfd_boolean is_get = (template->meta_opcode & 0x100);
4454 bfd_boolean is_dual = (template->meta_opcode & 0x4);
4455 bfd_boolean is_template = FALSE;
4456 const metag_reg *regs[2];
4457 unsigned int size;
4458 size_t count, regs_read;
4459
4460 memset(&addr, 0, sizeof(addr));
4461 addr.reloc_type = BFD_RELOC_UNUSED;
4462
4463 size = is_dual ? 8 : 4;
4464 count = is_dual ? 2 : 1;
4465
4466 if (is_get)
4467 {
4468 /* GETL can be used on one template table entry. */
4469 if (*l == 'T')
4470 count = 1;
4471
4472 l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE,
4473 FALSE, FALSE, FALSE);
4474 l = skip_comma (l);
4475
4476 if (l == NULL)
4477 {
4478 as_bad (_("unexpected end of line"));
4479 return NULL;
4480 }
4481
4482 l = parse_addr (l, &addr, size);
4483 }
4484 else
4485 {
4486 l = parse_addr (l, &addr, size);
4487
4488 l = skip_comma (l);
4489
4490 if (l == NULL)
4491 return NULL;
4492
4493 /* GETL can be used on one template table entry. */
4494 if (*l == 'T')
4495 count = 1;
4496
4497 l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE, FALSE,
4498 FALSE, FALSE);
4499 }
4500
4501 if (l == NULL)
4502 return NULL;
4503
4504 /* The first register dictates the unit. */
4505 if (regs[0]->unit == UNIT_DT)
4506 is_template = TRUE;
4507 else
4508 {
4509 if (regs[0]->unit == UNIT_D0 || regs[0]->unit == UNIT_RAM_D0 ||
4510 regs[0]->unit == UNIT_ACC_D0)
4511 unit = 0;
4512 else
4513 unit = 1;
4514 }
4515
4516 rd_reg = regs[0]->no;
4517
4518 /* The 'H' modifier allows a DSP GET/SET instruction to target the
4519 upper 8-bits of an accumulator. It is _only_ valid for the
4520 accumulators. */
4521 if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH)
4522 {
4523 if (is_template || !(rd_reg >= 16 && rd_reg < 20))
4524 {
4525 as_bad (_("'H' modifier only valid for accumulator registers"));
4526 return NULL;
4527 }
4528
4529 /* Top 8-bits of the accumulator. */
4530 rd_reg |= 8;
4531 }
4532
4533 if (is_template)
4534 {
4535 insn->bits = (template->meta_opcode | (1 << 1));
4536 }
4537 else
4538 {
4539 insn->bits = (template->meta_opcode | unit);
4540 }
4541
4542 insn->bits |= (rd_reg << 19);
4543
4544 if (addr.immediate)
4545 {
4546 int offset = addr.exp.X_add_number;
4547
4548 if (addr.negate)
4549 offset = -offset;
4550
4551 offset = offset / (int)size;
4552
4553 if (!within_signed_range (offset, DGET_SET_IMM_BITS))
4554 {
4555 as_bad (_("offset value out of range"));
4556 return NULL;
4557 }
4558
4559 offset = offset & DGET_SET_IMM_MASK;
4560
4561 insn->bits |= (1 << 13);
4562 insn->bits |= (offset << 9);
4563 }
4564 else
4565 {
4566 int au = (addr.base_reg->unit == UNIT_A1);
4567
4568 insn->bits |= (au << 18);
4569 insn->bits |= ((addr.base_reg->no & REG_MASK) << 14);
4570 insn->bits |= ((addr.offset_reg->no & REG_MASK) << 9);
4571 }
4572
4573 if (is_dual)
4574 insn->bits |= (1 << 2);
4575
4576 if (!is_addr_unit (addr.base_reg->unit))
4577 {
4578 as_bad (_("base unit must be either A0 or A1"));
4579 return NULL;
4580 }
4581
4582 unit = (addr.base_reg->unit == UNIT_A0) ? 0 : 1;
4583 insn->bits |= ((addr.base_reg->no << 14) | (unit << 18));
4584
4585 insn->len = 4;
4586
4587 return l;
4588 }
4589
4590 /* Parse a DSP template instruction. */
4591 static const char *
4592 parse_dtemplate (const char *line, metag_insn *insn,
4593 const insn_template *template)
4594 {
4595 const char *l = line;
4596 const metag_reg *regs[TEMPLATE_NUM_REGS];
4597 bfd_boolean daop_only = FALSE;
4598 int regs_val[4];
4599 int regs_which[4] = { -1, -1, -1, -1}; /* Register or immediate? */
4600 int i;
4601
4602 for (i = 0; i < TEMPLATE_NUM_REGS; i++)
4603 {
4604 if (l == NULL)
4605 {
4606 as_bad (_("unexpected end of line"));
4607 return NULL;
4608 }
4609
4610 /* We may only have 3 register operands. */
4611 if (*l == END_OF_INSN && i == 3)
4612 {
4613 daop_only = TRUE;
4614 break;
4615 }
4616
4617 if (i != 0)
4618 {
4619 l = skip_comma (l);
4620 if (l == NULL)
4621 return NULL;
4622 }
4623
4624 if (*l == IMM_CHAR)
4625 {
4626 l = parse_imm_constant (l, insn, &regs_val[i]);
4627 if (l == NULL)
4628 {
4629 as_bad (_("invalid immediate"));
4630 return NULL;
4631 }
4632 regs_which[i] = 0;
4633 }
4634 else
4635 {
4636 /* We can't tell from the template instantiation whether
4637 this is a load or store. So we have to try looking up the
4638 register name in both the load and store tables. */
4639 const char *l2 = l;
4640 l = __parse_gp_reg (l, &regs[i], TRUE);
4641 if (l == NULL)
4642 {
4643 /* Try the store table too. */
4644 l = __parse_gp_reg (l2, &regs[i], FALSE);
4645 if (l == NULL)
4646 {
4647 /* Then try a DSP register. */
4648 l = parse_dsp_insn_reg (l2, &regs[i]);
4649 if (l == NULL || regs[i]->unit == UNIT_DT)
4650 {
4651 as_bad (_("invalid register"));
4652 return NULL;
4653 }
4654 }
4655 }
4656 regs_which[i] = 1;
4657 }
4658 }
4659
4660 insn->bits = template->meta_opcode;
4661
4662 if (regs_which[0] == 0)
4663 insn->bits |= (regs_val[0] << 19);
4664 else if (regs_which[0] == 1)
4665 insn->bits |= (regs[0]->no << 19);
4666
4667 if (regs_which[1] == 0)
4668 insn->bits |= (regs_val[1] << 14);
4669 else if (regs_which[1] == 1)
4670 insn->bits |= (regs[1]->no << 14);
4671
4672 if (regs_which[2] == 0)
4673 insn->bits |= (regs_val[2] << 9);
4674 else if (regs_which[2] == 1)
4675 insn->bits |= (regs[2]->no << 9);
4676
4677 if (regs_which[3] == 0)
4678 insn->bits |= (regs_val[3] << 4);
4679 else if (regs_which[3] == 1)
4680 insn->bits |= (regs[3]->no << 4);
4681
4682 /* DaOp only. */
4683 if (daop_only)
4684 insn->bits |= (0x3 << 24); /* Set the minor opcode. */
4685 else if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH) /* Half Load/Store. */
4686 insn->bits |= (0x5 << 24); /* Set the minor opcode. */
4687
4688 insn->len = 4;
4689
4690 return l;
4691 }
4692
4693 /* Parse a DSP Template definiton memory reference, e.g
4694 [A0.7+A0.5++]. DSPRAM is set to true by this function if this
4695 template definition is a DSP RAM template definition. */
4696 static const char *
4697 template_mem_ref(const char *line, metag_addr *addr,
4698 bfd_boolean *dspram, int size, bfd_boolean load)
4699 {
4700 const char *l = line;
4701
4702 l = parse_dsp_addr (l, addr, size, load);
4703
4704 if (l != NULL)
4705 {
4706 if (is_addr_unit(addr->base_reg->unit))
4707 *dspram = FALSE;
4708 else
4709 *dspram = TRUE;
4710 }
4711
4712 return l;
4713 }
4714
4715 /* Sets LOAD to TRUE if this is a Template load definiton (otherwise
4716 it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT. */
4717 static const char *
4718 parse_template_regs (const char *line, bfd_boolean *load,
4719 unsigned int *addr_unit,
4720 const metag_reg **template_reg, metag_addr *addr,
4721 bfd_boolean *dspram, int size)
4722 {
4723 const char *l = line;
4724
4725 if (l == NULL)
4726 return NULL;
4727
4728 /* DSP Template load definition (Tx, [Ax]) */
4729 if (*l == 'T')
4730 {
4731 *load = TRUE;
4732 l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
4733 if (l == NULL)
4734 return NULL;
4735
4736 l = skip_comma (l);
4737
4738 l = template_mem_ref (l, addr, dspram, size, *load);
4739
4740 if (addr->base_reg->unit == UNIT_A1)
4741 *addr_unit = 1;
4742
4743 }
4744 else if (*l == ADDR_BEGIN_CHAR) /* DSP Template store ([Ax], Tx) */
4745 {
4746 *load = FALSE;
4747 l = template_mem_ref (l, addr, dspram, size, *load);
4748 l = skip_comma(l);
4749
4750 if (l == NULL)
4751 return NULL;
4752
4753 l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
4754 if (l == NULL)
4755 return NULL;
4756
4757 if (addr->base_reg->unit == UNIT_A1)
4758 *addr_unit = 1;
4759 }
4760 else
4761 {
4762 as_bad (_("invalid register operand"));
4763 return NULL;
4764 }
4765
4766 return l;
4767 }
4768
4769 #define INVALID_SHIFT (-1)
4770
4771 static metag_reg _reg;
4772
4773 /* Parse a template instruction definition. */
4774 static const char *
4775 interpret_template_regs(const char *line, metag_insn *insn,
4776 const metag_reg **regs,
4777 int *regs_shift, bfd_boolean *load, bfd_boolean *dspram,
4778 int size, int *ls_shift, int *au_shift,
4779 unsigned int *au, int *imm, int *imm_shift,
4780 unsigned int *imm_mask)
4781 {
4782 const char *l = line;
4783 metag_addr addr;
4784 const metag_reg *template_reg[1];
4785
4786 memset (&addr, 0, sizeof(addr));
4787
4788 regs_shift[0] = 19;
4789 regs_shift[1] = INVALID_SHIFT;
4790
4791 insn->bits |= (1 << 1);
4792
4793 l = skip_whitespace (l);
4794
4795 l = parse_template_regs (l, load, au, template_reg,
4796 &addr, dspram, size);
4797 if (l == NULL)
4798 {
4799 as_bad (_("could not parse template definition"));
4800 return NULL;
4801 }
4802
4803 regs[2] = template_reg[0];
4804 regs_shift[2] = 9;
4805
4806 /* DSPRAM definition. */
4807 if (*dspram)
4808 {
4809
4810 _reg = *addr.base_reg;
4811
4812 if (addr.immediate)
4813 {
4814 /* Set the post-increment bit in the register field. */
4815 if (addr.update)
4816 _reg.no |= 0x1;
4817 }
4818 else
4819 {
4820 /* The bottom bit of the increment register tells us
4821 whether it's increment register 0 or 1. */
4822 if (addr.offset_reg->no & 0x1)
4823 _reg.no |= 0x3;
4824 else
4825 _reg.no |= 0x2;
4826 }
4827
4828 regs[0] = &_reg;
4829
4830 insn->bits |= (0x3 << 17); /* This signifies a DSPRAM definition. */
4831 }
4832 else /* DaOpPaMe definition. */
4833 {
4834 regs[0] = addr.base_reg;
4835 if (addr.immediate)
4836 {
4837 /* Set the I bit. */
4838 insn->bits |= (1 << 18);
4839
4840 if (addr.update == 1)
4841 {
4842 if (addr.negate == 1)
4843 *imm = 0x3;
4844 else
4845 *imm = 0x1;
4846 }
4847
4848 *imm_shift = 14;
4849 *imm_mask = 0x3;
4850 }
4851 else
4852 {
4853 /* Setup the offset register. */
4854 regs[1] = addr.offset_reg;
4855 regs_shift[1] = 14;
4856 }
4857 *au_shift = 23;
4858 }
4859
4860 *ls_shift = 13;
4861
4862 return l;
4863 }
4864
4865 /* Does this combination of units need the O2R bit and can it be encoded? */
4866 static bfd_boolean
4867 units_need_o2r (enum metag_unit unit1, enum metag_unit unit2)
4868 {
4869 if (unit1 == unit2)
4870 return FALSE;
4871
4872 if (unit1 == UNIT_D0 || unit1 == UNIT_ACC_D0 || unit1 == UNIT_RAM_D0)
4873 {
4874 if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0 || unit2 == UNIT_D0)
4875 return FALSE;
4876
4877 switch (unit2)
4878 {
4879 case UNIT_A1:
4880 case UNIT_D1:
4881 case UNIT_RD:
4882 case UNIT_A0:
4883 return TRUE;
4884 default:
4885 return FALSE;
4886 }
4887 }
4888
4889 if (unit1 == UNIT_D1 || unit1 == UNIT_ACC_D1 || unit1 == UNIT_RAM_D1)
4890 {
4891 if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1 || unit2 == UNIT_D1)
4892 return FALSE;
4893
4894 switch (unit2)
4895 {
4896 case UNIT_A1:
4897 case UNIT_D0:
4898 case UNIT_RD:
4899 case UNIT_A0:
4900 return TRUE;
4901 default:
4902 return FALSE;
4903 }
4904 }
4905
4906 return FALSE;
4907 }
4908
4909 /* Return TRUE if this is a DSP data unit. */
4910 static bfd_boolean
4911 is_dsp_data_unit (const metag_reg *reg)
4912 {
4913 switch (reg->unit)
4914 {
4915 case UNIT_D0:
4916 case UNIT_D1:
4917 case UNIT_ACC_D0:
4918 case UNIT_ACC_D1:
4919 case UNIT_RAM_D0:
4920 case UNIT_RAM_D1:
4921 return TRUE;
4922 default:
4923 return FALSE;
4924 }
4925 }
4926
4927 static metag_reg o2r_reg;
4928
4929 /* Parse a DaOpPaMe load template definition. */
4930 static const char *
4931 parse_dalu (const char *line, metag_insn *insn,
4932 const insn_template *template)
4933 {
4934 const char *l = line;
4935 const char *ll;
4936 const metag_reg *regs[4];
4937 metag_addr addr;
4938 size_t regs_read;
4939 bfd_boolean is_mov = MAJOR_OPCODE (template->meta_opcode) == OPC_ADD;
4940 bfd_boolean is_cmp = ((MAJOR_OPCODE (template->meta_opcode) == OPC_CMP) &&
4941 ((template->meta_opcode & 0xee) == 0));
4942 bfd_boolean is_dual = (insn->dsp_width == DSP_WIDTH_DUAL);
4943 bfd_boolean is_quickrot64 = ((insn->dsp_action_flags & DSP_ACTION_QR64) != 0);
4944 int l1_shift = INVALID_SHIFT;
4945 bfd_boolean load = FALSE;
4946 int ls_shift = INVALID_SHIFT;
4947 bfd_boolean ar = FALSE;
4948 int ar_shift = INVALID_SHIFT;
4949 int regs_shift[3] = { INVALID_SHIFT, INVALID_SHIFT, INVALID_SHIFT };
4950 int imm = 0;
4951 int imm_shift = INVALID_SHIFT;
4952 unsigned int imm_mask = 0;
4953 unsigned int au = 0;
4954 int au_shift = INVALID_SHIFT;
4955 unsigned int du = 0;
4956 int du_shift = INVALID_SHIFT;
4957 unsigned int sc = ((insn->dsp_action_flags & DSP_ACTION_OV) != 0);
4958 int sc_shift = INVALID_SHIFT;
4959 unsigned int om = ((insn->dsp_action_flags & DSP_ACTION_MOD) != 0);
4960 int om_shift = INVALID_SHIFT;
4961 unsigned int o2r = 0;
4962 int o2r_shift = INVALID_SHIFT;
4963 unsigned int qr = 0;
4964 int qr_shift = INVALID_SHIFT;
4965 int qd_shift = INVALID_SHIFT;
4966 unsigned int qn = 0;
4967 int qn_shift = INVALID_SHIFT;
4968 unsigned int a1 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ZERO)) != 0);
4969 int a1_shift = INVALID_SHIFT;
4970 unsigned int a2 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD)) != 0);
4971 int a2_shift = INVALID_SHIFT;
4972 unsigned su = ((insn->dsp_action_flags & DSP_ACTION_UMUL) != 0);
4973 int su_shift = INVALID_SHIFT;
4974 unsigned int ac;
4975 int ac_shift = INVALID_SHIFT;
4976 unsigned int mx = (((insn->dsp_daoppame_flags & DSP_DAOPPAME_8) != 0) ||
4977 (insn->dsp_daoppame_flags & DSP_DAOPPAME_16) != 0);
4978 int mx_shift = INVALID_SHIFT;
4979 int size = is_dual ? 8 : 4;
4980 bfd_boolean dspram;
4981 bfd_boolean conditional = (MINOR_OPCODE (template->meta_opcode) & 0x4);
4982
4983 /* XFIXME: check the flags are valid with the instruction. */
4984 if (is_quickrot64 && !(template->arg_type & DSP_ARGS_QR))
4985 {
4986 as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction"));
4987 return NULL;
4988 }
4989
4990 insn->bits = template->meta_opcode;
4991
4992 memset (regs, 0, sizeof (regs));
4993 memset (&addr, 0, sizeof (addr));
4994
4995 /* There are the following forms of DSP ALU instructions,
4996
4997 * Group 1:
4998 19. D[T] Op De.r,Dx.r,De.r
4999 1. D[T] Op De.r,Dx.r,De.r|ACe.r [Accumulator in src 2]
5000 3. D[T] Op De.r,Dx.r,De.r[,Ae.r] [QUICKRoT]
5001 2. D[T] Op ACe.e,ACx.r,ACo.e [cross-unit accumulator op]
5002 5. D[T] Op De.r|ACe.r,Dx.r,De.r
5003 20. D[T] Op De.r,Dx.r|ACx.r,De.r
5004 8. D Opcc De.r,Dx.r,Rx.r
5005 6. D Op De.r,Dx.r,Rx.r|RD
5006 17. D Op De.r|ACe.r,Dx.r,Rx.r|RD
5007 7. D Op De.e,Dx.r,#I16
5008
5009 * Group 2:
5010 4. D[T] Op Dx.r,De.r
5011 10. D Op Dx.r,Rx.r|RD
5012 13. D Op Dx.r,Rx.r
5013 11. D Op Dx.r,#I16
5014 12. D[T] Op De.r,Dx.r
5015 14. D Op DSPe.r,Dx.r
5016 15. D Op DSPx.r,#I16
5017 16. D Op De.r,DSPx.r
5018 18. D Op De.r,Dx.r|ACx.r
5019
5020 * Group 3:
5021 22. D Op De.r,Dx.r|ACx.r,De.r|#I5
5022 23. D Op Ux.r,Dx.r|ACx.r,De.r|#I5
5023 21. D Op De.r,Dx.r|ACx.r,#I5 */
5024
5025 /* Group 1. */
5026 if (template->arg_type & DSP_ARGS_1)
5027 {
5028 du_shift = 24;
5029
5030 /* Could this be a cross-unit accumulator op,
5031 e.g. ACe.e,ACx.r,ACo.e */
5032 if (template->arg_type & DSP_ARGS_XACC)
5033 {
5034 ll = parse_dsp_regs_list (l, regs, 3, &regs_read, FALSE, FALSE,
5035 FALSE, FALSE);
5036 if (ll != NULL && regs_read == 3
5037 && is_accumulator_reg (regs[0]))
5038 {
5039 if (regs[0]->unit != regs[1]->unit ||
5040 regs[2]->unit == regs[1]->unit)
5041 {
5042 as_bad (_("invalid operands for cross-unit op"));
5043 return NULL;
5044 }
5045
5046 du = (regs[1]->unit == UNIT_ACC_D1);
5047 regs_shift[1] = 19;
5048 l = ll;
5049
5050 /* All cross-unit accumulator ops have bits 8 and 6 set. */
5051 insn->bits |= (5 << 6);
5052
5053 goto check_for_template;
5054 }
5055
5056 /* If we reach here, this instruction is not a
5057 cross-unit accumulator op. */
5058 }
5059
5060 if (template->arg_type & DSP_ARGS_SPLIT8)
5061 om_shift = 7;
5062
5063 sc_shift = 5;
5064 l1_shift = 4;
5065 o2r_shift = 0;
5066
5067 /* De.r|ACe.r,Dx.r,De.r */
5068 if (template->arg_type & DSP_ARGS_DACC)
5069 {
5070 /* XFIXME: these need moving? */
5071 a2_shift = 7;
5072 su_shift = 6;
5073 a1_shift = 2;
5074 om_shift = 3;
5075
5076 ll = parse_dsp_reg (l, &regs[0], FALSE, FALSE);
5077 if (ll != NULL)
5078 {
5079 /* Using ACe.r as the dst requires one of the P,N or Z
5080 flags to be used. */
5081 if (!(insn->dsp_action_flags &
5082 (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
5083 {
5084 as_bad (_("missing flags: one of 'P', 'N' or 'Z' required"));
5085 return NULL;
5086 }
5087
5088 l = ll;
5089 l = skip_comma (l);
5090 l = parse_dsp_regs_list (l, &regs[1], 2, &regs_read,
5091 TRUE, FALSE, FALSE, FALSE);
5092 if (l == NULL || regs_read != 2)
5093 {
5094 as_bad (_("invalid register"));
5095 return NULL;
5096 }
5097
5098 if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
5099 du = 1;
5100
5101 regs_shift[0] = 19;
5102 regs_shift[1] = 14;
5103 regs_shift[2] = 9;
5104 goto check_for_template;
5105 }
5106
5107 /* If we reach here, this instruction does not use the
5108 accumulator as the destination register. */
5109 if ((insn->dsp_action_flags &
5110 (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
5111 {
5112 as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating"));
5113 return NULL;
5114 }
5115 }
5116
5117 regs_shift[0] = 19;
5118
5119
5120 l = parse_dsp_regs_list (l, regs, 2, &regs_read, TRUE, FALSE, FALSE, TRUE);
5121 if (l == NULL || regs_read != 2)
5122 return NULL;
5123
5124 l = skip_comma (l);
5125 if (l == NULL)
5126 return NULL;
5127
5128 if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
5129 du = 1;
5130
5131 if (is_accumulator_reg(regs[0]) && !(template->arg_type & DSP_ARGS_DACC))
5132 {
5133 as_bad (_("accumulator not a valid destination"));
5134 return NULL;
5135 }
5136
5137 /* Check for immediate, e.g. De.r,Dx.r,#I16 */
5138 if (*l == IMM_CHAR)
5139 {
5140 l = parse_imm16 (l, insn, &imm);
5141 if (l == NULL)
5142 {
5143 as_bad (_("invalid immediate value"));
5144 return NULL;
5145 }
5146
5147 if (!within_signed_range (imm, IMM16_BITS))
5148 {
5149 as_bad (_("immediate value out of range"));
5150 return NULL;
5151 }
5152
5153 if (regs[0]->unit != regs[1]->unit || regs[0]->no != regs[1]->no)
5154 {
5155 as_bad (_("immediate value not allowed when source & dest differ"));
5156 return NULL;
5157 }
5158
5159 imm_mask = 0xffff;
5160 imm_shift = 3;
5161
5162 /* Set the I-bit */
5163 insn->bits |= (1 << 25);
5164
5165 insn->bits |= (0x3 << 0);
5166
5167 l1_shift = 2;
5168
5169 /* Remove any bits that have been set in the immediate
5170 field. */
5171 insn->bits &= ~(imm_mask << imm_shift);
5172 }
5173 else
5174 {
5175
5176 regs_shift[1] = 14;
5177 regs_shift[2] = 9;
5178
5179 /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */
5180 ll = parse_dsp_reg (l, &regs[2], FALSE, FALSE);
5181 if (ll != NULL)
5182 {
5183 l = ll;
5184
5185 if (!(template->arg_type & DSP_ARGS_ACC2))
5186 {
5187 as_bad (_("invalid register operand: %s"), regs[2]->name);
5188 return NULL;
5189 }
5190
5191 om_shift = 3;
5192 ar_shift = 7;
5193 ar = TRUE;
5194 }
5195 else
5196 {
5197 /* De.r,Dx.r,De.r */
5198 l = __parse_gp_reg (l, &regs[2], TRUE);
5199 if (l == NULL)
5200 return NULL;
5201 }
5202
5203 if (template->arg_type & DSP_ARGS_ACC2)
5204 om_shift = 3;
5205
5206 /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */
5207 if (template->arg_type & DSP_ARGS_QR)
5208 {
5209 if (conditional)
5210 qn_shift = 5;
5211 else
5212 {
5213 qn_shift = 7;
5214 qr_shift = 6;
5215 qd_shift = 5;
5216 }
5217
5218 l = skip_comma (l);
5219 if (l == NULL)
5220 {
5221 as_bad (_("QUICKRoT extension requires 4 registers"));
5222 return NULL;
5223 }
5224
5225 l = __parse_gp_reg (l, &regs[3], TRUE);
5226 if (l == NULL)
5227 {
5228 as_bad (_("invalid fourth register"));
5229 return NULL;
5230 }
5231
5232 if (!is_addr_unit (regs[3]->unit) ||
5233 !is_quickrot_reg (regs[3]->no))
5234 {
5235 as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register"));
5236 return NULL;
5237 }
5238
5239 qn = (regs[3]->no == 3);
5240 }
5241 }
5242
5243 check_for_template:
5244 /* This is the common exit path. Check for o2r. */
5245 if (regs[2] != NULL)
5246 {
5247 o2r = units_need_o2r (regs[1]->unit, regs[2]->unit);
5248 if (o2r)
5249 {
5250 o2r_reg.no = lookup_o2r (0, du, regs[2]);
5251 o2r_reg.unit = regs[2]->unit;
5252 regs[2] = &o2r_reg;
5253 }
5254 }
5255
5256 /* Check any DSP RAM pointers are valid for this unit. */
5257 if ((du && (regs[0]->unit == UNIT_RAM_D0)) ||
5258 (!du && (regs[0]->unit == UNIT_RAM_D1)) ||
5259 (du && (regs[1]->unit == UNIT_RAM_D0)) ||
5260 (!du && (regs[1]->unit == UNIT_RAM_D1)) ||
5261 (du && regs[2] && (regs[2]->unit == UNIT_RAM_D0)) ||
5262 (!du && regs[2] && (regs[2]->unit == UNIT_RAM_D1))) {
5263 as_bad (_("DSP RAM pointer in incorrect unit"));
5264 return NULL;
5265 }
5266
5267 /* Is this a template definition? */
5268 if (IS_TEMPLATE_DEF (insn))
5269 {
5270 l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5271 &dspram, size, &ls_shift, &au_shift,
5272 &au, &imm, &imm_shift, &imm_mask);
5273
5274 if (l == NULL)
5275 return NULL;
5276
5277 if (!dspram)
5278 mx_shift = 0;
5279 }
5280
5281 goto matched;
5282 }
5283
5284 /* Group 2. */
5285 if (template->arg_type & DSP_ARGS_2)
5286 {
5287 bfd_boolean is_xsd = ((MAJOR_OPCODE (template->meta_opcode) == OPC_MISC) &&
5288 (MINOR_OPCODE (template->meta_opcode) == 0xa));
5289 bfd_boolean is_fpu_mov = template->insn_type == INSN_DSP_FPU;
5290 bfd_boolean to_fpu = (template->meta_opcode >> 7) & 0x1;
5291
5292 if (is_xsd)
5293 du_shift = 0;
5294 else
5295 du_shift = 24;
5296
5297 l1_shift = 4;
5298
5299 /* CMPs and TSTs don't store to their destination operand. */
5300 ll = __parse_gp_reg (l, regs, is_cmp);
5301 if (ll == NULL)
5302 {
5303 /* DSPe.r,Dx.r or DSPx.r,#I16 */
5304 if (template->arg_type & DSP_ARGS_DSP_SRC1)
5305 {
5306 l = parse_dsp_reg (l, regs, FALSE, FALSE);
5307 if (l == NULL)
5308 {
5309 as_bad (_("invalid register operand #1"));
5310 return NULL;
5311 }
5312
5313 /* Only MOV instructions have a DSP register as a
5314 destination. Set the MOV DSPe.r opcode. The simple
5315 OR'ing is OK because the usual MOV opcode is 0x00. */
5316 insn->bits = (0x91 << 24);
5317 du_shift = 0;
5318 l1_shift = 2;
5319 regs_shift[0] = 19;
5320 }
5321 else
5322 {
5323 as_bad (_("invalid register operand #2"));
5324 return NULL;
5325 }
5326 }
5327 else
5328 {
5329 l = ll;
5330
5331 /* Everything but CMP and TST. */
5332 if (MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
5333 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
5334 MAJOR_OPCODE (insn->bits) == OPC_9 ||
5335 MAJOR_OPCODE (template->meta_opcode) == OPC_MISC ||
5336 ((template->meta_opcode & 0x0000002c) != 0))
5337 regs_shift[0] = 19;
5338 else
5339 regs_shift[0] = 14;
5340 }
5341
5342 if (!is_dsp_data_unit (regs[0]) && !(regs[0]->unit == UNIT_FX &&
5343 is_fpu_mov && to_fpu))
5344 return NULL;
5345
5346 du = (regs[0]->unit == UNIT_D1 || regs[0]->unit == UNIT_RAM_D1 ||
5347 regs[0]->unit == UNIT_ACC_D1);
5348
5349 l = skip_comma (l);
5350
5351 if (*l == IMM_CHAR)
5352 {
5353 if (template->arg_type & DSP_ARGS_IMM &&
5354 !(is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)))
5355 {
5356 l = parse_imm16 (l, insn, &imm);
5357 if (l == NULL)
5358 {
5359 as_bad (_("invalid immediate value"));
5360 return NULL;
5361 }
5362
5363 if (!within_signed_range (imm, IMM16_BITS))
5364 return NULL;
5365
5366 l1_shift = 2;
5367 regs_shift[0] = 19;
5368
5369 imm_mask = 0xffff;
5370 imm_shift = 3;
5371
5372 /* Set the I-bit unless it's a MOV because they're
5373 different. */
5374 if (!(is_mov && MAJOR_OPCODE (insn->bits) == OPC_9))
5375 insn->bits |= (1 << 25);
5376
5377 /* All instructions that takes immediates also have bit 1 set. */
5378 insn->bits |= (1 << 1);
5379
5380 if (MAJOR_OPCODE (insn->bits) != OPC_9)
5381 insn->bits |= (1 << 0);
5382
5383 insn->bits &= ~(1 << 8);
5384 }
5385 else
5386 {
5387 as_bad (_("this instruction does not accept an immediate"));
5388 return NULL;
5389 }
5390 }
5391 else
5392 {
5393 if (MAJOR_OPCODE (insn->bits) != OPC_9)
5394 {
5395 insn->bits |= (1 << 8);
5396 l1_shift = 4;
5397 }
5398
5399 ll = __parse_gp_reg (l, &regs[1], TRUE);
5400 if (ll == NULL)
5401 {
5402 if (template->arg_type & DSP_ARGS_DSP_SRC2)
5403 {
5404 l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
5405 if (l == NULL)
5406 {
5407 as_bad (_("invalid register operand #3"));
5408 return NULL;
5409 }
5410
5411 /* MOV and NEG. */
5412 if ((is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)) ||
5413 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB)
5414 {
5415 if (is_accumulator_reg (regs[1]))
5416 {
5417 if (is_fpu_mov)
5418 {
5419 as_bad (_("this instruction does not accept an accumulator"));
5420 return NULL;
5421 }
5422 ar_shift = 7;
5423 ar = 1;
5424 regs_shift[1] = 9;
5425 }
5426 else
5427 {
5428 du_shift = 0;
5429 l1_shift = 2;
5430 regs_shift[1] = 14;
5431 insn->bits = (0x92 << 24); /* Set opcode. */
5432 }
5433 }
5434 }
5435 else
5436 {
5437 as_bad (_("invalid register operand #4"));
5438 return NULL;
5439 }
5440 }
5441 else
5442 {
5443 /* Set the o2r bit if required. */
5444 if (!is_fpu_mov && units_need_o2r (regs[0]->unit, regs[1]->unit))
5445 {
5446 o2r_reg = *regs[1];
5447 o2r_reg.no = lookup_o2r (0, du, regs[1]);
5448 regs[1] = &o2r_reg;
5449 o2r_shift = 0;
5450 o2r = 1;
5451 }
5452 else if (!is_dsp_data_unit (regs[1]) &&
5453 !(is_fpu_mov && !to_fpu && regs[1]->unit == UNIT_FX))
5454 return NULL;
5455
5456 if (is_fpu_mov && to_fpu)
5457 du = (regs[1]->unit == UNIT_D1 ||
5458 regs[1]->unit == UNIT_RAM_D1 ||
5459 regs[1]->unit == UNIT_ACC_D1);
5460
5461 l = ll;
5462
5463 if (MAJOR_OPCODE (insn->bits) == OPC_ADD ||
5464 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
5465 (((template->meta_opcode & 0x0000002c) == 0) &&
5466 MAJOR_OPCODE (template->meta_opcode) != OPC_MISC))
5467 regs_shift[1] = 9;
5468 else
5469 regs_shift[1] = 14;
5470 }
5471 }
5472
5473 /* If it's an 0x0 MOV or NEG set some lower bits. */
5474 if ((MAJOR_OPCODE (insn->bits) == OPC_ADD ||
5475 MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) && !is_fpu_mov)
5476 {
5477 om_shift = 3;
5478 sc_shift = 5;
5479 insn->bits |= (1 << 2);
5480 }
5481
5482 /* Check for template definitons. */
5483 if (IS_TEMPLATE_DEF (insn))
5484 {
5485 l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5486 &dspram, size, &ls_shift, &au_shift,
5487 &au, &imm, &imm_shift, &imm_mask);
5488 mx_shift = 0;
5489
5490 if (l == NULL)
5491 return NULL;
5492 }
5493 goto matched;
5494 }
5495
5496 /* Group 3. */
5497 du_shift = 24;
5498 l1_shift = 4;
5499
5500 l = __parse_gp_reg (l, regs, FALSE);
5501 if (l == NULL)
5502 {
5503 as_bad (_("invalid register operand"));
5504 return NULL;
5505 }
5506
5507 l = skip_comma (l);
5508
5509 if (*l == 'A')
5510 {
5511 l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
5512 if (l == NULL)
5513 {
5514 as_bad (_("invalid accumulator register"));
5515 return NULL;
5516 }
5517 ac = 1;
5518 ac_shift = 0;
5519 }
5520 else
5521 {
5522 l = __parse_gp_reg (l, &regs[1], TRUE);
5523 if (l == NULL)
5524 {
5525 as_bad (_("invalid register operand"));
5526 return NULL;
5527 }
5528 }
5529
5530 regs_shift[0] = 19;
5531 regs_shift[1] = 14;
5532
5533 du = (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_ACC_D1
5534 || regs[1]->unit == UNIT_RAM_D1);
5535
5536 l = skip_comma (l);
5537
5538 if (*l == IMM_CHAR)
5539 {
5540 l = parse_imm_constant (l, insn, &imm);
5541 if (l == NULL)
5542 {
5543 as_bad (_("invalid immediate value"));
5544 return NULL;
5545 }
5546
5547 if (!within_unsigned_range (imm, IMM5_BITS))
5548 return NULL;
5549
5550 imm_mask = 0x1f;
5551 imm_shift = 9;
5552
5553 /* Set the I-bit */
5554 insn->bits |= (1 << 25);
5555 }
5556 else
5557 {
5558 regs_shift[2] = 9;
5559 l = __parse_gp_reg (l, &regs[2], TRUE);
5560 if (l == NULL)
5561 return NULL;
5562 }
5563
5564 /* Check for post-processing R,G,B flags. Conditional instructions
5565 do not have these bits. */
5566 if (insn->dsp_action_flags & DSP_ACTION_CLAMP9)
5567 {
5568 if ((template->meta_opcode >> 26) & 0x1)
5569 {
5570 as_bad (_("conditional instruction cannot use G flag"));
5571 return NULL;
5572 }
5573
5574 insn->bits |= (1 << 3);
5575 }
5576
5577 if (insn->dsp_action_flags & DSP_ACTION_CLAMP8)
5578 {
5579 if ((template->meta_opcode >> 26) & 0x1)
5580 {
5581 as_bad (_("conditional instruction cannot use B flag"));
5582 return NULL;
5583 }
5584
5585 insn->bits |= (0x3 << 2);
5586 }
5587
5588 if (insn->dsp_action_flags & DSP_ACTION_ROUND)
5589 {
5590 if ((template->meta_opcode >> 26) & 0x1)
5591 {
5592 as_bad (_("conditional instruction cannot use R flag"));
5593 return NULL;
5594 }
5595 insn->bits |= (1 << 2);
5596 }
5597
5598 /* Conditional Data Unit Shift instructions cannot be dual unit. */
5599 if ((template->meta_opcode >> 26) & 0x1)
5600 ls_shift = INVALID_SHIFT;
5601
5602 /* The Condition Is Always (CA) bit must be set if we're targetting a
5603 Ux.r register as the destination. This means that we can't have
5604 any other condition bits set. */
5605 if (!is_same_data_unit (regs[1]->unit, regs[0]->unit))
5606 {
5607 /* Set both the Conditional bit and the Condition is Always bit. */
5608 insn->bits |= (1 << 26);
5609 insn->bits |= (1 << 5);
5610
5611 /* Fill out the Ud field. */
5612 insn->bits |= (regs[0]->unit << 1);
5613 }
5614
5615 if (IS_TEMPLATE_DEF (insn))
5616 {
5617 l = interpret_template_regs(l, insn, regs, regs_shift, &load,
5618 &dspram, size, &ls_shift, &au_shift,
5619 &au, &imm, &imm_shift, &imm_mask);
5620
5621 if (l == NULL)
5622 return NULL;
5623
5624 if (!dspram)
5625 mx_shift = 5;
5626 }
5627
5628 /* Fall through. */
5629 matched:
5630
5631 /* Set the registers and immediate values. */
5632 if (regs_shift[0] != INVALID_SHIFT)
5633 insn->bits |= (regs[0]->no << regs_shift[0]);
5634
5635 if (regs_shift[1] != INVALID_SHIFT)
5636 insn->bits |= (regs[1]->no << regs_shift[1]);
5637
5638 if (regs_shift[2] != INVALID_SHIFT)
5639 insn->bits |= (regs[2]->no << regs_shift[2]);
5640
5641 /* Does this insn have an 'IMM' bit? The immediate value should
5642 already have been masked. */
5643 if (imm_shift != INVALID_SHIFT)
5644 insn->bits |= ((imm & imm_mask) << imm_shift);
5645
5646 /* Does this insn have an 'AU' bit? */
5647 if (au_shift != INVALID_SHIFT)
5648 insn->bits |= (au << au_shift);
5649
5650 /* Does this instruction have an 'LS' bit? */
5651 if (ls_shift != INVALID_SHIFT)
5652 insn->bits |= (load << ls_shift);
5653
5654 /* Does this instruction have an 'AR' bit? */
5655 if (ar)
5656 insn->bits |= (1 << ar_shift);
5657
5658 if (du_shift != INVALID_SHIFT)
5659 insn->bits |= (du << du_shift);
5660
5661 if (sc_shift != INVALID_SHIFT)
5662 insn->bits |= (sc << sc_shift);
5663
5664 if (om_shift != INVALID_SHIFT)
5665 insn->bits |= (om << om_shift);
5666
5667 if (o2r_shift != INVALID_SHIFT)
5668 insn->bits |= (o2r << o2r_shift);
5669
5670 if (qn_shift != INVALID_SHIFT)
5671 insn->bits |= (qn << qn_shift);
5672
5673 if (qr_shift != INVALID_SHIFT)
5674 insn->bits |= (qr << qr_shift);
5675
5676 if (qd_shift != INVALID_SHIFT)
5677 insn->bits |= (is_quickrot64 << qd_shift);
5678
5679 if (a1_shift != INVALID_SHIFT)
5680 insn->bits |= (a1 << a1_shift);
5681
5682 if (a2_shift != INVALID_SHIFT)
5683 insn->bits |= (a2 << a2_shift);
5684
5685 if (su_shift != INVALID_SHIFT)
5686 insn->bits |= (su << su_shift);
5687
5688 if (imm_shift != INVALID_SHIFT)
5689 insn->bits |= ((imm & imm_mask) << imm_shift);
5690
5691 if (ac_shift != INVALID_SHIFT)
5692 insn->bits |= (ac << ac_shift);
5693
5694 if (mx_shift != INVALID_SHIFT)
5695 insn->bits |= (mx << mx_shift);
5696
5697 if (is_dual)
5698 {
5699 if (l1_shift == INVALID_SHIFT)
5700 {
5701 as_bad (_("'L' modifier not valid for this instruction"));
5702 return NULL;
5703 }
5704
5705 insn->bits |= (1 << l1_shift);
5706 }
5707
5708 insn->len = 4;
5709
5710 return l;
5711 }
5712
5713 typedef const char *(*insn_parser)(const char *, metag_insn *,
5714 const insn_template *);
5715
5716 /* Parser table. */
5717 static const insn_parser insn_parsers[ENC_MAX] =
5718 {
5719 [ENC_NONE] = parse_none,
5720 [ENC_MOV_U2U] = parse_mov_u2u,
5721 [ENC_MOV_PORT] = parse_mov_port,
5722 [ENC_MMOV] = parse_mmov,
5723 [ENC_MDRD] = parse_mdrd,
5724 [ENC_MOVL_TTREC] = parse_movl_ttrec,
5725 [ENC_GET_SET] = parse_get_set,
5726 [ENC_GET_SET_EXT] = parse_get_set_ext,
5727 [ENC_MGET_MSET] = parse_mget_mset,
5728 [ENC_COND_SET] = parse_cond_set,
5729 [ENC_XFR] = parse_xfr,
5730 [ENC_MOV_CT] = parse_mov_ct,
5731 [ENC_SWAP] = parse_swap,
5732 [ENC_JUMP] = parse_jump,
5733 [ENC_CALLR] = parse_callr,
5734 [ENC_ALU] = parse_alu,
5735 [ENC_SHIFT] = parse_shift,
5736 [ENC_MIN_MAX] = parse_min_max,
5737 [ENC_BITOP] = parse_bitop,
5738 [ENC_CMP] = parse_cmp,
5739 [ENC_BRANCH] = parse_branch,
5740 [ENC_KICK] = parse_kick,
5741 [ENC_SWITCH] = parse_switch,
5742 [ENC_CACHER] = parse_cacher,
5743 [ENC_CACHEW] = parse_cachew,
5744 [ENC_ICACHE] = parse_icache,
5745 [ENC_LNKGET] = parse_lnkget,
5746 [ENC_FMOV] = parse_fmov,
5747 [ENC_FMMOV] = parse_fmmov,
5748 [ENC_FMOV_DATA] = parse_fmov_data,
5749 [ENC_FMOV_I] = parse_fmov_i,
5750 [ENC_FPACK] = parse_fpack,
5751 [ENC_FSWAP] = parse_fswap,
5752 [ENC_FCMP] = parse_fcmp,
5753 [ENC_FMINMAX] = parse_fminmax,
5754 [ENC_FCONV] = parse_fconv,
5755 [ENC_FCONVX] = parse_fconvx,
5756 [ENC_FBARITH] = parse_fbarith,
5757 [ENC_FEARITH] = parse_fearith,
5758 [ENC_FREC] = parse_frec,
5759 [ENC_FSIMD] = parse_fsimd,
5760 [ENC_FGET_SET_ACF] = parse_fget_set_acf,
5761 [ENC_DGET_SET] = parse_dget_set,
5762 [ENC_DTEMPLATE] = parse_dtemplate,
5763 [ENC_DALU] = parse_dalu,
5764 };
5765
5766 struct metag_core_option
5767 {
5768 char *name;
5769 unsigned int value;
5770 };
5771
5772 /* CPU type options. */
5773 static const struct metag_core_option metag_cpus[] =
5774 {
5775 {"all", CoreMeta11|CoreMeta12|CoreMeta21},
5776 {"metac11", CoreMeta11},
5777 {"metac12", CoreMeta12},
5778 {"metac21", CoreMeta21},
5779 {NULL, 0},
5780 };
5781
5782 /* FPU type options. */
5783 static const struct metag_core_option metag_fpus[] =
5784 {
5785 {"metac21", FpuMeta21},
5786 {NULL, 0},
5787 };
5788
5789 /* DSP type options. */
5790 static const struct metag_core_option metag_dsps[] =
5791 {
5792 {"metac21", DspMeta21},
5793 {NULL, 0},
5794 };
5795
5796 /* Parse a CPU command line option. */
5797 static int
5798 metag_parse_cpu (char * str)
5799 {
5800 const struct metag_core_option * opt;
5801 int optlen;
5802
5803 optlen = strlen (str);
5804
5805 if (optlen == 0)
5806 {
5807 as_bad (_("missing cpu name `%s'"), str);
5808 return 0;
5809 }
5810
5811 for (opt = metag_cpus; opt->name != NULL; opt++)
5812 if (strncmp (opt->name, str, optlen) == 0)
5813 {
5814 mcpu_opt = opt->value;
5815 return 1;
5816 }
5817
5818 as_bad (_("unknown cpu `%s'"), str);
5819 return 0;
5820 }
5821
5822 /* Parse an FPU command line option. */
5823 static int
5824 metag_parse_fpu (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 fpu name `%s'"), str);
5834 return 0;
5835 }
5836
5837 for (opt = metag_fpus; opt->name != NULL; opt++)
5838 if (strncmp (opt->name, str, optlen) == 0)
5839 {
5840 mfpu_opt = opt->value;
5841 return 1;
5842 }
5843
5844 as_bad (_("unknown fpu `%s'"), str);
5845 return 0;
5846 }
5847
5848 /* Parse a DSP command line option. */
5849 static int
5850 metag_parse_dsp (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 DSP name `%s'"), str);
5860 return 0;
5861 }
5862
5863 for (opt = metag_dsps; opt->name != NULL; opt++)
5864 if (strncmp (opt->name, str, optlen) == 0)
5865 {
5866 mdsp_opt = opt->value;
5867 return 1;
5868 }
5869
5870 as_bad (_("unknown DSP `%s'"), str);
5871 return 0;
5872 }
5873
5874 struct metag_long_option
5875 {
5876 char * option; /* Substring to match. */
5877 char * help; /* Help information. */
5878 int (* func) (char * subopt); /* Function to decode sub-option. */
5879 char * deprecated; /* If non-null, print this message. */
5880 };
5881
5882 struct metag_long_option metag_long_opts[] =
5883 {
5884 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
5885 metag_parse_cpu, NULL},
5886 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
5887 metag_parse_fpu, NULL},
5888 {"mdsp=", N_("<dsp name>\t assemble for DSP architecture <dsp name>"),
5889 metag_parse_dsp, NULL},
5890 {NULL, NULL, 0, NULL}
5891 };
5892
5893 int
5894 md_parse_option (int c, char * arg)
5895 {
5896 struct metag_long_option *lopt;
5897
5898 for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
5899 {
5900 /* These options are expected to have an argument. */
5901 if (c == lopt->option[0]
5902 && arg != NULL
5903 && strncmp (arg, lopt->option + 1,
5904 strlen (lopt->option + 1)) == 0)
5905 {
5906 #if WARN_DEPRECATED
5907 /* If the option is deprecated, tell the user. */
5908 if (lopt->deprecated != NULL)
5909 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
5910 _(lopt->deprecated));
5911 #endif
5912
5913 /* Call the sup-option parser. */
5914 return lopt->func (arg + strlen (lopt->option) - 1);
5915 }
5916 }
5917
5918 return 0;
5919 }
5920
5921 void
5922 md_show_usage (FILE * stream)
5923 {
5924 struct metag_long_option *lopt;
5925
5926 fprintf (stream, _(" Meta specific command line options:\n"));
5927
5928 for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
5929 if (lopt->help != NULL)
5930 fprintf (stream, " -%s%s\n", lopt->option, _(lopt->help));
5931 }
5932
5933 /* The target specific pseudo-ops which we support. */
5934 const pseudo_typeS md_pseudo_table[] =
5935 {
5936 { "word", cons, 2 },
5937 { NULL, NULL, 0 }
5938 };
5939
5940 void
5941 md_begin (void)
5942 {
5943 int c;
5944
5945 for (c = 0; c < 256; c++)
5946 {
5947 if (ISDIGIT (c))
5948 {
5949 register_chars[c] = c;
5950 /* LOCK0, LOCK1, LOCK2. */
5951 mnemonic_chars[c] = c;
5952 }
5953 else if (ISLOWER (c))
5954 {
5955 register_chars[c] = c;
5956 mnemonic_chars[c] = c;
5957 }
5958 else if (ISUPPER (c))
5959 {
5960 register_chars[c] = c;
5961 mnemonic_chars[c] = c;
5962 }
5963 else if (c == '.')
5964 {
5965 register_chars[c] = c;
5966 }
5967 }
5968 }
5969
5970 /* Parse a split condition code prefix. */
5971 static const char *
5972 parse_split_condition (const char *line, metag_insn *insn)
5973 {
5974 const char *l = line;
5975 const split_condition *scond;
5976 split_condition entry;
5977 char buf[4];
5978
5979 memcpy (buf, l, 4);
5980 buf[3] = '\0';
5981
5982 entry.name = buf;
5983
5984 scond = (const split_condition *) htab_find (scond_htab, &entry);
5985
5986 if (!scond)
5987 return NULL;
5988
5989 insn->scond = scond->code;
5990
5991 return l + strlen (scond->name);
5992 }
5993
5994 /* Parse an instruction prefix - F for float, D for DSP - and associated
5995 flags and condition codes. */
5996 static const char *
5997 parse_prefix (const char *line, metag_insn *insn)
5998 {
5999 const char *l = line;
6000
6001 l = skip_whitespace (l);
6002
6003 insn->type = INSN_GP;
6004
6005 if (TOLOWER (*l) == FPU_PREFIX_CHAR)
6006 {
6007 if (strncasecmp (l, FFB_INSN, strlen(FFB_INSN)))
6008 {
6009 insn->type = INSN_FPU;
6010
6011 l++;
6012
6013 if (*l == END_OF_INSN)
6014 {
6015 as_bad (_("premature end of floating point prefix"));
6016 return NULL;
6017 }
6018
6019 if (TOLOWER (*l) == FPU_DOUBLE_CHAR)
6020 {
6021 insn->fpu_width = FPU_WIDTH_DOUBLE;
6022 l++;
6023 }
6024 else if (TOLOWER (*l) == FPU_PAIR_CHAR)
6025 {
6026 const char *l2 = l;
6027
6028 /* Check this isn't a split condition beginning with L. */
6029 l2 = parse_split_condition (l2, insn);
6030
6031 if (l2 && is_whitespace_char (*l2))
6032 {
6033 l = l2;
6034 }
6035 else
6036 {
6037 insn->fpu_width = FPU_WIDTH_PAIR;
6038 l++;
6039 }
6040 }
6041 else
6042 {
6043 insn->fpu_width = FPU_WIDTH_SINGLE;
6044 }
6045
6046 if (TOLOWER (*l) == FPU_ACTION_ABS_CHAR)
6047 {
6048 insn->fpu_action_flags |= FPU_ACTION_ABS;
6049 l++;
6050 }
6051 else if (TOLOWER (*l) == FPU_ACTION_INV_CHAR)
6052 {
6053 insn->fpu_action_flags |= FPU_ACTION_INV;
6054 l++;
6055 }
6056
6057 if (TOLOWER (*l) == FPU_ACTION_QUIET_CHAR)
6058 {
6059 insn->fpu_action_flags |= FPU_ACTION_QUIET;
6060 l++;
6061 }
6062
6063 if (TOLOWER (*l) == FPU_ACTION_ZERO_CHAR)
6064 {
6065 insn->fpu_action_flags |= FPU_ACTION_ZERO;
6066 l++;
6067 }
6068
6069 if (! is_whitespace_char (*l))
6070 {
6071 l = parse_split_condition (l, insn);
6072
6073 if (!l)
6074 {
6075 as_bad (_("unknown floating point prefix character"));
6076 return NULL;
6077 }
6078 }
6079
6080 l = skip_space (l);
6081 }
6082 }
6083 else if (TOLOWER (*l) == DSP_PREFIX_CHAR)
6084 {
6085 if (strncasecmp (l, DCACHE_INSN, strlen (DCACHE_INSN)) &&
6086 strncasecmp (l, DEFR_INSN, strlen (DEFR_INSN)))
6087 {
6088 const char *ll = l;
6089 insn->type = INSN_DSP;
6090
6091 l++;
6092
6093 insn->dsp_width = DSP_WIDTH_SINGLE;
6094
6095 while (!is_whitespace_char (*l))
6096 {
6097 /* We have to check for split condition codes first
6098 because they are the longest strings to match,
6099 e.g. if the string contains "LLS" we want it to match
6100 the split condition code "LLS", not the dual unit
6101 character "L". */
6102 ll = l;
6103 l = parse_split_condition (l, insn);
6104
6105 if (l == NULL)
6106 l = ll;
6107 else
6108 continue;
6109
6110 /* Accept an FPU prefix char which may be used when doing
6111 template MOV with FPU registers. */
6112 if (TOLOWER(*l) == FPU_PREFIX_CHAR)
6113 {
6114 insn->type = INSN_DSP_FPU;
6115 l++;
6116 continue;
6117 }
6118
6119 if (TOLOWER(*l) == DSP_DUAL_CHAR)
6120 {
6121 insn->dsp_width = DSP_WIDTH_DUAL;
6122 l++;
6123 continue;
6124 }
6125
6126 if (TOLOWER(*l) == DSP_ACTION_QR64_CHAR)
6127 {
6128 insn->dsp_action_flags |= DSP_ACTION_QR64;
6129 l++;
6130 continue;
6131 }
6132
6133 if (TOLOWER(*l) == DSP_ACTION_UMUL_CHAR)
6134 {
6135 insn->dsp_action_flags |= DSP_ACTION_UMUL;
6136 l++;
6137 continue;
6138 }
6139
6140 if (TOLOWER(*l) == DSP_ACTION_ROUND_CHAR)
6141 {
6142 insn->dsp_action_flags |= DSP_ACTION_ROUND;
6143 l++;
6144 continue;
6145 }
6146
6147 if (TOLOWER(*l) == DSP_ACTION_CLAMP9_CHAR)
6148 {
6149 insn->dsp_action_flags |= DSP_ACTION_CLAMP9;
6150 l++;
6151 continue;
6152 }
6153
6154 if (TOLOWER(*l) == DSP_ACTION_CLAMP8_CHAR)
6155 {
6156 insn->dsp_action_flags |= DSP_ACTION_CLAMP8;
6157 l++;
6158 continue;
6159 }
6160
6161 if (TOLOWER(*l) == DSP_ACTION_MOD_CHAR)
6162 {
6163 insn->dsp_action_flags |= DSP_ACTION_MOD;
6164 l++;
6165 continue;
6166 }
6167
6168 if (TOLOWER(*l) == DSP_ACTION_ACC_ZERO_CHAR)
6169 {
6170 insn->dsp_action_flags |= DSP_ACTION_ACC_ZERO;
6171 l++;
6172 continue;
6173 }
6174
6175 if (TOLOWER(*l) == DSP_ACTION_ACC_ADD_CHAR)
6176 {
6177 insn->dsp_action_flags |= DSP_ACTION_ACC_ADD;
6178 l++;
6179 continue;
6180 }
6181
6182 if (TOLOWER(*l) == DSP_ACTION_ACC_SUB_CHAR)
6183 {
6184 insn->dsp_action_flags |= DSP_ACTION_ACC_SUB;
6185 l++;
6186 continue;
6187 }
6188
6189 if (TOLOWER(*l) == DSP_ACTION_OV_CHAR)
6190 {
6191 insn->dsp_action_flags |= DSP_ACTION_OV;
6192 l++;
6193 continue;
6194 }
6195
6196 if (TOLOWER(*l) == DSP_DAOPPAME_8_CHAR)
6197 {
6198 insn->dsp_daoppame_flags |= DSP_DAOPPAME_8;
6199 l++;
6200 continue;
6201 }
6202
6203 if (TOLOWER(*l) == DSP_DAOPPAME_16_CHAR)
6204 {
6205 insn->dsp_daoppame_flags |= DSP_DAOPPAME_16;
6206 l++;
6207 continue;
6208 }
6209
6210 if (TOLOWER(*l) == DSP_DAOPPAME_TEMP_CHAR)
6211 {
6212 insn->dsp_daoppame_flags |= DSP_DAOPPAME_TEMP;
6213 l++;
6214 continue;
6215 }
6216
6217 if (TOLOWER(*l) == DSP_DAOPPAME_HIGH_CHAR)
6218 {
6219 insn->dsp_daoppame_flags |= DSP_DAOPPAME_HIGH;
6220 l++;
6221 continue;
6222 }
6223
6224 as_bad (_("unknown DSP prefix character %c %s"), *l, l);
6225 return NULL;
6226 }
6227
6228 l = skip_space (l);
6229 }
6230 }
6231
6232 return l;
6233 }
6234
6235 /* Return a list of appropriate instruction parsers for MNEMONIC. */
6236 static insn_templates *
6237 find_insn_templates (const char *mnemonic)
6238 {
6239 insn_template template;
6240 insn_templates entry;
6241 insn_templates *slot;
6242
6243 entry.template = &template;
6244
6245 memcpy ((void *)&entry.template->name, &mnemonic, sizeof (char *));
6246
6247 slot = (insn_templates *) htab_find (mnemonic_htab, &entry);
6248
6249 if (slot)
6250 return slot;
6251
6252 return NULL;
6253 }
6254
6255 /* Make an uppercase copy of SRC into DST and return DST. */
6256 static char *
6257 strupper (char * dst, const char *src)
6258 {
6259 size_t i = 0;
6260
6261 while (src[i])
6262 {
6263 dst[i] = TOUPPER (src[i]);
6264 i++;
6265 }
6266
6267 dst[i] = 0;
6268
6269 return dst;
6270 }
6271
6272 /* Calculate a hash value for a template. */
6273 static hashval_t
6274 hash_templates (const void *p)
6275 {
6276 insn_templates *tp = (insn_templates *)p;
6277 char buf[MAX_MNEMONIC_LEN];
6278
6279 strupper (buf, tp->template->name);
6280
6281 return htab_hash_string (buf);
6282 }
6283
6284 /* Check if two templates are equal. */
6285 static int
6286 eq_templates (const void *a, const void *b)
6287 {
6288 insn_templates *ta = (insn_templates *)a;
6289 insn_templates *tb = (insn_templates *)b;
6290 return strcasecmp (ta->template->name, tb->template->name) == 0;
6291 }
6292
6293 /* Create the hash table required for parsing instructions. */
6294 static void
6295 create_mnemonic_htab (void)
6296 {
6297 size_t i, num_templates = sizeof(metag_optab)/sizeof(metag_optab[0]);
6298
6299 mnemonic_htab = htab_create_alloc (num_templates, hash_templates,
6300 eq_templates, NULL, xcalloc, free);
6301
6302 for (i = 0; i < num_templates; i++)
6303 {
6304 const insn_template *template = &metag_optab[i];
6305 insn_templates **slot = NULL;
6306 insn_templates *new_entry;
6307
6308 new_entry = xmalloc (sizeof (insn_templates));
6309
6310 new_entry->template = template;
6311 new_entry->next = NULL;
6312
6313 slot = (insn_templates **) htab_find_slot (mnemonic_htab, new_entry,
6314 INSERT);
6315
6316 if (*slot)
6317 {
6318 insn_templates *last_entry = *slot;
6319
6320 while (last_entry->next)
6321 last_entry = last_entry->next;
6322
6323 last_entry->next = new_entry;
6324 }
6325 else
6326 {
6327 *slot = new_entry;
6328 }
6329 }
6330 }
6331
6332 /* Calculate a hash value for a register. */
6333 static hashval_t
6334 hash_regs (const void *p)
6335 {
6336 metag_reg *rp = (metag_reg *)p;
6337 char buf[MAX_REG_LEN];
6338
6339 strupper (buf, rp->name);
6340
6341 return htab_hash_string (buf);
6342 }
6343
6344 /* Check if two registers are equal. */
6345 static int
6346 eq_regs (const void *a, const void *b)
6347 {
6348 metag_reg *ra = (metag_reg *)a;
6349 metag_reg *rb = (metag_reg *)b;
6350 return strcasecmp (ra->name, rb->name) == 0;
6351 }
6352
6353 /* Create the hash table required for parsing registers. */
6354 static void
6355 create_reg_htab (void)
6356 {
6357 size_t i, num_regs = sizeof(metag_regtab)/sizeof(metag_regtab[0]);
6358
6359 reg_htab = htab_create_alloc (num_regs, hash_regs,
6360 eq_regs, NULL, xcalloc, free);
6361
6362 for (i = 0; i < num_regs; i++)
6363 {
6364 const metag_reg *reg = &metag_regtab[i];
6365 const metag_reg **slot;
6366
6367 slot = (const metag_reg **) htab_find_slot (reg_htab, reg, INSERT);
6368
6369 if (!*slot)
6370 *slot = reg;
6371 }
6372 }
6373
6374 /* Create the hash table required for parsing DSP registers. */
6375 static void
6376 create_dspreg_htabs (void)
6377 {
6378 size_t i, num_regs = sizeof(metag_dsp_regtab)/sizeof(metag_dsp_regtab[0]);
6379 size_t h;
6380
6381 dsp_reg_htab = htab_create_alloc (num_regs, hash_regs,
6382 eq_regs, NULL, xcalloc, free);
6383
6384 for (i = 0; i < num_regs; i++)
6385 {
6386 const metag_reg *reg = &metag_dsp_regtab[i];
6387 const metag_reg **slot;
6388
6389 slot = (const metag_reg **) htab_find_slot (dsp_reg_htab, reg, INSERT);
6390
6391 /* Make sure there are no hash table collisions, which would
6392 require chaining entries. */
6393 BFD_ASSERT (*slot == NULL);
6394 *slot = reg;
6395 }
6396
6397 num_regs = sizeof(metag_dsp_tmpl_regtab[0])/sizeof(metag_dsp_tmpl_regtab[0][0]);
6398
6399 for (h = 0; h < 2; h++)
6400 {
6401 dsp_tmpl_reg_htab[h] = htab_create_alloc (num_regs, hash_regs,
6402 eq_regs, NULL, xcalloc, free);
6403 }
6404
6405 for (h = 0; h < 2; h++)
6406 {
6407 for (i = 0; i < num_regs; i++)
6408 {
6409 const metag_reg *reg = &metag_dsp_tmpl_regtab[h][i];
6410 const metag_reg **slot;
6411 slot = (const metag_reg **) htab_find_slot (dsp_tmpl_reg_htab[h],
6412 reg, INSERT);
6413
6414 /* Make sure there are no hash table collisions, which would
6415 require chaining entries. */
6416 BFD_ASSERT (*slot == NULL);
6417 *slot = reg;
6418 }
6419 }
6420 }
6421
6422 /* Calculate a hash value for a split condition code. */
6423 static hashval_t
6424 hash_scond (const void *p)
6425 {
6426 split_condition *cp = (split_condition *)p;
6427 char buf[4];
6428
6429 strupper (buf, cp->name);
6430
6431 return htab_hash_string (buf);
6432 }
6433
6434 /* Check if two split condition codes are equal. */
6435 static int
6436 eq_scond (const void *a, const void *b)
6437 {
6438 split_condition *ra = (split_condition *)a;
6439 split_condition *rb = (split_condition *)b;
6440
6441 return strcasecmp (ra->name, rb->name) == 0;
6442 }
6443
6444 /* Create the hash table required for parsing split condition codes. */
6445 static void
6446 create_scond_htab (void)
6447 {
6448 size_t i, nentries;
6449
6450 nentries = sizeof (metag_scondtab) / sizeof (metag_scondtab[0]);
6451
6452 scond_htab = htab_create_alloc (nentries, hash_scond, eq_scond,
6453 NULL, xcalloc, free);
6454 for (i = 0; i < nentries; i++)
6455 {
6456 const split_condition *scond = &metag_scondtab[i];
6457 const split_condition **slot;
6458
6459 slot = (const split_condition **) htab_find_slot (scond_htab,
6460 scond, INSERT);
6461 /* Make sure there are no hash table collisions, which would
6462 require chaining entries. */
6463 BFD_ASSERT (*slot == NULL);
6464 *slot = scond;
6465 }
6466 }
6467
6468 /* Entry point for instruction parsing. */
6469 static bfd_boolean
6470 parse_insn (const char *line, metag_insn *insn)
6471 {
6472 char mnemonic[MAX_MNEMONIC_LEN];
6473 const char *l = line;
6474 size_t mnemonic_len = 0;
6475 insn_templates *templates;
6476
6477 l = skip_space (l);
6478
6479 while (is_mnemonic_char(*l))
6480 {
6481 l++;
6482 mnemonic_len++;
6483 }
6484
6485 if (mnemonic_len >= MAX_MNEMONIC_LEN)
6486 {
6487 as_bad (_("instruction mnemonic too long: %s"), line);
6488 return FALSE;
6489 }
6490
6491 strncpy(mnemonic, line, mnemonic_len);
6492
6493 mnemonic[mnemonic_len] = '\0';
6494
6495 templates = find_insn_templates (mnemonic);
6496
6497 if (templates)
6498 {
6499 insn_templates *current_template = templates;
6500
6501 l = skip_space (l);
6502
6503 while (current_template)
6504 {
6505 const insn_template *template = current_template->template;
6506 enum insn_encoding encoding = template->encoding;
6507 insn_parser parser = insn_parsers[encoding];
6508
6509 current_template = current_template->next;
6510
6511 if (template->insn_type == INSN_GP &&
6512 !(template->core_flags & mcpu_opt))
6513 continue;
6514
6515 if (template->insn_type == INSN_FPU &&
6516 !(template->core_flags & mfpu_opt))
6517 continue;
6518
6519 if (template->insn_type == INSN_DSP &&
6520 !(template->core_flags & mdsp_opt))
6521 continue;
6522
6523 if (template->insn_type == INSN_DSP_FPU &&
6524 !((template->core_flags & mdsp_opt) &&
6525 (template->core_flags & mfpu_opt)))
6526 continue;
6527
6528 /* DSP instructions always require special decoding */
6529 if ((insn->type == INSN_DSP && (template->insn_type != INSN_DSP)) ||
6530 ((template->insn_type == INSN_DSP) && insn->type != INSN_DSP) ||
6531 (insn->type == INSN_DSP_FPU && (template->insn_type != INSN_DSP_FPU)) ||
6532 ((template->insn_type == INSN_DSP_FPU) && insn->type != INSN_DSP_FPU))
6533 continue;
6534
6535 if (parser)
6536 {
6537 const char *end = parser(l, insn, template);
6538
6539 if (end != NULL)
6540 {
6541 if (*end != END_OF_INSN)
6542 as_bad (_("junk at end of line: \"%s\""), line);
6543 else
6544 return TRUE;
6545 }
6546 }
6547 }
6548
6549 as_bad (_("failed to assemble instruction: \"%s\""), line);
6550 }
6551 else
6552 {
6553 if (insn->type == INSN_FPU)
6554 as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic);
6555 else
6556 as_bad (_("unknown mnemonic: \"%s\""), mnemonic);
6557 }
6558 return FALSE;
6559 }
6560
6561 static void
6562 output_insn (metag_insn *insn)
6563 {
6564 char *output;
6565
6566 output = frag_more (insn->len);
6567 dwarf2_emit_insn (insn->len);
6568
6569 if (insn->reloc_type != BFD_RELOC_UNUSED)
6570 {
6571 fix_new_exp (frag_now, output - frag_now->fr_literal,
6572 insn->reloc_size, &insn->reloc_exp,
6573 insn->reloc_pcrel, insn->reloc_type);
6574 }
6575
6576 md_number_to_chars (output, insn->bits, insn->len);
6577 }
6578
6579 void
6580 md_assemble (char *line)
6581 {
6582 const char *l = line;
6583 metag_insn insn;
6584
6585 memset (&insn, 0, sizeof(insn));
6586
6587 insn.reloc_type = BFD_RELOC_UNUSED;
6588 insn.reloc_pcrel = 0;
6589 insn.reloc_size = 4;
6590
6591 if (!mnemonic_htab)
6592 {
6593 create_mnemonic_htab ();
6594 create_reg_htab ();
6595 create_dspreg_htabs ();
6596 create_scond_htab ();
6597 }
6598
6599 l = parse_prefix (l, &insn);
6600
6601 if (l == NULL)
6602 return;
6603
6604 if (insn.type == INSN_DSP &&
6605 !mdsp_opt)
6606 {
6607 as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"),
6608 line);
6609 return;
6610 }
6611 else if (insn.type == INSN_FPU &&
6612 !mfpu_opt)
6613 {
6614 as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"),
6615 line);
6616 return;
6617 }
6618
6619 if (!parse_insn (l, &insn))
6620 return;
6621
6622 output_insn (&insn);
6623 }
6624
6625 void
6626 md_operand (expressionS * expressionP)
6627 {
6628 if (* input_line_pointer == IMM_CHAR)
6629 {
6630 input_line_pointer ++;
6631 expression (expressionP);
6632 }
6633 }
6634
6635 valueT
6636 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
6637 {
6638 return size;
6639 }
6640
6641 symbolS *
6642 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
6643 {
6644 return NULL;
6645 }
6646
6647 /* Functions concerning relocs. */
6648
6649 /* The location from which a PC relative jump should be calculated,
6650 given a PC relative reloc. */
6651
6652 long
6653 md_pcrel_from_section (fixS * fixP, segT sec)
6654 {
6655 if ((fixP->fx_addsy != (symbolS *) NULL
6656 && (! S_IS_DEFINED (fixP->fx_addsy)
6657 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
6658 || metag_force_relocation (fixP))
6659 {
6660 /* The symbol is undefined (or is defined but not in this section).
6661 Let the linker figure it out. */
6662 return 0;
6663 }
6664
6665 return fixP->fx_frag->fr_address + fixP->fx_where;
6666 }
6667
6668 /* Write a value out to the object file, using the appropriate endianness. */
6669
6670 void
6671 md_number_to_chars (char * buf, valueT val, int n)
6672 {
6673 number_to_chars_littleendian (buf, val, n);
6674 }
6675
6676 /* Turn a string in input_line_pointer into a floating point constant of type
6677 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
6678 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
6679 */
6680
6681 /* Equal to MAX_PRECISION in atof-ieee.c */
6682 #define MAX_LITTLENUMS 6
6683
6684 char *
6685 md_atof (int type, char * litP, int * sizeP)
6686 {
6687 int i;
6688 int prec;
6689 LITTLENUM_TYPE words [MAX_LITTLENUMS];
6690 char * t;
6691
6692 switch (type)
6693 {
6694 case 'f':
6695 case 'F':
6696 case 's':
6697 case 'S':
6698 prec = 2;
6699 break;
6700
6701 case 'd':
6702 case 'D':
6703 case 'r':
6704 case 'R':
6705 prec = 4;
6706 break;
6707
6708 /* FIXME: Some targets allow other format chars for bigger sizes here. */
6709
6710 default:
6711 * sizeP = 0;
6712 return _("Bad call to md_atof()");
6713 }
6714
6715 t = atof_ieee (input_line_pointer, type, words);
6716 if (t)
6717 input_line_pointer = t;
6718 * sizeP = prec * sizeof (LITTLENUM_TYPE);
6719
6720 for (i = 0; i < prec; i++)
6721 {
6722 md_number_to_chars (litP, (valueT) words[i],
6723 sizeof (LITTLENUM_TYPE));
6724 litP += sizeof (LITTLENUM_TYPE);
6725 }
6726
6727 return 0;
6728 }
6729
6730 /* If this function returns non-zero, it prevents the relocation
6731 against symbol(s) in the FIXP from being replaced with relocations
6732 against section symbols, and guarantees that a relocation will be
6733 emitted even when the value can be resolved locally. */
6734
6735 int
6736 metag_force_relocation (fixS * fix)
6737 {
6738 switch (fix->fx_r_type)
6739 {
6740 case BFD_RELOC_METAG_RELBRANCH_PLT:
6741 case BFD_RELOC_METAG_TLS_LE:
6742 case BFD_RELOC_METAG_TLS_IE:
6743 case BFD_RELOC_METAG_TLS_LDO:
6744 case BFD_RELOC_METAG_TLS_LDM:
6745 case BFD_RELOC_METAG_TLS_GD:
6746 return 1;
6747 default:
6748 ;
6749 }
6750
6751 return generic_force_reloc (fix);
6752 }
6753
6754 bfd_boolean
6755 metag_fix_adjustable (fixS * fixP)
6756 {
6757 if (fixP->fx_addsy == NULL)
6758 return 1;
6759
6760 /* Prevent all adjustments to global symbols. */
6761 if (S_IS_EXTERNAL (fixP->fx_addsy))
6762 return 0;
6763 if (S_IS_WEAK (fixP->fx_addsy))
6764 return 0;
6765
6766 if (fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTOFF ||
6767 fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTOFF ||
6768 fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOTOFF ||
6769 fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOT ||
6770 fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTPC ||
6771 fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTPC ||
6772 fixP->fx_r_type == BFD_RELOC_METAG_HI16_PLT ||
6773 fixP->fx_r_type == BFD_RELOC_METAG_LO16_PLT ||
6774 fixP->fx_r_type == BFD_RELOC_METAG_RELBRANCH_PLT)
6775 return 0;
6776
6777 /* We need the symbol name for the VTABLE entries. */
6778 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6779 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6780 return 0;
6781
6782 return 1;
6783 }
6784
6785 /* Return an initial guess of the length by which a fragment must grow to
6786 hold a branch to reach its destination.
6787 Also updates fr_type/fr_subtype as necessary.
6788
6789 Called just before doing relaxation.
6790 Any symbol that is now undefined will not become defined.
6791 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
6792 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
6793 Although it may not be explicit in the frag, pretend fr_var starts with a
6794 0 value. */
6795
6796 int
6797 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
6798 segT segment ATTRIBUTE_UNUSED)
6799 {
6800 /* No assembler relaxation is defined (or necessary) for this port. */
6801 abort ();
6802 }
6803
6804 /* *fragP has been relaxed to its final size, and now needs to have
6805 the bytes inside it modified to conform to the new size.
6806
6807 Called after relaxation is finished.
6808 fragP->fr_type == rs_machine_dependent.
6809 fragP->fr_subtype is the subtype of what the address relaxed to. */
6810
6811 void
6812 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
6813 fragS * fragP ATTRIBUTE_UNUSED)
6814 {
6815 /* No assembler relaxation is defined (or necessary) for this port. */
6816 abort ();
6817 }
6818
6819 /* This is called from HANDLE_ALIGN in tc-metag.h. */
6820
6821 void
6822 metag_handle_align (fragS * fragP)
6823 {
6824 static char const noop[4] = { 0xfe, 0xff, 0xff, 0xa0 };
6825 int bytes, fix;
6826 char *p;
6827
6828 if (fragP->fr_type != rs_align_code)
6829 return;
6830
6831 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
6832 p = fragP->fr_literal + fragP->fr_fix;
6833 fix = 0;
6834
6835 if (bytes & 3)
6836 {
6837 fix = bytes & 3;
6838 memset (p, 0, fix);
6839 p += fix;
6840 bytes -= fix;
6841 }
6842
6843 while (bytes >= 4)
6844 {
6845 memcpy (p, noop, 4);
6846 p += 4;
6847 bytes -= 4;
6848 fix += 4;
6849 }
6850
6851 fragP->fr_fix += fix;
6852 fragP->fr_var = 4;
6853 }
6854
6855 static char *
6856 metag_end_of_match (char * cont, char * what)
6857 {
6858 int len = strlen (what);
6859
6860 if (strncasecmp (cont, what, strlen (what)) == 0
6861 && ! is_part_of_name (cont[len]))
6862 return cont + len;
6863
6864 return NULL;
6865 }
6866
6867 int
6868 metag_parse_name (char const * name, expressionS * exprP, enum expr_mode mode,
6869 char * nextcharP)
6870 {
6871 char *next = input_line_pointer;
6872 char *next_end;
6873 int reloc_type;
6874 operatorT op_type;
6875 segT segment;
6876
6877 exprP->X_op_symbol = NULL;
6878 exprP->X_md = BFD_RELOC_UNUSED;
6879
6880 if (strcmp (name, GOT_NAME) == 0)
6881 {
6882 if (! GOT_symbol)
6883 GOT_symbol = symbol_find_or_make (name);
6884
6885 exprP->X_add_symbol = GOT_symbol;
6886 no_suffix:
6887 /* If we have an absolute symbol or a
6888 reg, then we know its value now. */
6889 segment = S_GET_SEGMENT (exprP->X_add_symbol);
6890 if (mode != expr_defer && segment == absolute_section)
6891 {
6892 exprP->X_op = O_constant;
6893 exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
6894 exprP->X_add_symbol = NULL;
6895 }
6896 else if (mode != expr_defer && segment == reg_section)
6897 {
6898 exprP->X_op = O_register;
6899 exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
6900 exprP->X_add_symbol = NULL;
6901 }
6902 else
6903 {
6904 exprP->X_op = O_symbol;
6905 exprP->X_add_number = 0;
6906 }
6907
6908 return 1;
6909 }
6910
6911 exprP->X_add_symbol = symbol_find_or_make (name);
6912
6913 if (*nextcharP != '@')
6914 goto no_suffix;
6915 else if ((next_end = metag_end_of_match (next + 1, "GOTOFF")))
6916 {
6917 reloc_type = BFD_RELOC_METAG_GOTOFF;
6918 op_type = O_PIC_reloc;
6919 }
6920 else if ((next_end = metag_end_of_match (next + 1, "GOT")))
6921 {
6922 reloc_type = BFD_RELOC_METAG_GETSET_GOT;
6923 op_type = O_PIC_reloc;
6924 }
6925 else if ((next_end = metag_end_of_match (next + 1, "PLT")))
6926 {
6927 reloc_type = BFD_RELOC_METAG_PLT;
6928 op_type = O_PIC_reloc;
6929 }
6930 else if ((next_end = metag_end_of_match (next + 1, "TLSGD")))
6931 {
6932 reloc_type = BFD_RELOC_METAG_TLS_GD;
6933 op_type = O_PIC_reloc;
6934 }
6935 else if ((next_end = metag_end_of_match (next + 1, "TLSLDM")))
6936 {
6937 reloc_type = BFD_RELOC_METAG_TLS_LDM;
6938 op_type = O_PIC_reloc;
6939 }
6940 else if ((next_end = metag_end_of_match (next + 1, "TLSLDO")))
6941 {
6942 reloc_type = BFD_RELOC_METAG_TLS_LDO;
6943 op_type = O_PIC_reloc;
6944 }
6945 else if ((next_end = metag_end_of_match (next + 1, "TLSIE")))
6946 {
6947 reloc_type = BFD_RELOC_METAG_TLS_IE;
6948 op_type = O_PIC_reloc;
6949 }
6950 else if ((next_end = metag_end_of_match (next + 1, "TLSIENONPIC")))
6951 {
6952 reloc_type = BFD_RELOC_METAG_TLS_IENONPIC;
6953 op_type = O_PIC_reloc; /* FIXME: is this correct? */
6954 }
6955 else if ((next_end = metag_end_of_match (next + 1, "TLSLE")))
6956 {
6957 reloc_type = BFD_RELOC_METAG_TLS_LE;
6958 op_type = O_PIC_reloc;
6959 }
6960 else
6961 goto no_suffix;
6962
6963 *input_line_pointer = *nextcharP;
6964 input_line_pointer = next_end;
6965 *nextcharP = *input_line_pointer;
6966 *input_line_pointer = '\0';
6967
6968 exprP->X_op = op_type;
6969 exprP->X_add_number = 0;
6970 exprP->X_md = reloc_type;
6971
6972 return 1;
6973 }
6974
6975 /* If while processing a fixup, a reloc really needs to be created
6976 then it is done here. */
6977
6978 arelent *
6979 tc_gen_reloc (seg, fixp)
6980 asection *seg ATTRIBUTE_UNUSED;
6981 fixS *fixp;
6982 {
6983 arelent *reloc;
6984
6985 reloc = (arelent *) xmalloc (sizeof (arelent));
6986 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
6987 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
6988 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
6989
6990 reloc->addend = fixp->fx_offset;
6991 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
6992
6993 if (reloc->howto == (reloc_howto_type *) NULL)
6994 {
6995 as_bad_where (fixp->fx_file, fixp->fx_line,
6996 /* xgettext:c-format. */
6997 _("reloc %d not supported by object file format"),
6998 (int) fixp->fx_r_type);
6999
7000 xfree (reloc);
7001
7002 return NULL;
7003 }
7004
7005 return reloc;
7006 }
7007
7008 static unsigned int
7009 md_chars_to_number (char *val, int n)
7010 {
7011 int retval;
7012 unsigned char * where = (unsigned char *) val;
7013
7014 for (retval = 0; n--;)
7015 {
7016 retval <<= 8;
7017 retval |= where[n];
7018 }
7019 return retval;
7020 }
7021
7022 void
7023 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
7024 {
7025 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
7026 int value = (int)*valP;
7027
7028 switch (fixP->fx_r_type)
7029 {
7030 case BFD_RELOC_METAG_TLS_GD:
7031 case BFD_RELOC_METAG_TLS_LE_HI16:
7032 case BFD_RELOC_METAG_TLS_LE_LO16:
7033 case BFD_RELOC_METAG_TLS_IE:
7034 case BFD_RELOC_METAG_TLS_IENONPIC_HI16:
7035 case BFD_RELOC_METAG_TLS_IENONPIC_LO16:
7036 case BFD_RELOC_METAG_TLS_LDM:
7037 case BFD_RELOC_METAG_TLS_LDO_HI16:
7038 case BFD_RELOC_METAG_TLS_LDO_LO16:
7039 S_SET_THREAD_LOCAL (fixP->fx_addsy);
7040 /* Fall through */
7041
7042 case BFD_RELOC_METAG_HIADDR16:
7043 case BFD_RELOC_METAG_LOADDR16:
7044 case BFD_RELOC_VTABLE_INHERIT:
7045 case BFD_RELOC_VTABLE_ENTRY:
7046 fixP->fx_done = FALSE;
7047 break;
7048
7049 case BFD_RELOC_METAG_REL8:
7050 if (!within_unsigned_range (value, IMM8_BITS))
7051 {
7052 as_bad_where (fixP->fx_file, fixP->fx_line,
7053 "rel8 out of range %d", value);
7054 }
7055 else
7056 {
7057 unsigned int newval;
7058 newval = md_chars_to_number (buf, 4);
7059 newval = (newval & 0xffffc03f) | ((value & IMM8_MASK) << 6);
7060 md_number_to_chars (buf, newval, 4);
7061 }
7062 break;
7063 case BFD_RELOC_METAG_REL16:
7064 if (!within_unsigned_range (value, IMM16_BITS))
7065 {
7066 as_bad_where (fixP->fx_file, fixP->fx_line,
7067 "rel16 out of range %d", value);
7068 }
7069 else
7070 {
7071 unsigned int newval;
7072 newval = md_chars_to_number (buf, 4);
7073 newval = (newval & 0xfff80007) | ((value & IMM16_MASK) << 3);
7074 md_number_to_chars (buf, newval, 4);
7075 }
7076 break;
7077
7078 case BFD_RELOC_8:
7079 md_number_to_chars (buf, value, 1);
7080 break;
7081 case BFD_RELOC_16:
7082 md_number_to_chars (buf, value, 2);
7083 break;
7084 case BFD_RELOC_32:
7085 md_number_to_chars (buf, value, 4);
7086 break;
7087 case BFD_RELOC_64:
7088 md_number_to_chars (buf, value, 8);
7089
7090 case BFD_RELOC_METAG_RELBRANCH:
7091 if (!value)
7092 break;
7093
7094 value = value / 4;
7095
7096 if (!within_signed_range (value, IMM19_BITS))
7097 {
7098 as_bad_where (fixP->fx_file, fixP->fx_line,
7099 "relbranch out of range %d", value);
7100 }
7101 else
7102 {
7103 unsigned int newval;
7104 newval = md_chars_to_number (buf, 4);
7105 newval = (newval & 0xff00001f) | ((value & IMM19_MASK) << 5);
7106 md_number_to_chars (buf, newval, 4);
7107 }
7108 break;
7109 default:
7110 break;
7111 }
7112
7113 if (fixP->fx_addsy == NULL)
7114 fixP->fx_done = TRUE;
7115 }