1 /* tc-s12z.c -- Assembler code for the Freescale S12Z
2 Copyright (C) 2018-2019 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
22 #include "safe-ctype.h"
24 #include "dwarf2dbg.h"
25 #include "opcode/s12z.h"
30 const char comment_chars
[] = ";";
32 const char line_comment_chars
[] = "#*";
33 const char line_separator_chars
[] = "";
35 static char * register_prefix
= NULL
;
37 const char EXP_CHARS
[] = "eE";
38 const char FLT_CHARS
[] = "dD";
40 static char *fail_line_pointer
;
43 /* Options and initialization. */
45 const char *md_shortopts
= "";
47 struct option md_longopts
[] =
49 {"mreg-prefix", required_argument
, NULL
, OPTION_MD_BASE
},
50 {NULL
, no_argument
, NULL
, 0}
53 size_t md_longopts_size
= sizeof (md_longopts
);
56 relax_typeS md_relax_table
[] =
61 /* This table describes all the machine specific pseudo-ops the assembler
62 has to support. The fields are:
63 pseudo-op name without dot
64 function to call to execute this pseudo-op
65 Integer arg to pass to the function. */
66 const pseudo_typeS md_pseudo_table
[] =
72 /* Get the target cpu for the assembler. */
74 s12z_arch_format (void)
91 /* Listing header selected according to cpu. */
93 s12z_listing_header (void)
99 md_show_usage (FILE *stream
)
102 _("\ns12z options:\n"
103 " -mreg-prefix=PREFIX set a prefix used to indicate register names (default none)"
108 s12z_print_statistics (FILE *file ATTRIBUTE_UNUSED
)
113 md_parse_option (int c
, const char *arg
)
118 register_prefix
= xstrdup (arg
);
127 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
133 md_atof (int type
, char *litP
, int *sizeP
)
135 return ieee_md_atof (type
, litP
, sizeP
, TRUE
);
139 md_section_align (asection
*seg
, valueT addr
)
141 int align
= bfd_get_section_alignment (stdoutput
, seg
);
142 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
151 s12z_init_after_args (void)
159 skip_whites (char *p
)
161 while (*p
== ' ' || *p
== '\t')
169 /* Start a new insn that contains at least 'size' bytes. Record the
170 line information of that insn in the dwarf2 debug sections. */
172 s12z_new_insn (int size
)
174 char *f
= frag_more (size
);
176 dwarf2_emit_insn (size
);
183 static bfd_boolean
lex_reg_name (uint16_t which
, int *reg
);
186 lex_constant (long *v
)
189 char *p
= input_line_pointer
;
191 /* A constant may not have the same value as a register
194 if (lex_reg_name (~0, &dummy
))
196 input_line_pointer
= p
;
201 *v
= strtol (p
, &end
, 0);
202 if (errno
== 0 && end
!= p
)
204 input_line_pointer
= end
;
214 char *p
= input_line_pointer
;
218 input_line_pointer
++;
224 lex_expression (expressionS
*exp
)
226 char *ilp
= input_line_pointer
;
228 exp
->X_op
= O_absent
;
233 if (lex_reg_name (~0, &dummy
))
237 if (exp
->X_op
!= O_absent
)
241 fail_line_pointer
= input_line_pointer
;
242 input_line_pointer
= ilp
;
246 /* Immediate operand.
247 If EXP_O is non-null, then a symbolic expression is permitted,
248 in which case, EXP_O will be populated with the parsed expression.
251 lex_imm (long *v
, expressionS
*exp_o
)
253 char *ilp
= input_line_pointer
;
255 if (*input_line_pointer
!= '#')
258 input_line_pointer
++;
260 if (!lex_expression (&exp
))
263 if (exp
.X_op
!= O_constant
)
266 as_bad (_("A non-constant expression is not permitted here"));
271 *v
= exp
.X_add_number
;
275 fail_line_pointer
= input_line_pointer
;
276 input_line_pointer
= ilp
;
280 /* Short mmediate operand */
282 lex_imm_e4 (long *val
)
284 char *ilp
= input_line_pointer
;
285 if ((lex_imm (val
, NULL
)))
287 if ((*val
== -1) || (*val
> 0 && *val
<= 15))
292 fail_line_pointer
= input_line_pointer
;
293 input_line_pointer
= ilp
;
298 lex_match_string (const char *s
)
300 char *p
= input_line_pointer
;
301 while (p
!= 0 && *p
!= '\t' && *p
!= ' ' && *p
!= '\0')
306 size_t len
= p
- input_line_pointer
;
307 if (len
!= strlen (s
))
310 if (0 == strncasecmp (s
, input_line_pointer
, len
))
312 input_line_pointer
= p
;
319 /* Parse a register name.
320 WHICH is a ORwise combination of the registers which are accepted.
322 On success, REG will be filled with the index of the register which
323 was successfully scanned.
326 lex_reg_name (uint16_t which
, int *reg
)
328 char *p
= input_line_pointer
;
333 /* Scan (and ignore) the register prefix. */
336 int len
= strlen (register_prefix
);
337 if (0 == strncmp (register_prefix
, p
, len
))
343 char *start_of_reg_name
= p
;
345 while ((*p
>= 'a' && *p
<='z')
346 || (*p
>= '0' && *p
<= '9')
347 || (*p
>= 'A' && *p
<='Z'))
352 size_t len
= p
- start_of_reg_name
;
358 for (i
= 0; i
< S12Z_N_REGISTERS
; ++i
)
360 gas_assert (registers
[i
].name
);
362 if (len
== strlen (registers
[i
].name
)
363 && 0 == strncasecmp (registers
[i
].name
, start_of_reg_name
, len
))
365 if ((0x1U
<< i
) & which
)
367 input_line_pointer
= p
;
378 lex_force_match (char x
)
380 char *p
= input_line_pointer
;
383 as_bad (_("Expecting '%c'"), x
);
387 input_line_pointer
++;
392 lex_opr (uint8_t *buffer
, int *n_bytes
, expressionS
*exp
,
395 char *ilp
= input_line_pointer
;
396 uint8_t *xb
= buffer
;
399 exp
->X_op
= O_absent
;
402 if (lex_imm_e4 (&imm
))
406 as_bad (_("An immediate value in a source operand is inappropriate"));
417 else if (lex_reg_name (REG_BIT_Dn
, ®
))
424 else if (lex_match ('['))
426 if (lex_expression (exp
))
428 long c
= exp
->X_add_number
;
431 if (lex_reg_name (REG_BIT_XYSP
, ®
))
434 if (c
<= 255 && c
>= -256)
444 *xb
|= (reg
- REG_X
) << 4;
448 for (i
= 1; i
< *n_bytes
; ++i
)
450 buffer
[i
] = c
>> (8 * (*n_bytes
- i
- 1));
455 as_bad (_("Bad operand for constant offset"));
468 else if (lex_reg_name (REG_BIT_Dn
, ®
))
470 if (!lex_force_match (','))
474 if (lex_reg_name (REG_BIT_XY
, ®2
))
478 *xb
|= (reg2
- REG_X
) << 4;
483 as_bad (_("Invalid operand for register offset"));
491 if (!lex_force_match (']'))
495 else if (lex_match ('('))
498 if (lex_constant (&c
))
500 if (!lex_force_match (','))
503 if (lex_reg_name (REG_BIT_XYSP
, ®2
))
505 if (reg2
!= REG_P
&& c
>= 0 && c
<= 15)
509 *xb
|= (reg2
- REG_X
) << 4;
512 else if (c
>= -256 && c
<= 255)
516 *xb
|= (reg2
- REG_X
) << 4;
525 *xb
|= (reg2
- REG_X
) << 4;
531 else if (lex_reg_name (REG_BIT_Dn
, ®2
))
533 if (c
>= -1 * (long) (0x1u
<< 17)
535 c
< (long) (0x1u
<< 17) - 1)
540 *xb
|= ((c
>> 16) & 0x03) << 4;
556 as_bad (_("Bad operand for constant offset"));
560 else if (lex_reg_name (REG_BIT_Dn
, ®
))
565 if (lex_reg_name (REG_BIT_XYS
, ®2
))
569 *xb
|= (reg2
- REG_X
) << 4;
574 as_bad (_("Invalid operand for register offset"));
583 else if (lex_reg_name (REG_BIT_XYS
, ®
))
589 as_bad (_("Invalid register for postdecrement operation"));
595 else if (reg
== REG_Y
)
598 else if (lex_match ('+'))
603 else if (reg
== REG_Y
)
605 else if (reg
== REG_S
)
613 else if (lex_match ('+'))
615 if (lex_reg_name (REG_BIT_XY
, ®
))
620 else if (reg
== REG_Y
)
625 as_bad (_("Invalid register for preincrement operation"));
629 else if (lex_match ('-'))
631 if (lex_reg_name (REG_BIT_XYS
, ®
))
636 else if (reg
== REG_Y
)
638 else if (reg
== REG_S
)
643 as_bad (_("Invalid register for predecrement operation"));
652 if (! lex_match (')'))
656 else if (lex_expression (exp
))
663 if (exp
->X_op
== O_constant
)
665 valueT value
= exp
->X_add_number
;
667 if (value
< (0x1U
<< 14))
674 else if (value
< (0x1U
<< 19))
677 if (value
& (0x1U
<< 17))
679 if (value
& (0x1U
<< 16))
682 buffer
[1] = value
>> 8;
689 buffer
[1] = value
>> 16;
690 buffer
[2] = value
>> 8;
698 fail_line_pointer
= input_line_pointer
;
699 input_line_pointer
= ilp
;
704 lex_offset (long *val
)
707 char *p
= input_line_pointer
;
712 if (*p
!= '+' && *p
!= '-')
715 bool negative
= (*p
== '-');
719 *val
= strtol (p
, &end
, 0);
724 input_line_pointer
= end
;
735 typedef int (*parse_operand_func
) (const struct instruction
*);
741 /* The "page" to which the instruction belongs.
742 This is also only a hint. Some instructions might have modes in both
746 /* This is a hint - and only a hint - about the opcode of the instruction.
747 The parse_operand_func is free to ignore it.
751 parse_operand_func parse_operands
;
753 /* Some instructions can be encoded with a different opcode */
758 no_operands (const struct instruction
*insn
)
760 if (*input_line_pointer
!= '\0')
762 as_bad (_("Garbage at end of instruction"));
766 char *f
= s12z_new_insn (insn
->page
);
768 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
770 number_to_chars_bigendian (f
++, insn
->opc
, 1);
777 emit_reloc (expressionS
*exp
, char *f
, int size
, enum bfd_reloc_code_real reloc
)
779 if (exp
->X_op
!= O_absent
&& exp
->X_op
!= O_constant
)
781 fixS
*fix
= fix_new_exp (frag_now
,
782 f
- frag_now
->fr_literal
,
787 /* Some third party tools seem to use the lower bits
788 of this addend for flags. They don't get added
789 to the final location. The purpose of these flags
790 is not known. We simply set it to zero. */
791 fix
->fx_addnumber
= 0x00;
795 /* Emit the code for an OPR address mode operand */
797 emit_opr (char *f
, const uint8_t *buffer
, int n_bytes
, expressionS
*exp
)
800 number_to_chars_bigendian (f
++, buffer
[0], 1);
802 emit_reloc (exp
, f
, 3, BFD_RELOC_S12Z_OPR
);
804 for (i
= 1; i
< n_bytes
; ++i
)
805 number_to_chars_bigendian (f
++, buffer
[i
], 1);
810 /* Emit the code for a 24 bit direct address operand */
812 emit_ext24 (char *f
, long v
)
814 number_to_chars_bigendian (f
, v
, 3);
820 opr (const struct instruction
*insn
)
825 if (lex_opr (buffer
, &n_bytes
, &exp
, false))
827 /* Large constant direct values are more efficiently encoded as ext24 mode.
828 Otherwise a decision has to be deferred to a relax. */
829 if (exp
.X_op
== O_constant
831 && insn
->alt_opc
!= 0)
833 char *f
= s12z_new_insn (4);
835 /* I don't think there are any instances of page 2 opcodes in this case */
836 gas_assert (insn
->page
== 1);
838 number_to_chars_bigendian (f
++, insn
->alt_opc
, 1);
840 emit_ext24 (f
, exp
.X_add_number
);
844 char *f
= s12z_new_insn (n_bytes
+ 1);
845 number_to_chars_bigendian (f
++, insn
->opc
, 1);
847 emit_opr (f
, buffer
, n_bytes
, &exp
);
855 /* Parse a 15 bit offset, as an expression.
856 LONG_DISPLACEMENT will be set to true if the offset is wider than 7 bits.
859 lex_15_bit_offset (bool *long_displacement
, expressionS
*exp
)
861 char *ilp
= input_line_pointer
;
864 if (lex_offset (&val
))
866 exp
->X_op
= O_absent
;
867 exp
->X_add_number
= val
;
869 else if (lex_expression (exp
))
871 if (exp
->X_op
== O_constant
)
873 val
= exp
->X_add_number
;
877 /* If a symbol was parsed we don't know the displacement.
878 We have to assume it is long, and relax it later if possible. */
879 *long_displacement
= true;
885 exp
->X_op
= O_absent
;
889 if (val
> 0x3FFF || val
< -0x4000)
891 as_fatal (_("Offset is outside of 15 bit range"));
895 *long_displacement
= (val
> 63 || val
< -64);
900 fail_line_pointer
= input_line_pointer
;
901 input_line_pointer
= ilp
;
906 emit_15_bit_offset (char *f
, int where
, expressionS
*exp
)
909 if (exp
->X_op
!= O_absent
&& exp
->X_op
!= O_constant
)
911 exp
->X_add_number
+= where
;
912 fixS
*fix
= fix_new_exp (frag_now
,
913 f
- frag_now
->fr_literal
,
918 fix
->fx_addnumber
= where
- 2;
922 long val
= exp
->X_add_number
;
923 bool long_displacement
= (val
> 63 || val
< -64);
924 if (long_displacement
)
929 number_to_chars_bigendian (f
++, val
, long_displacement
? 2 : 1);
934 rel (const struct instruction
*insn
)
936 bool long_displacement
;
939 if (! lex_15_bit_offset (&long_displacement
, &exp
))
942 char *f
= s12z_new_insn (long_displacement
? 3 : 2);
943 number_to_chars_bigendian (f
++, insn
->opc
, 1);
944 emit_15_bit_offset (f
, 3, &exp
);
949 reg_inh (const struct instruction
*insn
)
952 if (lex_reg_name (REG_BIT_Dn
, ®
))
954 char *f
= s12z_new_insn (insn
->page
);
956 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
958 number_to_chars_bigendian (f
++, insn
->opc
+ reg
, 1);
966 /* Special case for CLR X and CLR Y */
968 clr_xy (const struct instruction
*insn ATTRIBUTE_UNUSED
)
971 if (lex_reg_name (REG_BIT_XY
, ®
))
973 char *f
= s12z_new_insn (1);
974 number_to_chars_bigendian (f
, 0x9a + reg
- REG_X
, 1);
981 /* Some instructions have a suffix like ".l", ".b", ".w" etc
982 which indicates the size of the operands. */
984 size_from_suffix (const struct instruction
*insn
, int idx
)
986 const char *dot
= strchr (insn
->name
, '.');
992 switch (dot
[1 + idx
])
1007 as_fatal (_("Bad size"));
1014 mul_reg_reg_reg (const struct instruction
*insn
)
1016 char *ilp
= input_line_pointer
;
1019 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1022 if (!lex_match (','))
1026 if (!lex_reg_name (REG_BIT_Dn
, &Dj
))
1029 if (!lex_match (','))
1033 if (!lex_reg_name (REG_BIT_Dn
, &Dk
))
1036 char *f
= s12z_new_insn (insn
->page
+ 1);
1037 if (insn
->page
== 2)
1038 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1040 number_to_chars_bigendian (f
++, insn
->opc
+ Dd
, 1);
1041 const char *dot
= strchrnul (insn
->name
, '.');
1052 as_fatal (_("BAD MUL"));
1059 number_to_chars_bigendian (f
++, mb
, 1);
1064 fail_line_pointer
= input_line_pointer
;
1065 input_line_pointer
= ilp
;
1071 mul_reg_reg_imm (const struct instruction
*insn
)
1073 char *ilp
= input_line_pointer
;
1076 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1079 if (!lex_match (','))
1083 if (!lex_reg_name (REG_BIT_Dn
, &Dj
))
1086 if (!lex_match (','))
1090 if (!lex_imm (&imm
, NULL
))
1094 int size
= size_from_suffix (insn
, 0);
1096 char *f
= s12z_new_insn (insn
->page
+ 1 + size
);
1097 if (insn
->page
== 2)
1098 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1100 number_to_chars_bigendian (f
++, insn
->opc
+ Dd
, 1);
1102 const char *dot
= strchrnul (insn
->name
, '.');
1112 as_fatal (_("BAD MUL"));
1119 number_to_chars_bigendian (f
++, mb
, 1);
1120 number_to_chars_bigendian (f
++, imm
, size
);
1125 fail_line_pointer
= input_line_pointer
;
1126 input_line_pointer
= ilp
;
1132 mul_reg_reg_opr (const struct instruction
*insn
)
1134 char *ilp
= input_line_pointer
;
1137 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1140 if (!lex_match (','))
1144 if (!lex_reg_name (REG_BIT_Dn
, &Dj
))
1147 if (!lex_match (','))
1153 if (!lex_opr (buffer
, &n_bytes
, &exp
, true))
1156 int size
= size_from_suffix (insn
, 0);
1158 char *f
= s12z_new_insn (insn
->page
+ 1 + n_bytes
);
1159 if (insn
->page
== 2)
1160 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1162 number_to_chars_bigendian (f
++, insn
->opc
+ Dd
, 1);
1164 const char *dot
= strchrnul (insn
->name
, '.');
1174 as_fatal (_("BAD MUL"));
1181 number_to_chars_bigendian (f
++, mb
, 1);
1183 emit_opr (f
, buffer
, n_bytes
, &exp
);
1188 fail_line_pointer
= input_line_pointer
;
1189 input_line_pointer
= ilp
;
1194 mul_reg_opr_opr (const struct instruction
*insn
)
1196 char *ilp
= input_line_pointer
;
1199 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1202 if (!lex_match (','))
1208 if (!lex_opr (buffer1
, &n_bytes1
, &exp1
, false))
1211 if (!lex_match (','))
1217 if (!lex_opr (buffer2
, &n_bytes2
, &exp2
, false))
1220 int size1
= size_from_suffix (insn
, 0);
1221 int size2
= size_from_suffix (insn
, 1);
1223 char *f
= s12z_new_insn (insn
->page
+ 1 + n_bytes1
+ n_bytes2
);
1224 if (insn
->page
== 2)
1225 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1227 number_to_chars_bigendian (f
++, insn
->opc
+ Dd
, 1);
1229 const char *dot
= strchrnul (insn
->name
, '.');
1239 as_fatal (_("BAD MUL"));
1243 mb
|= (size1
- 1) << 4;
1244 mb
|= (size2
- 1) << 2;
1245 number_to_chars_bigendian (f
++, mb
, 1);
1247 f
= emit_opr (f
, buffer1
, n_bytes1
, &exp1
);
1248 f
= emit_opr (f
, buffer2
, n_bytes2
, &exp2
);
1253 fail_line_pointer
= input_line_pointer
;
1254 input_line_pointer
= ilp
;
1259 #define REG_BIT_GRP0 \
1260 ((0x1U << REG_D2) | \
1261 (0x1U << REG_D3) | \
1262 (0x1U << REG_CCH) | \
1263 (0x1U << REG_CCL) | \
1264 (0x1U << REG_D0) | \
1267 #define REG_BIT_GRP1 \
1268 ((0x1U << REG_D4) | \
1269 (0x1U << REG_D5) | \
1270 (0x1U << REG_D6) | \
1271 (0x1U << REG_D7) | \
1275 static const uint8_t reg_map
[] =
1295 lex_reg_list (uint16_t grp
, uint16_t *reg_bits
)
1297 if (lex_match (','))
1300 if (!lex_reg_name (grp
, ®
))
1302 *reg_bits
|= 0x1u
<< reg
;
1303 lex_reg_list (grp
, reg_bits
);
1311 psh_pull (const struct instruction
*insn
)
1314 (0 == strcmp ("pul", insn
->name
)) ? 0x80: 0x00;
1316 if (lex_match_string ("all16b"))
1320 else if (lex_match_string ("all"))
1327 if (!lex_reg_name (REG_BIT_GRP1
| REG_BIT_GRP0
, ®1
))
1329 uint16_t admitted_group
= 0;
1331 if ((0x1U
<< reg1
) & REG_BIT_GRP1
)
1332 admitted_group
= REG_BIT_GRP1
;
1333 else if ((0x1U
<< reg1
) & REG_BIT_GRP0
)
1334 admitted_group
= REG_BIT_GRP0
;
1336 uint16_t reg_bits
= 0x1 << reg1
;
1337 if (!lex_reg_list (admitted_group
, ®_bits
))
1340 if (reg_bits
& REG_BIT_GRP1
)
1344 for (i
= 0; i
< 16; ++i
)
1346 if (reg_bits
& (0x1u
<< i
))
1351 char *f
= s12z_new_insn (2);
1352 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1353 number_to_chars_bigendian (f
++, pb
, 1);
1357 fail_line_pointer
= input_line_pointer
;
1363 tfr (const struct instruction
*insn
)
1366 if (!lex_reg_name (~0, ®1
))
1369 if (!lex_match (','))
1373 if (!lex_reg_name (~0, ®2
))
1376 if ( ((0 == strcasecmp ("sex", insn
->name
))
1377 || (0 == strcasecmp ("zex", insn
->name
)))
1378 && (registers
[reg2
].bytes
<= registers
[reg1
].bytes
))
1379 as_warn (_("Source register for %s is no larger than the destination register"),
1381 else if (reg1
== reg2
)
1382 as_warn (_("The destination and source registers are identical"));
1384 char *f
= s12z_new_insn (1 + insn
->page
);
1385 if (insn
->page
== 2)
1386 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1388 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1389 number_to_chars_bigendian (f
++, reg1
<< 4 | reg2
, 1);
1394 fail_line_pointer
= input_line_pointer
;
1399 imm8 (const struct instruction
*insn
)
1402 if (! lex_imm (&imm
, NULL
))
1404 if (imm
> 127 || imm
< -128)
1406 as_bad (_("Immediate value %ld is out of range for instruction %s"),
1410 char *f
= s12z_new_insn (2);
1411 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1412 number_to_chars_bigendian (f
++, imm
, 1);
1418 reg_imm (const struct instruction
*insn
, int allowed_reg
)
1420 char *ilp
= input_line_pointer
;
1422 if (lex_reg_name (allowed_reg
, ®
))
1424 if (!lex_force_match (','))
1427 if (! lex_imm (&imm
, NULL
))
1430 short size
= registers
[reg
].bytes
;
1431 char *f
= s12z_new_insn (insn
->page
+ size
);
1432 if (insn
->page
== 2)
1433 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1435 number_to_chars_bigendian (f
++, insn
->opc
+ reg
, 1);
1436 number_to_chars_bigendian (f
++, imm
, size
);
1441 fail_line_pointer
= input_line_pointer
;
1442 input_line_pointer
= ilp
;
1448 regd_imm (const struct instruction
*insn
)
1450 return reg_imm (insn
, REG_BIT_Dn
);
1454 regdxy_imm (const struct instruction
*insn
)
1456 return reg_imm (insn
, REG_BIT_Dn
| REG_BIT_XY
);
1461 regs_imm (const struct instruction
*insn
)
1463 return reg_imm (insn
, 0x1U
<< REG_S
);
1467 trap_imm (const struct instruction
*insn ATTRIBUTE_UNUSED
)
1470 if (! lex_imm (&imm
, NULL
))
1473 if (imm
< 0x92 || imm
> 0xFF ||
1474 (imm
>= 0xA0 && imm
<= 0xA7) ||
1475 (imm
>= 0xB0 && imm
<= 0xB7))
1477 as_bad (_("trap value %ld is not valid"), imm
);
1482 char *f
= s12z_new_insn (2);
1483 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1484 number_to_chars_bigendian (f
++, imm
& 0xFF, 1);
1491 fail_line_pointer
= input_line_pointer
;
1497 /* Special one byte instruction CMP X, Y */
1499 regx_regy (const struct instruction
*insn
)
1502 if (lex_reg_name (0x1U
<< REG_X
, ®
))
1504 if (lex_force_match (','))
1506 if (lex_reg_name (0x1U
<< REG_Y
, ®
))
1508 char *f
= s12z_new_insn (1);
1509 number_to_chars_bigendian (f
, insn
->opc
, 1);
1517 /* Special one byte instruction SUB D6, X, Y */
1519 regd6_regx_regy (const struct instruction
*insn
)
1521 char *ilp
= input_line_pointer
;
1523 if (!lex_reg_name (0x1U
<< REG_D6
, ®
))
1526 if (!lex_match (','))
1529 if (!lex_reg_name (0x1U
<< REG_X
, ®
))
1532 if (!lex_match (','))
1535 if (!lex_reg_name (0x1U
<< REG_Y
, ®
))
1538 char *f
= s12z_new_insn (1);
1539 number_to_chars_bigendian (f
, insn
->opc
, 1);
1543 fail_line_pointer
= input_line_pointer
;
1544 input_line_pointer
= ilp
;
1548 /* Special one byte instruction SUB D6, Y, X */
1550 regd6_regy_regx (const struct instruction
*insn
)
1552 char *ilp
= input_line_pointer
;
1554 if (!lex_reg_name (0x1U
<< REG_D6
, ®
))
1557 if (!lex_match (','))
1560 if (!lex_reg_name (0x1U
<< REG_Y
, ®
))
1563 if (!lex_match (','))
1566 if (!lex_reg_name (0x1U
<< REG_X
, ®
))
1569 char *f
= s12z_new_insn (1);
1570 number_to_chars_bigendian (f
, insn
->opc
, 1);
1574 fail_line_pointer
= input_line_pointer
;
1575 input_line_pointer
= ilp
;
1580 reg_opr (const struct instruction
*insn
, int allowed_regs
,
1583 char *ilp
= input_line_pointer
;
1585 if (lex_reg_name (allowed_regs
, ®
))
1587 if (!lex_force_match (','))
1593 if (lex_opr (buffer
, &n_bytes
, &exp
, immediate_ok
))
1595 /* Large constant direct values are more efficiently encoded as ext24 mode.
1596 Otherwise a decision has to be deferred to a relax. */
1597 if (exp
.X_op
== O_constant
1598 && buffer
[0] == 0xFA
1599 && insn
->alt_opc
!= 0)
1601 char *f
= s12z_new_insn (4);
1603 /* I don't think there are any instances of page 2 opcodes in this case */
1604 gas_assert (insn
->page
== 1);
1606 number_to_chars_bigendian (f
++, insn
->alt_opc
+ reg
, 1);
1608 emit_ext24 (f
, exp
.X_add_number
);
1612 char *f
= s12z_new_insn (n_bytes
+ insn
->page
);
1614 if (insn
->page
== 2)
1615 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1617 number_to_chars_bigendian (f
++, insn
->opc
+ reg
, 1);
1619 emit_opr (f
, buffer
, n_bytes
, &exp
);
1627 fail_line_pointer
= input_line_pointer
;
1628 input_line_pointer
= ilp
;
1634 regdxy_opr_dest (const struct instruction
*insn
)
1636 return reg_opr (insn
, REG_BIT_Dn
| REG_BIT_XY
, false);
1640 regdxy_opr_src (const struct instruction
*insn
)
1642 return reg_opr (insn
, REG_BIT_Dn
| REG_BIT_XY
, true);
1647 regd_opr (const struct instruction
*insn
)
1649 return reg_opr (insn
, REG_BIT_Dn
, true);
1653 /* OP0: S; OP1: destination OPR */
1655 regs_opr_dest (const struct instruction
*insn
)
1657 return reg_opr (insn
, 0x1U
<< REG_S
, false);
1660 /* OP0: S; OP1: source OPR */
1662 regs_opr_src (const struct instruction
*insn
)
1664 return reg_opr (insn
, 0x1U
<< REG_S
, true);
1668 imm_opr (const struct instruction
*insn
)
1670 char *ilp
= input_line_pointer
;
1673 int size
= size_from_suffix (insn
, 0);
1674 exp0
.X_op
= O_absent
;
1676 /* Note: The ternary expression below means that "MOV.x #symbol,
1677 mem-expr" is accepted when x is a member of {'w', 'p', 'l'} but
1679 The Freescale assembler accepts "MOV.b #symbol, mem-expr" but
1680 produces obviously incorrect code. Since such an instruction
1681 would require an 8-bit reloc (which we don't have) and some
1682 non-optimal kludges in the OPR encoding, it seems sensible that
1683 such instructions should be rejected. */
1684 if (!lex_imm (&imm
, size
> 1 ? &exp0
: NULL
))
1687 if (!lex_match (','))
1693 if (!lex_opr (buffer
, &n_bytes
, &exp1
, false))
1696 char *f
= s12z_new_insn (1 + n_bytes
+ size
);
1697 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1699 emit_reloc (&exp0
, f
, size
, size
== 4 ? BFD_RELOC_32
: BFD_RELOC_S12Z_OPR
);
1702 for (i
= 0; i
< size
; ++i
)
1703 number_to_chars_bigendian (f
++, imm
>> (CHAR_BIT
* (size
- i
- 1)), 1);
1705 emit_opr (f
, buffer
, n_bytes
, &exp1
);
1710 fail_line_pointer
= input_line_pointer
;
1711 input_line_pointer
= ilp
;
1716 opr_opr (const struct instruction
*insn
)
1718 char *ilp
= input_line_pointer
;
1723 if (!lex_opr (buffer1
, &n_bytes1
, &exp1
, false))
1727 if (!lex_match (','))
1733 if (!lex_opr (buffer2
, &n_bytes2
, &exp2
, false))
1736 char *f
= s12z_new_insn (1 + n_bytes1
+ n_bytes2
);
1737 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1739 f
= emit_opr (f
, buffer1
, n_bytes1
, &exp1
);
1740 f
= emit_opr (f
, buffer2
, n_bytes2
, &exp2
);
1745 fail_line_pointer
= input_line_pointer
;
1746 input_line_pointer
= ilp
;
1751 reg67sxy_opr (const struct instruction
*insn
)
1754 if (!lex_reg_name (REG_BIT_XYS
| (0x1U
<< REG_D6
) | (0x1U
<< REG_D7
), ®
))
1757 if (!lex_match (','))
1763 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
1766 char *f
= s12z_new_insn (1 + n_bytes
);
1767 number_to_chars_bigendian (f
++, insn
->opc
+ reg
- REG_D6
, 1);
1768 emit_opr (f
, buffer
, n_bytes
, &exp
);
1774 rotate (const struct instruction
*insn
, short dir
)
1779 if (lex_opr (buffer
, &n_bytes
, &exp
, false))
1781 char *f
= s12z_new_insn (n_bytes
+ 2);
1782 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1783 int size
= size_from_suffix (insn
, 0);
1790 number_to_chars_bigendian (f
++, sb
, 1);
1791 emit_opr (f
, buffer
, n_bytes
, &exp
);
1800 rol (const struct instruction
*insn
)
1802 return rotate (insn
, 1);
1806 ror (const struct instruction
*insn
)
1808 return rotate (insn
, 0);
1812 /* Shift instruction with a register operand and an immediate #1 or #2
1813 left = 1; right = 0;
1814 logical = 0; arithmetic = 1;
1817 lex_shift_reg_imm1 (const struct instruction
*insn
, short type
, short dir
)
1820 This function is highly unusual and a bit wierd!
1821 It first matches the input against a register {d0, d1, ... d7} followed by an immediate
1823 Then, it rewinds the input and parses it again as a OPR.
1825 char *ilp
= input_line_pointer
;
1828 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1833 if (!lex_match (','))
1837 if (!lex_imm (&imm
, NULL
))
1840 if (imm
!= 1 && imm
!= 2)
1842 input_line_pointer
= ilp
;
1844 /* Now parse the first operand again */
1850 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
1853 gas_assert (n_bytes
== 1);
1861 char *f
= s12z_new_insn (3);
1862 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1863 number_to_chars_bigendian (f
++, sb
, 1);
1864 emit_opr (f
, buffer
, n_bytes
, &exp
);
1869 fail_line_pointer
= input_line_pointer
;
1870 input_line_pointer
= ilp
;
1874 /* Shift instruction with a register operand.
1875 left = 1; right = 0;
1876 logical = 0; arithmetic = 1; */
1878 lex_shift_reg (const struct instruction
*insn
, short type
, short dir
)
1881 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1886 if (!lex_match (','))
1889 if (!lex_reg_name (REG_BIT_Dn
, &Ds
))
1894 if (!lex_match (','))
1902 if (lex_reg_name (REG_BIT_Dn
, &Dn
))
1904 char *f
= s12z_new_insn (3);
1905 number_to_chars_bigendian (f
++, insn
->opc
| Dd
, 1);
1906 number_to_chars_bigendian (f
++, sb
, 1);
1909 number_to_chars_bigendian (f
++, xb
, 1);
1913 else if (lex_imm (&imm
, NULL
))
1915 if (imm
< 0 || imm
> 31)
1917 as_bad (_("Shift value should be in the range [0,31]"));
1922 if (imm
== 1 || imm
== 2)
1929 sb
|= (imm
& 0x01) << 3;
1932 char *f
= s12z_new_insn (n_bytes
);
1933 number_to_chars_bigendian (f
++, insn
->opc
| Dd
, 1);
1934 number_to_chars_bigendian (f
++, sb
, 1);
1939 number_to_chars_bigendian (f
++, xb
, 1);
1946 fail_line_pointer
= input_line_pointer
;
1951 impute_shift_dir_and_type (const struct instruction
*insn
, short *type
, short *dir
)
1955 switch (insn
->name
[0])
1964 as_fatal (_("Bad shift mode"));
1968 switch (insn
->name
[2])
1977 as_fatal (_("Bad shift *direction"));
1982 /* Shift instruction with a OPR operand */
1984 shift_two_operand (const struct instruction
*insn
)
1987 char *ilp
= input_line_pointer
;
1991 impute_shift_dir_and_type (insn
, &type
, &dir
);
1995 int size
= size_from_suffix (insn
, 0);
2001 if (!lex_opr (buffer
, &n_opr_bytes
, &exp
, false))
2004 if (!lex_match (','))
2008 if (!lex_imm (&imm
, NULL
))
2011 if (imm
!= 1 && imm
!= 2)
2017 char *f
= s12z_new_insn (2 + n_opr_bytes
);
2018 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2019 number_to_chars_bigendian (f
++, sb
, 1);
2020 emit_opr (f
, buffer
, n_opr_bytes
, &exp
);
2025 fail_line_pointer
= input_line_pointer
;
2026 input_line_pointer
= ilp
;
2030 /* Shift instruction with a OPR operand */
2032 shift_opr_imm (const struct instruction
*insn
)
2034 char *ilp
= input_line_pointer
;
2038 impute_shift_dir_and_type (insn
, &type
, &dir
);
2041 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
2044 if (!lex_match (','))
2053 if (!lex_opr (buffer1
, &n_opr_bytes1
, &exp1
, false))
2056 n_bytes
+= n_opr_bytes1
;
2057 if (!lex_match (','))
2061 int n_opr_bytes2
= 0;
2064 bool immediate
= false;
2065 if (lex_imm (&imm
, NULL
))
2069 else if (!lex_opr (buffer2
, &n_opr_bytes2
, &exp2
, false))
2074 int size
= size_from_suffix (insn
, 0);
2084 if (imm
== 2 || imm
== 1)
2099 n_bytes
+= n_opr_bytes2
;
2103 char *f
= s12z_new_insn (n_bytes
);
2104 number_to_chars_bigendian (f
++, insn
->opc
| Dd
, 1);
2105 number_to_chars_bigendian (f
++, sb
, 1);
2106 f
= emit_opr (f
, buffer1
, n_opr_bytes1
, &exp1
);
2109 if (imm
!= 1 && imm
!= 2)
2111 number_to_chars_bigendian (f
++, 0x70 | (imm
>> 1), 1);
2116 f
= emit_opr (f
, buffer2
, n_opr_bytes2
, &exp2
);
2122 fail_line_pointer
= input_line_pointer
;
2123 input_line_pointer
= ilp
;
2127 /* Shift instruction with a register operand */
2129 shift_reg (const struct instruction
*insn
)
2133 impute_shift_dir_and_type (insn
, &type
, &dir
);
2135 if (lex_shift_reg_imm1 (insn
, type
, dir
))
2138 return lex_shift_reg (insn
, type
, dir
);
2142 bm_regd_imm (const struct instruction
*insn
)
2144 char *ilp
= input_line_pointer
;
2146 if (!lex_reg_name (REG_BIT_Dn
, &Di
))
2149 if (!lex_match (','))
2153 if (!lex_imm (&imm
, NULL
))
2157 uint8_t bm
= imm
<< 3;
2160 char *f
= s12z_new_insn (2);
2161 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2162 number_to_chars_bigendian (f
++, bm
, 1);
2167 fail_line_pointer
= input_line_pointer
;
2168 input_line_pointer
= ilp
;
2173 bm_opr_reg (const struct instruction
*insn
)
2175 char *ilp
= input_line_pointer
;
2181 if (!lex_opr (buffer
, &n_opr_bytes
, &exp
, false))
2184 if (!lex_match (','))
2188 if (!lex_reg_name (REG_BIT_Dn
, &Dn
))
2191 uint8_t bm
= Dn
<< 4;
2192 int size
= size_from_suffix (insn
, 0);
2193 bm
|= (size
- 1) << 2;
2196 char *f
= s12z_new_insn (2 + n_opr_bytes
);
2197 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2198 number_to_chars_bigendian (f
++, bm
, 1);
2200 emit_opr (f
, buffer
, n_opr_bytes
, &exp
);
2205 fail_line_pointer
= input_line_pointer
;
2206 input_line_pointer
= ilp
;
2212 bm_opr_imm (const struct instruction
*insn
)
2214 char *ilp
= input_line_pointer
;
2220 if (!lex_opr (buffer
, &n_opr_bytes
, &exp
, false))
2223 if (!lex_match (','))
2228 if (!lex_imm (&imm
, NULL
))
2231 int size
= size_from_suffix (insn
, 0);
2233 if (imm
< 0 || imm
>= size
* 8)
2235 as_bad (_("Immediate operand %ld is inappropriate for size of instruction"), imm
);
2244 bm
|= (imm
& 0x07) << 4;
2248 char *f
= s12z_new_insn (2 + n_opr_bytes
);
2249 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2250 number_to_chars_bigendian (f
++, bm
, 1);
2251 emit_opr (f
, buffer
, n_opr_bytes
, &exp
);
2256 fail_line_pointer
= input_line_pointer
;
2257 input_line_pointer
= ilp
;
2263 bm_regd_reg (const struct instruction
*insn
)
2265 char *ilp
= input_line_pointer
;
2267 if (!lex_reg_name (REG_BIT_Dn
, &Di
))
2270 if (!lex_match (','))
2274 if (!lex_reg_name (REG_BIT_Dn
, &Dn
))
2277 uint8_t bm
= Dn
<< 4;
2280 uint8_t xb
= Di
| 0xb8;
2282 char *f
= s12z_new_insn (3);
2283 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2284 number_to_chars_bigendian (f
++, bm
, 1);
2285 number_to_chars_bigendian (f
++, xb
, 1);
2290 fail_line_pointer
= input_line_pointer
;
2291 input_line_pointer
= ilp
;
2300 bf_reg_opr_imm (const struct instruction
*insn
, short ie
)
2302 char *ilp
= input_line_pointer
;
2304 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
2307 if (!lex_match (','))
2314 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2317 if (!lex_match (','))
2321 if (!lex_imm (&width
, NULL
))
2324 if (width
< 0 || width
> 31)
2326 as_bad (_("Invalid width value for %s"), insn
->name
);
2330 if (!lex_match (':'))
2334 if (!lex_constant (&offset
))
2337 if (offset
< 0 || offset
> 31)
2339 as_bad (_("Invalid offset value for %s"), insn
->name
);
2343 uint8_t i1
= width
<< 5;
2346 int size
= size_from_suffix (insn
, 0);
2347 uint8_t bb
= ie
? 0x80 : 0x00;
2349 bb
|= (size
- 1) << 2;
2352 char *f
= s12z_new_insn (4 + n_bytes
);
2353 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2354 number_to_chars_bigendian (f
++, 0x08 | Dd
, 1);
2355 number_to_chars_bigendian (f
++, bb
, 1);
2356 number_to_chars_bigendian (f
++, i1
, 1);
2358 emit_opr (f
, buffer
, n_bytes
, &exp
);
2363 fail_line_pointer
= input_line_pointer
;
2364 input_line_pointer
= ilp
;
2370 bf_opr_reg_imm (const struct instruction
*insn
, short ie
)
2372 char *ilp
= input_line_pointer
;
2376 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2379 if (!lex_match (','))
2383 if (!lex_reg_name (REG_BIT_Dn
, &Ds
))
2386 if (!lex_match (','))
2390 if (!lex_imm (&width
, NULL
))
2393 if (width
< 0 || width
> 31)
2395 as_bad (_("Invalid width value for %s"), insn
->name
);
2399 if (!lex_match (':'))
2403 if (!lex_constant (&offset
))
2406 if (offset
< 0 || offset
> 31)
2408 as_bad (_("Invalid offset value for %s"), insn
->name
);
2412 uint8_t i1
= width
<< 5;
2415 int size
= size_from_suffix (insn
, 0);
2416 uint8_t bb
= ie
? 0x80 : 0x00;
2418 bb
|= (size
- 1) << 2;
2421 char *f
= s12z_new_insn (4 + n_bytes
);
2422 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2423 number_to_chars_bigendian (f
++, 0x08 | Ds
, 1);
2424 number_to_chars_bigendian (f
++, bb
, 1);
2425 number_to_chars_bigendian (f
++, i1
, 1);
2427 emit_opr (f
, buffer
, n_bytes
, &exp
);
2432 fail_line_pointer
= input_line_pointer
;
2433 input_line_pointer
= ilp
;
2440 bf_reg_reg_imm (const struct instruction
*insn
, short ie
)
2442 char *ilp
= input_line_pointer
;
2444 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
2447 if (!lex_match (','))
2451 if (!lex_reg_name (REG_BIT_Dn
, &Ds
))
2454 if (!lex_match (','))
2458 if (!lex_imm (&width
, NULL
))
2461 if (width
< 0 || width
> 31)
2463 as_bad (_("Invalid width value for %s"), insn
->name
);
2467 if (!lex_match (':'))
2471 if (!lex_constant (&offset
))
2474 if (offset
< 0 || offset
> 31)
2476 as_bad (_("Invalid offset value for %s"), insn
->name
);
2480 uint8_t bb
= ie
? 0x80 : 0x00;
2485 uint8_t i1
= width
<< 5;
2488 char *f
= s12z_new_insn (4);
2489 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2490 number_to_chars_bigendian (f
++, 0x08 | Dd
, 1);
2491 number_to_chars_bigendian (f
++, bb
, 1);
2492 number_to_chars_bigendian (f
++, i1
, 1);
2497 fail_line_pointer
= input_line_pointer
;
2498 input_line_pointer
= ilp
;
2503 bf_reg_reg_reg (const struct instruction
*insn ATTRIBUTE_UNUSED
, short ie
)
2505 char *ilp
= input_line_pointer
;
2507 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
2510 if (!lex_match (','))
2514 if (!lex_reg_name (REG_BIT_Dn
, &Ds
))
2517 if (!lex_match (','))
2521 if (!lex_reg_name ((0x01u
<< REG_D2
) |
2528 uint8_t bb
= ie
? 0x80 : 0x00;
2532 char *f
= s12z_new_insn (3);
2533 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2534 number_to_chars_bigendian (f
++, 0x08 | Dd
, 1);
2535 number_to_chars_bigendian (f
++, bb
, 1);
2540 fail_line_pointer
= input_line_pointer
;
2541 input_line_pointer
= ilp
;
2546 bf_opr_reg_reg (const struct instruction
*insn
, short ie
)
2548 char *ilp
= input_line_pointer
;
2553 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2556 if (!lex_match (','))
2561 if (!lex_reg_name (REG_BIT_Dn
, &Ds
))
2564 if (!lex_match (','))
2569 if (!lex_reg_name ((0x01u
<< REG_D2
) |
2576 int size
= size_from_suffix (insn
, 0);
2577 uint8_t bb
= ie
? 0x80 : 0x00;
2580 bb
|= (size
- 1) << 2;
2582 char *f
= s12z_new_insn (3 + n_bytes
);
2583 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2584 number_to_chars_bigendian (f
++, 0x08 | Ds
, 1);
2585 number_to_chars_bigendian (f
++, bb
, 1);
2587 emit_opr (f
, buffer
, n_bytes
, &exp
);
2592 fail_line_pointer
= input_line_pointer
;
2593 input_line_pointer
= ilp
;
2599 bf_reg_opr_reg (const struct instruction
*insn
, short ie
)
2601 char *ilp
= input_line_pointer
;
2603 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
2606 if (!lex_match (','))
2613 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2616 if (!lex_match (','))
2620 if (!lex_reg_name ((0x01u
<< REG_D2
) |
2627 int size
= size_from_suffix (insn
, 0);
2628 uint8_t bb
= ie
? 0x80 : 0x00;
2631 bb
|= (size
- 1) << 2;
2633 char *f
= s12z_new_insn (3 + n_bytes
);
2634 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2635 number_to_chars_bigendian (f
++, 0x08 | Dd
, 1);
2636 number_to_chars_bigendian (f
++, bb
, 1);
2638 emit_opr (f
, buffer
, n_bytes
, &exp
);
2643 fail_line_pointer
= input_line_pointer
;
2644 input_line_pointer
= ilp
;
2651 bfe_reg_reg_reg (const struct instruction
*insn
)
2653 return bf_reg_reg_reg (insn
, 0);
2657 bfi_reg_reg_reg (const struct instruction
*insn
)
2659 return bf_reg_reg_reg (insn
, 1);
2663 bfe_reg_reg_imm (const struct instruction
*insn
)
2665 return bf_reg_reg_imm (insn
, 0);
2669 bfi_reg_reg_imm (const struct instruction
*insn
)
2671 return bf_reg_reg_imm (insn
, 1);
2676 bfe_reg_opr_reg (const struct instruction
*insn
)
2678 return bf_reg_opr_reg (insn
, 0);
2682 bfi_reg_opr_reg (const struct instruction
*insn
)
2684 return bf_reg_opr_reg (insn
, 1);
2689 bfe_opr_reg_reg (const struct instruction
*insn
)
2691 return bf_opr_reg_reg (insn
, 0);
2695 bfi_opr_reg_reg (const struct instruction
*insn
)
2697 return bf_opr_reg_reg (insn
, 1);
2701 bfe_reg_opr_imm (const struct instruction
*insn
)
2703 return bf_reg_opr_imm (insn
, 0);
2707 bfi_reg_opr_imm (const struct instruction
*insn
)
2709 return bf_reg_opr_imm (insn
, 1);
2713 bfe_opr_reg_imm (const struct instruction
*insn
)
2715 return bf_opr_reg_imm (insn
, 0);
2719 bfi_opr_reg_imm (const struct instruction
*insn
)
2721 return bf_opr_reg_imm (insn
, 1);
2728 tb_reg_rel (const struct instruction
*insn
)
2730 char *ilp
= input_line_pointer
;
2733 if (!lex_reg_name (REG_BIT_Dn
| REG_BIT_XY
, ®
))
2736 if (!lex_match (','))
2739 bool long_displacement
;
2741 if (! lex_15_bit_offset (&long_displacement
, &exp
))
2745 if (reg
== REG_X
|| reg
== REG_Y
)
2756 if (0 == strncmp (insn
->name
+ 2, "ne", 2))
2758 else if (0 == strncmp (insn
->name
+ 2, "eq", 2))
2760 else if (0 == strncmp (insn
->name
+ 2, "pl", 2))
2762 else if (0 == strncmp (insn
->name
+ 2, "mi", 2))
2764 else if (0 == strncmp (insn
->name
+ 2, "gt", 2))
2766 else if (0 == strncmp (insn
->name
+ 2, "le", 2))
2769 switch (insn
->name
[0])
2781 char *f
= s12z_new_insn (long_displacement
? 4 : 3);
2782 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2783 number_to_chars_bigendian (f
++, lb
, 1);
2785 emit_15_bit_offset (f
, 4, &exp
);
2790 fail_line_pointer
= input_line_pointer
;
2791 input_line_pointer
= ilp
;
2797 tb_opr_rel (const struct instruction
*insn
)
2799 char *ilp
= input_line_pointer
;
2804 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2807 if (!lex_match (','))
2810 bool long_displacement
;
2812 if (! lex_15_bit_offset (&long_displacement
, &exp2
))
2817 if (0 == strncmp (insn
->name
+ 2, "ne", 2))
2819 else if (0 == strncmp (insn
->name
+ 2, "eq", 2))
2821 else if (0 == strncmp (insn
->name
+ 2, "pl", 2))
2823 else if (0 == strncmp (insn
->name
+ 2, "mi", 2))
2825 else if (0 == strncmp (insn
->name
+ 2, "gt", 2))
2827 else if (0 == strncmp (insn
->name
+ 2, "le", 2))
2830 switch (insn
->name
[0])
2842 int size
= size_from_suffix (insn
, 0);
2846 char *f
= s12z_new_insn (n_bytes
+ (long_displacement
? 4 : 3));
2847 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2848 number_to_chars_bigendian (f
++, lb
, 1);
2849 f
= emit_opr (f
, buffer
, n_bytes
, &exp
);
2851 emit_15_bit_offset (f
, n_bytes
+ 4, &exp2
);
2856 fail_line_pointer
= input_line_pointer
;
2857 input_line_pointer
= ilp
;
2865 test_br_reg_reg_rel (const struct instruction
*insn
)
2867 char *ilp
= input_line_pointer
;
2870 if (!lex_reg_name (REG_BIT_Dn
, &Di
))
2873 if (!lex_match (','))
2878 if (!lex_reg_name (REG_BIT_Dn
, &Dn
))
2881 if (!lex_match (','))
2885 bool long_displacement
;
2887 if (! lex_15_bit_offset (&long_displacement
, &exp
))
2896 char *f
= s12z_new_insn (long_displacement
? 5 : 4);
2897 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2898 number_to_chars_bigendian (f
++, bm
, 1);
2899 number_to_chars_bigendian (f
++, xb
, 1);
2901 emit_15_bit_offset (f
, 5, &exp
);
2906 fail_line_pointer
= input_line_pointer
;
2907 input_line_pointer
= ilp
;
2912 test_br_opr_reg_rel (const struct instruction
*insn
)
2914 char *ilp
= input_line_pointer
;
2919 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2922 if (!lex_match (','))
2926 if (!lex_reg_name (REG_BIT_Dn
, &Dn
))
2929 if (!lex_match (','))
2934 int size
= size_from_suffix (insn
, 0);
2935 bm
|= (size
-1) << 2;
2937 bool long_displacement
;
2940 if (! lex_15_bit_offset (&long_displacement
, &exp2
))
2943 int n
= n_bytes
+ (long_displacement
? 4 : 3);
2944 char *f
= s12z_new_insn (n
);
2945 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2946 number_to_chars_bigendian (f
++, bm
, 1);
2947 f
= emit_opr (f
, buffer
, n_bytes
, &exp
);
2949 emit_15_bit_offset (f
, n
, &exp2
);
2954 fail_line_pointer
= input_line_pointer
;
2955 input_line_pointer
= ilp
;
2961 test_br_opr_imm_rel (const struct instruction
*insn
)
2963 char *ilp
= input_line_pointer
;
2968 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2971 if (!lex_match (','))
2975 if (!lex_imm (&imm
, NULL
))
2978 if (imm
< 0 || imm
> 31)
2981 if (!lex_match (','))
2984 bool long_displacement
;
2986 if (! lex_15_bit_offset (&long_displacement
, &exp2
))
2989 int size
= size_from_suffix (insn
, 0);
2992 bm
|= (imm
& 0x07) << 4;
2993 bm
|= (imm
>> 3) & 0x03;
2999 char *f
= s12z_new_insn (n_bytes
+ (long_displacement
? 4 : 3));
3000 number_to_chars_bigendian (f
++, insn
->opc
, 1);
3001 number_to_chars_bigendian (f
++, bm
, 1);
3002 f
= emit_opr (f
, buffer
, n_bytes
, &exp
);
3004 emit_15_bit_offset (f
, n_bytes
+ 4, &exp2
);
3009 fail_line_pointer
= input_line_pointer
;
3010 input_line_pointer
= ilp
;
3016 test_br_reg_imm_rel (const struct instruction
*insn
)
3018 char *ilp
= input_line_pointer
;
3021 if (!lex_reg_name (REG_BIT_Dn
, &Di
))
3024 if (!lex_match (','))
3028 if (!lex_imm (&imm
, NULL
))
3031 if (imm
< 0 || imm
> 31)
3035 if (!lex_match (','))
3038 bool long_displacement
;
3040 if (! lex_15_bit_offset (&long_displacement
, &exp
))
3046 char *f
= s12z_new_insn (long_displacement
? 4 : 3);
3047 number_to_chars_bigendian (f
++, insn
->opc
, 1);
3048 number_to_chars_bigendian (f
++, bm
, 1);
3050 emit_15_bit_offset (f
, 4, &exp
);
3055 fail_line_pointer
= input_line_pointer
;
3056 input_line_pointer
= ilp
;
3063 static const struct instruction opcodes
[] = {
3064 {"bgnd", 1, 0x00, no_operands
, 0},
3065 {"nop", 1, 0x01, no_operands
, 0},
3067 {"brclr", 1, 0x02, test_br_reg_reg_rel
, 0},
3068 {"brset", 1, 0x03, test_br_reg_reg_rel
, 0},
3070 {"brclr", 1, 0x02, test_br_reg_imm_rel
, 0},
3071 {"brset", 1, 0x03, test_br_reg_imm_rel
, 0},
3073 {"brclr.b", 1, 0x02, test_br_opr_reg_rel
, 0},
3074 {"brclr.w", 1, 0x02, test_br_opr_reg_rel
, 0},
3075 {"brclr.l", 1, 0x02, test_br_opr_reg_rel
, 0},
3077 {"brset.b", 1, 0x03, test_br_opr_reg_rel
, 0},
3078 {"brset.w", 1, 0x03, test_br_opr_reg_rel
, 0},
3079 {"brset.l", 1, 0x03, test_br_opr_reg_rel
, 0},
3081 {"brclr.b", 1, 0x02, test_br_opr_imm_rel
, 0},
3082 {"brclr.w", 1, 0x02, test_br_opr_imm_rel
, 0},
3083 {"brclr.l", 1, 0x02, test_br_opr_imm_rel
, 0},
3085 {"brset.b", 1, 0x03, test_br_opr_imm_rel
, 0},
3086 {"brset.w", 1, 0x03, test_br_opr_imm_rel
, 0},
3087 {"brset.l", 1, 0x03, test_br_opr_imm_rel
, 0},
3089 {"psh", 1, 0x04, psh_pull
, 0},
3090 {"pul", 1, 0x04, psh_pull
, 0},
3092 {"rts", 1, 0x05, no_operands
, 0},
3093 {"lea", 1, 0x06, reg67sxy_opr
, 0},
3095 {"dbne", 1, 0x0b, tb_reg_rel
, 0},
3096 {"dbeq", 1, 0x0b, tb_reg_rel
, 0},
3097 {"dbpl", 1, 0x0b, tb_reg_rel
, 0},
3098 {"dbmi", 1, 0x0b, tb_reg_rel
, 0},
3099 {"dbgt", 1, 0x0b, tb_reg_rel
, 0},
3100 {"dble", 1, 0x0b, tb_reg_rel
, 0},
3102 {"dbne.b", 1, 0x0b, tb_opr_rel
, 0},
3103 {"dbeq.b", 1, 0x0b, tb_opr_rel
, 0},
3104 {"dbpl.b", 1, 0x0b, tb_opr_rel
, 0},
3105 {"dbmi.b", 1, 0x0b, tb_opr_rel
, 0},
3106 {"dbgt.b", 1, 0x0b, tb_opr_rel
, 0},
3107 {"dble.b", 1, 0x0b, tb_opr_rel
, 0},
3109 {"dbne.w", 1, 0x0b, tb_opr_rel
, 0},
3110 {"dbeq.w", 1, 0x0b, tb_opr_rel
, 0},
3111 {"dbpl.w", 1, 0x0b, tb_opr_rel
, 0},
3112 {"dbmi.w", 1, 0x0b, tb_opr_rel
, 0},
3113 {"dbgt.w", 1, 0x0b, tb_opr_rel
, 0},
3114 {"dble.w", 1, 0x0b, tb_opr_rel
, 0},
3116 {"dbne.p", 1, 0x0b, tb_opr_rel
, 0},
3117 {"dbeq.p", 1, 0x0b, tb_opr_rel
, 0},
3118 {"dbpl.p", 1, 0x0b, tb_opr_rel
, 0},
3119 {"dbmi.p", 1, 0x0b, tb_opr_rel
, 0},
3120 {"dbgt.p", 1, 0x0b, tb_opr_rel
, 0},
3121 {"dble.p", 1, 0x0b, tb_opr_rel
, 0},
3123 {"dbne.l", 1, 0x0b, tb_opr_rel
, 0},
3124 {"dbeq.l", 1, 0x0b, tb_opr_rel
, 0},
3125 {"dbpl.l", 1, 0x0b, tb_opr_rel
, 0},
3126 {"dbmi.l", 1, 0x0b, tb_opr_rel
, 0},
3127 {"dbgt.l", 1, 0x0b, tb_opr_rel
, 0},
3128 {"dble.l", 1, 0x0b, tb_opr_rel
, 0},
3130 {"tbne", 1, 0x0b, tb_reg_rel
, 0},
3131 {"tbeq", 1, 0x0b, tb_reg_rel
, 0},
3132 {"tbpl", 1, 0x0b, tb_reg_rel
, 0},
3133 {"tbmi", 1, 0x0b, tb_reg_rel
, 0},
3134 {"tbgt", 1, 0x0b, tb_reg_rel
, 0},
3135 {"tble", 1, 0x0b, tb_reg_rel
, 0},
3137 {"tbne.b", 1, 0x0b, tb_opr_rel
, 0},
3138 {"tbeq.b", 1, 0x0b, tb_opr_rel
, 0},
3139 {"tbpl.b", 1, 0x0b, tb_opr_rel
, 0},
3140 {"tbmi.b", 1, 0x0b, tb_opr_rel
, 0},
3141 {"tbgt.b", 1, 0x0b, tb_opr_rel
, 0},
3142 {"tble.b", 1, 0x0b, tb_opr_rel
, 0},
3144 {"tbne.w", 1, 0x0b, tb_opr_rel
, 0},
3145 {"tbeq.w", 1, 0x0b, tb_opr_rel
, 0},
3146 {"tbpl.w", 1, 0x0b, tb_opr_rel
, 0},
3147 {"tbmi.w", 1, 0x0b, tb_opr_rel
, 0},
3148 {"tbgt.w", 1, 0x0b, tb_opr_rel
, 0},
3149 {"tble.w", 1, 0x0b, tb_opr_rel
, 0},
3151 {"tbne.p", 1, 0x0b, tb_opr_rel
, 0},
3152 {"tbeq.p", 1, 0x0b, tb_opr_rel
, 0},
3153 {"tbpl.p", 1, 0x0b, tb_opr_rel
, 0},
3154 {"tbmi.p", 1, 0x0b, tb_opr_rel
, 0},
3155 {"tbgt.p", 1, 0x0b, tb_opr_rel
, 0},
3156 {"tble.p", 1, 0x0b, tb_opr_rel
, 0},
3158 {"tbne.l", 1, 0x0b, tb_opr_rel
, 0},
3159 {"tbeq.l", 1, 0x0b, tb_opr_rel
, 0},
3160 {"tbpl.l", 1, 0x0b, tb_opr_rel
, 0},
3161 {"tbmi.l", 1, 0x0b, tb_opr_rel
, 0},
3162 {"tbgt.l", 1, 0x0b, tb_opr_rel
, 0},
3163 {"tble.l", 1, 0x0b, tb_opr_rel
, 0},
3165 {"mov.b", 1, 0x0c, imm_opr
, 0},
3166 {"mov.w", 1, 0x0d, imm_opr
, 0},
3167 {"mov.p", 1, 0x0e, imm_opr
, 0},
3168 {"mov.l", 1, 0x0f, imm_opr
, 0},
3170 {"rol", 1, 0x10, rol
, 0},
3171 {"rol.b", 1, 0x10, rol
, 0},
3172 {"rol.w", 1, 0x10, rol
, 0},
3173 {"rol.p", 1, 0x10, rol
, 0},
3174 {"rol.l", 1, 0x10, rol
, 0},
3176 {"ror", 1, 0x10, ror
, 0},
3177 {"ror.b", 1, 0x10, ror
, 0},
3178 {"ror.w", 1, 0x10, ror
, 0},
3179 {"ror.p", 1, 0x10, ror
, 0},
3180 {"ror.l", 1, 0x10, ror
, 0},
3182 {"lsl", 1, 0x10, shift_reg
, 0},
3183 {"lsr", 1, 0x10, shift_reg
, 0},
3184 {"asl", 1, 0x10, shift_reg
, 0},
3185 {"asr", 1, 0x10, shift_reg
, 0},
3187 {"lsl.b", 1, 0x10, shift_two_operand
, 0},
3188 {"lsl.w", 1, 0x10, shift_two_operand
, 0},
3189 {"lsl.p", 1, 0x10, shift_two_operand
, 0},
3190 {"lsl.l", 1, 0x10, shift_two_operand
, 0},
3191 {"asl.b", 1, 0x10, shift_two_operand
, 0},
3192 {"asl.w", 1, 0x10, shift_two_operand
, 0},
3193 {"asl.p", 1, 0x10, shift_two_operand
, 0},
3194 {"asl.l", 1, 0x10, shift_two_operand
, 0},
3196 {"lsr.b", 1, 0x10, shift_two_operand
, 0},
3197 {"lsr.w", 1, 0x10, shift_two_operand
, 0},
3198 {"lsr.p", 1, 0x10, shift_two_operand
, 0},
3199 {"lsr.l", 1, 0x10, shift_two_operand
, 0},
3200 {"asr.b", 1, 0x10, shift_two_operand
, 0},
3201 {"asr.w", 1, 0x10, shift_two_operand
, 0},
3202 {"asr.p", 1, 0x10, shift_two_operand
, 0},
3203 {"asr.l", 1, 0x10, shift_two_operand
, 0},
3205 {"lsl.b", 1, 0x10, shift_opr_imm
, 0},
3206 {"lsl.w", 1, 0x10, shift_opr_imm
, 0},
3207 {"lsl.p", 1, 0x10, shift_opr_imm
, 0},
3208 {"lsl.l", 1, 0x10, shift_opr_imm
, 0},
3209 {"asl.b", 1, 0x10, shift_opr_imm
, 0},
3210 {"asl.w", 1, 0x10, shift_opr_imm
, 0},
3211 {"asl.p", 1, 0x10, shift_opr_imm
, 0},
3212 {"asl.l", 1, 0x10, shift_opr_imm
, 0},
3214 {"lsr.b", 1, 0x10, shift_opr_imm
, 0},
3215 {"lsr.w", 1, 0x10, shift_opr_imm
, 0},
3216 {"lsr.p", 1, 0x10, shift_opr_imm
, 0},
3217 {"lsr.l", 1, 0x10, shift_opr_imm
, 0},
3218 {"asr.b", 1, 0x10, shift_opr_imm
, 0},
3219 {"asr.w", 1, 0x10, shift_opr_imm
, 0},
3220 {"asr.p", 1, 0x10, shift_opr_imm
, 0},
3221 {"asr.l", 1, 0x10, shift_opr_imm
, 0},
3223 {"mov.b", 1, 0x1c, opr_opr
, 0},
3224 {"mov.w", 1, 0x1d, opr_opr
, 0},
3225 {"mov.p", 1, 0x1e, opr_opr
, 0},
3226 {"mov.l", 1, 0x1f, opr_opr
, 0},
3228 {"bra", 1, 0x20, rel
, 0},
3229 {"bsr", 1, 0x21, rel
, 0},
3230 {"bhi", 1, 0x22, rel
, 0},
3231 {"bls", 1, 0x23, rel
, 0},
3232 {"bcc", 1, 0x24, rel
, 0},
3233 {"bhs", 1, 0x24, rel
, 0}, /* Alias for bcc */
3234 {"bcs", 1, 0x25, rel
, 0},
3235 {"blo", 1, 0x25, rel
, 0}, /* Alias for bcs */
3236 {"bne", 1, 0x26, rel
, 0},
3237 {"beq", 1, 0x27, rel
, 0},
3238 {"bvc", 1, 0x28, rel
, 0},
3239 {"bvs", 1, 0x29, rel
, 0},
3240 {"bpl", 1, 0x2a, rel
, 0},
3241 {"bmi", 1, 0x2b, rel
, 0},
3242 {"bge", 1, 0x2c, rel
, 0},
3243 {"blt", 1, 0x2d, rel
, 0},
3244 {"bgt", 1, 0x2e, rel
, 0},
3245 {"ble", 1, 0x2f, rel
, 0},
3247 {"inc", 1, 0x30, reg_inh
, 0},
3248 {"clr", 1, 0x38, reg_inh
, 0},
3249 {"dec", 1, 0x40, reg_inh
, 0},
3251 {"muls", 1, 0x48, mul_reg_reg_reg
, 0},
3252 {"mulu", 1, 0x48, mul_reg_reg_reg
, 0},
3254 {"muls.b", 1, 0x48, mul_reg_reg_opr
, 0},
3255 {"muls.w", 1, 0x48, mul_reg_reg_opr
, 0},
3256 {"muls.l", 1, 0x48, mul_reg_reg_opr
, 0},
3258 {"mulu.b", 1, 0x48, mul_reg_reg_opr
, 0},
3259 {"mulu.w", 1, 0x48, mul_reg_reg_opr
, 0},
3260 {"mulu.l", 1, 0x48, mul_reg_reg_opr
, 0},
3262 {"muls.b", 1, 0x48, mul_reg_reg_imm
, 0},
3263 {"muls.w", 1, 0x48, mul_reg_reg_imm
, 0},
3264 {"muls.l", 1, 0x48, mul_reg_reg_imm
, 0},
3266 {"mulu.b", 1, 0x48, mul_reg_reg_imm
, 0},
3267 {"mulu.w", 1, 0x48, mul_reg_reg_imm
, 0},
3268 {"mulu.l", 1, 0x48, mul_reg_reg_imm
, 0},
3270 {"muls.bb", 1, 0x48, mul_reg_opr_opr
, 0},
3271 {"muls.bw", 1, 0x48, mul_reg_opr_opr
, 0},
3272 {"muls.bp", 1, 0x48, mul_reg_opr_opr
, 0},
3273 {"muls.bl", 1, 0x48, mul_reg_opr_opr
, 0},
3275 {"muls.wb", 1, 0x48, mul_reg_opr_opr
, 0},
3276 {"muls.ww", 1, 0x48, mul_reg_opr_opr
, 0},
3277 {"muls.wp", 1, 0x48, mul_reg_opr_opr
, 0},
3278 {"muls.wl", 1, 0x48, mul_reg_opr_opr
, 0},
3280 {"muls.pb", 1, 0x48, mul_reg_opr_opr
, 0},
3281 {"muls.pw", 1, 0x48, mul_reg_opr_opr
, 0},
3282 {"muls.pp", 1, 0x48, mul_reg_opr_opr
, 0},
3283 {"muls.pl", 1, 0x48, mul_reg_opr_opr
, 0},
3285 {"muls.lb", 1, 0x48, mul_reg_opr_opr
, 0},
3286 {"muls.lw", 1, 0x48, mul_reg_opr_opr
, 0},
3287 {"muls.lp", 1, 0x48, mul_reg_opr_opr
, 0},
3288 {"muls.ll", 1, 0x48, mul_reg_opr_opr
, 0},
3290 {"mulu.bb", 1, 0x48, mul_reg_opr_opr
, 0},
3291 {"mulu.bw", 1, 0x48, mul_reg_opr_opr
, 0},
3292 {"mulu.bp", 1, 0x48, mul_reg_opr_opr
, 0},
3293 {"mulu.bl", 1, 0x48, mul_reg_opr_opr
, 0},
3295 {"mulu.wb", 1, 0x48, mul_reg_opr_opr
, 0},
3296 {"mulu.ww", 1, 0x48, mul_reg_opr_opr
, 0},
3297 {"mulu.wp", 1, 0x48, mul_reg_opr_opr
, 0},
3298 {"mulu.wl", 1, 0x48, mul_reg_opr_opr
, 0},
3300 {"mulu.pb", 1, 0x48, mul_reg_opr_opr
, 0},
3301 {"mulu.pw", 1, 0x48, mul_reg_opr_opr
, 0},
3302 {"mulu.pp", 1, 0x48, mul_reg_opr_opr
, 0},
3303 {"mulu.pl", 1, 0x48, mul_reg_opr_opr
, 0},
3305 {"mulu.lb", 1, 0x48, mul_reg_opr_opr
, 0},
3306 {"mulu.lw", 1, 0x48, mul_reg_opr_opr
, 0},
3307 {"mulu.lp", 1, 0x48, mul_reg_opr_opr
, 0},
3308 {"mulu.ll", 1, 0x48, mul_reg_opr_opr
, 0},
3310 {"add", 1, 0x50, regd_imm
, 0},
3311 {"and", 1, 0x58, regd_imm
, 0},
3313 {"add", 1, 0x60, regd_opr
, 0},
3314 {"and", 1, 0x68, regd_opr
, 0},
3316 {"sub", 1, 0x70, regd_imm
, 0},
3317 {"or", 1, 0x78, regd_imm
, 0},
3319 {"sub", 1, 0x80, regd_opr
, 0},
3320 {"or", 1, 0x88, regd_opr
, 0},
3322 {"ld", 1, 0x90, regdxy_imm
, 0},
3324 {"clr", 1, 0x9a, clr_xy
, 0},
3325 {"tfr", 1, 0x9e, tfr
, 0},
3326 {"zex", 1, 0x9e, tfr
, 0},
3328 {"ld", 1, 0xa0, regdxy_opr_src
, 0xb0},
3330 {"jmp", 1, 0xaa, opr
, 0xba},
3331 {"jsr", 1, 0xab, opr
, 0xbb},
3333 {"exg", 1, 0xae, tfr
, 0},
3334 {"sex", 1, 0xae, tfr
, 0},
3336 {"st", 1, 0xc0, regdxy_opr_dest
, 0xd0},
3338 {"andcc", 1, 0xce, imm8
, 0},
3339 {"orcc", 1, 0xde, imm8
, 0},
3341 {"inc.b", 1, 0x9c, opr
, 0},
3342 {"inc.w", 1, 0x9d, opr
, 0},
3343 {"inc.l", 1, 0x9f, opr
, 0},
3345 {"dec.b", 1, 0xac, opr
, 0},
3346 {"dec.w", 1, 0xad, opr
, 0},
3347 {"dec.l", 1, 0xaf, opr
, 0},
3349 {"clr.b", 1, 0xbc, opr
, 0},
3350 {"clr.w", 1, 0xbd, opr
, 0},
3351 {"clr.p", 1, 0xbe, opr
, 0},
3352 {"clr.l", 1, 0xbf, opr
, 0},
3354 {"com.b", 1, 0xcc, opr
, 0},
3355 {"com.w", 1, 0xcd, opr
, 0},
3356 {"com.l", 1, 0xcf, opr
, 0},
3358 {"neg.b", 1, 0xdc, opr
, 0},
3359 {"neg.w", 1, 0xdd, opr
, 0},
3360 {"neg.l", 1, 0xdf, opr
, 0},
3362 {"bclr", 1, 0xec, bm_regd_imm
, 0},
3363 {"bset", 1, 0xed, bm_regd_imm
, 0},
3364 {"btgl", 1, 0xee, bm_regd_imm
, 0},
3366 {"bclr", 1, 0xec, bm_regd_reg
, 0},
3367 {"bset", 1, 0xed, bm_regd_reg
, 0},
3368 {"btgl", 1, 0xee, bm_regd_reg
, 0},
3370 {"bclr.b", 1, 0xec, bm_opr_imm
, 0},
3371 {"bclr.w", 1, 0xec, bm_opr_imm
, 0},
3372 {"bclr.l", 1, 0xec, bm_opr_imm
, 0},
3374 {"bset.b", 1, 0xed, bm_opr_imm
, 0},
3375 {"bset.w", 1, 0xed, bm_opr_imm
, 0},
3376 {"bset.l", 1, 0xed, bm_opr_imm
, 0},
3378 {"btgl.b", 1, 0xee, bm_opr_imm
, 0},
3379 {"btgl.w", 1, 0xee, bm_opr_imm
, 0},
3380 {"btgl.l", 1, 0xee, bm_opr_imm
, 0},
3382 {"bclr.b", 1, 0xec, bm_opr_reg
, 0},
3383 {"bclr.w", 1, 0xec, bm_opr_reg
, 0},
3384 {"bclr.l", 1, 0xec, bm_opr_reg
, 0},
3386 {"bset.b", 1, 0xed, bm_opr_reg
, 0},
3387 {"bset.w", 1, 0xed, bm_opr_reg
, 0},
3388 {"bset.l", 1, 0xed, bm_opr_reg
, 0},
3390 {"btgl.b", 1, 0xee, bm_opr_reg
, 0},
3391 {"btgl.w", 1, 0xee, bm_opr_reg
, 0},
3392 {"btgl.l", 1, 0xee, bm_opr_reg
, 0},
3394 {"cmp", 1, 0xe0, regdxy_imm
, 0},
3395 {"cmp", 1, 0xf0, regdxy_opr_src
, 0},
3397 {"cmp", 1, 0xfc, regx_regy
, 0},
3398 {"sub", 1, 0xfd, regd6_regx_regy
, 0},
3399 {"sub", 1, 0xfe, regd6_regy_regx
, 0},
3401 {"swi", 1, 0xff, no_operands
, 0},
3405 /* The -10 below is a kludge. The opcode is in fact 0x00 */
3406 {"ld", 2, -10, regs_opr_src
, 0},
3408 /* The -9 below is a kludge. The opcode is in fact 0x01 */
3409 {"st", 2, -9, regs_opr_dest
, 0},
3411 /* The -8 below is a kludge. The opcode is in fact 0x02 */
3412 {"cmp", 2, -8, regs_opr_src
, 0},
3414 /* The -7 below is a kludge. The opcode is in fact 0x03 */
3415 {"ld", 2, -7, regs_imm
, 0},
3417 /* The -6 below is a kludge. The opcode is in fact 0x04 */
3418 {"cmp", 2, -6, regs_imm
, 0},
3420 {"bfext", 2, 0x08, bfe_reg_reg_reg
, 0},
3421 {"bfext", 2, 0x08, bfe_reg_reg_imm
, 0},
3422 {"bfext.b", 2, 0x08, bfe_reg_opr_reg
, 0},
3423 {"bfext.w", 2, 0x08, bfe_reg_opr_reg
, 0},
3424 {"bfext.p", 2, 0x08, bfe_reg_opr_reg
, 0},
3425 {"bfext.l", 2, 0x08, bfe_reg_opr_reg
, 0},
3426 {"bfext.b", 2, 0x08, bfe_opr_reg_reg
, 0},
3427 {"bfext.w", 2, 0x08, bfe_opr_reg_reg
, 0},
3428 {"bfext.p", 2, 0x08, bfe_opr_reg_reg
, 0},
3429 {"bfext.l", 2, 0x08, bfe_opr_reg_reg
, 0},
3430 {"bfext.b", 2, 0x08, bfe_reg_opr_imm
, 0},
3431 {"bfext.w", 2, 0x08, bfe_reg_opr_imm
, 0},
3432 {"bfext.p", 2, 0x08, bfe_reg_opr_imm
, 0},
3433 {"bfext.l", 2, 0x08, bfe_reg_opr_imm
, 0},
3434 {"bfext.b", 2, 0x08, bfe_opr_reg_imm
, 0},
3435 {"bfext.w", 2, 0x08, bfe_opr_reg_imm
, 0},
3436 {"bfext.p", 2, 0x08, bfe_opr_reg_imm
, 0},
3437 {"bfext.l", 2, 0x08, bfe_opr_reg_imm
, 0},
3440 {"bfins", 2, 0x08, bfi_reg_reg_reg
, 0},
3441 {"bfins", 2, 0x08, bfi_reg_reg_imm
, 0},
3442 {"bfins.b", 2, 0x08, bfi_reg_opr_reg
, 0},
3443 {"bfins.w", 2, 0x08, bfi_reg_opr_reg
, 0},
3444 {"bfins.p", 2, 0x08, bfi_reg_opr_reg
, 0},
3445 {"bfins.l", 2, 0x08, bfi_reg_opr_reg
, 0},
3446 {"bfins.b", 2, 0x08, bfi_opr_reg_reg
, 0},
3447 {"bfins.w", 2, 0x08, bfi_opr_reg_reg
, 0},
3448 {"bfins.p", 2, 0x08, bfi_opr_reg_reg
, 0},
3449 {"bfins.l", 2, 0x08, bfi_opr_reg_reg
, 0},
3450 {"bfins.b", 2, 0x08, bfi_reg_opr_imm
, 0},
3451 {"bfins.w", 2, 0x08, bfi_reg_opr_imm
, 0},
3452 {"bfins.p", 2, 0x08, bfi_reg_opr_imm
, 0},
3453 {"bfins.l", 2, 0x08, bfi_reg_opr_imm
, 0},
3454 {"bfins.b", 2, 0x08, bfi_opr_reg_imm
, 0},
3455 {"bfins.w", 2, 0x08, bfi_opr_reg_imm
, 0},
3456 {"bfins.p", 2, 0x08, bfi_opr_reg_imm
, 0},
3457 {"bfins.l", 2, 0x08, bfi_opr_reg_imm
, 0},
3460 {"minu", 2, 0x10, regd_opr
, 0},
3461 {"maxu", 2, 0x18, regd_opr
, 0},
3462 {"mins", 2, 0x20, regd_opr
, 0},
3463 {"maxs", 2, 0x28, regd_opr
, 0},
3465 {"clb", 2, 0x91, tfr
, 0},
3467 {"trap", 2, 0x00, trap_imm
, 0},
3468 {"abs", 2, 0x40, reg_inh
, 0},
3469 {"sat", 2, 0xa0, reg_inh
, 0},
3471 {"rti", 2, 0x90, no_operands
, 0},
3472 {"stop", 2, 0x05, no_operands
, 0},
3473 {"wai", 2, 0x06, no_operands
, 0},
3474 {"sys", 2, 0x07, no_operands
, 0},
3476 {"bit", 2, 0x58, regd_imm
, 0},
3477 {"bit", 2, 0x68, regd_opr
, 0},
3479 {"adc", 2, 0x50, regd_imm
, 0},
3480 {"adc", 2, 0x60, regd_opr
, 0},
3482 {"sbc", 2, 0x70, regd_imm
, 0},
3483 {"eor", 2, 0x78, regd_imm
, 0},
3485 {"sbc", 2, 0x80, regd_opr
, 0},
3486 {"eor", 2, 0x88, regd_opr
, 0},
3488 {"divs", 2, 0x30, mul_reg_reg_reg
, 0},
3489 {"divu", 2, 0x30, mul_reg_reg_reg
, 0},
3491 {"divs.b", 2, 0x30, mul_reg_reg_opr
, 0},
3492 {"divs.w", 2, 0x30, mul_reg_reg_opr
, 0},
3493 {"divs.l", 2, 0x30, mul_reg_reg_opr
, 0},
3495 {"divu.b", 2, 0x30, mul_reg_reg_opr
, 0},
3496 {"divu.w", 2, 0x30, mul_reg_reg_opr
, 0},
3497 {"divu.l", 2, 0x30, mul_reg_reg_opr
, 0},
3499 {"divs.b", 2, 0x30, mul_reg_reg_imm
, 0},
3500 {"divs.w", 2, 0x30, mul_reg_reg_imm
, 0},
3501 {"divs.l", 2, 0x30, mul_reg_reg_imm
, 0},
3503 {"divu.b", 2, 0x30, mul_reg_reg_imm
, 0},
3504 {"divu.w", 2, 0x30, mul_reg_reg_imm
, 0},
3505 {"divu.l", 2, 0x30, mul_reg_reg_imm
, 0},
3507 {"divs.bb", 2, 0x30, mul_reg_opr_opr
, 0},
3508 {"divs.bw", 2, 0x30, mul_reg_opr_opr
, 0},
3509 {"divs.bp", 2, 0x30, mul_reg_opr_opr
, 0},
3510 {"divs.bl", 2, 0x30, mul_reg_opr_opr
, 0},
3512 {"divs.wb", 2, 0x30, mul_reg_opr_opr
, 0},
3513 {"divs.ww", 2, 0x30, mul_reg_opr_opr
, 0},
3514 {"divs.wp", 2, 0x30, mul_reg_opr_opr
, 0},
3515 {"divs.wl", 2, 0x30, mul_reg_opr_opr
, 0},
3517 {"divs.pb", 2, 0x30, mul_reg_opr_opr
, 0},
3518 {"divs.pw", 2, 0x30, mul_reg_opr_opr
, 0},
3519 {"divs.pp", 2, 0x30, mul_reg_opr_opr
, 0},
3520 {"divs.pl", 2, 0x30, mul_reg_opr_opr
, 0},
3522 {"divs.lb", 2, 0x30, mul_reg_opr_opr
, 0},
3523 {"divs.lw", 2, 0x30, mul_reg_opr_opr
, 0},
3524 {"divs.lp", 2, 0x30, mul_reg_opr_opr
, 0},
3525 {"divs.ll", 2, 0x30, mul_reg_opr_opr
, 0},
3527 {"divu.bb", 2, 0x30, mul_reg_opr_opr
, 0},
3528 {"divu.bw", 2, 0x30, mul_reg_opr_opr
, 0},
3529 {"divu.bp", 2, 0x30, mul_reg_opr_opr
, 0},
3530 {"divu.bl", 2, 0x30, mul_reg_opr_opr
, 0},
3532 {"divu.wb", 2, 0x30, mul_reg_opr_opr
, 0},
3533 {"divu.ww", 2, 0x30, mul_reg_opr_opr
, 0},
3534 {"divu.wp", 2, 0x30, mul_reg_opr_opr
, 0},
3535 {"divu.wl", 2, 0x30, mul_reg_opr_opr
, 0},
3537 {"divu.pb", 2, 0x30, mul_reg_opr_opr
, 0},
3538 {"divu.pw", 2, 0x30, mul_reg_opr_opr
, 0},
3539 {"divu.pp", 2, 0x30, mul_reg_opr_opr
, 0},
3540 {"divu.pl", 2, 0x30, mul_reg_opr_opr
, 0},
3542 {"divu.lb", 2, 0x30, mul_reg_opr_opr
, 0},
3543 {"divu.lw", 2, 0x30, mul_reg_opr_opr
, 0},
3544 {"divu.lp", 2, 0x30, mul_reg_opr_opr
, 0},
3545 {"divu.ll", 2, 0x30, mul_reg_opr_opr
, 0},
3549 {"qmuls", 2, 0xb0, mul_reg_reg_reg
, 0},
3550 {"qmulu", 2, 0xb0, mul_reg_reg_reg
, 0},
3552 {"qmuls.b", 2, 0xb0, mul_reg_reg_opr
, 0},
3553 {"qmuls.w", 2, 0xb0, mul_reg_reg_opr
, 0},
3554 {"qmuls.l", 2, 0xb0, mul_reg_reg_opr
, 0},
3556 {"qmulu.b", 2, 0xb0, mul_reg_reg_opr
, 0},
3557 {"qmulu.w", 2, 0xb0, mul_reg_reg_opr
, 0},
3558 {"qmulu.l", 2, 0xb0, mul_reg_reg_opr
, 0},
3560 {"qmuls.b", 2, 0xb0, mul_reg_reg_imm
, 0},
3561 {"qmuls.w", 2, 0xb0, mul_reg_reg_imm
, 0},
3562 {"qmuls.l", 2, 0xb0, mul_reg_reg_imm
, 0},
3564 {"qmulu.b", 2, 0xb0, mul_reg_reg_imm
, 0},
3565 {"qmulu.w", 2, 0xb0, mul_reg_reg_imm
, 0},
3566 {"qmulu.l", 2, 0xb0, mul_reg_reg_imm
, 0},
3568 {"qmuls.bb", 2, 0xb0, mul_reg_opr_opr
, 0},
3569 {"qmuls.bw", 2, 0xb0, mul_reg_opr_opr
, 0},
3570 {"qmuls.bp", 2, 0xb0, mul_reg_opr_opr
, 0},
3571 {"qmuls.bl", 2, 0xb0, mul_reg_opr_opr
, 0},
3573 {"qmuls.wb", 2, 0xb0, mul_reg_opr_opr
, 0},
3574 {"qmuls.ww", 2, 0xb0, mul_reg_opr_opr
, 0},
3575 {"qmuls.wp", 2, 0xb0, mul_reg_opr_opr
, 0},
3576 {"qmuls.wl", 2, 0xb0, mul_reg_opr_opr
, 0},
3578 {"qmuls.pb", 2, 0xb0, mul_reg_opr_opr
, 0},
3579 {"qmuls.pw", 2, 0xb0, mul_reg_opr_opr
, 0},
3580 {"qmuls.pp", 2, 0xb0, mul_reg_opr_opr
, 0},
3581 {"qmuls.pl", 2, 0xb0, mul_reg_opr_opr
, 0},
3583 {"qmuls.lb", 2, 0xb0, mul_reg_opr_opr
, 0},
3584 {"qmuls.lw", 2, 0xb0, mul_reg_opr_opr
, 0},
3585 {"qmuls.lp", 2, 0xb0, mul_reg_opr_opr
, 0},
3586 {"qmuls.ll", 2, 0xb0, mul_reg_opr_opr
, 0},
3588 {"qmulu.bb", 2, 0xb0, mul_reg_opr_opr
, 0},
3589 {"qmulu.bw", 2, 0xb0, mul_reg_opr_opr
, 0},
3590 {"qmulu.bp", 2, 0xb0, mul_reg_opr_opr
, 0},
3591 {"qmulu.bl", 2, 0xb0, mul_reg_opr_opr
, 0},
3593 {"qmulu.wb", 2, 0xb0, mul_reg_opr_opr
, 0},
3594 {"qmulu.ww", 2, 0xb0, mul_reg_opr_opr
, 0},
3595 {"qmulu.wp", 2, 0xb0, mul_reg_opr_opr
, 0},
3596 {"qmulu.wl", 2, 0xb0, mul_reg_opr_opr
, 0},
3598 {"qmulu.pb", 2, 0xb0, mul_reg_opr_opr
, 0},
3599 {"qmulu.pw", 2, 0xb0, mul_reg_opr_opr
, 0},
3600 {"qmulu.pp", 2, 0xb0, mul_reg_opr_opr
, 0},
3601 {"qmulu.pl", 2, 0xb0, mul_reg_opr_opr
, 0},
3603 {"qmulu.lb", 2, 0xb0, mul_reg_opr_opr
, 0},
3604 {"qmulu.lw", 2, 0xb0, mul_reg_opr_opr
, 0},
3605 {"qmulu.lp", 2, 0xb0, mul_reg_opr_opr
, 0},
3606 {"qmulu.ll", 2, 0xb0, mul_reg_opr_opr
, 0},
3611 {"macs", 2, 0x48, mul_reg_reg_reg
, 0},
3612 {"macu", 2, 0x48, mul_reg_reg_reg
, 0},
3614 {"macs.b", 2, 0x48, mul_reg_reg_opr
, 0},
3615 {"macs.w", 2, 0x48, mul_reg_reg_opr
, 0},
3616 {"macs.l", 2, 0x48, mul_reg_reg_opr
, 0},
3618 {"macu.b", 2, 0x48, mul_reg_reg_opr
, 0},
3619 {"macu.w", 2, 0x48, mul_reg_reg_opr
, 0},
3620 {"macu.l", 2, 0x48, mul_reg_reg_opr
, 0},
3622 {"macs.b", 2, 0x48, mul_reg_reg_imm
, 0},
3623 {"macs.w", 2, 0x48, mul_reg_reg_imm
, 0},
3624 {"macs.l", 2, 0x48, mul_reg_reg_imm
, 0},
3626 {"macu.b", 2, 0x48, mul_reg_reg_imm
, 0},
3627 {"macu.w", 2, 0x48, mul_reg_reg_imm
, 0},
3628 {"macu.l", 2, 0x48, mul_reg_reg_imm
, 0},
3630 {"macs.bb", 2, 0x48, mul_reg_opr_opr
, 0},
3631 {"macs.bw", 2, 0x48, mul_reg_opr_opr
, 0},
3632 {"macs.bp", 2, 0x48, mul_reg_opr_opr
, 0},
3633 {"macs.bl", 2, 0x48, mul_reg_opr_opr
, 0},
3635 {"macs.wb", 2, 0x48, mul_reg_opr_opr
, 0},
3636 {"macs.ww", 2, 0x48, mul_reg_opr_opr
, 0},
3637 {"macs.wp", 2, 0x48, mul_reg_opr_opr
, 0},
3638 {"macs.wl", 2, 0x48, mul_reg_opr_opr
, 0},
3640 {"macs.pb", 2, 0x48, mul_reg_opr_opr
, 0},
3641 {"macs.pw", 2, 0x48, mul_reg_opr_opr
, 0},
3642 {"macs.pp", 2, 0x48, mul_reg_opr_opr
, 0},
3643 {"macs.pl", 2, 0x48, mul_reg_opr_opr
, 0},
3645 {"macs.lb", 2, 0x48, mul_reg_opr_opr
, 0},
3646 {"macs.lw", 2, 0x48, mul_reg_opr_opr
, 0},
3647 {"macs.lp", 2, 0x48, mul_reg_opr_opr
, 0},
3648 {"macs.ll", 2, 0x48, mul_reg_opr_opr
, 0},
3650 {"macu.bb", 2, 0x48, mul_reg_opr_opr
, 0},
3651 {"macu.bw", 2, 0x48, mul_reg_opr_opr
, 0},
3652 {"macu.bp", 2, 0x48, mul_reg_opr_opr
, 0},
3653 {"macu.bl", 2, 0x48, mul_reg_opr_opr
, 0},
3655 {"macu.wb", 2, 0x48, mul_reg_opr_opr
, 0},
3656 {"macu.ww", 2, 0x48, mul_reg_opr_opr
, 0},
3657 {"macu.wp", 2, 0x48, mul_reg_opr_opr
, 0},
3658 {"macu.wl", 2, 0x48, mul_reg_opr_opr
, 0},
3660 {"macu.pb", 2, 0x48, mul_reg_opr_opr
, 0},
3661 {"macu.pw", 2, 0x48, mul_reg_opr_opr
, 0},
3662 {"macu.pp", 2, 0x48, mul_reg_opr_opr
, 0},
3663 {"macu.pl", 2, 0x48, mul_reg_opr_opr
, 0},
3665 {"macu.lb", 2, 0x48, mul_reg_opr_opr
, 0},
3666 {"macu.lw", 2, 0x48, mul_reg_opr_opr
, 0},
3667 {"macu.lp", 2, 0x48, mul_reg_opr_opr
, 0},
3668 {"macu.ll", 2, 0x48, mul_reg_opr_opr
, 0},
3673 {"mods", 2, 0x38, mul_reg_reg_reg
, 0},
3674 {"modu", 2, 0x38, mul_reg_reg_reg
, 0},
3676 {"mods.b", 2, 0x38, mul_reg_reg_opr
, 0},
3677 {"mods.w", 2, 0x38, mul_reg_reg_opr
, 0},
3678 {"mods.l", 2, 0x38, mul_reg_reg_opr
, 0},
3680 {"modu.b", 2, 0x38, mul_reg_reg_opr
, 0},
3681 {"modu.w", 2, 0x38, mul_reg_reg_opr
, 0},
3682 {"modu.l", 2, 0x38, mul_reg_reg_opr
, 0},
3684 {"mods.b", 2, 0x38, mul_reg_reg_imm
, 0},
3685 {"mods.w", 2, 0x38, mul_reg_reg_imm
, 0},
3686 {"mods.l", 2, 0x38, mul_reg_reg_imm
, 0},
3688 {"modu.b", 2, 0x38, mul_reg_reg_imm
, 0},
3689 {"modu.w", 2, 0x38, mul_reg_reg_imm
, 0},
3690 {"modu.l", 2, 0x38, mul_reg_reg_imm
, 0},
3692 {"mods.bb", 2, 0x38, mul_reg_opr_opr
, 0},
3693 {"mods.bw", 2, 0x38, mul_reg_opr_opr
, 0},
3694 {"mods.bp", 2, 0x38, mul_reg_opr_opr
, 0},
3695 {"mods.bl", 2, 0x38, mul_reg_opr_opr
, 0},
3697 {"mods.wb", 2, 0x38, mul_reg_opr_opr
, 0},
3698 {"mods.ww", 2, 0x38, mul_reg_opr_opr
, 0},
3699 {"mods.wp", 2, 0x38, mul_reg_opr_opr
, 0},
3700 {"mods.wl", 2, 0x38, mul_reg_opr_opr
, 0},
3702 {"mods.pb", 2, 0x38, mul_reg_opr_opr
, 0},
3703 {"mods.pw", 2, 0x38, mul_reg_opr_opr
, 0},
3704 {"mods.pp", 2, 0x38, mul_reg_opr_opr
, 0},
3705 {"mods.pl", 2, 0x38, mul_reg_opr_opr
, 0},
3707 {"mods.lb", 2, 0x38, mul_reg_opr_opr
, 0},
3708 {"mods.lw", 2, 0x38, mul_reg_opr_opr
, 0},
3709 {"mods.lp", 2, 0x38, mul_reg_opr_opr
, 0},
3710 {"mods.ll", 2, 0x38, mul_reg_opr_opr
, 0},
3712 {"modu.bb", 2, 0x38, mul_reg_opr_opr
, 0},
3713 {"modu.bw", 2, 0x38, mul_reg_opr_opr
, 0},
3714 {"modu.bp", 2, 0x38, mul_reg_opr_opr
, 0},
3715 {"modu.bl", 2, 0x38, mul_reg_opr_opr
, 0},
3717 {"modu.wb", 2, 0x38, mul_reg_opr_opr
, 0},
3718 {"modu.ww", 2, 0x38, mul_reg_opr_opr
, 0},
3719 {"modu.wp", 2, 0x38, mul_reg_opr_opr
, 0},
3720 {"modu.wl", 2, 0x38, mul_reg_opr_opr
, 0},
3722 {"modu.pb", 2, 0x38, mul_reg_opr_opr
, 0},
3723 {"modu.pw", 2, 0x38, mul_reg_opr_opr
, 0},
3724 {"modu.pp", 2, 0x38, mul_reg_opr_opr
, 0},
3725 {"modu.pl", 2, 0x38, mul_reg_opr_opr
, 0},
3727 {"modu.lb", 2, 0x38, mul_reg_opr_opr
, 0},
3728 {"modu.lw", 2, 0x38, mul_reg_opr_opr
, 0},
3729 {"modu.lp", 2, 0x38, mul_reg_opr_opr
, 0},
3730 {"modu.ll", 2, 0x38, mul_reg_opr_opr
, 0}
3734 /* Gas line assembler entry point. */
3736 /* This is the main entry point for the machine-dependent assembler. str
3737 points to a machine-dependent instruction. This function is supposed to
3738 emit the frags/bytes it assembles to. */
3740 md_assemble (char *str
)
3747 fail_line_pointer
= NULL
;
3749 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
3750 lower case (the opcode table only has lower case op-codes). */
3751 for (op_start
= op_end
= str
;
3752 *op_end
&& !is_end_of_line
[(int)*op_end
] && *op_end
!= ' ';
3755 name
[nlen
] = TOLOWER (op_start
[nlen
]);
3757 gas_assert (nlen
< sizeof (name
) - 1);
3763 as_bad (_("No instruction or missing opcode."));
3767 input_line_pointer
= skip_whites (op_end
);
3770 for (i
= 0; i
< sizeof (opcodes
) / sizeof (opcodes
[0]); ++i
)
3772 const struct instruction
*opc
= opcodes
+ i
;
3773 if (0 == strcmp (name
, opc
->name
))
3775 if (opc
->parse_operands (opc
))
3781 as_bad (_("Invalid instruction: \"%s\""), str
);
3782 as_bad (_("First invalid token: \"%s\""), fail_line_pointer
);
3783 while (*input_line_pointer
++)
3791 /* Relocation, relaxation and frag conversions. */
3793 /* PC-relative offsets are relative to the start of the
3794 next instruction. That is, the address of the offset, plus its
3795 size, since the offset is always the last part of the insn. */
3797 md_pcrel_from (fixS
*fixP
)
3799 long ret
= fixP
->fx_size
+ fixP
->fx_frag
->fr_address
;
3800 if (fixP
->fx_addsy
&& S_IS_DEFINED (fixP
->fx_addsy
))
3801 ret
+= fixP
->fx_where
;
3807 /* We need a port-specific relaxation function to cope with sym2 - sym1
3808 relative expressions with both symbols in the same segment (but not
3809 necessarily in the same frag as this insn), for example:
3810 ldab sym2-(sym1-2),pc
3812 The offset can be 5, 9 or 16 bits long. */
3815 s12z_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
*fragP ATTRIBUTE_UNUSED
,
3816 long stretch ATTRIBUTE_UNUSED
)
3822 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec ATTRIBUTE_UNUSED
,
3823 fragS
*fragP ATTRIBUTE_UNUSED
)
3827 /* On an ELF system, we can't relax a weak symbol. The weak symbol
3828 can be overridden at final link time by a non weak symbol. We can
3829 relax externally visible symbol because there is no shared library
3830 and such symbol can't be overridden (unless they are weak). */
3832 /* Force truly undefined symbols to their maximum size, and generally set up
3833 the frag list to be relaxed. */
3835 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
, asection
*segment ATTRIBUTE_UNUSED
)
3841 /* If while processing a fixup, a reloc really needs to be created
3842 then it is done here. */
3844 tc_gen_reloc (asection
*section
, fixS
*fixp
)
3846 arelent
*reloc
= XNEW (arelent
);
3847 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3848 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3849 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3850 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3851 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3853 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3854 _("Relocation %d is not supported by object file format."),
3855 (int) fixp
->fx_r_type
);
3859 if (0 == (section
->flags
& SEC_CODE
))
3860 reloc
->addend
= fixp
->fx_offset
;
3862 reloc
->addend
= fixp
->fx_addnumber
;
3867 /* See whether we need to force a relocation into the output file. */
3869 tc_s12z_force_relocation (fixS
*fixP
)
3871 return generic_force_reloc (fixP
);
3874 /* Here we decide which fixups can be adjusted to make them relative
3875 to the beginning of the section instead of the symbol. Basically
3876 we need to make sure that the linker relaxation is done
3877 correctly, so in some cases we force the original symbol to be
3880 tc_s12z_fix_adjustable (fixS
*fixP ATTRIBUTE_UNUSED
)
3886 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
3890 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
3893 /* We don't actually support subtracting a symbol. */
3894 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
3895 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
3898 Patch the instruction with the resolved operand. Elf relocation
3899 info will also be generated to take care of linker/loader fixups.
3901 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
3903 switch (fixP
->fx_r_type
)
3906 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
3909 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
3912 bfd_putb24 ((bfd_vma
) value
, (unsigned char *) where
);
3914 case BFD_RELOC_S12Z_OPR
:
3916 switch (fixP
->fx_size
)
3919 bfd_putb24 ((bfd_vma
) value
, (unsigned char *) where
);
3922 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
3930 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
3932 case BFD_RELOC_16_PCREL
:
3933 if (value
< -0x4000 || value
> 0x3FFF)
3934 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3935 _("Value out of 16-bit range."));
3937 bfd_putb16 ((bfd_vma
) value
| 0x8000, (unsigned char *) where
);
3941 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3942 fixP
->fx_line
, fixP
->fx_r_type
);
3946 /* Set the ELF specific flags. */
3948 s12z_elf_final_processing (void)