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