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