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