[PATCH 8/57][Arm][GAS] Add support for MVE instructions: vcvt
[deliverable/binutils-gdb.git] / gas / config / tc-s12z.c
CommitLineData
7b4ae824 1/* tc-s12z.c -- Assembler code for the Freescale S12Z
82704155 2 Copyright (C) 2018-2019 Free Software Foundation, Inc.
7b4ae824
JD
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA. */
20
21#include "as.h"
22#include "safe-ctype.h"
23#include "subsegs.h"
24#include "dwarf2dbg.h"
7ba3ba91 25#include "opcode/s12z.h"
7b4ae824
JD
26#include <stdint.h>
27#include <limits.h>
28#include <stdbool.h>
29
30const char comment_chars[] = ";";
31
32const char line_comment_chars[] = "#*";
33const char line_separator_chars[] = "";
34
95008a88
JD
35static char * register_prefix = NULL;
36
7b4ae824
JD
37const char EXP_CHARS[] = "eE";
38const char FLT_CHARS[] = "dD";
39
40static char *fail_line_pointer;
41
42\f
43/* Options and initialization. */
44
95008a88 45const char *md_shortopts = "";
7b4ae824
JD
46
47struct option md_longopts[] =
48 {
95008a88
JD
49 {"mreg-prefix", required_argument, NULL, OPTION_MD_BASE},
50 {NULL, no_argument, NULL, 0}
7b4ae824
JD
51 };
52
53size_t md_longopts_size = sizeof (md_longopts);
54\f
55
56relax_typeS md_relax_table[] =
57 {
58
59 };
60
61/* This table describes all the machine specific pseudo-ops the assembler
62 has to support. The fields are:
63 pseudo-op name without dot
64 function to call to execute this pseudo-op
65 Integer arg to pass to the function. */
66const pseudo_typeS md_pseudo_table[] =
67 {
68 {0, 0, 0}
69 };
70\f
71
72/* Get the target cpu for the assembler. */
73const char *
74s12z_arch_format (void)
75{
76 return "elf32-s12z";
77}
78
79enum bfd_architecture
80s12z_arch (void)
81{
82 return bfd_arch_s12z;
83}
84
85int
86s12z_mach (void)
87{
88 return 0;
89}
90
91/* Listing header selected according to cpu. */
92const char *
93s12z_listing_header (void)
94{
95 return "S12Z GAS ";
96}
97
98void
95008a88 99md_show_usage (FILE *stream)
7b4ae824 100{
95008a88
JD
101 fprintf (stream,
102 _("\ns12z options:\n"
103 " -mreg-prefix=PREFIX set a prefix used to indicate register names (default none)"
104 "\n"));
7b4ae824
JD
105}
106
107void
108s12z_print_statistics (FILE *file ATTRIBUTE_UNUSED)
109{
110}
111
112int
95008a88 113md_parse_option (int c, const char *arg)
7b4ae824 114{
95008a88
JD
115 switch (c)
116 {
117 case OPTION_MD_BASE:
118 register_prefix = xstrdup (arg);
119 break;
120 default:
121 return 0;
122 }
123 return 1;
7b4ae824
JD
124}
125\f
126symbolS *
127md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
128{
129 return 0;
130}
131
132const char *
133md_atof (int type, char *litP, int *sizeP)
134{
135 return ieee_md_atof (type, litP, sizeP, TRUE);
136}
137
138valueT
139md_section_align (asection *seg, valueT addr)
140{
141 int align = bfd_get_section_alignment (stdoutput, seg);
142 return ((addr + (1 << align) - 1) & -(1 << align));
143}
144
145void
146md_begin (void)
147{
148}
149
150void
151s12z_init_after_args (void)
152{
153}
154\f
155/* Builtin help. */
156
157
158static char *
159skip_whites (char *p)
160{
161 while (*p == ' ' || *p == '\t')
162 p++;
163
164 return p;
165}
166
167
168
169/* Start a new insn that contains at least 'size' bytes. Record the
170 line information of that insn in the dwarf2 debug sections. */
171static char *
172s12z_new_insn (int size)
173{
174 char *f = frag_more (size);
175
176 dwarf2_emit_insn (size);
177
178 return f;
179}
180
181\f
182
d04ebfb8 183static bfd_boolean lex_reg_name (uint16_t which, int *reg);
7b4ae824 184
d04ebfb8 185static bfd_boolean
7b4ae824
JD
186lex_constant (long *v)
187{
188 char *end = NULL;
189 char *p = input_line_pointer;
190
191 /* A constant may not have the same value as a register
192 eg: "d6" */
193 int dummy;
194 if (lex_reg_name (~0, &dummy))
195 {
196 input_line_pointer = p;
d04ebfb8 197 return false;
7b4ae824
JD
198 }
199
200 errno = 0;
201 *v = strtol (p, &end, 0);
202 if (errno == 0 && end != p)
203 {
204 input_line_pointer = end;
d04ebfb8 205 return true;
7b4ae824
JD
206 }
207
d04ebfb8 208 return false;
7b4ae824
JD
209}
210
d04ebfb8 211static bfd_boolean
7b4ae824
JD
212lex_match (char x)
213{
214 char *p = input_line_pointer;
215 if (*p != x)
d04ebfb8 216 return false;
7b4ae824
JD
217
218 input_line_pointer++;
d04ebfb8 219 return true;
7b4ae824
JD
220}
221
222
d04ebfb8 223static bfd_boolean
7b4ae824
JD
224lex_expression (expressionS *exp)
225{
226 char *ilp = input_line_pointer;
227 int dummy;
228 exp->X_op = O_absent;
229
230 if (lex_match ('#'))
231 goto fail;
232
233 if (lex_reg_name (~0, &dummy))
234 goto fail;
235
236 expression (exp);
237 if (exp->X_op != O_absent)
d04ebfb8 238 return true;
7b4ae824
JD
239
240 fail:
241 fail_line_pointer = input_line_pointer;
242 input_line_pointer = ilp;
d04ebfb8 243 return false;
7b4ae824
JD
244}
245
c6f14c0d
JD
246/* Immediate operand.
247 If EXP_O is non-null, then a symbolic expression is permitted,
248 in which case, EXP_O will be populated with the parsed expression.
249 */
d04ebfb8 250static bfd_boolean
c6f14c0d 251lex_imm (long *v, expressionS *exp_o)
7b4ae824
JD
252{
253 char *ilp = input_line_pointer;
254
255 if (*input_line_pointer != '#')
256 goto fail;
257
258 input_line_pointer++;
259 expressionS exp;
260 if (!lex_expression (&exp))
261 goto fail;
262
263 if (exp.X_op != O_constant)
c6f14c0d
JD
264 {
265 if (!exp_o)
266 as_bad (_("A non-constant expression is not permitted here"));
267 else
268 *exp_o = exp;
269 }
7b4ae824
JD
270
271 *v = exp.X_add_number;
d04ebfb8 272 return true;
7b4ae824
JD
273
274fail:
275 fail_line_pointer = input_line_pointer;
276 input_line_pointer = ilp;
d04ebfb8 277 return false;
7b4ae824
JD
278}
279
280/* Short mmediate operand */
d04ebfb8 281static bfd_boolean
7b4ae824
JD
282lex_imm_e4 (long *val)
283{
284 char *ilp = input_line_pointer;
c6f14c0d 285 if ((lex_imm (val, NULL)))
7b4ae824
JD
286 {
287 if ((*val == -1) || (*val > 0 && *val <= 15))
288 {
d04ebfb8 289 return true;
7b4ae824
JD
290 }
291 }
292 fail_line_pointer = input_line_pointer;
293 input_line_pointer = ilp;
d04ebfb8 294 return false;
7b4ae824
JD
295}
296
d04ebfb8 297static bfd_boolean
7b4ae824
JD
298lex_match_string (const char *s)
299{
300 char *p = input_line_pointer;
301 while (p != 0 && *p != '\t' && *p != ' ' && *p != '\0')
302 {
303 p++;
304 }
305
306 size_t len = p - input_line_pointer;
307 if (len != strlen (s))
d04ebfb8 308 return false;
7b4ae824
JD
309
310 if (0 == strncasecmp (s, input_line_pointer, len))
311 {
312 input_line_pointer = p;
d04ebfb8 313 return true;
7b4ae824
JD
314 }
315
d04ebfb8 316 return false;
7b4ae824
JD
317}
318
319/* Parse a register name.
320 WHICH is a ORwise combination of the registers which are accepted.
321 ~0 accepts all.
322 On success, REG will be filled with the index of the register which
323 was successfully scanned.
324*/
d04ebfb8 325static bfd_boolean
7b4ae824
JD
326lex_reg_name (uint16_t which, int *reg)
327{
328 char *p = input_line_pointer;
95008a88
JD
329
330 if (p == 0)
331 return false;
332
333 /* Scan (and ignore) the register prefix. */
334 if (register_prefix)
335 {
336 int len = strlen (register_prefix);
337 if (0 == strncmp (register_prefix, p, len))
338 p += len;
339 else
340 return false;
341 }
342
343 char *start_of_reg_name = p;
344
345 while ((*p >= 'a' && *p <='z')
346 || (*p >= '0' && *p <= '9')
347 || (*p >= 'A' && *p <='Z'))
7b4ae824
JD
348 {
349 p++;
350 }
351
95008a88 352 size_t len = p - start_of_reg_name;
7b4ae824
JD
353
354 if (len <= 0)
d04ebfb8 355 return false;
7b4ae824
JD
356
357 int i;
358 for (i = 0; i < S12Z_N_REGISTERS; ++i)
359 {
360 gas_assert (registers[i].name);
361
e7b47f2e 362 if (len == strlen (registers[i].name)
95008a88 363 && 0 == strncasecmp (registers[i].name, start_of_reg_name, len))
7b4ae824
JD
364 {
365 if ((0x1U << i) & which)
366 {
367 input_line_pointer = p;
368 *reg = i;
d04ebfb8 369 return true;
7b4ae824
JD
370 }
371 }
372 }
373
d04ebfb8 374 return false;
7b4ae824
JD
375}
376
377static int
378lex_force_match (char x)
379{
380 char *p = input_line_pointer;
381 if (*p != x)
382 {
383 as_bad (_("Expecting '%c'"), x);
d04ebfb8 384 return false;
7b4ae824
JD
385 }
386
387 input_line_pointer++;
d04ebfb8 388 return true;
7b4ae824
JD
389}
390
d04ebfb8 391static bfd_boolean
8b3a46f9
JD
392lex_opr (uint8_t *buffer, int *n_bytes, expressionS *exp,
393 bool immediate_ok)
7b4ae824
JD
394{
395 char *ilp = input_line_pointer;
396 uint8_t *xb = buffer;
397 int reg;
398 long imm;
399 exp->X_op = O_absent;
400 *n_bytes = 0;
401 *xb = 0;
402 if (lex_imm_e4 (&imm))
403 {
8b3a46f9
JD
404 if (!immediate_ok)
405 {
406 as_bad (_("An immediate value in a source operand is inappropriate"));
d04ebfb8 407 return false;
8b3a46f9 408 }
7b4ae824
JD
409 if (imm > 0)
410 *xb = imm;
411 else
412 *xb = 0;
413 *xb |= 0x70;
414 *n_bytes = 1;
d04ebfb8 415 return true;
7b4ae824
JD
416 }
417 else if (lex_reg_name (REG_BIT_Dn, &reg))
418 {
419 *xb = reg;
420 *xb |= 0xb8;
421 *n_bytes = 1;
d04ebfb8 422 return true;
7b4ae824
JD
423 }
424 else if (lex_match ('['))
425 {
426 if (lex_expression (exp))
427 {
428 long c = exp->X_add_number;
429 if (lex_match (','))
430 {
431 if (lex_reg_name (REG_BIT_XYSP, &reg))
432 {
433 int i;
434 if (c <= 255 && c >= -256)
435 {
436 *n_bytes = 2;
437 *xb |= 0xc4;
438 }
439 else
440 {
441 *n_bytes = 4;
442 *xb |= 0xc6;
443 }
444 *xb |= (reg - REG_X) << 4;
445
446 if (c < 0)
447 *xb |= 0x01;
448 for (i = 1; i < *n_bytes ; ++i)
449 {
450 buffer[i] = c >> (8 * (*n_bytes - i - 1));
451 }
452 }
453 else
454 {
455 as_bad (_("Bad operand for constant offset"));
456 goto fail;
457 }
458 }
459 else
460 {
461 *xb = 0xfe;
462 *n_bytes = 4;
463 buffer[1] = c >> 16;
464 buffer[2] = c >> 8;
465 buffer[3] = c;
466 }
467 }
468 else if (lex_reg_name (REG_BIT_Dn, &reg))
469 {
470 if (!lex_force_match (','))
471 goto fail;
472
473 int reg2;
474 if (lex_reg_name (REG_BIT_XY, &reg2))
475 {
476 *n_bytes = 1;
477 *xb = reg;
478 *xb |= (reg2 - REG_X) << 4;
479 *xb |= 0xc8;
480 }
481 else
482 {
483 as_bad (_("Invalid operand for register offset"));
484 goto fail;
485 }
486 }
487 else
488 {
489 goto fail;
490 }
491 if (!lex_force_match (']'))
492 goto fail;
d04ebfb8 493 return true;
7b4ae824
JD
494 }
495 else if (lex_match ('('))
496 {
497 long c;
498 if (lex_constant (&c))
499 {
500 if (!lex_force_match (','))
501 goto fail;
502 int reg2;
503 if (lex_reg_name (REG_BIT_XYSP, &reg2))
504 {
505 if (reg2 != REG_P && c >= 0 && c <= 15)
506 {
507 *n_bytes = 1;
508 *xb = 0x40;
509 *xb |= (reg2 - REG_X) << 4;
510 *xb |= c;
511 }
512 else if (c >= -256 && c <= 255)
513 {
514 *n_bytes = 2;
515 *xb = 0xc0;
516 *xb |= (reg2 - REG_X) << 4;
517 if (c < 0)
518 *xb |= 0x01;
519 buffer[1] = c;
520 }
521 else
522 {
523 *n_bytes = 4;
524 *xb = 0xc2;
525 *xb |= (reg2 - REG_X) << 4;
526 buffer[1] = c >> 16;
527 buffer[2] = c >> 8;
528 buffer[3] = c;
529 }
530 }
531 else if (lex_reg_name (REG_BIT_Dn, &reg2))
532 {
533 if (c >= -1 * (long) (0x1u << 17)
534 &&
535 c < (long) (0x1u << 17) - 1)
536 {
537 *n_bytes = 3;
538 *xb = 0x80;
539 *xb |= reg2;
540 *xb |= ((c >> 16) & 0x03) << 4;
541 buffer[1] = c >> 8;
542 buffer[2] = c;
543 }
544 else
545 {
546 *n_bytes = 4;
547 *xb = 0xe8;
548 *xb |= reg2;
549 buffer[1] = c >> 16;
550 buffer[2] = c >> 8;
551 buffer[3] = c;
552 }
553 }
554 else
555 {
556 as_bad (_("Bad operand for constant offset"));
557 goto fail;
558 }
559 }
560 else if (lex_reg_name (REG_BIT_Dn, &reg))
561 {
562 if (lex_match (','))
563 {
564 int reg2;
565 if (lex_reg_name (REG_BIT_XYS, &reg2))
566 {
567 *n_bytes = 1;
568 *xb = 0x88;
569 *xb |= (reg2 - REG_X) << 4;
570 *xb |= reg;
571 }
572 else
573 {
574 as_bad (_("Invalid operand for register offset"));
575 goto fail;
576 }
577 }
578 else
579 {
580 goto fail;
581 }
582 }
583 else if (lex_reg_name (REG_BIT_XYS, &reg))
584 {
585 if (lex_match ('-'))
586 {
587 if (reg == REG_S)
588 {
589 as_bad (_("Invalid register for postdecrement operation"));
590 goto fail;
591 }
592 *n_bytes = 1;
593 if (reg == REG_X)
594 *xb = 0xc7;
595 else if (reg == REG_Y)
596 *xb = 0xd7;
597 }
598 else if (lex_match ('+'))
599 {
600 *n_bytes = 1;
601 if (reg == REG_X)
602 *xb = 0xe7;
603 else if (reg == REG_Y)
604 *xb = 0xf7;
605 else if (reg == REG_S)
606 *xb = 0xff;
607 }
608 else
609 {
610 goto fail;
611 }
612 }
613 else if (lex_match ('+'))
614 {
615 if (lex_reg_name (REG_BIT_XY, &reg))
616 {
617 *n_bytes = 1;
618 if (reg == REG_X)
619 *xb = 0xe3;
620 else if (reg == REG_Y)
621 *xb = 0xf3;
622 }
623 else
624 {
625 as_bad (_("Invalid register for preincrement operation"));
626 goto fail;
627 }
628 }
629 else if (lex_match ('-'))
630 {
631 if (lex_reg_name (REG_BIT_XYS, &reg))
632 {
633 *n_bytes = 1;
634 if (reg == REG_X)
635 *xb = 0xc3;
636 else if (reg == REG_Y)
637 *xb = 0xd3;
638 else if (reg == REG_S)
639 *xb = 0xfb;
640 }
641 else
642 {
643 as_bad (_("Invalid register for predecrement operation"));
644 goto fail;
645 }
646 }
647 else
648 {
649 goto fail;
650 }
651
652 if (! lex_match (')'))
653 goto fail;
d04ebfb8 654 return true;
7b4ae824
JD
655 }
656 else if (lex_expression (exp))
657 {
658 *xb = 0xfa;
659 *n_bytes = 4;
660 buffer[1] = 0;
661 buffer[2] = 0;
662 buffer[3] = 0;
663 if (exp->X_op == O_constant)
664 {
fa9d2bd6
MR
665 valueT value = exp->X_add_number;
666
667 if (value < (0x1U << 14))
7b4ae824
JD
668 {
669 *xb = 0x00;
670 *n_bytes = 2;
fa9d2bd6
MR
671 *xb |= value >> 8;
672 buffer[1] = value;
7b4ae824 673 }
fa9d2bd6 674 else if (value < (0x1U << 19))
7b4ae824
JD
675 {
676 *xb = 0xf8;
fa9d2bd6 677 if (value & (0x1U << 17))
7b4ae824 678 *xb |= 0x04;
fa9d2bd6 679 if (value & (0x1U << 16))
7b4ae824
JD
680 *xb |= 0x01;
681 *n_bytes = 3;
fa9d2bd6
MR
682 buffer[1] = value >> 8;
683 buffer[2] = value;
7b4ae824
JD
684 }
685 else
686 {
687 *xb = 0xfa;
688 *n_bytes = 4;
fa9d2bd6
MR
689 buffer[1] = value >> 16;
690 buffer[2] = value >> 8;
691 buffer[3] = value;
7b4ae824
JD
692 }
693 }
d04ebfb8 694 return true;
7b4ae824
JD
695 }
696
697 fail:
698 fail_line_pointer = input_line_pointer;
699 input_line_pointer = ilp;
d04ebfb8 700 return false;
7b4ae824
JD
701}
702
d04ebfb8 703static bfd_boolean
7b4ae824
JD
704lex_offset (long *val)
705{
706 char *end = NULL;
707 char *p = input_line_pointer;
708
709 if (*p++ != '*')
d04ebfb8 710 return false;
7b4ae824
JD
711
712 if (*p != '+' && *p != '-')
d04ebfb8 713 return false;
7b4ae824
JD
714
715 bool negative = (*p == '-');
716 p++;
717
718 errno = 0;
719 *val = strtol (p, &end, 0);
720 if (errno == 0)
721 {
722 if (negative)
723 *val *= -1;
724 input_line_pointer = end;
d04ebfb8 725 return true;
7b4ae824
JD
726 }
727
d04ebfb8 728 return false;
7b4ae824
JD
729}
730
731\f
732
733struct instruction;
734
735typedef int (*parse_operand_func) (const struct instruction *);
736
737struct instruction
738{
739 const char *name;
740
741 /* The "page" to which the instruction belongs.
742 This is also only a hint. Some instructions might have modes in both
743 pages... */
744 char page;
745
746 /* This is a hint - and only a hint - about the opcode of the instruction.
747 The parse_operand_func is free to ignore it.
748 */
749 uint8_t opc;
750
751 parse_operand_func parse_operands;
752
753 /* Some instructions can be encoded with a different opcode */
754 uint8_t alt_opc;
755};
756
757static int
758no_operands (const struct instruction *insn)
759{
760 if (*input_line_pointer != '\0')
761 {
762 as_bad (_("Garbage at end of instruction"));
d04ebfb8 763 return false;
7b4ae824
JD
764 }
765
766 char *f = s12z_new_insn (insn->page);
767 if (insn->page == 2)
768 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
769
770 number_to_chars_bigendian (f++, insn->opc, 1);
771
d04ebfb8 772 return true;
7b4ae824
JD
773}
774
c6f14c0d
JD
775
776static void
777emit_reloc (expressionS *exp, char *f, int size, enum bfd_reloc_code_real reloc)
7b4ae824 778{
7b4ae824
JD
779 if (exp->X_op != O_absent && exp->X_op != O_constant)
780 {
d5dcaf1b
JD
781 fixS *fix = fix_new_exp (frag_now,
782 f - frag_now->fr_literal,
c6f14c0d 783 size,
d5dcaf1b
JD
784 exp,
785 FALSE,
c6f14c0d 786 reloc);
d5dcaf1b 787 /* Some third party tools seem to use the lower bits
c6f14c0d
JD
788 of this addend for flags. They don't get added
789 to the final location. The purpose of these flags
790 is not known. We simply set it to zero. */
d5dcaf1b 791 fix->fx_addnumber = 0x00;
7b4ae824 792 }
c6f14c0d
JD
793}
794
795/* Emit the code for an OPR address mode operand */
796static char *
797emit_opr (char *f, const uint8_t *buffer, int n_bytes, expressionS *exp)
798{
799 int i;
800 number_to_chars_bigendian (f++, buffer[0], 1);
801
802 emit_reloc (exp, f, 3, BFD_RELOC_S12Z_OPR);
803
7b4ae824
JD
804 for (i = 1; i < n_bytes; ++i)
805 number_to_chars_bigendian (f++, buffer[i], 1);
806
807 return f;
808}
809
810/* Emit the code for a 24 bit direct address operand */
811static char *
812emit_ext24 (char *f, long v)
813{
814 number_to_chars_bigendian (f, v, 3);
815
816 return f + 3;
817}
818
d04ebfb8 819static bfd_boolean
7b4ae824
JD
820opr (const struct instruction *insn)
821{
822 uint8_t buffer[4];
823 int n_bytes;
824 expressionS exp;
8b3a46f9 825 if (lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
826 {
827 /* Large constant direct values are more efficiently encoded as ext24 mode.
828 Otherwise a decision has to be deferred to a relax. */
829 if (exp.X_op == O_constant
830 && buffer[0] == 0xFA
831 && insn->alt_opc != 0)
832 {
833 char *f = s12z_new_insn (4);
834
835 /* I don't think there are any instances of page 2 opcodes in this case */
836 gas_assert (insn->page == 1);
837
838 number_to_chars_bigendian (f++, insn->alt_opc, 1);
839
840 emit_ext24 (f, exp.X_add_number);
841 }
842 else
843 {
844 char *f = s12z_new_insn (n_bytes + 1);
845 number_to_chars_bigendian (f++, insn->opc, 1);
846
847 emit_opr (f, buffer, n_bytes, &exp);
848 }
d04ebfb8 849 return true;
7b4ae824
JD
850 }
851
d04ebfb8 852 return false;
7b4ae824
JD
853}
854
855/* Parse a 15 bit offset, as an expression.
856 LONG_DISPLACEMENT will be set to true if the offset is wider than 7 bits.
857 */
d04ebfb8 858static bfd_boolean
7b4ae824
JD
859lex_15_bit_offset (bool *long_displacement, expressionS *exp)
860{
861 char *ilp = input_line_pointer;
862
863 long val;
864 if (lex_offset (&val))
865 {
866 exp->X_op = O_absent;
867 exp->X_add_number = val;
868 }
869 else if (lex_expression (exp))
870 {
871 if (exp->X_op == O_constant)
872 {
873 val = exp->X_add_number;
874 }
875 else
876 {
877 /* If a symbol was parsed we don't know the displacement.
878 We have to assume it is long, and relax it later if possible. */
879 *long_displacement = true;
d04ebfb8 880 return true;
7b4ae824
JD
881 }
882 }
883 else
884 {
885 exp->X_op = O_absent;
886 goto fail;
887 }
888
889 if (val > 0x3FFF || val < -0x4000)
890 {
891 as_fatal (_("Offset is outside of 15 bit range"));
d04ebfb8 892 return false;
7b4ae824
JD
893 }
894
895 *long_displacement = (val > 63 || val < -64);
896
d04ebfb8 897 return true;
7b4ae824
JD
898
899 fail:
900 fail_line_pointer = input_line_pointer;
901 input_line_pointer = ilp;
d04ebfb8 902 return false;
7b4ae824
JD
903}
904
905static void
906emit_15_bit_offset (char *f, int where, expressionS *exp)
907{
908 gas_assert (exp);
909 if (exp->X_op != O_absent && exp->X_op != O_constant)
910 {
911 exp->X_add_number += where;
912 fixS *fix = fix_new_exp (frag_now,
913 f - frag_now->fr_literal,
914 2,
915 exp,
916 TRUE,
917 BFD_RELOC_16_PCREL);
918 fix->fx_addnumber = where - 2;
919 }
920 else
921 {
922 long val = exp->X_add_number;
923 bool long_displacement = (val > 63 || val < -64);
924 if (long_displacement)
925 val |= 0x8000;
926 else
927 val &= 0x7F;
928
929 number_to_chars_bigendian (f++, val, long_displacement ? 2 : 1);
930 }
931}
932
d04ebfb8 933static bfd_boolean
7b4ae824
JD
934rel (const struct instruction *insn)
935{
936 bool long_displacement;
937
938 expressionS exp;
939 if (! lex_15_bit_offset (&long_displacement, &exp))
d04ebfb8 940 return false;
7b4ae824
JD
941
942 char *f = s12z_new_insn (long_displacement ? 3 : 2);
943 number_to_chars_bigendian (f++, insn->opc, 1);
944 emit_15_bit_offset (f, 3, &exp);
d04ebfb8 945 return true;
7b4ae824
JD
946}
947
d04ebfb8 948static bfd_boolean
7b4ae824
JD
949reg_inh (const struct instruction *insn)
950{
951 int reg;
952 if (lex_reg_name (REG_BIT_Dn, &reg))
953 {
954 char *f = s12z_new_insn (insn->page);
955 if (insn->page == 2)
956 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
957
958 number_to_chars_bigendian (f++, insn->opc + reg, 1);
d04ebfb8 959 return true;
7b4ae824
JD
960 }
961
d04ebfb8 962 return false;
7b4ae824
JD
963}
964
965
966/* Special case for CLR X and CLR Y */
d04ebfb8 967static bfd_boolean
7b4ae824
JD
968clr_xy (const struct instruction *insn ATTRIBUTE_UNUSED)
969{
970 int reg;
971 if (lex_reg_name (REG_BIT_XY, &reg))
972 {
973 char *f = s12z_new_insn (1);
974 number_to_chars_bigendian (f, 0x9a + reg - REG_X, 1);
d04ebfb8 975 return true;
7b4ae824
JD
976 }
977
d04ebfb8 978 return false;
7b4ae824
JD
979}
980
981/* Some instructions have a suffix like ".l", ".b", ".w" etc
982 which indicates the size of the operands. */
d04ebfb8 983static bfd_boolean
7b4ae824
JD
984size_from_suffix (const struct instruction *insn, int idx)
985{
986 const char *dot = strchr (insn->name, '.');
987
988 if (dot == NULL)
989 return -3;
990
991 int size = -2;
992 switch (dot[1 + idx])
993 {
994 case 'b':
995 size = 1;
996 break;
997 case 'w':
998 size = 2;
999 break;
1000 case 'p':
1001 size = 3;
1002 break;
1003 case 'l':
1004 size = 4;
1005 break;
1006 default:
1007 as_fatal (_("Bad size"));
1008 };
1009
1010 return size;
1011}
1012
d04ebfb8 1013static bfd_boolean
7b4ae824
JD
1014mul_reg_reg_reg (const struct instruction *insn)
1015{
1016 char *ilp = input_line_pointer;
1017
1018 int Dd;
1019 if (!lex_reg_name (REG_BIT_Dn, &Dd))
1020 goto fail;
1021
1022 if (!lex_match (','))
1023 goto fail;
1024
1025 int Dj;
1026 if (!lex_reg_name (REG_BIT_Dn, &Dj))
1027 goto fail;
1028
1029 if (!lex_match (','))
1030 goto fail;
1031
1032 int Dk;
1033 if (!lex_reg_name (REG_BIT_Dn, &Dk))
1034 goto fail;
1035
1036 char *f = s12z_new_insn (insn->page + 1);
1037 if (insn->page == 2)
1038 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
1039
1040 number_to_chars_bigendian (f++, insn->opc + Dd, 1);
1041 const char *dot = strchrnul (insn->name, '.');
1042 uint8_t mb ;
1043 switch (dot[-1])
1044 {
1045 case 's':
1046 mb = 0x80;
1047 break;
1048 case 'u':
1049 mb = 0x00;
1050 break;
1051 default:
1052 as_fatal (_("BAD MUL"));
1053 break;
1054 }
1055
1056 mb |= Dj << 3;
1057 mb |= Dk;
1058
1059 number_to_chars_bigendian (f++, mb, 1);
1060
d04ebfb8 1061 return true;
7b4ae824
JD
1062
1063 fail:
1064 fail_line_pointer = input_line_pointer;
1065 input_line_pointer = ilp;
d04ebfb8 1066 return false;
7b4ae824
JD
1067}
1068
1069
d04ebfb8 1070static bfd_boolean
7b4ae824
JD
1071mul_reg_reg_imm (const struct instruction *insn)
1072{
1073 char *ilp = input_line_pointer;
1074
1075 int Dd;
1076 if (!lex_reg_name (REG_BIT_Dn, &Dd))
1077 goto fail;
1078
1079 if (!lex_match (','))
1080 goto fail;
1081
1082 int Dj;
1083 if (!lex_reg_name (REG_BIT_Dn, &Dj))
1084 goto fail;
1085
1086 if (!lex_match (','))
1087 goto fail;
1088
1089 long imm;
c6f14c0d 1090 if (!lex_imm (&imm, NULL))
7b4ae824
JD
1091 goto fail;
1092
1093
1094 int size = size_from_suffix (insn, 0);
1095
1096 char *f = s12z_new_insn (insn->page + 1 + size);
1097 if (insn->page == 2)
1098 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
1099
1100 number_to_chars_bigendian (f++, insn->opc + Dd, 1);
1101 uint8_t mb = 0x44;
1102 const char *dot = strchrnul (insn->name, '.');
1103 switch (dot[-1])
1104 {
1105 case 's':
1106 mb |= 0x80;
1107 break;
1108 case 'u':
1109 mb |= 0x00;
1110 break;
1111 default:
1112 as_fatal (_("BAD MUL"));
1113 break;
1114 }
1115
1116 mb |= Dj << 3;
1117 mb |= size - 1;
1118
1119 number_to_chars_bigendian (f++, mb, 1);
1120 number_to_chars_bigendian (f++, imm, size);
1121
d04ebfb8 1122 return true;
7b4ae824
JD
1123
1124 fail:
1125 fail_line_pointer = input_line_pointer;
1126 input_line_pointer = ilp;
d04ebfb8 1127 return false;
7b4ae824
JD
1128}
1129
1130
d04ebfb8 1131static bfd_boolean
7b4ae824
JD
1132mul_reg_reg_opr (const struct instruction *insn)
1133{
1134 char *ilp = input_line_pointer;
1135
1136 int Dd;
1137 if (!lex_reg_name (REG_BIT_Dn, &Dd))
1138 goto fail;
1139
1140 if (!lex_match (','))
1141 goto fail;
1142
1143 int Dj;
1144 if (!lex_reg_name (REG_BIT_Dn, &Dj))
1145 goto fail;
1146
1147 if (!lex_match (','))
1148 goto fail;
1149
1150 uint8_t buffer[4];
1151 int n_bytes;
1152 expressionS exp;
8b3a46f9 1153 if (!lex_opr (buffer, &n_bytes, &exp, true))
7b4ae824
JD
1154 goto fail;
1155
1156 int size = size_from_suffix (insn, 0);
1157
1158 char *f = s12z_new_insn (insn->page + 1 + n_bytes);
1159 if (insn->page == 2)
1160 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
1161
1162 number_to_chars_bigendian (f++, insn->opc + Dd, 1);
1163 uint8_t mb = 0x40;
1164 const char *dot = strchrnul (insn->name, '.');
1165 switch (dot[-1])
1166 {
1167 case 's':
1168 mb |= 0x80;
1169 break;
1170 case 'u':
1171 mb |= 0x00;
1172 break;
1173 default:
1174 as_fatal (_("BAD MUL"));
1175 break;
1176 }
1177
1178 mb |= Dj << 3;
1179 mb |= size - 1;
1180
1181 number_to_chars_bigendian (f++, mb, 1);
1182
1183 emit_opr (f, buffer, n_bytes, &exp);
1184
d04ebfb8 1185 return true;
7b4ae824
JD
1186
1187 fail:
1188 fail_line_pointer = input_line_pointer;
1189 input_line_pointer = ilp;
d04ebfb8 1190 return false;
7b4ae824
JD
1191}
1192
d04ebfb8 1193static bfd_boolean
7b4ae824
JD
1194mul_reg_opr_opr (const struct instruction *insn)
1195{
1196 char *ilp = input_line_pointer;
1197
1198 int Dd;
1199 if (!lex_reg_name (REG_BIT_Dn, &Dd))
1200 goto fail;
1201
1202 if (!lex_match (','))
1203 goto fail;
1204
1205 uint8_t buffer1[4];
1206 int n_bytes1;
1207 expressionS exp1;
8b3a46f9 1208 if (!lex_opr (buffer1, &n_bytes1, &exp1, false))
7b4ae824
JD
1209 goto fail;
1210
1211 if (!lex_match (','))
1212 goto fail;
1213
1214 uint8_t buffer2[4];
1215 int n_bytes2;
1216 expressionS exp2;
8b3a46f9 1217 if (!lex_opr (buffer2, &n_bytes2, &exp2, false))
7b4ae824
JD
1218 goto fail;
1219
1220 int size1 = size_from_suffix (insn, 0);
1221 int size2 = size_from_suffix (insn, 1);
1222
1223 char *f = s12z_new_insn (insn->page + 1 + n_bytes1 + n_bytes2);
1224 if (insn->page == 2)
1225 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
1226
1227 number_to_chars_bigendian (f++, insn->opc + Dd, 1);
1228 uint8_t mb = 0x42;
1229 const char *dot = strchrnul (insn->name, '.');
1230 switch (dot[-1])
1231 {
1232 case 's':
1233 mb |= 0x80;
1234 break;
1235 case 'u':
1236 mb |= 0x00;
1237 break;
1238 default:
1239 as_fatal (_("BAD MUL"));
1240 break;
1241 }
1242
1243 mb |= (size1 - 1) << 4;
1244 mb |= (size2 - 1) << 2;
1245 number_to_chars_bigendian (f++, mb, 1);
1246
1247 f = emit_opr (f, buffer1, n_bytes1, &exp1);
1248 f = emit_opr (f, buffer2, n_bytes2, &exp2);
1249
d04ebfb8 1250 return true;
7b4ae824
JD
1251
1252 fail:
1253 fail_line_pointer = input_line_pointer;
1254 input_line_pointer = ilp;
d04ebfb8 1255 return false;
7b4ae824
JD
1256}
1257
1258
1259#define REG_BIT_GRP0 \
1260 ((0x1U << REG_D2) | \
1261 (0x1U << REG_D3) | \
1262 (0x1U << REG_CCH) | \
1263 (0x1U << REG_CCL) | \
1264 (0x1U << REG_D0) | \
1265 (0x1U << REG_D1))
1266
1267#define REG_BIT_GRP1 \
1268 ((0x1U << REG_D4) | \
1269 (0x1U << REG_D5) | \
1270 (0x1U << REG_D6) | \
1271 (0x1U << REG_D7) | \
1272 (0x1U << REG_X) | \
1273 (0x1U << REG_Y))
1274
1275static const uint8_t reg_map [] =
1276 {
1277 0x02, // D2
1278 0x01, // D3
1279 0x20,
1280 0x10, // D5
1281 0x08, // D0
1282 0x04, // D1
1283 0x08, // D6
1284 0x04, // D7
1285 0x02,
1286 0x01, // Y
1287 0x00,
1288 0x00,
1289 0x20, // CCH
1290 0x10, // CCL
1291 0x00
1292 };
1293
1294static int
1295lex_reg_list (uint16_t grp, uint16_t *reg_bits)
1296{
1297 if (lex_match (','))
1298 {
1299 int reg;
1300 if (!lex_reg_name (grp, &reg))
d04ebfb8 1301 return false;
7b4ae824
JD
1302 *reg_bits |= 0x1u << reg;
1303 lex_reg_list (grp, reg_bits);
1304 }
1305
1306 /* Empty list */
d04ebfb8 1307 return true;
7b4ae824
JD
1308}
1309
d04ebfb8 1310static bfd_boolean
7b4ae824
JD
1311psh_pull (const struct instruction *insn)
1312{
1313 uint8_t pb =
1314 (0 == strcmp ("pul", insn->name)) ? 0x80: 0x00;
1315
1316 if (lex_match_string ("all16b"))
1317 {
1318 pb |= 0x40;
1319 }
1320 else if (lex_match_string ("all"))
1321 {
1322 /* Nothing to do */
1323 }
1324 else
1325 {
1326 int reg1;
1327 if (!lex_reg_name (REG_BIT_GRP1 | REG_BIT_GRP0, &reg1))
1328 goto fail;
1329 uint16_t admitted_group = 0;
1330
1331 if ((0x1U << reg1) & REG_BIT_GRP1)
1332 admitted_group = REG_BIT_GRP1;
1333 else if ((0x1U << reg1) & REG_BIT_GRP0)
1334 admitted_group = REG_BIT_GRP0;
1335
1336 uint16_t reg_bits = 0x1 << reg1;
1337 if (!lex_reg_list (admitted_group, &reg_bits))
1338 goto fail;
1339
1340 if (reg_bits & REG_BIT_GRP1)
1341 pb |= 0x40;
1342
1343 int i;
1344 for (i = 0; i < 16; ++i)
1345 {
1346 if (reg_bits & (0x1u << i))
1347 pb |= reg_map[i];
1348 }
1349 }
1350
1351 char *f = s12z_new_insn (2);
1352 number_to_chars_bigendian (f++, insn->opc, 1);
1353 number_to_chars_bigendian (f++, pb, 1);
d04ebfb8 1354 return true;
7b4ae824
JD
1355
1356 fail:
1357 fail_line_pointer = input_line_pointer;
d04ebfb8 1358 return false;
7b4ae824
JD
1359}
1360
1361
d04ebfb8 1362static bfd_boolean
7b4ae824
JD
1363tfr (const struct instruction *insn)
1364{
1365 int reg1;
1366 if (!lex_reg_name (~0, &reg1))
1367 goto fail;
1368
1369 if (!lex_match (','))
1370 goto fail;
1371
1372 int reg2;
1373 if (!lex_reg_name (~0, &reg2))
1374 goto fail;
1375
77fdb0e0
JD
1376 if ( ((0 == strcasecmp ("sex", insn->name))
1377 || (0 == strcasecmp ("zex", insn->name)))
1378 && (registers[reg2].bytes <= registers[reg1].bytes))
1379 as_warn (_("Source register for %s is no larger than the destination register"),
1380 insn->name);
1d4d8669
JD
1381 else if (reg1 == reg2)
1382 as_warn (_("The destination and source registers are identical"));
7b4ae824
JD
1383
1384 char *f = s12z_new_insn (1 + insn->page);
1385 if (insn->page == 2)
1386 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
1387
1388 number_to_chars_bigendian (f++, insn->opc, 1);
1389 number_to_chars_bigendian (f++, reg1 << 4 | reg2, 1);
1390
d04ebfb8 1391 return true;
7b4ae824
JD
1392
1393 fail:
1394 fail_line_pointer = input_line_pointer;
d04ebfb8 1395 return false;
7b4ae824
JD
1396}
1397
d04ebfb8 1398static bfd_boolean
7b4ae824
JD
1399imm8 (const struct instruction *insn)
1400{
1401 long imm;
c6f14c0d 1402 if (! lex_imm (&imm, NULL))
d04ebfb8 1403 return false;
7b4ae824
JD
1404 if (imm > 127 || imm < -128)
1405 {
1406 as_bad (_("Immediate value %ld is out of range for instruction %s"),
1407 imm, insn->name);
1408 }
1409
1410 char *f = s12z_new_insn (2);
1411 number_to_chars_bigendian (f++, insn->opc, 1);
1412 number_to_chars_bigendian (f++, imm, 1);
1413
d04ebfb8 1414 return true;
7b4ae824
JD
1415}
1416
d04ebfb8 1417static bfd_boolean
7b4ae824
JD
1418reg_imm (const struct instruction *insn, int allowed_reg)
1419{
1420 char *ilp = input_line_pointer;
1421 int reg;
1422 if (lex_reg_name (allowed_reg, &reg))
1423 {
1424 if (!lex_force_match (','))
1425 goto fail;
1426 long imm;
c6f14c0d 1427 if (! lex_imm (&imm, NULL))
7b4ae824
JD
1428 goto fail;
1429
1430 short size = registers[reg].bytes;
1431 char *f = s12z_new_insn (insn->page + size);
1432 if (insn->page == 2)
1433 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
1434
1435 number_to_chars_bigendian (f++, insn->opc + reg, 1);
1436 number_to_chars_bigendian (f++, imm, size);
d04ebfb8 1437 return true;
7b4ae824
JD
1438 }
1439
1440 fail:
1441 fail_line_pointer = input_line_pointer;
1442 input_line_pointer = ilp;
d04ebfb8 1443 return false;
7b4ae824
JD
1444}
1445
1446
d04ebfb8 1447static bfd_boolean
7b4ae824
JD
1448regd_imm (const struct instruction *insn)
1449{
1450 return reg_imm (insn, REG_BIT_Dn);
1451}
1452
d04ebfb8 1453static bfd_boolean
7b4ae824
JD
1454regdxy_imm (const struct instruction *insn)
1455{
1456 return reg_imm (insn, REG_BIT_Dn | REG_BIT_XY);
1457}
1458
1459
d04ebfb8 1460static bfd_boolean
7b4ae824
JD
1461regs_imm (const struct instruction *insn)
1462{
1463 return reg_imm (insn, 0x1U << REG_S);
1464}
1465
d04ebfb8 1466static bfd_boolean
7b4ae824
JD
1467trap_imm (const struct instruction *insn ATTRIBUTE_UNUSED)
1468{
1469 long imm = -1;
c6f14c0d 1470 if (! lex_imm (&imm, NULL))
7b4ae824
JD
1471 goto fail;
1472
1473 if (imm < 0x92 || imm > 0xFF ||
1474 (imm >= 0xA0 && imm <= 0xA7) ||
1475 (imm >= 0xB0 && imm <= 0xB7))
1476 {
1477 as_bad (_("trap value %ld is not valid"), imm);
d04ebfb8 1478 return false;
7b4ae824
JD
1479 }
1480 else
1481 {
1482 char *f = s12z_new_insn (2);
1483 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
1484 number_to_chars_bigendian (f++, imm & 0xFF, 1);
d04ebfb8 1485 return true;
7b4ae824
JD
1486 }
1487
d04ebfb8 1488 return true;
7b4ae824
JD
1489
1490 fail:
1491 fail_line_pointer = input_line_pointer;
d04ebfb8 1492 return false;
7b4ae824
JD
1493}
1494
1495
1496
1497/* Special one byte instruction CMP X, Y */
d04ebfb8 1498static bfd_boolean
7b4ae824
JD
1499regx_regy (const struct instruction *insn)
1500{
1501 int reg;
1502 if (lex_reg_name (0x1U << REG_X, &reg))
1503 {
1504 if (lex_force_match (','))
1505 {
1506 if (lex_reg_name (0x1U << REG_Y, &reg))
1507 {
1508 char *f = s12z_new_insn (1);
1509 number_to_chars_bigendian (f, insn->opc, 1);
d04ebfb8 1510 return true;
7b4ae824
JD
1511 }
1512 }
1513 }
d04ebfb8 1514 return false;
7b4ae824
JD
1515}
1516
1517/* Special one byte instruction SUB D6, X, Y */
d04ebfb8 1518static bfd_boolean
7b4ae824
JD
1519regd6_regx_regy (const struct instruction *insn)
1520{
1521 char *ilp = input_line_pointer;
1522 int reg;
1523 if (!lex_reg_name (0x1U << REG_D6, &reg))
1524 goto fail;
1525
1526 if (!lex_match (','))
1527 goto fail;
1528
1529 if (!lex_reg_name (0x1U << REG_X, &reg))
1530 goto fail;
1531
1532 if (!lex_match (','))
1533 goto fail;
1534
1535 if (!lex_reg_name (0x1U << REG_Y, &reg))
1536 goto fail;
1537
1538 char *f = s12z_new_insn (1);
1539 number_to_chars_bigendian (f, insn->opc, 1);
d04ebfb8 1540 return true;
7b4ae824
JD
1541
1542 fail:
1543 fail_line_pointer = input_line_pointer;
1544 input_line_pointer = ilp;
d04ebfb8 1545 return false;
7b4ae824
JD
1546}
1547
1548/* Special one byte instruction SUB D6, Y, X */
d04ebfb8 1549static bfd_boolean
7b4ae824
JD
1550regd6_regy_regx (const struct instruction *insn)
1551{
1552 char *ilp = input_line_pointer;
1553 int reg;
1554 if (!lex_reg_name (0x1U << REG_D6, &reg))
1555 goto fail;
1556
1557 if (!lex_match (','))
1558 goto fail;
1559
1560 if (!lex_reg_name (0x1U << REG_Y, &reg))
1561 goto fail;
1562
1563 if (!lex_match (','))
1564 goto fail;
1565
1566 if (!lex_reg_name (0x1U << REG_X, &reg))
1567 goto fail;
1568
1569 char *f = s12z_new_insn (1);
1570 number_to_chars_bigendian (f, insn->opc, 1);
d04ebfb8 1571 return true;
7b4ae824
JD
1572
1573 fail:
1574 fail_line_pointer = input_line_pointer;
1575 input_line_pointer = ilp;
d04ebfb8 1576 return false;
7b4ae824
JD
1577}
1578
d04ebfb8 1579static bfd_boolean
8b3a46f9
JD
1580reg_opr (const struct instruction *insn, int allowed_regs,
1581 bool immediate_ok)
7b4ae824
JD
1582{
1583 char *ilp = input_line_pointer;
1584 int reg;
1585 if (lex_reg_name (allowed_regs, &reg))
1586 {
1587 if (!lex_force_match (','))
1588 goto fail;
1589
1590 uint8_t buffer[4];
1591 int n_bytes;
1592 expressionS exp;
8b3a46f9 1593 if (lex_opr (buffer, &n_bytes, &exp, immediate_ok))
7b4ae824
JD
1594 {
1595 /* Large constant direct values are more efficiently encoded as ext24 mode.
1596 Otherwise a decision has to be deferred to a relax. */
1597 if (exp.X_op == O_constant
1598 && buffer[0] == 0xFA
1599 && insn->alt_opc != 0)
1600 {
1601 char *f = s12z_new_insn (4);
1602
1603 /* I don't think there are any instances of page 2 opcodes in this case */
1604 gas_assert (insn->page == 1);
1605
1606 number_to_chars_bigendian (f++, insn->alt_opc + reg, 1);
1607
1608 emit_ext24 (f, exp.X_add_number);
1609 }
1610 else
1611 {
1612 char *f = s12z_new_insn (n_bytes + insn->page);
1613
1614 if (insn->page == 2)
1615 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
1616
1617 number_to_chars_bigendian (f++, insn->opc + reg, 1);
1618
1619 emit_opr (f, buffer, n_bytes, &exp);
1620 }
1621
d04ebfb8 1622 return true;
7b4ae824
JD
1623 }
1624 }
1625
1626 fail:
1627 fail_line_pointer = input_line_pointer;
1628 input_line_pointer = ilp;
d04ebfb8 1629 return false;
7b4ae824
JD
1630}
1631
1632
d04ebfb8 1633static bfd_boolean
8b3a46f9 1634regdxy_opr_dest (const struct instruction *insn)
7b4ae824 1635{
8b3a46f9 1636 return reg_opr (insn, REG_BIT_Dn | REG_BIT_XY, false);
7b4ae824
JD
1637}
1638
d04ebfb8 1639static bfd_boolean
8b3a46f9
JD
1640regdxy_opr_src (const struct instruction *insn)
1641{
1642 return reg_opr (insn, REG_BIT_Dn | REG_BIT_XY, true);
1643}
1644
1645
d04ebfb8 1646static bfd_boolean
7b4ae824
JD
1647regd_opr (const struct instruction *insn)
1648{
8b3a46f9 1649 return reg_opr (insn, REG_BIT_Dn, true);
7b4ae824
JD
1650}
1651
1652
8b3a46f9 1653/* OP0: S; OP1: destination OPR */
d04ebfb8 1654static bfd_boolean
8b3a46f9
JD
1655regs_opr_dest (const struct instruction *insn)
1656{
1657 return reg_opr (insn, 0x1U << REG_S, false);
1658}
1659
1660/* OP0: S; OP1: source OPR */
d04ebfb8 1661static bfd_boolean
8b3a46f9 1662regs_opr_src (const struct instruction *insn)
7b4ae824 1663{
8b3a46f9 1664 return reg_opr (insn, 0x1U << REG_S, true);
7b4ae824
JD
1665}
1666
d04ebfb8 1667static bfd_boolean
7b4ae824
JD
1668imm_opr (const struct instruction *insn)
1669{
1670 char *ilp = input_line_pointer;
1671 long imm;
c6f14c0d
JD
1672 expressionS exp0;
1673 int size = size_from_suffix (insn, 0);
1674 exp0.X_op = O_absent;
1675
1676 /* Note: The ternary expression below means that "MOV.x #symbol,
1677 mem-expr" is accepted when x is a member of {'w', 'p', 'l'} but
1678 not when it is 'b'.
1679 The Freescale assembler accepts "MOV.b #symbol, mem-expr" but
1680 produces obviously incorrect code. Since such an instruction
1681 would require an 8-bit reloc (which we don't have) and some
1682 non-optimal kludges in the OPR encoding, it seems sensible that
1683 such instructions should be rejected. */
1684 if (!lex_imm (&imm, size > 1 ? &exp0 : NULL))
7b4ae824
JD
1685 goto fail;
1686
1687 if (!lex_match (','))
1688 goto fail;
1689
1690 uint8_t buffer[4];
1691 int n_bytes;
c6f14c0d
JD
1692 expressionS exp1;
1693 if (!lex_opr (buffer, &n_bytes, &exp1, false))
7b4ae824
JD
1694 goto fail;
1695
7b4ae824
JD
1696 char *f = s12z_new_insn (1 + n_bytes + size);
1697 number_to_chars_bigendian (f++, insn->opc, 1);
1698
c6f14c0d
JD
1699 emit_reloc (&exp0, f, size, size == 4 ? BFD_RELOC_32 : BFD_RELOC_S12Z_OPR);
1700
7b4ae824
JD
1701 int i;
1702 for (i = 0; i < size; ++i)
1703 number_to_chars_bigendian (f++, imm >> (CHAR_BIT * (size - i - 1)), 1);
1704
c6f14c0d 1705 emit_opr (f, buffer, n_bytes, &exp1);
7b4ae824 1706
d04ebfb8 1707 return true;
7b4ae824
JD
1708
1709 fail:
1710 fail_line_pointer = input_line_pointer;
1711 input_line_pointer = ilp;
d04ebfb8 1712 return false;
7b4ae824
JD
1713}
1714
d04ebfb8 1715static bfd_boolean
7b4ae824
JD
1716opr_opr (const struct instruction *insn)
1717{
1718 char *ilp = input_line_pointer;
1719
1720 uint8_t buffer1[4];
1721 int n_bytes1;
1722 expressionS exp1;
8b3a46f9 1723 if (!lex_opr (buffer1, &n_bytes1, &exp1, false))
7b4ae824
JD
1724 goto fail;
1725
1726
1727 if (!lex_match (','))
1728 goto fail;
1729
1730 uint8_t buffer2[4];
1731 int n_bytes2;
1732 expressionS exp2;
8b3a46f9 1733 if (!lex_opr (buffer2, &n_bytes2, &exp2, false))
7b4ae824
JD
1734 goto fail;
1735
1736 char *f = s12z_new_insn (1 + n_bytes1 + n_bytes2);
1737 number_to_chars_bigendian (f++, insn->opc, 1);
1738
1739 f = emit_opr (f, buffer1, n_bytes1, &exp1);
1740 f = emit_opr (f, buffer2, n_bytes2, &exp2);
1741
d04ebfb8 1742 return true;
7b4ae824
JD
1743
1744 fail:
1745 fail_line_pointer = input_line_pointer;
1746 input_line_pointer = ilp;
d04ebfb8 1747 return false;
7b4ae824
JD
1748}
1749
d04ebfb8 1750static bfd_boolean
7b4ae824
JD
1751reg67sxy_opr (const struct instruction *insn)
1752{
1753 int reg;
1754 if (!lex_reg_name (REG_BIT_XYS | (0x1U << REG_D6) | (0x1U << REG_D7), &reg))
d04ebfb8 1755 return false;
7b4ae824
JD
1756
1757 if (!lex_match (','))
d04ebfb8 1758 return false;
7b4ae824
JD
1759
1760 uint8_t buffer[4];
1761 int n_bytes;
1762 expressionS exp;
8b3a46f9 1763 if (!lex_opr (buffer, &n_bytes, &exp, false))
d04ebfb8 1764 return false;
7b4ae824
JD
1765
1766 char *f = s12z_new_insn (1 + n_bytes);
1767 number_to_chars_bigendian (f++, insn->opc + reg - REG_D6, 1);
1768 emit_opr (f, buffer, n_bytes, &exp);
1769
d04ebfb8 1770 return true;
7b4ae824
JD
1771}
1772
d04ebfb8 1773static bfd_boolean
7b4ae824
JD
1774rotate (const struct instruction *insn, short dir)
1775{
1776 uint8_t buffer[4];
1777 int n_bytes;
1778 expressionS exp;
8b3a46f9 1779 if (lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
1780 {
1781 char *f = s12z_new_insn (n_bytes + 2);
1782 number_to_chars_bigendian (f++, insn->opc, 1);
1783 int size = size_from_suffix (insn, 0);
1784 if (size < 0)
1785 size = 1;
1786 uint8_t sb = 0x24;
1787 sb |= size - 1;
1788 if (dir)
1789 sb |= 0x40;
1790 number_to_chars_bigendian (f++, sb, 1);
1791 emit_opr (f, buffer, n_bytes, &exp);
1792
d04ebfb8 1793 return true;
7b4ae824
JD
1794 }
1795
d04ebfb8 1796 return false;
7b4ae824
JD
1797}
1798
d04ebfb8 1799static bfd_boolean
7b4ae824
JD
1800rol (const struct instruction *insn)
1801{
1802 return rotate (insn, 1);
1803}
1804
d04ebfb8 1805static bfd_boolean
7b4ae824
JD
1806ror (const struct instruction *insn)
1807{
1808 return rotate (insn, 0);
1809}
1810
1811
1812/* Shift instruction with a register operand and an immediate #1 or #2
1813 left = 1; right = 0;
1814 logical = 0; arithmetic = 1;
1815*/
d04ebfb8 1816static bfd_boolean
7b4ae824
JD
1817lex_shift_reg_imm1 (const struct instruction *insn, short type, short dir)
1818{
1819 /*
1820 This function is highly unusual and a bit wierd!
1821 It first matches the input against a register {d0, d1, ... d7} followed by an immediate
1822 {#1, #2}.
1823 Then, it rewinds the input and parses it again as a OPR.
1824 */
1825 char *ilp = input_line_pointer;
1826
1827 int Dd;
1828 if (!lex_reg_name (REG_BIT_Dn, &Dd))
1829 {
1830 goto fail;
1831 }
1832
1833 if (!lex_match (','))
1834 goto fail;
1835
1836 long imm = -1;
c6f14c0d 1837 if (!lex_imm (&imm, NULL))
7b4ae824
JD
1838 goto fail;
1839
1840 if (imm != 1 && imm != 2)
1841 goto fail;
1842 input_line_pointer = ilp;
1843
1844 /* Now parse the first operand again */
1845
1846 uint8_t buffer[4];
1847 int n_bytes;
1848
1849 expressionS exp;
8b3a46f9 1850 if (!lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
1851 goto fail;
1852
1853 gas_assert (n_bytes == 1);
1854
1855 uint8_t sb = 0x34;
1856 sb |= dir << 6;
1857 sb |= type << 7;
1858 if (imm == 2)
1859 sb |= 0x08;
1860
1861 char *f = s12z_new_insn (3);
1862 number_to_chars_bigendian (f++, insn->opc, 1);
1863 number_to_chars_bigendian (f++, sb, 1);
1864 emit_opr (f, buffer, n_bytes, &exp);
1865
d04ebfb8 1866 return true;
7b4ae824
JD
1867
1868 fail:
1869 fail_line_pointer = input_line_pointer;
1870 input_line_pointer = ilp;
d04ebfb8 1871 return false;
7b4ae824
JD
1872}
1873
1874/* Shift instruction with a register operand.
1875 left = 1; right = 0;
1876 logical = 0; arithmetic = 1; */
d04ebfb8 1877static bfd_boolean
7b4ae824
JD
1878lex_shift_reg (const struct instruction *insn, short type, short dir)
1879{
1880 int Dd, Ds, Dn;
1881 if (!lex_reg_name (REG_BIT_Dn, &Dd))
1882 {
1883 goto fail;
1884 }
1885
1886 if (!lex_match (','))
1887 goto fail;
1888
1889 if (!lex_reg_name (REG_BIT_Dn, &Ds))
1890 {
1891 goto fail;
1892 }
1893
1894 if (!lex_match (','))
1895 goto fail;
1896
1897 uint8_t sb = 0x10;
1898 sb |= Ds;
1899 sb |= dir << 6;
1900 sb |= type << 7;
1901 long imm;
1902 if (lex_reg_name (REG_BIT_Dn, &Dn))
1903 {
1904 char *f = s12z_new_insn (3);
1905 number_to_chars_bigendian (f++, insn->opc | Dd, 1);
1906 number_to_chars_bigendian (f++, sb, 1);
1907 uint8_t xb = 0xb8;
1908 xb |= Dn;
1909 number_to_chars_bigendian (f++, xb, 1);
1910
d04ebfb8 1911 return true;
7b4ae824 1912 }
c6f14c0d 1913 else if (lex_imm (&imm, NULL))
7b4ae824
JD
1914 {
1915 if (imm < 0 || imm > 31)
1916 {
1917 as_bad (_("Shift value should be in the range [0,31]"));
1918 goto fail;
1919 }
1920
1921 int n_bytes = 3;
1922 if (imm == 1 || imm == 2)
1923 {
1924 n_bytes = 2;
1925 sb &= ~0x10;
1926 }
1927 else
1928 {
1929 sb |= (imm & 0x01) << 3;
1930 }
1931
1932 char *f = s12z_new_insn (n_bytes);
1933 number_to_chars_bigendian (f++, insn->opc | Dd, 1);
1934 number_to_chars_bigendian (f++, sb, 1);
1935 if (n_bytes > 2)
1936 {
1937 uint8_t xb = 0x70;
1938 xb |= imm >> 1;
1939 number_to_chars_bigendian (f++, xb, 1);
1940 }
1941
d04ebfb8 1942 return true;
7b4ae824
JD
1943 }
1944
1945 fail:
1946 fail_line_pointer = input_line_pointer;
d04ebfb8 1947 return false;
7b4ae824
JD
1948}
1949
1950static void
1951impute_shift_dir_and_type (const struct instruction *insn, short *type, short *dir)
1952{
1953 *dir = -1;
1954 *type = -1;
1955 switch (insn->name[0])
1956 {
1957 case 'l':
1958 *type = 0;
1959 break;
1960 case 'a':
1961 *type = 1;
1962 break;
1963 default:
1964 as_fatal (_("Bad shift mode"));
1965 break;
1966 }
1967
1968 switch (insn->name[2])
1969 {
1970 case 'l':
1971 *dir = 1;
1972 break;
1973 case 'r':
1974 *dir = 0;
1975 break;
1976 default:
1977 as_fatal (_("Bad shift *direction"));
1978 break;
1979 }
1980}
1981
1982/* Shift instruction with a OPR operand */
d04ebfb8 1983static bfd_boolean
7b4ae824
JD
1984shift_two_operand (const struct instruction *insn)
1985{
1986 uint8_t sb = 0x34;
1987 char *ilp = input_line_pointer;
1988
1989 short dir = -1;
1990 short type = -1;
1991 impute_shift_dir_and_type (insn, &type, &dir);
1992 sb |= dir << 6;
1993 sb |= type << 7;
1994
1995 int size = size_from_suffix (insn, 0);
1996 sb |= size - 1;
1997
1998 uint8_t buffer[4];
1999 int n_opr_bytes;
2000 expressionS exp;
8b3a46f9 2001 if (!lex_opr (buffer, &n_opr_bytes, &exp, false))
7b4ae824
JD
2002 goto fail;
2003
2004 if (!lex_match (','))
2005 goto fail;
2006
2007 long imm = -1;
c6f14c0d 2008 if (!lex_imm (&imm, NULL))
7b4ae824
JD
2009 goto fail;
2010
2011 if (imm != 1 && imm != 2)
2012 goto fail;
2013
2014 if (imm == 2)
2015 sb |= 0x08;
2016
2017 char *f = s12z_new_insn (2 + n_opr_bytes);
2018 number_to_chars_bigendian (f++, insn->opc, 1);
2019 number_to_chars_bigendian (f++, sb, 1);
2020 emit_opr (f, buffer, n_opr_bytes, &exp);
2021
d04ebfb8 2022 return true;
7b4ae824
JD
2023
2024 fail:
2025 fail_line_pointer = input_line_pointer;
2026 input_line_pointer = ilp;
d04ebfb8 2027 return false;
7b4ae824
JD
2028}
2029
2030/* Shift instruction with a OPR operand */
d04ebfb8 2031static bfd_boolean
7b4ae824
JD
2032shift_opr_imm (const struct instruction *insn)
2033{
2034 char *ilp = input_line_pointer;
2035
2036 short dir = -1;
2037 short type = -1;
2038 impute_shift_dir_and_type (insn, &type, &dir);
2039
2040 int Dd = 0;
2041 if (!lex_reg_name (REG_BIT_Dn, &Dd))
2042 goto fail;
2043
2044 if (!lex_match (','))
2045 goto fail;
2046
2047 int n_bytes = 2;
2048
2049 uint8_t buffer1[4];
2050 int n_opr_bytes1;
2051
2052 expressionS exp1;
8b3a46f9 2053 if (!lex_opr (buffer1, &n_opr_bytes1, &exp1, false))
7b4ae824
JD
2054 goto fail;
2055
2056 n_bytes += n_opr_bytes1;
2057 if (!lex_match (','))
2058 goto fail;
2059
2060 uint8_t buffer2[4];
2061 int n_opr_bytes2 = 0;
2062 expressionS exp2;
2063 long imm;
2064 bool immediate = false;
c6f14c0d 2065 if (lex_imm (&imm, NULL))
7b4ae824
JD
2066 {
2067 immediate = true;
2068 }
8b3a46f9 2069 else if (!lex_opr (buffer2, &n_opr_bytes2, &exp2, false))
7b4ae824
JD
2070 goto fail;
2071
2072 uint8_t sb = 0x20;
2073
2074 int size = size_from_suffix (insn, 0);
2075
2076 if (size != -1)
2077 sb |= size - 1;
2078
2079 sb |= dir << 6;
2080 sb |= type << 7;
2081
2082 if (immediate)
2083 {
2084 if (imm == 2 || imm == 1)
2085 {
2086 if (imm == 2)
2087 sb |= 0x08;
2088 }
2089 else
2090 {
2091 n_bytes++;
2092 sb |= 0x10;
2093 if (imm % 2)
2094 sb |= 0x08;
2095 }
2096 }
2097 else
2098 {
2099 n_bytes += n_opr_bytes2;
2100 sb |= 0x10;
2101 }
2102
2103 char *f = s12z_new_insn (n_bytes);
2104 number_to_chars_bigendian (f++, insn->opc | Dd, 1);
2105 number_to_chars_bigendian (f++, sb, 1);
2106 f = emit_opr (f, buffer1, n_opr_bytes1, &exp1);
2107 if (immediate)
2108 {
2109 if (imm != 1 && imm != 2)
2110 {
2111 number_to_chars_bigendian (f++, 0x70 | (imm >> 1), 1);
2112 }
2113 }
2114 else
2115 {
2116 f = emit_opr (f, buffer2, n_opr_bytes2, &exp2);
2117 }
2118
d04ebfb8 2119 return true;
7b4ae824
JD
2120
2121 fail:
2122 fail_line_pointer = input_line_pointer;
2123 input_line_pointer = ilp;
d04ebfb8 2124 return false;
7b4ae824
JD
2125}
2126
2127/* Shift instruction with a register operand */
d04ebfb8 2128static bfd_boolean
7b4ae824
JD
2129shift_reg (const struct instruction *insn)
2130{
2131 short dir = -1;
2132 short type = -1;
2133 impute_shift_dir_and_type (insn, &type, &dir);
2134
2135 if (lex_shift_reg_imm1 (insn, type, dir))
d04ebfb8 2136 return true;
7b4ae824
JD
2137
2138 return lex_shift_reg (insn, type, dir);
2139}
2140
d04ebfb8 2141static bfd_boolean
7b4ae824
JD
2142bm_regd_imm (const struct instruction *insn)
2143{
2144 char *ilp = input_line_pointer;
2145 int Di = 0;
2146 if (!lex_reg_name (REG_BIT_Dn, &Di))
2147 goto fail;
2148
2149 if (!lex_match (','))
2150 goto fail;
2151
2152 long imm;
c6f14c0d 2153 if (!lex_imm (&imm, NULL))
7b4ae824
JD
2154 goto fail;
2155
2156
2157 uint8_t bm = imm << 3;
2158 bm |= Di;
2159
2160 char *f = s12z_new_insn (2);
2161 number_to_chars_bigendian (f++, insn->opc, 1);
2162 number_to_chars_bigendian (f++, bm, 1);
2163
d04ebfb8 2164 return true;
7b4ae824
JD
2165
2166 fail:
2167 fail_line_pointer = input_line_pointer;
2168 input_line_pointer = ilp;
d04ebfb8 2169 return false;
7b4ae824
JD
2170}
2171
d04ebfb8 2172static bfd_boolean
7b4ae824
JD
2173bm_opr_reg (const struct instruction *insn)
2174{
2175 char *ilp = input_line_pointer;
2176
2177 uint8_t buffer[4];
2178 int n_opr_bytes;
2179
2180 expressionS exp;
8b3a46f9 2181 if (!lex_opr (buffer, &n_opr_bytes, &exp, false))
7b4ae824
JD
2182 goto fail;
2183
2184 if (!lex_match (','))
2185 goto fail;
2186
2187 int Dn = 0;
2188 if (!lex_reg_name (REG_BIT_Dn, &Dn))
2189 goto fail;
2190
2191 uint8_t bm = Dn << 4;
2192 int size = size_from_suffix (insn, 0);
2193 bm |= (size - 1) << 2;
2194 bm |= 0x81;
2195
2196 char *f = s12z_new_insn (2 + n_opr_bytes);
2197 number_to_chars_bigendian (f++, insn->opc, 1);
2198 number_to_chars_bigendian (f++, bm, 1);
2199
2200 emit_opr (f, buffer, n_opr_bytes, &exp);
2201
d04ebfb8 2202 return true;
7b4ae824
JD
2203
2204 fail:
2205 fail_line_pointer = input_line_pointer;
2206 input_line_pointer = ilp;
d04ebfb8 2207 return false;
7b4ae824
JD
2208}
2209
2210
d04ebfb8 2211static bfd_boolean
7b4ae824
JD
2212bm_opr_imm (const struct instruction *insn)
2213{
2214 char *ilp = input_line_pointer;
2215
2216 uint8_t buffer[4];
2217 int n_opr_bytes;
2218
2219 expressionS exp;
8b3a46f9 2220 if (!lex_opr (buffer, &n_opr_bytes, &exp, false))
7b4ae824
JD
2221 goto fail;
2222
2223 if (!lex_match (','))
2224 goto fail;
2225
2226
2227 long imm;
c6f14c0d 2228 if (!lex_imm (&imm, NULL))
7b4ae824
JD
2229 goto fail;
2230
2231 int size = size_from_suffix (insn, 0);
2232
2233 if (imm < 0 || imm >= size * 8)
2234 {
2235 as_bad (_("Immediate operand %ld is inappropriate for size of instruction"), imm);
2236 goto fail;
2237 }
2238
2239 uint8_t bm = 0x80;
2240 if (size == 2)
2241 bm |= 0x02;
2242 else if (size == 4)
2243 bm |= 0x08;
2244 bm |= (imm & 0x07) << 4;
2245 bm |= (imm >> 3);
2246
2247
2248 char *f = s12z_new_insn (2 + n_opr_bytes);
2249 number_to_chars_bigendian (f++, insn->opc, 1);
2250 number_to_chars_bigendian (f++, bm, 1);
2251 emit_opr (f, buffer, n_opr_bytes, &exp);
2252
d04ebfb8 2253 return true;
7b4ae824
JD
2254
2255 fail:
2256 fail_line_pointer = input_line_pointer;
2257 input_line_pointer = ilp;
d04ebfb8 2258 return false;
7b4ae824
JD
2259}
2260
2261
d04ebfb8 2262static bfd_boolean
7b4ae824
JD
2263bm_regd_reg (const struct instruction *insn)
2264{
2265 char *ilp = input_line_pointer;
2266 int Di = 0;
2267 if (!lex_reg_name (REG_BIT_Dn, &Di))
2268 goto fail;
2269
2270 if (!lex_match (','))
2271 goto fail;
2272
2273 int Dn = 0;
2274 if (!lex_reg_name (REG_BIT_Dn, &Dn))
2275 goto fail;
2276
2277 uint8_t bm = Dn << 4;
2278 bm |= 0x81;
2279
2280 uint8_t xb = Di | 0xb8;
2281
2282 char *f = s12z_new_insn (3);
2283 number_to_chars_bigendian (f++, insn->opc, 1);
2284 number_to_chars_bigendian (f++, bm, 1);
2285 number_to_chars_bigendian (f++, xb, 1);
2286
d04ebfb8 2287 return true;
7b4ae824
JD
2288
2289 fail:
2290 fail_line_pointer = input_line_pointer;
2291 input_line_pointer = ilp;
d04ebfb8 2292 return false;
7b4ae824
JD
2293}
2294
2295
2296\f
2297
2298
d04ebfb8 2299static bfd_boolean
7b4ae824
JD
2300bf_reg_opr_imm (const struct instruction *insn, short ie)
2301{
2302 char *ilp = input_line_pointer;
2303 int Dd = 0;
2304 if (!lex_reg_name (REG_BIT_Dn, &Dd))
2305 goto fail;
2306
2307 if (!lex_match (','))
2308 goto fail;
2309
2310 uint8_t buffer[4];
2311 int n_bytes;
2312
2313 expressionS exp;
8b3a46f9 2314 if (!lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
2315 goto fail;
2316
2317 if (!lex_match (','))
2318 goto fail;
2319
2320 long width;
c6f14c0d 2321 if (!lex_imm (&width, NULL))
7b4ae824
JD
2322 goto fail;
2323
2324 if (width < 0 || width > 31)
2325 {
2326 as_bad (_("Invalid width value for %s"), insn->name);
2327 goto fail;
2328 }
2329
2330 if (!lex_match (':'))
2331 goto fail;
2332
2333 long offset;
2334 if (!lex_constant (&offset))
2335 goto fail;
2336
2337 if (offset < 0 || offset > 31)
2338 {
2339 as_bad (_("Invalid offset value for %s"), insn->name);
2340 goto fail;
2341 }
2342
2343 uint8_t i1 = width << 5;
2344 i1 |= offset;
2345
2346 int size = size_from_suffix (insn, 0);
2347 uint8_t bb = ie ? 0x80 : 0x00;
2348 bb |= 0x60;
2349 bb |= (size - 1) << 2;
2350 bb |= width >> 3;
2351
2352 char *f = s12z_new_insn (4 + n_bytes);
2353 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
2354 number_to_chars_bigendian (f++, 0x08 | Dd, 1);
2355 number_to_chars_bigendian (f++, bb, 1);
2356 number_to_chars_bigendian (f++, i1, 1);
2357
2358 emit_opr (f, buffer, n_bytes, &exp);
2359
d04ebfb8 2360 return true;
7b4ae824
JD
2361
2362 fail:
2363 fail_line_pointer = input_line_pointer;
2364 input_line_pointer = ilp;
d04ebfb8 2365 return false;
7b4ae824
JD
2366}
2367
2368
d04ebfb8 2369static bfd_boolean
7b4ae824
JD
2370bf_opr_reg_imm (const struct instruction *insn, short ie)
2371{
2372 char *ilp = input_line_pointer;
2373 uint8_t buffer[4];
2374 int n_bytes;
2375 expressionS exp;
8b3a46f9 2376 if (!lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
2377 goto fail;
2378
2379 if (!lex_match (','))
2380 goto fail;
2381
2382 int Ds = 0;
2383 if (!lex_reg_name (REG_BIT_Dn, &Ds))
2384 goto fail;
2385
2386 if (!lex_match (','))
2387 goto fail;
2388
2389 long width;
c6f14c0d 2390 if (!lex_imm (&width, NULL))
7b4ae824
JD
2391 goto fail;
2392
2393 if (width < 0 || width > 31)
2394 {
2395 as_bad (_("Invalid width value for %s"), insn->name);
2396 goto fail;
2397 }
2398
2399 if (!lex_match (':'))
2400 goto fail;
2401
2402 long offset;
2403 if (!lex_constant (&offset))
2404 goto fail;
2405
2406 if (offset < 0 || offset > 31)
2407 {
2408 as_bad (_("Invalid offset value for %s"), insn->name);
2409 goto fail;
2410 }
2411
2412 uint8_t i1 = width << 5;
2413 i1 |= offset;
2414
2415 int size = size_from_suffix (insn, 0);
2416 uint8_t bb = ie ? 0x80 : 0x00;
2417 bb |= 0x70;
2418 bb |= (size - 1) << 2;
2419 bb |= width >> 3;
2420
2421 char *f = s12z_new_insn (4 + n_bytes);
2422 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
2423 number_to_chars_bigendian (f++, 0x08 | Ds, 1);
2424 number_to_chars_bigendian (f++, bb, 1);
2425 number_to_chars_bigendian (f++, i1, 1);
2426
2427 emit_opr (f, buffer, n_bytes, &exp);
2428
d04ebfb8 2429 return true;
7b4ae824
JD
2430
2431 fail:
2432 fail_line_pointer = input_line_pointer;
2433 input_line_pointer = ilp;
d04ebfb8 2434 return false;
7b4ae824
JD
2435}
2436
2437
2438
d04ebfb8 2439static bfd_boolean
7b4ae824
JD
2440bf_reg_reg_imm (const struct instruction *insn, short ie)
2441{
2442 char *ilp = input_line_pointer;
2443 int Dd = 0;
2444 if (!lex_reg_name (REG_BIT_Dn, &Dd))
2445 goto fail;
2446
2447 if (!lex_match (','))
2448 goto fail;
2449
2450 int Ds = 0;
2451 if (!lex_reg_name (REG_BIT_Dn, &Ds))
2452 goto fail;
2453
2454 if (!lex_match (','))
2455 goto fail;
2456
2457 long width;
c6f14c0d 2458 if (!lex_imm (&width, NULL))
7b4ae824
JD
2459 goto fail;
2460
2461 if (width < 0 || width > 31)
2462 {
2463 as_bad (_("Invalid width value for %s"), insn->name);
2464 goto fail;
2465 }
2466
2467 if (!lex_match (':'))
2468 goto fail;
2469
2470 long offset;
2471 if (!lex_constant (&offset))
2472 goto fail;
2473
2474 if (offset < 0 || offset > 31)
2475 {
2476 as_bad (_("Invalid offset value for %s"), insn->name);
2477 goto fail;
2478 }
2479
2480 uint8_t bb = ie ? 0x80 : 0x00;
2481 bb |= 0x20;
2482 bb |= Ds << 2;
2483 bb |= width >> 3;
2484
2485 uint8_t i1 = width << 5;
2486 i1 |= offset;
2487
2488 char *f = s12z_new_insn (4);
2489 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
2490 number_to_chars_bigendian (f++, 0x08 | Dd, 1);
2491 number_to_chars_bigendian (f++, bb, 1);
2492 number_to_chars_bigendian (f++, i1, 1);
2493
d04ebfb8 2494 return true;
7b4ae824
JD
2495
2496 fail:
2497 fail_line_pointer = input_line_pointer;
2498 input_line_pointer = ilp;
d04ebfb8 2499 return false;
7b4ae824
JD
2500}
2501
d04ebfb8 2502static bfd_boolean
7b4ae824
JD
2503bf_reg_reg_reg (const struct instruction *insn ATTRIBUTE_UNUSED, short ie)
2504{
2505 char *ilp = input_line_pointer;
2506 int Dd = 0;
2507 if (!lex_reg_name (REG_BIT_Dn, &Dd))
2508 goto fail;
2509
2510 if (!lex_match (','))
2511 goto fail;
2512
2513 int Ds = 0;
2514 if (!lex_reg_name (REG_BIT_Dn, &Ds))
2515 goto fail;
2516
2517 if (!lex_match (','))
2518 goto fail;
2519
2520 int Dp = 0;
2521 if (!lex_reg_name ((0x01u << REG_D2) |
2522 (0x01u << REG_D3) |
2523 (0x01u << REG_D4) |
2524 (0x01u << REG_D5),
2525 &Dp))
2526 goto fail;
2527
2528 uint8_t bb = ie ? 0x80 : 0x00;
2529 bb |= Ds << 2;
2530 bb |= Dp;
2531
2532 char *f = s12z_new_insn (3);
2533 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
2534 number_to_chars_bigendian (f++, 0x08 | Dd, 1);
2535 number_to_chars_bigendian (f++, bb , 1);
2536
d04ebfb8 2537 return true;
7b4ae824
JD
2538
2539 fail:
2540 fail_line_pointer = input_line_pointer;
2541 input_line_pointer = ilp;
d04ebfb8 2542 return false;
7b4ae824
JD
2543}
2544
d04ebfb8 2545static bfd_boolean
7b4ae824
JD
2546bf_opr_reg_reg (const struct instruction *insn, short ie)
2547{
2548 char *ilp = input_line_pointer;
2549
2550 uint8_t buffer[4];
2551 int n_bytes;
2552 expressionS exp;
8b3a46f9 2553 if (!lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
2554 goto fail;
2555
2556 if (!lex_match (','))
2557 goto fail;
2558
2559
2560 int Ds = 0;
2561 if (!lex_reg_name (REG_BIT_Dn, &Ds))
2562 goto fail;
2563
2564 if (!lex_match (','))
2565 goto fail;
2566
2567
2568 int Dp = 0;
2569 if (!lex_reg_name ((0x01u << REG_D2) |
2570 (0x01u << REG_D3) |
2571 (0x01u << REG_D4) |
2572 (0x01u << REG_D5),
2573 &Dp))
2574 goto fail;
2575
2576 int size = size_from_suffix (insn, 0);
2577 uint8_t bb = ie ? 0x80 : 0x00;
2578 bb |= 0x50;
2579 bb |= Dp;
2580 bb |= (size - 1) << 2;
2581
2582 char *f = s12z_new_insn (3 + n_bytes);
2583 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
2584 number_to_chars_bigendian (f++, 0x08 | Ds, 1);
2585 number_to_chars_bigendian (f++, bb , 1);
2586
2587 emit_opr (f, buffer, n_bytes, &exp);
2588
d04ebfb8 2589 return true;
7b4ae824
JD
2590
2591 fail:
2592 fail_line_pointer = input_line_pointer;
2593 input_line_pointer = ilp;
d04ebfb8 2594 return false;
7b4ae824
JD
2595}
2596
2597
d04ebfb8 2598static bfd_boolean
7b4ae824
JD
2599bf_reg_opr_reg (const struct instruction *insn, short ie)
2600{
2601 char *ilp = input_line_pointer;
2602 int Dd = 0;
2603 if (!lex_reg_name (REG_BIT_Dn, &Dd))
2604 goto fail;
2605
2606 if (!lex_match (','))
2607 goto fail;
2608
2609
2610 uint8_t buffer[4];
2611 int n_bytes;
2612 expressionS exp;
8b3a46f9 2613 if (!lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
2614 goto fail;
2615
2616 if (!lex_match (','))
2617 goto fail;
2618
2619 int Dp = 0;
2620 if (!lex_reg_name ((0x01u << REG_D2) |
2621 (0x01u << REG_D3) |
2622 (0x01u << REG_D4) |
2623 (0x01u << REG_D5),
2624 &Dp))
2625 goto fail;
2626
2627 int size = size_from_suffix (insn, 0);
2628 uint8_t bb = ie ? 0x80 : 0x00;
2629 bb |= 0x40;
2630 bb |= Dp;
2631 bb |= (size - 1) << 2;
2632
2633 char *f = s12z_new_insn (3 + n_bytes);
2634 number_to_chars_bigendian (f++, PAGE2_PREBYTE, 1);
2635 number_to_chars_bigendian (f++, 0x08 | Dd, 1);
2636 number_to_chars_bigendian (f++, bb , 1);
2637
2638 emit_opr (f, buffer, n_bytes, &exp);
2639
d04ebfb8 2640 return true;
7b4ae824
JD
2641
2642 fail:
2643 fail_line_pointer = input_line_pointer;
2644 input_line_pointer = ilp;
d04ebfb8 2645 return false;
7b4ae824
JD
2646}
2647
2648
2649
d04ebfb8 2650static bfd_boolean
7b4ae824
JD
2651bfe_reg_reg_reg (const struct instruction *insn)
2652{
2653 return bf_reg_reg_reg (insn, 0);
2654}
2655
d04ebfb8 2656static bfd_boolean
7b4ae824
JD
2657bfi_reg_reg_reg (const struct instruction *insn)
2658{
2659 return bf_reg_reg_reg (insn, 1);
2660}
2661
d04ebfb8 2662static bfd_boolean
7b4ae824
JD
2663bfe_reg_reg_imm (const struct instruction *insn)
2664{
2665 return bf_reg_reg_imm (insn, 0);
2666}
2667
d04ebfb8 2668static bfd_boolean
7b4ae824
JD
2669bfi_reg_reg_imm (const struct instruction *insn)
2670{
2671 return bf_reg_reg_imm (insn, 1);
2672}
2673
2674
d04ebfb8 2675static bfd_boolean
7b4ae824
JD
2676bfe_reg_opr_reg (const struct instruction *insn)
2677{
2678 return bf_reg_opr_reg (insn, 0);
2679}
2680
d04ebfb8 2681static bfd_boolean
7b4ae824
JD
2682bfi_reg_opr_reg (const struct instruction *insn)
2683{
2684 return bf_reg_opr_reg (insn, 1);
2685}
2686
2687
d04ebfb8 2688static bfd_boolean
7b4ae824
JD
2689bfe_opr_reg_reg (const struct instruction *insn)
2690{
2691 return bf_opr_reg_reg (insn, 0);
2692}
2693
d04ebfb8 2694static bfd_boolean
7b4ae824
JD
2695bfi_opr_reg_reg (const struct instruction *insn)
2696{
2697 return bf_opr_reg_reg (insn, 1);
2698}
2699
d04ebfb8 2700static bfd_boolean
7b4ae824
JD
2701bfe_reg_opr_imm (const struct instruction *insn)
2702{
2703 return bf_reg_opr_imm (insn, 0);
2704}
2705
d04ebfb8 2706static bfd_boolean
7b4ae824
JD
2707bfi_reg_opr_imm (const struct instruction *insn)
2708{
2709 return bf_reg_opr_imm (insn, 1);
2710}
2711
d04ebfb8 2712static bfd_boolean
7b4ae824
JD
2713bfe_opr_reg_imm (const struct instruction *insn)
2714{
2715 return bf_opr_reg_imm (insn, 0);
2716}
2717
d04ebfb8 2718static bfd_boolean
7b4ae824
JD
2719bfi_opr_reg_imm (const struct instruction *insn)
2720{
2721 return bf_opr_reg_imm (insn, 1);
2722}
2723
2724\f
2725
2726
d04ebfb8 2727static bfd_boolean
7b4ae824
JD
2728tb_reg_rel (const struct instruction *insn)
2729{
2730 char *ilp = input_line_pointer;
2731
2732 int reg;
2733 if (!lex_reg_name (REG_BIT_Dn | REG_BIT_XY, &reg))
2734 goto fail;
2735
2736 if (!lex_match (','))
2737 goto fail;
2738
2739 bool long_displacement;
2740 expressionS exp;
2741 if (! lex_15_bit_offset (&long_displacement, &exp))
2742 goto fail;
2743
2744 uint8_t lb = 0x00;
2745 if (reg == REG_X || reg == REG_Y)
2746 {
2747 lb |= 0x08;
2748 }
2749 else
2750 {
2751 lb |= reg;
2752 }
2753 if (reg == REG_Y)
2754 lb |= 0x01;
2755
2756 if (0 == strncmp (insn->name + 2, "ne", 2))
2757 lb |= 0x00 << 4;
2758 else if (0 == strncmp (insn->name + 2, "eq", 2))
2759 lb |= 0x01 << 4;
2760 else if (0 == strncmp (insn->name + 2, "pl", 2))
2761 lb |= 0x02 << 4;
2762 else if (0 == strncmp (insn->name + 2, "mi", 2))
2763 lb |= 0x03 << 4;
2764 else if (0 == strncmp (insn->name + 2, "gt", 2))
2765 lb |= 0x04 << 4;
2766 else if (0 == strncmp (insn->name + 2, "le", 2))
2767 lb |= 0x05 << 4;
2768
2769 switch (insn->name[0])
2770 {
2771 case 'd':
2772 lb |= 0x80;
2773 break;
2774 case 't':
2775 break;
2776 default:
2777 gas_assert (0);
2778 break;
2779 };
2780
2781 char *f = s12z_new_insn (long_displacement ? 4 : 3);
2782 number_to_chars_bigendian (f++, insn->opc, 1);
2783 number_to_chars_bigendian (f++, lb, 1);
2784
2785 emit_15_bit_offset (f, 4, &exp);
2786
d04ebfb8 2787 return true;
7b4ae824
JD
2788
2789 fail:
2790 fail_line_pointer = input_line_pointer;
2791 input_line_pointer = ilp;
d04ebfb8 2792 return false;
7b4ae824
JD
2793}
2794
2795
d04ebfb8 2796static bfd_boolean
7b4ae824
JD
2797tb_opr_rel (const struct instruction *insn)
2798{
2799 char *ilp = input_line_pointer;
2800
2801 uint8_t buffer[4];
2802 int n_bytes;
2803 expressionS exp;
8b3a46f9 2804 if (!lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
2805 goto fail;
2806
2807 if (!lex_match (','))
2808 goto fail;
2809
2810 bool long_displacement;
2811 expressionS exp2;
2812 if (! lex_15_bit_offset (&long_displacement, &exp2))
2813 goto fail;
2814
2815 uint8_t lb = 0x0C;
2816
2817 if (0 == strncmp (insn->name + 2, "ne", 2))
2818 lb |= 0x00 << 4;
2819 else if (0 == strncmp (insn->name + 2, "eq", 2))
2820 lb |= 0x01 << 4;
2821 else if (0 == strncmp (insn->name + 2, "pl", 2))
2822 lb |= 0x02 << 4;
2823 else if (0 == strncmp (insn->name + 2, "mi", 2))
2824 lb |= 0x03 << 4;
2825 else if (0 == strncmp (insn->name + 2, "gt", 2))
2826 lb |= 0x04 << 4;
2827 else if (0 == strncmp (insn->name + 2, "le", 2))
2828 lb |= 0x05 << 4;
2829
2830 switch (insn->name[0])
2831 {
2832 case 'd':
2833 lb |= 0x80;
2834 break;
2835 case 't':
2836 break;
2837 default:
2838 gas_assert (0);
2839 break;
2840 };
2841
2842 int size = size_from_suffix (insn, 0);
2843
2844 lb |= size -1;
2845
2846 char *f = s12z_new_insn (n_bytes + (long_displacement ? 4 : 3));
2847 number_to_chars_bigendian (f++, insn->opc, 1);
2848 number_to_chars_bigendian (f++, lb, 1);
2849 f = emit_opr (f, buffer, n_bytes, &exp);
2850
2851 emit_15_bit_offset (f, n_bytes + 4, &exp2);
2852
d04ebfb8 2853 return true;
7b4ae824
JD
2854
2855 fail:
2856 fail_line_pointer = input_line_pointer;
2857 input_line_pointer = ilp;
d04ebfb8 2858 return false;
7b4ae824
JD
2859}
2860
2861\f
2862
2863
d04ebfb8 2864static bfd_boolean
7b4ae824
JD
2865test_br_reg_reg_rel (const struct instruction *insn)
2866{
2867 char *ilp = input_line_pointer;
2868
2869 int Di = 0;
2870 if (!lex_reg_name (REG_BIT_Dn, &Di))
2871 goto fail;
2872
2873 if (!lex_match (','))
2874 goto fail;
2875
2876
2877 int Dn = 0;
2878 if (!lex_reg_name (REG_BIT_Dn, &Dn))
2879 goto fail;
2880
2881 if (!lex_match (','))
2882 goto fail;
2883
2884
2885 bool long_displacement;
2886 expressionS exp;
2887 if (! lex_15_bit_offset (&long_displacement, &exp))
2888 goto fail;
2889
2890 uint8_t bm = 0x81;
2891 uint8_t xb = 0xb8;
2892
2893 bm |= Dn << 4;
2894 xb |= Di;
2895
2896 char *f = s12z_new_insn (long_displacement ? 5 : 4);
2897 number_to_chars_bigendian (f++, insn->opc, 1);
2898 number_to_chars_bigendian (f++, bm, 1);
2899 number_to_chars_bigendian (f++, xb, 1);
2900
2901 emit_15_bit_offset (f, 5, &exp);
2902
d04ebfb8 2903 return true;
7b4ae824
JD
2904
2905 fail:
2906 fail_line_pointer = input_line_pointer;
2907 input_line_pointer = ilp;
d04ebfb8 2908 return false;
7b4ae824
JD
2909}
2910
d04ebfb8 2911static bfd_boolean
7b4ae824
JD
2912test_br_opr_reg_rel (const struct instruction *insn)
2913{
2914 char *ilp = input_line_pointer;
2915
2916 uint8_t buffer[4];
2917 int n_bytes;
2918 expressionS exp;
8b3a46f9 2919 if (!lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
2920 goto fail;
2921
2922 if (!lex_match (','))
2923 goto fail;
2924
2925 int Dn = 0;
2926 if (!lex_reg_name (REG_BIT_Dn, &Dn))
2927 goto fail;
2928
2929 if (!lex_match (','))
2930 goto fail;
2931
2932 uint8_t bm = 0x81;
2933 bm |= Dn << 4;
2934 int size = size_from_suffix (insn, 0);
2935 bm |= (size -1) << 2;
2936
2937 bool long_displacement;
2938
2939 expressionS exp2;
2940 if (! lex_15_bit_offset (&long_displacement, &exp2))
2941 goto fail;
2942
2943 int n = n_bytes + (long_displacement ? 4 : 3);
2944 char *f = s12z_new_insn (n);
2945 number_to_chars_bigendian (f++, insn->opc, 1);
2946 number_to_chars_bigendian (f++, bm, 1);
2947 f = emit_opr (f, buffer, n_bytes, &exp);
2948
2949 emit_15_bit_offset (f, n, &exp2);
2950
d04ebfb8 2951 return true;
7b4ae824
JD
2952
2953 fail:
2954 fail_line_pointer = input_line_pointer;
2955 input_line_pointer = ilp;
d04ebfb8 2956 return false;
7b4ae824
JD
2957}
2958
2959
d04ebfb8 2960static bfd_boolean
7b4ae824
JD
2961test_br_opr_imm_rel (const struct instruction *insn)
2962{
2963 char *ilp = input_line_pointer;
2964
2965 uint8_t buffer[4];
2966 int n_bytes;
2967 expressionS exp;
8b3a46f9 2968 if (!lex_opr (buffer, &n_bytes, &exp, false))
7b4ae824
JD
2969 goto fail;
2970
2971 if (!lex_match (','))
2972 goto fail;
2973
2974 long imm;
c6f14c0d 2975 if (!lex_imm (&imm, NULL))
7b4ae824
JD
2976 goto fail;
2977
2978 if (imm < 0 || imm > 31)
2979 goto fail;
2980
2981 if (!lex_match (','))
2982 goto fail;
2983
2984 bool long_displacement;
2985 expressionS exp2;
2986 if (! lex_15_bit_offset (&long_displacement, &exp2))
2987 goto fail;
2988
2989 int size = size_from_suffix (insn, 0);
2990
2991 uint8_t bm = 0x80;
2992 bm |= (imm & 0x07) << 4;
2993 bm |= (imm >> 3) & 0x03;
2994 if (size == 4)
2995 bm |= 0x08;
2996 else if (size == 2)
2997 bm |= 0x02;
2998
2999 char *f = s12z_new_insn (n_bytes + (long_displacement ? 4 : 3));
3000 number_to_chars_bigendian (f++, insn->opc, 1);
3001 number_to_chars_bigendian (f++, bm, 1);
3002 f = emit_opr (f, buffer, n_bytes, &exp);
3003
3004 emit_15_bit_offset (f, n_bytes + 4, &exp2);
3005
d04ebfb8 3006 return true;
7b4ae824
JD
3007
3008 fail:
3009 fail_line_pointer = input_line_pointer;
3010 input_line_pointer = ilp;
d04ebfb8 3011 return false;
7b4ae824
JD
3012}
3013
3014
d04ebfb8 3015static bfd_boolean
7b4ae824
JD
3016test_br_reg_imm_rel (const struct instruction *insn)
3017{
3018 char *ilp = input_line_pointer;
3019
3020 int Di = 0;
3021 if (!lex_reg_name (REG_BIT_Dn, &Di))
3022 goto fail;
3023
3024 if (!lex_match (','))
3025 goto fail;
3026
3027 long imm;
c6f14c0d 3028 if (!lex_imm (&imm, NULL))
7b4ae824
JD
3029 goto fail;
3030
3031 if (imm < 0 || imm > 31)
3032 goto fail;
3033
3034
3035 if (!lex_match (','))
3036 goto fail;
3037
3038 bool long_displacement;
3039 expressionS exp;
3040 if (! lex_15_bit_offset (&long_displacement, &exp))
3041 goto fail;
3042
3043 uint8_t bm = Di;
3044 bm |= imm << 3;
3045
3046 char *f = s12z_new_insn (long_displacement ? 4 : 3);
3047 number_to_chars_bigendian (f++, insn->opc, 1);
3048 number_to_chars_bigendian (f++, bm, 1);
3049
3050 emit_15_bit_offset (f, 4, &exp);
3051
d04ebfb8 3052 return true;
7b4ae824
JD
3053
3054 fail:
3055 fail_line_pointer = input_line_pointer;
3056 input_line_pointer = ilp;
d04ebfb8 3057 return false;
7b4ae824
JD
3058}
3059
3060
3061\f
3062
3063static const struct instruction opcodes[] = {
3064 {"bgnd", 1, 0x00, no_operands, 0},
3065 {"nop", 1, 0x01, no_operands, 0},
3066
3067 {"brclr", 1, 0x02, test_br_reg_reg_rel, 0},
3068 {"brset", 1, 0x03, test_br_reg_reg_rel, 0},
3069
3070 {"brclr", 1, 0x02, test_br_reg_imm_rel, 0},
3071 {"brset", 1, 0x03, test_br_reg_imm_rel, 0},
3072
3073 {"brclr.b", 1, 0x02, test_br_opr_reg_rel, 0},
3074 {"brclr.w", 1, 0x02, test_br_opr_reg_rel, 0},
3075 {"brclr.l", 1, 0x02, test_br_opr_reg_rel, 0},
3076
3077 {"brset.b", 1, 0x03, test_br_opr_reg_rel, 0},
3078 {"brset.w", 1, 0x03, test_br_opr_reg_rel, 0},
3079 {"brset.l", 1, 0x03, test_br_opr_reg_rel, 0},
3080
3081 {"brclr.b", 1, 0x02, test_br_opr_imm_rel, 0},
3082 {"brclr.w", 1, 0x02, test_br_opr_imm_rel, 0},
3083 {"brclr.l", 1, 0x02, test_br_opr_imm_rel, 0},
3084
3085 {"brset.b", 1, 0x03, test_br_opr_imm_rel, 0},
3086 {"brset.w", 1, 0x03, test_br_opr_imm_rel, 0},
3087 {"brset.l", 1, 0x03, test_br_opr_imm_rel, 0},
3088
3089 {"psh", 1, 0x04, psh_pull, 0},
3090 {"pul", 1, 0x04, psh_pull, 0},
3091
3092 {"rts", 1, 0x05, no_operands, 0},
3093 {"lea", 1, 0x06, reg67sxy_opr, 0},
3094
3095 {"dbne", 1, 0x0b, tb_reg_rel, 0},
3096 {"dbeq", 1, 0x0b, tb_reg_rel, 0},
3097 {"dbpl", 1, 0x0b, tb_reg_rel, 0},
3098 {"dbmi", 1, 0x0b, tb_reg_rel, 0},
3099 {"dbgt", 1, 0x0b, tb_reg_rel, 0},
3100 {"dble", 1, 0x0b, tb_reg_rel, 0},
3101
3102 {"dbne.b", 1, 0x0b, tb_opr_rel, 0},
3103 {"dbeq.b", 1, 0x0b, tb_opr_rel, 0},
3104 {"dbpl.b", 1, 0x0b, tb_opr_rel, 0},
3105 {"dbmi.b", 1, 0x0b, tb_opr_rel, 0},
3106 {"dbgt.b", 1, 0x0b, tb_opr_rel, 0},
3107 {"dble.b", 1, 0x0b, tb_opr_rel, 0},
3108
3109 {"dbne.w", 1, 0x0b, tb_opr_rel, 0},
3110 {"dbeq.w", 1, 0x0b, tb_opr_rel, 0},
3111 {"dbpl.w", 1, 0x0b, tb_opr_rel, 0},
3112 {"dbmi.w", 1, 0x0b, tb_opr_rel, 0},
3113 {"dbgt.w", 1, 0x0b, tb_opr_rel, 0},
3114 {"dble.w", 1, 0x0b, tb_opr_rel, 0},
3115
3116 {"dbne.p", 1, 0x0b, tb_opr_rel, 0},
3117 {"dbeq.p", 1, 0x0b, tb_opr_rel, 0},
3118 {"dbpl.p", 1, 0x0b, tb_opr_rel, 0},
3119 {"dbmi.p", 1, 0x0b, tb_opr_rel, 0},
3120 {"dbgt.p", 1, 0x0b, tb_opr_rel, 0},
3121 {"dble.p", 1, 0x0b, tb_opr_rel, 0},
3122
3123 {"dbne.l", 1, 0x0b, tb_opr_rel, 0},
3124 {"dbeq.l", 1, 0x0b, tb_opr_rel, 0},
3125 {"dbpl.l", 1, 0x0b, tb_opr_rel, 0},
3126 {"dbmi.l", 1, 0x0b, tb_opr_rel, 0},
3127 {"dbgt.l", 1, 0x0b, tb_opr_rel, 0},
3128 {"dble.l", 1, 0x0b, tb_opr_rel, 0},
3129
3130 {"tbne", 1, 0x0b, tb_reg_rel, 0},
3131 {"tbeq", 1, 0x0b, tb_reg_rel, 0},
3132 {"tbpl", 1, 0x0b, tb_reg_rel, 0},
3133 {"tbmi", 1, 0x0b, tb_reg_rel, 0},
3134 {"tbgt", 1, 0x0b, tb_reg_rel, 0},
3135 {"tble", 1, 0x0b, tb_reg_rel, 0},
3136
3137 {"tbne.b", 1, 0x0b, tb_opr_rel, 0},
3138 {"tbeq.b", 1, 0x0b, tb_opr_rel, 0},
3139 {"tbpl.b", 1, 0x0b, tb_opr_rel, 0},
3140 {"tbmi.b", 1, 0x0b, tb_opr_rel, 0},
3141 {"tbgt.b", 1, 0x0b, tb_opr_rel, 0},
3142 {"tble.b", 1, 0x0b, tb_opr_rel, 0},
3143
3144 {"tbne.w", 1, 0x0b, tb_opr_rel, 0},
3145 {"tbeq.w", 1, 0x0b, tb_opr_rel, 0},
3146 {"tbpl.w", 1, 0x0b, tb_opr_rel, 0},
3147 {"tbmi.w", 1, 0x0b, tb_opr_rel, 0},
3148 {"tbgt.w", 1, 0x0b, tb_opr_rel, 0},
3149 {"tble.w", 1, 0x0b, tb_opr_rel, 0},
3150
3151 {"tbne.p", 1, 0x0b, tb_opr_rel, 0},
3152 {"tbeq.p", 1, 0x0b, tb_opr_rel, 0},
3153 {"tbpl.p", 1, 0x0b, tb_opr_rel, 0},
3154 {"tbmi.p", 1, 0x0b, tb_opr_rel, 0},
3155 {"tbgt.p", 1, 0x0b, tb_opr_rel, 0},
3156 {"tble.p", 1, 0x0b, tb_opr_rel, 0},
3157
3158 {"tbne.l", 1, 0x0b, tb_opr_rel, 0},
3159 {"tbeq.l", 1, 0x0b, tb_opr_rel, 0},
3160 {"tbpl.l", 1, 0x0b, tb_opr_rel, 0},
3161 {"tbmi.l", 1, 0x0b, tb_opr_rel, 0},
3162 {"tbgt.l", 1, 0x0b, tb_opr_rel, 0},
3163 {"tble.l", 1, 0x0b, tb_opr_rel, 0},
3164
3165 {"mov.b", 1, 0x0c, imm_opr, 0},
3166 {"mov.w", 1, 0x0d, imm_opr, 0},
3167 {"mov.p", 1, 0x0e, imm_opr, 0},
3168 {"mov.l", 1, 0x0f, imm_opr, 0},
3169
3170 {"rol", 1, 0x10, rol, 0},
3171 {"rol.b", 1, 0x10, rol, 0},
3172 {"rol.w", 1, 0x10, rol, 0},
3173 {"rol.p", 1, 0x10, rol, 0},
3174 {"rol.l", 1, 0x10, rol, 0},
3175
3176 {"ror", 1, 0x10, ror, 0},
3177 {"ror.b", 1, 0x10, ror, 0},
3178 {"ror.w", 1, 0x10, ror, 0},
3179 {"ror.p", 1, 0x10, ror, 0},
3180 {"ror.l", 1, 0x10, ror, 0},
3181
3182 {"lsl", 1, 0x10, shift_reg, 0},
3183 {"lsr", 1, 0x10, shift_reg, 0},
3184 {"asl", 1, 0x10, shift_reg, 0},
3185 {"asr", 1, 0x10, shift_reg, 0},
3186
3187 {"lsl.b", 1, 0x10, shift_two_operand, 0},
3188 {"lsl.w", 1, 0x10, shift_two_operand, 0},
3189 {"lsl.p", 1, 0x10, shift_two_operand, 0},
3190 {"lsl.l", 1, 0x10, shift_two_operand, 0},
3191 {"asl.b", 1, 0x10, shift_two_operand, 0},
3192 {"asl.w", 1, 0x10, shift_two_operand, 0},
3193 {"asl.p", 1, 0x10, shift_two_operand, 0},
3194 {"asl.l", 1, 0x10, shift_two_operand, 0},
3195
3196 {"lsr.b", 1, 0x10, shift_two_operand, 0},
3197 {"lsr.w", 1, 0x10, shift_two_operand, 0},
3198 {"lsr.p", 1, 0x10, shift_two_operand, 0},
3199 {"lsr.l", 1, 0x10, shift_two_operand, 0},
3200 {"asr.b", 1, 0x10, shift_two_operand, 0},
3201 {"asr.w", 1, 0x10, shift_two_operand, 0},
3202 {"asr.p", 1, 0x10, shift_two_operand, 0},
3203 {"asr.l", 1, 0x10, shift_two_operand, 0},
3204
3205 {"lsl.b", 1, 0x10, shift_opr_imm, 0},
3206 {"lsl.w", 1, 0x10, shift_opr_imm, 0},
3207 {"lsl.p", 1, 0x10, shift_opr_imm, 0},
3208 {"lsl.l", 1, 0x10, shift_opr_imm, 0},
3209 {"asl.b", 1, 0x10, shift_opr_imm, 0},
3210 {"asl.w", 1, 0x10, shift_opr_imm, 0},
3211 {"asl.p", 1, 0x10, shift_opr_imm, 0},
3212 {"asl.l", 1, 0x10, shift_opr_imm, 0},
3213
3214 {"lsr.b", 1, 0x10, shift_opr_imm, 0},
3215 {"lsr.w", 1, 0x10, shift_opr_imm, 0},
3216 {"lsr.p", 1, 0x10, shift_opr_imm, 0},
3217 {"lsr.l", 1, 0x10, shift_opr_imm, 0},
3218 {"asr.b", 1, 0x10, shift_opr_imm, 0},
3219 {"asr.w", 1, 0x10, shift_opr_imm, 0},
3220 {"asr.p", 1, 0x10, shift_opr_imm, 0},
3221 {"asr.l", 1, 0x10, shift_opr_imm, 0},
3222
3223 {"mov.b", 1, 0x1c, opr_opr, 0},
3224 {"mov.w", 1, 0x1d, opr_opr, 0},
3225 {"mov.p", 1, 0x1e, opr_opr, 0},
3226 {"mov.l", 1, 0x1f, opr_opr, 0},
3227
3228 {"bra", 1, 0x20, rel, 0},
3229 {"bsr", 1, 0x21, rel, 0},
3230 {"bhi", 1, 0x22, rel, 0},
3231 {"bls", 1, 0x23, rel, 0},
3232 {"bcc", 1, 0x24, rel, 0},
51534d7a 3233 {"bhs", 1, 0x24, rel, 0}, /* Alias for bcc */
7b4ae824 3234 {"bcs", 1, 0x25, rel, 0},
51534d7a 3235 {"blo", 1, 0x25, rel, 0}, /* Alias for bcs */
7b4ae824
JD
3236 {"bne", 1, 0x26, rel, 0},
3237 {"beq", 1, 0x27, rel, 0},
3238 {"bvc", 1, 0x28, rel, 0},
3239 {"bvs", 1, 0x29, rel, 0},
3240 {"bpl", 1, 0x2a, rel, 0},
3241 {"bmi", 1, 0x2b, rel, 0},
3242 {"bge", 1, 0x2c, rel, 0},
3243 {"blt", 1, 0x2d, rel, 0},
3244 {"bgt", 1, 0x2e, rel, 0},
3245 {"ble", 1, 0x2f, rel, 0},
3246
3247 {"inc", 1, 0x30, reg_inh, 0},
3248 {"clr", 1, 0x38, reg_inh, 0},
3249 {"dec", 1, 0x40, reg_inh, 0},
3250
3251 {"muls", 1, 0x48, mul_reg_reg_reg, 0},
3252 {"mulu", 1, 0x48, mul_reg_reg_reg, 0},
3253
3254 {"muls.b", 1, 0x48, mul_reg_reg_opr, 0},
3255 {"muls.w", 1, 0x48, mul_reg_reg_opr, 0},
3256 {"muls.l", 1, 0x48, mul_reg_reg_opr, 0},
3257
3258 {"mulu.b", 1, 0x48, mul_reg_reg_opr, 0},
3259 {"mulu.w", 1, 0x48, mul_reg_reg_opr, 0},
3260 {"mulu.l", 1, 0x48, mul_reg_reg_opr, 0},
3261
3262 {"muls.b", 1, 0x48, mul_reg_reg_imm, 0},
3263 {"muls.w", 1, 0x48, mul_reg_reg_imm, 0},
3264 {"muls.l", 1, 0x48, mul_reg_reg_imm, 0},
3265
3266 {"mulu.b", 1, 0x48, mul_reg_reg_imm, 0},
3267 {"mulu.w", 1, 0x48, mul_reg_reg_imm, 0},
3268 {"mulu.l", 1, 0x48, mul_reg_reg_imm, 0},
3269
3270 {"muls.bb", 1, 0x48, mul_reg_opr_opr, 0},
3271 {"muls.bw", 1, 0x48, mul_reg_opr_opr, 0},
3272 {"muls.bp", 1, 0x48, mul_reg_opr_opr, 0},
3273 {"muls.bl", 1, 0x48, mul_reg_opr_opr, 0},
3274
3275 {"muls.wb", 1, 0x48, mul_reg_opr_opr, 0},
3276 {"muls.ww", 1, 0x48, mul_reg_opr_opr, 0},
3277 {"muls.wp", 1, 0x48, mul_reg_opr_opr, 0},
3278 {"muls.wl", 1, 0x48, mul_reg_opr_opr, 0},
3279
3280 {"muls.pb", 1, 0x48, mul_reg_opr_opr, 0},
3281 {"muls.pw", 1, 0x48, mul_reg_opr_opr, 0},
3282 {"muls.pp", 1, 0x48, mul_reg_opr_opr, 0},
3283 {"muls.pl", 1, 0x48, mul_reg_opr_opr, 0},
3284
3285 {"muls.lb", 1, 0x48, mul_reg_opr_opr, 0},
3286 {"muls.lw", 1, 0x48, mul_reg_opr_opr, 0},
3287 {"muls.lp", 1, 0x48, mul_reg_opr_opr, 0},
3288 {"muls.ll", 1, 0x48, mul_reg_opr_opr, 0},
3289
3290 {"mulu.bb", 1, 0x48, mul_reg_opr_opr, 0},
3291 {"mulu.bw", 1, 0x48, mul_reg_opr_opr, 0},
3292 {"mulu.bp", 1, 0x48, mul_reg_opr_opr, 0},
3293 {"mulu.bl", 1, 0x48, mul_reg_opr_opr, 0},
3294
3295 {"mulu.wb", 1, 0x48, mul_reg_opr_opr, 0},
3296 {"mulu.ww", 1, 0x48, mul_reg_opr_opr, 0},
3297 {"mulu.wp", 1, 0x48, mul_reg_opr_opr, 0},
3298 {"mulu.wl", 1, 0x48, mul_reg_opr_opr, 0},
3299
3300 {"mulu.pb", 1, 0x48, mul_reg_opr_opr, 0},
3301 {"mulu.pw", 1, 0x48, mul_reg_opr_opr, 0},
3302 {"mulu.pp", 1, 0x48, mul_reg_opr_opr, 0},
3303 {"mulu.pl", 1, 0x48, mul_reg_opr_opr, 0},
3304
3305 {"mulu.lb", 1, 0x48, mul_reg_opr_opr, 0},
3306 {"mulu.lw", 1, 0x48, mul_reg_opr_opr, 0},
3307 {"mulu.lp", 1, 0x48, mul_reg_opr_opr, 0},
3308 {"mulu.ll", 1, 0x48, mul_reg_opr_opr, 0},
3309
3310 {"add", 1, 0x50, regd_imm, 0},
3311 {"and", 1, 0x58, regd_imm, 0},
3312
3313 {"add", 1, 0x60, regd_opr, 0},
3314 {"and", 1, 0x68, regd_opr, 0},
3315
3316 {"sub", 1, 0x70, regd_imm, 0},
3317 {"or", 1, 0x78, regd_imm, 0},
3318
3319 {"sub", 1, 0x80, regd_opr, 0},
3320 {"or", 1, 0x88, regd_opr, 0},
3321
3322 {"ld", 1, 0x90, regdxy_imm, 0},
3323
3324 {"clr", 1, 0x9a, clr_xy, 0},
3325 {"tfr", 1, 0x9e, tfr, 0},
3326 {"zex", 1, 0x9e, tfr, 0},
3327
8b3a46f9 3328 {"ld", 1, 0xa0, regdxy_opr_src, 0xb0},
7b4ae824
JD
3329
3330 {"jmp", 1, 0xaa, opr, 0xba},
3331 {"jsr", 1, 0xab, opr, 0xbb},
3332
3333 {"exg", 1, 0xae, tfr, 0},
3334 {"sex", 1, 0xae, tfr, 0},
3335
8b3a46f9 3336 {"st", 1, 0xc0, regdxy_opr_dest, 0xd0},
7b4ae824
JD
3337
3338 {"andcc", 1, 0xce, imm8, 0},
3339 {"orcc", 1, 0xde, imm8, 0},
3340
3341 {"inc.b", 1, 0x9c, opr, 0},
3342 {"inc.w", 1, 0x9d, opr, 0},
3343 {"inc.l", 1, 0x9f, opr, 0},
3344
3345 {"dec.b", 1, 0xac, opr, 0},
3346 {"dec.w", 1, 0xad, opr, 0},
3347 {"dec.l", 1, 0xaf, opr, 0},
3348
3349 {"clr.b", 1, 0xbc, opr, 0},
3350 {"clr.w", 1, 0xbd, opr, 0},
3351 {"clr.p", 1, 0xbe, opr, 0},
3352 {"clr.l", 1, 0xbf, opr, 0},
3353
3354 {"com.b", 1, 0xcc, opr, 0},
3355 {"com.w", 1, 0xcd, opr, 0},
3356 {"com.l", 1, 0xcf, opr, 0},
3357
3358 {"neg.b", 1, 0xdc, opr, 0},
3359 {"neg.w", 1, 0xdd, opr, 0},
3360 {"neg.l", 1, 0xdf, opr, 0},
3361
3362 {"bclr", 1, 0xec, bm_regd_imm, 0},
3363 {"bset", 1, 0xed, bm_regd_imm, 0},
3364 {"btgl", 1, 0xee, bm_regd_imm, 0},
3365
3366 {"bclr", 1, 0xec, bm_regd_reg, 0},
3367 {"bset", 1, 0xed, bm_regd_reg, 0},
3368 {"btgl", 1, 0xee, bm_regd_reg, 0},
3369
3370 {"bclr.b", 1, 0xec, bm_opr_imm, 0},
3371 {"bclr.w", 1, 0xec, bm_opr_imm, 0},
3372 {"bclr.l", 1, 0xec, bm_opr_imm, 0},
3373
3374 {"bset.b", 1, 0xed, bm_opr_imm, 0},
3375 {"bset.w", 1, 0xed, bm_opr_imm, 0},
3376 {"bset.l", 1, 0xed, bm_opr_imm, 0},
3377
3378 {"btgl.b", 1, 0xee, bm_opr_imm, 0},
3379 {"btgl.w", 1, 0xee, bm_opr_imm, 0},
3380 {"btgl.l", 1, 0xee, bm_opr_imm, 0},
3381
3382 {"bclr.b", 1, 0xec, bm_opr_reg, 0},
3383 {"bclr.w", 1, 0xec, bm_opr_reg, 0},
3384 {"bclr.l", 1, 0xec, bm_opr_reg, 0},
3385
3386 {"bset.b", 1, 0xed, bm_opr_reg, 0},
3387 {"bset.w", 1, 0xed, bm_opr_reg, 0},
3388 {"bset.l", 1, 0xed, bm_opr_reg, 0},
3389
3390 {"btgl.b", 1, 0xee, bm_opr_reg, 0},
3391 {"btgl.w", 1, 0xee, bm_opr_reg, 0},
3392 {"btgl.l", 1, 0xee, bm_opr_reg, 0},
3393
3394 {"cmp", 1, 0xe0, regdxy_imm, 0},
8b3a46f9 3395 {"cmp", 1, 0xf0, regdxy_opr_src, 0},
7b4ae824
JD
3396
3397 {"cmp", 1, 0xfc, regx_regy, 0},
3398 {"sub", 1, 0xfd, regd6_regx_regy, 0},
3399 {"sub", 1, 0xfe, regd6_regy_regx, 0},
3400
3401 {"swi", 1, 0xff, no_operands, 0},
3402
3403 /* Page 2 */
3404
3405 /* The -10 below is a kludge. The opcode is in fact 0x00 */
8b3a46f9 3406 {"ld", 2, -10, regs_opr_src, 0},
7b4ae824
JD
3407
3408 /* The -9 below is a kludge. The opcode is in fact 0x01 */
8b3a46f9 3409 {"st", 2, -9, regs_opr_dest, 0},
7b4ae824
JD
3410
3411 /* The -8 below is a kludge. The opcode is in fact 0x02 */
8b3a46f9 3412 {"cmp", 2, -8, regs_opr_src, 0},
7b4ae824
JD
3413
3414 /* The -7 below is a kludge. The opcode is in fact 0x03 */
3415 {"ld", 2, -7, regs_imm, 0},
3416
3417 /* The -6 below is a kludge. The opcode is in fact 0x04 */
3418 {"cmp", 2, -6, regs_imm, 0},
3419
3420 {"bfext", 2, 0x08, bfe_reg_reg_reg, 0},
3421 {"bfext", 2, 0x08, bfe_reg_reg_imm, 0},
3422 {"bfext.b", 2, 0x08, bfe_reg_opr_reg, 0},
3423 {"bfext.w", 2, 0x08, bfe_reg_opr_reg, 0},
3424 {"bfext.p", 2, 0x08, bfe_reg_opr_reg, 0},
3425 {"bfext.l", 2, 0x08, bfe_reg_opr_reg, 0},
3426 {"bfext.b", 2, 0x08, bfe_opr_reg_reg, 0},
3427 {"bfext.w", 2, 0x08, bfe_opr_reg_reg, 0},
3428 {"bfext.p", 2, 0x08, bfe_opr_reg_reg, 0},
3429 {"bfext.l", 2, 0x08, bfe_opr_reg_reg, 0},
3430 {"bfext.b", 2, 0x08, bfe_reg_opr_imm, 0},
3431 {"bfext.w", 2, 0x08, bfe_reg_opr_imm, 0},
3432 {"bfext.p", 2, 0x08, bfe_reg_opr_imm, 0},
3433 {"bfext.l", 2, 0x08, bfe_reg_opr_imm, 0},
3434 {"bfext.b", 2, 0x08, bfe_opr_reg_imm, 0},
3435 {"bfext.w", 2, 0x08, bfe_opr_reg_imm, 0},
3436 {"bfext.p", 2, 0x08, bfe_opr_reg_imm, 0},
3437 {"bfext.l", 2, 0x08, bfe_opr_reg_imm, 0},
3438
3439
3440 {"bfins", 2, 0x08, bfi_reg_reg_reg, 0},
3441 {"bfins", 2, 0x08, bfi_reg_reg_imm, 0},
3442 {"bfins.b", 2, 0x08, bfi_reg_opr_reg, 0},
3443 {"bfins.w", 2, 0x08, bfi_reg_opr_reg, 0},
3444 {"bfins.p", 2, 0x08, bfi_reg_opr_reg, 0},
3445 {"bfins.l", 2, 0x08, bfi_reg_opr_reg, 0},
3446 {"bfins.b", 2, 0x08, bfi_opr_reg_reg, 0},
3447 {"bfins.w", 2, 0x08, bfi_opr_reg_reg, 0},
3448 {"bfins.p", 2, 0x08, bfi_opr_reg_reg, 0},
3449 {"bfins.l", 2, 0x08, bfi_opr_reg_reg, 0},
3450 {"bfins.b", 2, 0x08, bfi_reg_opr_imm, 0},
3451 {"bfins.w", 2, 0x08, bfi_reg_opr_imm, 0},
3452 {"bfins.p", 2, 0x08, bfi_reg_opr_imm, 0},
3453 {"bfins.l", 2, 0x08, bfi_reg_opr_imm, 0},
3454 {"bfins.b", 2, 0x08, bfi_opr_reg_imm, 0},
3455 {"bfins.w", 2, 0x08, bfi_opr_reg_imm, 0},
3456 {"bfins.p", 2, 0x08, bfi_opr_reg_imm, 0},
3457 {"bfins.l", 2, 0x08, bfi_opr_reg_imm, 0},
3458
3459
3460 {"minu", 2, 0x10, regd_opr, 0},
3461 {"maxu", 2, 0x18, regd_opr, 0},
3462 {"mins", 2, 0x20, regd_opr, 0},
3463 {"maxs", 2, 0x28, regd_opr, 0},
3464
3465 {"clb", 2, 0x91, tfr, 0},
3466
3467 {"trap", 2, 0x00, trap_imm, 0},
3468 {"abs", 2, 0x40, reg_inh, 0},
3469 {"sat", 2, 0xa0, reg_inh, 0},
3470
3471 {"rti", 2, 0x90, no_operands, 0},
3472 {"stop", 2, 0x05, no_operands, 0},
3473 {"wai", 2, 0x06, no_operands, 0},
3474 {"sys", 2, 0x07, no_operands, 0},
3475
3476 {"bit", 2, 0x58, regd_imm, 0},
3477 {"bit", 2, 0x68, regd_opr, 0},
3478
3479 {"adc", 2, 0x50, regd_imm, 0},
3480 {"adc", 2, 0x60, regd_opr, 0},
3481
3482 {"sbc", 2, 0x70, regd_imm, 0},
3483 {"eor", 2, 0x78, regd_imm, 0},
3484
3485 {"sbc", 2, 0x80, regd_opr, 0},
3486 {"eor", 2, 0x88, regd_opr, 0},
3487
3488 {"divs", 2, 0x30, mul_reg_reg_reg, 0},
3489 {"divu", 2, 0x30, mul_reg_reg_reg, 0},
3490
3491 {"divs.b", 2, 0x30, mul_reg_reg_opr, 0},
3492 {"divs.w", 2, 0x30, mul_reg_reg_opr, 0},
3493 {"divs.l", 2, 0x30, mul_reg_reg_opr, 0},
3494
3495 {"divu.b", 2, 0x30, mul_reg_reg_opr, 0},
3496 {"divu.w", 2, 0x30, mul_reg_reg_opr, 0},
3497 {"divu.l", 2, 0x30, mul_reg_reg_opr, 0},
3498
3499 {"divs.b", 2, 0x30, mul_reg_reg_imm, 0},
3500 {"divs.w", 2, 0x30, mul_reg_reg_imm, 0},
3501 {"divs.l", 2, 0x30, mul_reg_reg_imm, 0},
3502
3503 {"divu.b", 2, 0x30, mul_reg_reg_imm, 0},
3504 {"divu.w", 2, 0x30, mul_reg_reg_imm, 0},
3505 {"divu.l", 2, 0x30, mul_reg_reg_imm, 0},
3506
3507 {"divs.bb", 2, 0x30, mul_reg_opr_opr, 0},
3508 {"divs.bw", 2, 0x30, mul_reg_opr_opr, 0},
3509 {"divs.bp", 2, 0x30, mul_reg_opr_opr, 0},
3510 {"divs.bl", 2, 0x30, mul_reg_opr_opr, 0},
3511
3512 {"divs.wb", 2, 0x30, mul_reg_opr_opr, 0},
3513 {"divs.ww", 2, 0x30, mul_reg_opr_opr, 0},
3514 {"divs.wp", 2, 0x30, mul_reg_opr_opr, 0},
3515 {"divs.wl", 2, 0x30, mul_reg_opr_opr, 0},
3516
3517 {"divs.pb", 2, 0x30, mul_reg_opr_opr, 0},
3518 {"divs.pw", 2, 0x30, mul_reg_opr_opr, 0},
3519 {"divs.pp", 2, 0x30, mul_reg_opr_opr, 0},
3520 {"divs.pl", 2, 0x30, mul_reg_opr_opr, 0},
3521
3522 {"divs.lb", 2, 0x30, mul_reg_opr_opr, 0},
3523 {"divs.lw", 2, 0x30, mul_reg_opr_opr, 0},
3524 {"divs.lp", 2, 0x30, mul_reg_opr_opr, 0},
3525 {"divs.ll", 2, 0x30, mul_reg_opr_opr, 0},
3526
3527 {"divu.bb", 2, 0x30, mul_reg_opr_opr, 0},
3528 {"divu.bw", 2, 0x30, mul_reg_opr_opr, 0},
3529 {"divu.bp", 2, 0x30, mul_reg_opr_opr, 0},
3530 {"divu.bl", 2, 0x30, mul_reg_opr_opr, 0},
3531
3532 {"divu.wb", 2, 0x30, mul_reg_opr_opr, 0},
3533 {"divu.ww", 2, 0x30, mul_reg_opr_opr, 0},
3534 {"divu.wp", 2, 0x30, mul_reg_opr_opr, 0},
3535 {"divu.wl", 2, 0x30, mul_reg_opr_opr, 0},
3536
3537 {"divu.pb", 2, 0x30, mul_reg_opr_opr, 0},
3538 {"divu.pw", 2, 0x30, mul_reg_opr_opr, 0},
3539 {"divu.pp", 2, 0x30, mul_reg_opr_opr, 0},
3540 {"divu.pl", 2, 0x30, mul_reg_opr_opr, 0},
3541
3542 {"divu.lb", 2, 0x30, mul_reg_opr_opr, 0},
3543 {"divu.lw", 2, 0x30, mul_reg_opr_opr, 0},
3544 {"divu.lp", 2, 0x30, mul_reg_opr_opr, 0},
3545 {"divu.ll", 2, 0x30, mul_reg_opr_opr, 0},
3546
3547 //
3548
3549 {"qmuls", 2, 0xb0, mul_reg_reg_reg, 0},
3550 {"qmulu", 2, 0xb0, mul_reg_reg_reg, 0},
3551
3552 {"qmuls.b", 2, 0xb0, mul_reg_reg_opr, 0},
3553 {"qmuls.w", 2, 0xb0, mul_reg_reg_opr, 0},
3554 {"qmuls.l", 2, 0xb0, mul_reg_reg_opr, 0},
3555
3556 {"qmulu.b", 2, 0xb0, mul_reg_reg_opr, 0},
3557 {"qmulu.w", 2, 0xb0, mul_reg_reg_opr, 0},
3558 {"qmulu.l", 2, 0xb0, mul_reg_reg_opr, 0},
3559
3560 {"qmuls.b", 2, 0xb0, mul_reg_reg_imm, 0},
3561 {"qmuls.w", 2, 0xb0, mul_reg_reg_imm, 0},
3562 {"qmuls.l", 2, 0xb0, mul_reg_reg_imm, 0},
3563
3564 {"qmulu.b", 2, 0xb0, mul_reg_reg_imm, 0},
3565 {"qmulu.w", 2, 0xb0, mul_reg_reg_imm, 0},
3566 {"qmulu.l", 2, 0xb0, mul_reg_reg_imm, 0},
3567
3568 {"qmuls.bb", 2, 0xb0, mul_reg_opr_opr, 0},
3569 {"qmuls.bw", 2, 0xb0, mul_reg_opr_opr, 0},
3570 {"qmuls.bp", 2, 0xb0, mul_reg_opr_opr, 0},
3571 {"qmuls.bl", 2, 0xb0, mul_reg_opr_opr, 0},
3572
3573 {"qmuls.wb", 2, 0xb0, mul_reg_opr_opr, 0},
3574 {"qmuls.ww", 2, 0xb0, mul_reg_opr_opr, 0},
3575 {"qmuls.wp", 2, 0xb0, mul_reg_opr_opr, 0},
3576 {"qmuls.wl", 2, 0xb0, mul_reg_opr_opr, 0},
3577
3578 {"qmuls.pb", 2, 0xb0, mul_reg_opr_opr, 0},
3579 {"qmuls.pw", 2, 0xb0, mul_reg_opr_opr, 0},
3580 {"qmuls.pp", 2, 0xb0, mul_reg_opr_opr, 0},
3581 {"qmuls.pl", 2, 0xb0, mul_reg_opr_opr, 0},
3582
3583 {"qmuls.lb", 2, 0xb0, mul_reg_opr_opr, 0},
3584 {"qmuls.lw", 2, 0xb0, mul_reg_opr_opr, 0},
3585 {"qmuls.lp", 2, 0xb0, mul_reg_opr_opr, 0},
3586 {"qmuls.ll", 2, 0xb0, mul_reg_opr_opr, 0},
3587
3588 {"qmulu.bb", 2, 0xb0, mul_reg_opr_opr, 0},
3589 {"qmulu.bw", 2, 0xb0, mul_reg_opr_opr, 0},
3590 {"qmulu.bp", 2, 0xb0, mul_reg_opr_opr, 0},
3591 {"qmulu.bl", 2, 0xb0, mul_reg_opr_opr, 0},
3592
3593 {"qmulu.wb", 2, 0xb0, mul_reg_opr_opr, 0},
3594 {"qmulu.ww", 2, 0xb0, mul_reg_opr_opr, 0},
3595 {"qmulu.wp", 2, 0xb0, mul_reg_opr_opr, 0},
3596 {"qmulu.wl", 2, 0xb0, mul_reg_opr_opr, 0},
3597
3598 {"qmulu.pb", 2, 0xb0, mul_reg_opr_opr, 0},
3599 {"qmulu.pw", 2, 0xb0, mul_reg_opr_opr, 0},
3600 {"qmulu.pp", 2, 0xb0, mul_reg_opr_opr, 0},
3601 {"qmulu.pl", 2, 0xb0, mul_reg_opr_opr, 0},
3602
3603 {"qmulu.lb", 2, 0xb0, mul_reg_opr_opr, 0},
3604 {"qmulu.lw", 2, 0xb0, mul_reg_opr_opr, 0},
3605 {"qmulu.lp", 2, 0xb0, mul_reg_opr_opr, 0},
3606 {"qmulu.ll", 2, 0xb0, mul_reg_opr_opr, 0},
3607
3608
3609 //
3610
3611 {"macs", 2, 0x48, mul_reg_reg_reg, 0},
3612 {"macu", 2, 0x48, mul_reg_reg_reg, 0},
3613
3614 {"macs.b", 2, 0x48, mul_reg_reg_opr, 0},
3615 {"macs.w", 2, 0x48, mul_reg_reg_opr, 0},
3616 {"macs.l", 2, 0x48, mul_reg_reg_opr, 0},
3617
3618 {"macu.b", 2, 0x48, mul_reg_reg_opr, 0},
3619 {"macu.w", 2, 0x48, mul_reg_reg_opr, 0},
3620 {"macu.l", 2, 0x48, mul_reg_reg_opr, 0},
3621
3622 {"macs.b", 2, 0x48, mul_reg_reg_imm, 0},
3623 {"macs.w", 2, 0x48, mul_reg_reg_imm, 0},
3624 {"macs.l", 2, 0x48, mul_reg_reg_imm, 0},
3625
3626 {"macu.b", 2, 0x48, mul_reg_reg_imm, 0},
3627 {"macu.w", 2, 0x48, mul_reg_reg_imm, 0},
3628 {"macu.l", 2, 0x48, mul_reg_reg_imm, 0},
3629
3630 {"macs.bb", 2, 0x48, mul_reg_opr_opr, 0},
3631 {"macs.bw", 2, 0x48, mul_reg_opr_opr, 0},
3632 {"macs.bp", 2, 0x48, mul_reg_opr_opr, 0},
3633 {"macs.bl", 2, 0x48, mul_reg_opr_opr, 0},
3634
3635 {"macs.wb", 2, 0x48, mul_reg_opr_opr, 0},
3636 {"macs.ww", 2, 0x48, mul_reg_opr_opr, 0},
3637 {"macs.wp", 2, 0x48, mul_reg_opr_opr, 0},
3638 {"macs.wl", 2, 0x48, mul_reg_opr_opr, 0},
3639
3640 {"macs.pb", 2, 0x48, mul_reg_opr_opr, 0},
3641 {"macs.pw", 2, 0x48, mul_reg_opr_opr, 0},
3642 {"macs.pp", 2, 0x48, mul_reg_opr_opr, 0},
3643 {"macs.pl", 2, 0x48, mul_reg_opr_opr, 0},
3644
3645 {"macs.lb", 2, 0x48, mul_reg_opr_opr, 0},
3646 {"macs.lw", 2, 0x48, mul_reg_opr_opr, 0},
3647 {"macs.lp", 2, 0x48, mul_reg_opr_opr, 0},
3648 {"macs.ll", 2, 0x48, mul_reg_opr_opr, 0},
3649
3650 {"macu.bb", 2, 0x48, mul_reg_opr_opr, 0},
3651 {"macu.bw", 2, 0x48, mul_reg_opr_opr, 0},
3652 {"macu.bp", 2, 0x48, mul_reg_opr_opr, 0},
3653 {"macu.bl", 2, 0x48, mul_reg_opr_opr, 0},
3654
3655 {"macu.wb", 2, 0x48, mul_reg_opr_opr, 0},
3656 {"macu.ww", 2, 0x48, mul_reg_opr_opr, 0},
3657 {"macu.wp", 2, 0x48, mul_reg_opr_opr, 0},
3658 {"macu.wl", 2, 0x48, mul_reg_opr_opr, 0},
3659
3660 {"macu.pb", 2, 0x48, mul_reg_opr_opr, 0},
3661 {"macu.pw", 2, 0x48, mul_reg_opr_opr, 0},
3662 {"macu.pp", 2, 0x48, mul_reg_opr_opr, 0},
3663 {"macu.pl", 2, 0x48, mul_reg_opr_opr, 0},
3664
3665 {"macu.lb", 2, 0x48, mul_reg_opr_opr, 0},
3666 {"macu.lw", 2, 0x48, mul_reg_opr_opr, 0},
3667 {"macu.lp", 2, 0x48, mul_reg_opr_opr, 0},
3668 {"macu.ll", 2, 0x48, mul_reg_opr_opr, 0},
3669
3670
3671 //
3672
3673 {"mods", 2, 0x38, mul_reg_reg_reg, 0},
3674 {"modu", 2, 0x38, mul_reg_reg_reg, 0},
3675
3676 {"mods.b", 2, 0x38, mul_reg_reg_opr, 0},
3677 {"mods.w", 2, 0x38, mul_reg_reg_opr, 0},
3678 {"mods.l", 2, 0x38, mul_reg_reg_opr, 0},
3679
3680 {"modu.b", 2, 0x38, mul_reg_reg_opr, 0},
3681 {"modu.w", 2, 0x38, mul_reg_reg_opr, 0},
3682 {"modu.l", 2, 0x38, mul_reg_reg_opr, 0},
3683
3684 {"mods.b", 2, 0x38, mul_reg_reg_imm, 0},
3685 {"mods.w", 2, 0x38, mul_reg_reg_imm, 0},
3686 {"mods.l", 2, 0x38, mul_reg_reg_imm, 0},
3687
3688 {"modu.b", 2, 0x38, mul_reg_reg_imm, 0},
3689 {"modu.w", 2, 0x38, mul_reg_reg_imm, 0},
3690 {"modu.l", 2, 0x38, mul_reg_reg_imm, 0},
3691
3692 {"mods.bb", 2, 0x38, mul_reg_opr_opr, 0},
3693 {"mods.bw", 2, 0x38, mul_reg_opr_opr, 0},
3694 {"mods.bp", 2, 0x38, mul_reg_opr_opr, 0},
3695 {"mods.bl", 2, 0x38, mul_reg_opr_opr, 0},
3696
3697 {"mods.wb", 2, 0x38, mul_reg_opr_opr, 0},
3698 {"mods.ww", 2, 0x38, mul_reg_opr_opr, 0},
3699 {"mods.wp", 2, 0x38, mul_reg_opr_opr, 0},
3700 {"mods.wl", 2, 0x38, mul_reg_opr_opr, 0},
3701
3702 {"mods.pb", 2, 0x38, mul_reg_opr_opr, 0},
3703 {"mods.pw", 2, 0x38, mul_reg_opr_opr, 0},
3704 {"mods.pp", 2, 0x38, mul_reg_opr_opr, 0},
3705 {"mods.pl", 2, 0x38, mul_reg_opr_opr, 0},
3706
3707 {"mods.lb", 2, 0x38, mul_reg_opr_opr, 0},
3708 {"mods.lw", 2, 0x38, mul_reg_opr_opr, 0},
3709 {"mods.lp", 2, 0x38, mul_reg_opr_opr, 0},
3710 {"mods.ll", 2, 0x38, mul_reg_opr_opr, 0},
3711
3712 {"modu.bb", 2, 0x38, mul_reg_opr_opr, 0},
3713 {"modu.bw", 2, 0x38, mul_reg_opr_opr, 0},
3714 {"modu.bp", 2, 0x38, mul_reg_opr_opr, 0},
3715 {"modu.bl", 2, 0x38, mul_reg_opr_opr, 0},
3716
3717 {"modu.wb", 2, 0x38, mul_reg_opr_opr, 0},
3718 {"modu.ww", 2, 0x38, mul_reg_opr_opr, 0},
3719 {"modu.wp", 2, 0x38, mul_reg_opr_opr, 0},
3720 {"modu.wl", 2, 0x38, mul_reg_opr_opr, 0},
3721
3722 {"modu.pb", 2, 0x38, mul_reg_opr_opr, 0},
3723 {"modu.pw", 2, 0x38, mul_reg_opr_opr, 0},
3724 {"modu.pp", 2, 0x38, mul_reg_opr_opr, 0},
3725 {"modu.pl", 2, 0x38, mul_reg_opr_opr, 0},
3726
3727 {"modu.lb", 2, 0x38, mul_reg_opr_opr, 0},
3728 {"modu.lw", 2, 0x38, mul_reg_opr_opr, 0},
3729 {"modu.lp", 2, 0x38, mul_reg_opr_opr, 0},
3730 {"modu.ll", 2, 0x38, mul_reg_opr_opr, 0}
3731};
3732
3733\f
3734/* Gas line assembler entry point. */
3735
3736/* This is the main entry point for the machine-dependent assembler. str
3737 points to a machine-dependent instruction. This function is supposed to
3738 emit the frags/bytes it assembles to. */
3739void
3740md_assemble (char *str)
3741{
3742 char *op_start;
3743 char *op_end;
3744 char name[20];
3745 size_t nlen = 0;
3746
3747 fail_line_pointer = NULL;
3748
3749 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
3750 lower case (the opcode table only has lower case op-codes). */
3751 for (op_start = op_end = str;
3752 *op_end && !is_end_of_line[(int)*op_end] && *op_end != ' ';
3753 op_end++)
3754 {
3755 name[nlen] = TOLOWER (op_start[nlen]);
3756 nlen++;
3757 gas_assert (nlen < sizeof (name) - 1);
3758 }
3759 name[nlen] = 0;
3760
3761 if (nlen == 0)
3762 {
3763 as_bad (_("No instruction or missing opcode."));
3764 return;
3765 }
3766
3767 input_line_pointer = skip_whites (op_end);
3768
3769 size_t i;
3770 for (i = 0; i < sizeof (opcodes) / sizeof (opcodes[0]); ++i)
3771 {
3772 const struct instruction *opc = opcodes + i;
3773 if (0 == strcmp (name, opc->name))
3774 {
3775 if (opc->parse_operands (opc))
3776 return;
3777 continue;
3778 }
3779 }
3780
3781 as_bad (_("Invalid instruction: \"%s\""), str);
3782 as_bad (_("First invalid token: \"%s\""), fail_line_pointer);
3783 while (*input_line_pointer++)
3784 ;
3785}
3786
3787\f
3788
3789
3790\f
3791/* Relocation, relaxation and frag conversions. */
3792
3793/* PC-relative offsets are relative to the start of the
3794 next instruction. That is, the address of the offset, plus its
3795 size, since the offset is always the last part of the insn. */
3796long
3797md_pcrel_from (fixS *fixP)
3798{
3799 long ret = fixP->fx_size + fixP->fx_frag->fr_address;
3800 if (fixP->fx_addsy && S_IS_DEFINED (fixP->fx_addsy))
3801 ret += fixP->fx_where;
3802
3803 return ret;
3804}
3805
3806
3807/* We need a port-specific relaxation function to cope with sym2 - sym1
3808 relative expressions with both symbols in the same segment (but not
3809 necessarily in the same frag as this insn), for example:
3810 ldab sym2-(sym1-2),pc
3811 sym1:
3812 The offset can be 5, 9 or 16 bits long. */
3813
3814long
3815s12z_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP ATTRIBUTE_UNUSED,
3816 long stretch ATTRIBUTE_UNUSED)
3817{
d04ebfb8 3818 return false;
7b4ae824
JD
3819}
3820
3821void
3822md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
3823 fragS *fragP ATTRIBUTE_UNUSED)
3824{
3825}
3826
3827/* On an ELF system, we can't relax a weak symbol. The weak symbol
3828 can be overridden at final link time by a non weak symbol. We can
3829 relax externally visible symbol because there is no shared library
3830 and such symbol can't be overridden (unless they are weak). */
3831
3832/* Force truly undefined symbols to their maximum size, and generally set up
3833 the frag list to be relaxed. */
3834int
3835md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, asection *segment ATTRIBUTE_UNUSED)
3836{
d04ebfb8 3837 return false;
7b4ae824
JD
3838}
3839
3840
3841/* If while processing a fixup, a reloc really needs to be created
3842 then it is done here. */
3843arelent *
3844tc_gen_reloc (asection *section, fixS *fixp)
3845{
3846 arelent *reloc = XNEW (arelent);
3847 reloc->sym_ptr_ptr = XNEW (asymbol *);
3848 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3849 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3850 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3851 if (reloc->howto == (reloc_howto_type *) NULL)
3852 {
3853 as_bad_where (fixp->fx_file, fixp->fx_line,
3854 _("Relocation %d is not supported by object file format."),
3855 (int) fixp->fx_r_type);
3856 return NULL;
3857 }
3858
3859 if (0 == (section->flags & SEC_CODE))
3860 reloc->addend = fixp->fx_offset;
3861 else
3862 reloc->addend = fixp->fx_addnumber;
3863
3864 return reloc;
3865}
3866
3867/* See whether we need to force a relocation into the output file. */
3868int
3869tc_s12z_force_relocation (fixS *fixP)
3870{
3871 return generic_force_reloc (fixP);
3872}
3873
3874/* Here we decide which fixups can be adjusted to make them relative
3875 to the beginning of the section instead of the symbol. Basically
3876 we need to make sure that the linker relaxation is done
3877 correctly, so in some cases we force the original symbol to be
3878 used. */
d04ebfb8 3879bfd_boolean
7b4ae824
JD
3880tc_s12z_fix_adjustable (fixS *fixP ATTRIBUTE_UNUSED)
3881{
d04ebfb8 3882 return true;
7b4ae824
JD
3883}
3884
3885void
3886md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
3887{
3888 long value = *valP;
3889
3890 if (fixP->fx_addsy == (symbolS *) NULL)
3891 fixP->fx_done = 1;
3892
3893 /* We don't actually support subtracting a symbol. */
3894 if (fixP->fx_subsy != (symbolS *) NULL)
3895 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
3896
3897 /*
3898 Patch the instruction with the resolved operand. Elf relocation
3899 info will also be generated to take care of linker/loader fixups.
3900 */
3901 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
3902
3903 switch (fixP->fx_r_type)
3904 {
3905 case BFD_RELOC_8:
3906 ((bfd_byte *) where)[0] = (bfd_byte) value;
3907 break;
405b6196
JD
3908 case BFD_RELOC_16:
3909 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
3910 break;
7b4ae824
JD
3911 case BFD_RELOC_24:
3912 bfd_putb24 ((bfd_vma) value, (unsigned char *) where);
3913 break;
c6f14c0d
JD
3914 case BFD_RELOC_S12Z_OPR:
3915 {
3916 switch (fixP->fx_size)
3917 {
3918 case 3:
3919 bfd_putb24 ((bfd_vma) value, (unsigned char *) where);
3920 break;
3921 case 2:
3922 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
3923 break;
3924 default:
3925 abort ();
3926 }
3927 }
3928 break;
7b4ae824
JD
3929 case BFD_RELOC_32:
3930 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
3931 break;
3932 case BFD_RELOC_16_PCREL:
91bae991 3933 if (value < -0x4000 || value > 0x3FFF)
7b4ae824
JD
3934 as_bad_where (fixP->fx_file, fixP->fx_line,
3935 _("Value out of 16-bit range."));
3936
3937 bfd_putb16 ((bfd_vma) value | 0x8000, (unsigned char *) where);
3938 break;
3939
3940 default:
3941 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3942 fixP->fx_line, fixP->fx_r_type);
3943 }
3944}
3945
3946/* Set the ELF specific flags. */
3947void
3948s12z_elf_final_processing (void)
3949{
3950}
This page took 0.2254 seconds and 4 git commands to generate.