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 const char EXP_CHARS
[] = "eE";
36 const char FLT_CHARS
[] = "dD";
38 static char *fail_line_pointer
;
41 /* Options and initialization. */
43 const char *md_shortopts
= "Sm:";
45 struct option md_longopts
[] =
49 size_t md_longopts_size
= sizeof (md_longopts
);
52 relax_typeS md_relax_table
[] =
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
[] =
68 /* Get the target cpu for the assembler. */
70 s12z_arch_format (void)
87 /* Listing header selected according to cpu. */
89 s12z_listing_header (void)
95 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
100 s12z_print_statistics (FILE *file ATTRIBUTE_UNUSED
)
105 md_parse_option (int c ATTRIBUTE_UNUSED
, const char *arg ATTRIBUTE_UNUSED
)
111 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
117 md_atof (int type
, char *litP
, int *sizeP
)
119 return ieee_md_atof (type
, litP
, sizeP
, TRUE
);
123 md_section_align (asection
*seg
, valueT addr
)
125 int align
= bfd_get_section_alignment (stdoutput
, seg
);
126 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
135 s12z_init_after_args (void)
143 skip_whites (char *p
)
145 while (*p
== ' ' || *p
== '\t')
153 /* Start a new insn that contains at least 'size' bytes. Record the
154 line information of that insn in the dwarf2 debug sections. */
156 s12z_new_insn (int size
)
158 char *f
= frag_more (size
);
160 dwarf2_emit_insn (size
);
167 static int lex_reg_name (uint16_t which
, int *reg
);
170 lex_constant (long *v
)
173 char *p
= input_line_pointer
;
175 /* A constant may not have the same value as a register
178 if (lex_reg_name (~0, &dummy
))
180 input_line_pointer
= p
;
185 *v
= strtol (p
, &end
, 0);
186 if (errno
== 0 && end
!= p
)
188 input_line_pointer
= end
;
198 char *p
= input_line_pointer
;
202 input_line_pointer
++;
208 lex_expression (expressionS
*exp
)
210 char *ilp
= input_line_pointer
;
212 exp
->X_op
= O_absent
;
217 if (lex_reg_name (~0, &dummy
))
221 if (exp
->X_op
!= O_absent
)
225 fail_line_pointer
= input_line_pointer
;
226 input_line_pointer
= ilp
;
230 /* immediate operand */
234 char *ilp
= input_line_pointer
;
236 if (*input_line_pointer
!= '#')
239 input_line_pointer
++;
241 if (!lex_expression (&exp
))
244 if (exp
.X_op
!= O_constant
)
247 *v
= exp
.X_add_number
;
251 fail_line_pointer
= input_line_pointer
;
252 input_line_pointer
= ilp
;
256 /* Short mmediate operand */
258 lex_imm_e4 (long *val
)
260 char *ilp
= input_line_pointer
;
263 if ((*val
== -1) || (*val
> 0 && *val
<= 15))
268 fail_line_pointer
= input_line_pointer
;
269 input_line_pointer
= ilp
;
274 lex_match_string (const char *s
)
276 char *p
= input_line_pointer
;
277 while (p
!= 0 && *p
!= '\t' && *p
!= ' ' && *p
!= '\0')
282 size_t len
= p
- input_line_pointer
;
283 if (len
!= strlen (s
))
286 if (0 == strncasecmp (s
, input_line_pointer
, len
))
288 input_line_pointer
= p
;
295 /* Parse a register name.
296 WHICH is a ORwise combination of the registers which are accepted.
298 On success, REG will be filled with the index of the register which
299 was successfully scanned.
302 lex_reg_name (uint16_t which
, int *reg
)
304 char *p
= input_line_pointer
;
306 ((*p
>= 'a' && *p
<='z') || (*p
>= '0' && *p
<= '9') || (*p
>= 'A' && *p
<='Z')))
311 size_t len
= p
- input_line_pointer
;
317 for (i
= 0; i
< S12Z_N_REGISTERS
; ++i
)
319 gas_assert (registers
[i
].name
);
321 if (len
== strlen (registers
[i
].name
)
322 && 0 == strncasecmp (registers
[i
].name
, input_line_pointer
, len
))
324 if ((0x1U
<< i
) & which
)
326 input_line_pointer
= p
;
337 lex_force_match (char x
)
339 char *p
= input_line_pointer
;
342 as_bad (_("Expecting '%c'"), x
);
346 input_line_pointer
++;
351 lex_opr (uint8_t *buffer
, int *n_bytes
, expressionS
*exp
,
354 char *ilp
= input_line_pointer
;
355 uint8_t *xb
= buffer
;
358 exp
->X_op
= O_absent
;
361 if (lex_imm_e4 (&imm
))
365 as_bad (_("An immediate value in a source operand is inappropriate"));
376 else if (lex_reg_name (REG_BIT_Dn
, ®
))
383 else if (lex_match ('['))
385 if (lex_expression (exp
))
387 long c
= exp
->X_add_number
;
390 if (lex_reg_name (REG_BIT_XYSP
, ®
))
393 if (c
<= 255 && c
>= -256)
403 *xb
|= (reg
- REG_X
) << 4;
407 for (i
= 1; i
< *n_bytes
; ++i
)
409 buffer
[i
] = c
>> (8 * (*n_bytes
- i
- 1));
414 as_bad (_("Bad operand for constant offset"));
427 else if (lex_reg_name (REG_BIT_Dn
, ®
))
429 if (!lex_force_match (','))
433 if (lex_reg_name (REG_BIT_XY
, ®2
))
437 *xb
|= (reg2
- REG_X
) << 4;
442 as_bad (_("Invalid operand for register offset"));
450 if (!lex_force_match (']'))
454 else if (lex_match ('('))
457 if (lex_constant (&c
))
459 if (!lex_force_match (','))
462 if (lex_reg_name (REG_BIT_XYSP
, ®2
))
464 if (reg2
!= REG_P
&& c
>= 0 && c
<= 15)
468 *xb
|= (reg2
- REG_X
) << 4;
471 else if (c
>= -256 && c
<= 255)
475 *xb
|= (reg2
- REG_X
) << 4;
484 *xb
|= (reg2
- REG_X
) << 4;
490 else if (lex_reg_name (REG_BIT_Dn
, ®2
))
492 if (c
>= -1 * (long) (0x1u
<< 17)
494 c
< (long) (0x1u
<< 17) - 1)
499 *xb
|= ((c
>> 16) & 0x03) << 4;
515 as_bad (_("Bad operand for constant offset"));
519 else if (lex_reg_name (REG_BIT_Dn
, ®
))
524 if (lex_reg_name (REG_BIT_XYS
, ®2
))
528 *xb
|= (reg2
- REG_X
) << 4;
533 as_bad (_("Invalid operand for register offset"));
542 else if (lex_reg_name (REG_BIT_XYS
, ®
))
548 as_bad (_("Invalid register for postdecrement operation"));
554 else if (reg
== REG_Y
)
557 else if (lex_match ('+'))
562 else if (reg
== REG_Y
)
564 else if (reg
== REG_S
)
572 else if (lex_match ('+'))
574 if (lex_reg_name (REG_BIT_XY
, ®
))
579 else if (reg
== REG_Y
)
584 as_bad (_("Invalid register for preincrement operation"));
588 else if (lex_match ('-'))
590 if (lex_reg_name (REG_BIT_XYS
, ®
))
595 else if (reg
== REG_Y
)
597 else if (reg
== REG_S
)
602 as_bad (_("Invalid register for predecrement operation"));
611 if (! lex_match (')'))
615 else if (lex_expression (exp
))
622 if (exp
->X_op
== O_constant
)
624 valueT value
= exp
->X_add_number
;
626 if (value
< (0x1U
<< 14))
633 else if (value
< (0x1U
<< 19))
636 if (value
& (0x1U
<< 17))
638 if (value
& (0x1U
<< 16))
641 buffer
[1] = value
>> 8;
648 buffer
[1] = value
>> 16;
649 buffer
[2] = value
>> 8;
657 fail_line_pointer
= input_line_pointer
;
658 input_line_pointer
= ilp
;
663 lex_offset (long *val
)
666 char *p
= input_line_pointer
;
671 if (*p
!= '+' && *p
!= '-')
674 bool negative
= (*p
== '-');
678 *val
= strtol (p
, &end
, 0);
683 input_line_pointer
= end
;
694 typedef int (*parse_operand_func
) (const struct instruction
*);
700 /* The "page" to which the instruction belongs.
701 This is also only a hint. Some instructions might have modes in both
705 /* This is a hint - and only a hint - about the opcode of the instruction.
706 The parse_operand_func is free to ignore it.
710 parse_operand_func parse_operands
;
712 /* Some instructions can be encoded with a different opcode */
717 no_operands (const struct instruction
*insn
)
719 if (*input_line_pointer
!= '\0')
721 as_bad (_("Garbage at end of instruction"));
725 char *f
= s12z_new_insn (insn
->page
);
727 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
729 number_to_chars_bigendian (f
++, insn
->opc
, 1);
734 /* Emit the code for an OPR address mode operand */
736 emit_opr (char *f
, const uint8_t *buffer
, int n_bytes
, expressionS
*exp
)
739 number_to_chars_bigendian (f
++, buffer
[0], 1);
740 if (exp
->X_op
!= O_absent
&& exp
->X_op
!= O_constant
)
742 fixS
*fix
= fix_new_exp (frag_now
,
743 f
- frag_now
->fr_literal
,
748 /* Some third party tools seem to use the lower bits
749 of this addend for flags. They don't get added
750 to the final location. The purpose of these flags
751 is not known. We simply set it to zero. */
752 fix
->fx_addnumber
= 0x00;
754 for (i
= 1; i
< n_bytes
; ++i
)
755 number_to_chars_bigendian (f
++, buffer
[i
], 1);
760 /* Emit the code for a 24 bit direct address operand */
762 emit_ext24 (char *f
, long v
)
764 number_to_chars_bigendian (f
, v
, 3);
770 opr (const struct instruction
*insn
)
775 if (lex_opr (buffer
, &n_bytes
, &exp
, false))
777 /* Large constant direct values are more efficiently encoded as ext24 mode.
778 Otherwise a decision has to be deferred to a relax. */
779 if (exp
.X_op
== O_constant
781 && insn
->alt_opc
!= 0)
783 char *f
= s12z_new_insn (4);
785 /* I don't think there are any instances of page 2 opcodes in this case */
786 gas_assert (insn
->page
== 1);
788 number_to_chars_bigendian (f
++, insn
->alt_opc
, 1);
790 emit_ext24 (f
, exp
.X_add_number
);
794 char *f
= s12z_new_insn (n_bytes
+ 1);
795 number_to_chars_bigendian (f
++, insn
->opc
, 1);
797 emit_opr (f
, buffer
, n_bytes
, &exp
);
805 /* Parse a 15 bit offset, as an expression.
806 LONG_DISPLACEMENT will be set to true if the offset is wider than 7 bits.
809 lex_15_bit_offset (bool *long_displacement
, expressionS
*exp
)
811 char *ilp
= input_line_pointer
;
814 if (lex_offset (&val
))
816 exp
->X_op
= O_absent
;
817 exp
->X_add_number
= val
;
819 else if (lex_expression (exp
))
821 if (exp
->X_op
== O_constant
)
823 val
= exp
->X_add_number
;
827 /* If a symbol was parsed we don't know the displacement.
828 We have to assume it is long, and relax it later if possible. */
829 *long_displacement
= true;
835 exp
->X_op
= O_absent
;
839 if (val
> 0x3FFF || val
< -0x4000)
841 as_fatal (_("Offset is outside of 15 bit range"));
845 *long_displacement
= (val
> 63 || val
< -64);
850 fail_line_pointer
= input_line_pointer
;
851 input_line_pointer
= ilp
;
856 emit_15_bit_offset (char *f
, int where
, expressionS
*exp
)
859 if (exp
->X_op
!= O_absent
&& exp
->X_op
!= O_constant
)
861 exp
->X_add_number
+= where
;
862 fixS
*fix
= fix_new_exp (frag_now
,
863 f
- frag_now
->fr_literal
,
868 fix
->fx_addnumber
= where
- 2;
872 long val
= exp
->X_add_number
;
873 bool long_displacement
= (val
> 63 || val
< -64);
874 if (long_displacement
)
879 number_to_chars_bigendian (f
++, val
, long_displacement
? 2 : 1);
884 rel (const struct instruction
*insn
)
886 bool long_displacement
;
889 if (! lex_15_bit_offset (&long_displacement
, &exp
))
892 char *f
= s12z_new_insn (long_displacement
? 3 : 2);
893 number_to_chars_bigendian (f
++, insn
->opc
, 1);
894 emit_15_bit_offset (f
, 3, &exp
);
899 reg_inh (const struct instruction
*insn
)
902 if (lex_reg_name (REG_BIT_Dn
, ®
))
904 char *f
= s12z_new_insn (insn
->page
);
906 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
908 number_to_chars_bigendian (f
++, insn
->opc
+ reg
, 1);
916 /* Special case for CLR X and CLR Y */
918 clr_xy (const struct instruction
*insn ATTRIBUTE_UNUSED
)
921 if (lex_reg_name (REG_BIT_XY
, ®
))
923 char *f
= s12z_new_insn (1);
924 number_to_chars_bigendian (f
, 0x9a + reg
- REG_X
, 1);
931 /* Some instructions have a suffix like ".l", ".b", ".w" etc
932 which indicates the size of the operands. */
934 size_from_suffix (const struct instruction
*insn
, int idx
)
936 const char *dot
= strchr (insn
->name
, '.');
942 switch (dot
[1 + idx
])
957 as_fatal (_("Bad size"));
964 mul_reg_reg_reg (const struct instruction
*insn
)
966 char *ilp
= input_line_pointer
;
969 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
972 if (!lex_match (','))
976 if (!lex_reg_name (REG_BIT_Dn
, &Dj
))
979 if (!lex_match (','))
983 if (!lex_reg_name (REG_BIT_Dn
, &Dk
))
986 char *f
= s12z_new_insn (insn
->page
+ 1);
988 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
990 number_to_chars_bigendian (f
++, insn
->opc
+ Dd
, 1);
991 const char *dot
= strchrnul (insn
->name
, '.');
1002 as_fatal (_("BAD MUL"));
1009 number_to_chars_bigendian (f
++, mb
, 1);
1014 fail_line_pointer
= input_line_pointer
;
1015 input_line_pointer
= ilp
;
1021 mul_reg_reg_imm (const struct instruction
*insn
)
1023 char *ilp
= input_line_pointer
;
1026 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1029 if (!lex_match (','))
1033 if (!lex_reg_name (REG_BIT_Dn
, &Dj
))
1036 if (!lex_match (','))
1040 if (!lex_imm (&imm
))
1044 int size
= size_from_suffix (insn
, 0);
1046 char *f
= s12z_new_insn (insn
->page
+ 1 + size
);
1047 if (insn
->page
== 2)
1048 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1050 number_to_chars_bigendian (f
++, insn
->opc
+ Dd
, 1);
1052 const char *dot
= strchrnul (insn
->name
, '.');
1062 as_fatal (_("BAD MUL"));
1069 number_to_chars_bigendian (f
++, mb
, 1);
1070 number_to_chars_bigendian (f
++, imm
, size
);
1075 fail_line_pointer
= input_line_pointer
;
1076 input_line_pointer
= ilp
;
1082 mul_reg_reg_opr (const struct instruction
*insn
)
1084 char *ilp
= input_line_pointer
;
1087 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1090 if (!lex_match (','))
1094 if (!lex_reg_name (REG_BIT_Dn
, &Dj
))
1097 if (!lex_match (','))
1103 if (!lex_opr (buffer
, &n_bytes
, &exp
, true))
1106 int size
= size_from_suffix (insn
, 0);
1108 char *f
= s12z_new_insn (insn
->page
+ 1 + n_bytes
);
1109 if (insn
->page
== 2)
1110 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1112 number_to_chars_bigendian (f
++, insn
->opc
+ Dd
, 1);
1114 const char *dot
= strchrnul (insn
->name
, '.');
1124 as_fatal (_("BAD MUL"));
1131 number_to_chars_bigendian (f
++, mb
, 1);
1133 emit_opr (f
, buffer
, n_bytes
, &exp
);
1138 fail_line_pointer
= input_line_pointer
;
1139 input_line_pointer
= ilp
;
1144 mul_reg_opr_opr (const struct instruction
*insn
)
1146 char *ilp
= input_line_pointer
;
1149 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1152 if (!lex_match (','))
1158 if (!lex_opr (buffer1
, &n_bytes1
, &exp1
, false))
1161 if (!lex_match (','))
1167 if (!lex_opr (buffer2
, &n_bytes2
, &exp2
, false))
1170 int size1
= size_from_suffix (insn
, 0);
1171 int size2
= size_from_suffix (insn
, 1);
1173 char *f
= s12z_new_insn (insn
->page
+ 1 + n_bytes1
+ n_bytes2
);
1174 if (insn
->page
== 2)
1175 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1177 number_to_chars_bigendian (f
++, insn
->opc
+ Dd
, 1);
1179 const char *dot
= strchrnul (insn
->name
, '.');
1189 as_fatal (_("BAD MUL"));
1193 mb
|= (size1
- 1) << 4;
1194 mb
|= (size2
- 1) << 2;
1195 number_to_chars_bigendian (f
++, mb
, 1);
1197 f
= emit_opr (f
, buffer1
, n_bytes1
, &exp1
);
1198 f
= emit_opr (f
, buffer2
, n_bytes2
, &exp2
);
1203 fail_line_pointer
= input_line_pointer
;
1204 input_line_pointer
= ilp
;
1209 #define REG_BIT_GRP0 \
1210 ((0x1U << REG_D2) | \
1211 (0x1U << REG_D3) | \
1212 (0x1U << REG_CCH) | \
1213 (0x1U << REG_CCL) | \
1214 (0x1U << REG_D0) | \
1217 #define REG_BIT_GRP1 \
1218 ((0x1U << REG_D4) | \
1219 (0x1U << REG_D5) | \
1220 (0x1U << REG_D6) | \
1221 (0x1U << REG_D7) | \
1225 static const uint8_t reg_map
[] =
1245 lex_reg_list (uint16_t grp
, uint16_t *reg_bits
)
1247 if (lex_match (','))
1250 if (!lex_reg_name (grp
, ®
))
1252 *reg_bits
|= 0x1u
<< reg
;
1253 lex_reg_list (grp
, reg_bits
);
1261 psh_pull (const struct instruction
*insn
)
1264 (0 == strcmp ("pul", insn
->name
)) ? 0x80: 0x00;
1266 if (lex_match_string ("all16b"))
1270 else if (lex_match_string ("all"))
1277 if (!lex_reg_name (REG_BIT_GRP1
| REG_BIT_GRP0
, ®1
))
1279 uint16_t admitted_group
= 0;
1281 if ((0x1U
<< reg1
) & REG_BIT_GRP1
)
1282 admitted_group
= REG_BIT_GRP1
;
1283 else if ((0x1U
<< reg1
) & REG_BIT_GRP0
)
1284 admitted_group
= REG_BIT_GRP0
;
1286 uint16_t reg_bits
= 0x1 << reg1
;
1287 if (!lex_reg_list (admitted_group
, ®_bits
))
1290 if (reg_bits
& REG_BIT_GRP1
)
1294 for (i
= 0; i
< 16; ++i
)
1296 if (reg_bits
& (0x1u
<< i
))
1301 char *f
= s12z_new_insn (2);
1302 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1303 number_to_chars_bigendian (f
++, pb
, 1);
1307 fail_line_pointer
= input_line_pointer
;
1313 tfr (const struct instruction
*insn
)
1316 if (!lex_reg_name (~0, ®1
))
1319 if (!lex_match (','))
1323 if (!lex_reg_name (~0, ®2
))
1326 if ( ((0 == strcasecmp ("sex", insn
->name
))
1327 || (0 == strcasecmp ("zex", insn
->name
)))
1328 && (registers
[reg2
].bytes
<= registers
[reg1
].bytes
))
1329 as_warn (_("Source register for %s is no larger than the destination register"),
1331 else if (reg1
== reg2
)
1332 as_warn (_("The destination and source registers are identical"));
1334 char *f
= s12z_new_insn (1 + insn
->page
);
1335 if (insn
->page
== 2)
1336 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1338 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1339 number_to_chars_bigendian (f
++, reg1
<< 4 | reg2
, 1);
1344 fail_line_pointer
= input_line_pointer
;
1349 imm8 (const struct instruction
*insn
)
1352 if (! lex_imm (&imm
))
1354 if (imm
> 127 || imm
< -128)
1356 as_bad (_("Immediate value %ld is out of range for instruction %s"),
1360 char *f
= s12z_new_insn (2);
1361 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1362 number_to_chars_bigendian (f
++, imm
, 1);
1368 reg_imm (const struct instruction
*insn
, int allowed_reg
)
1370 char *ilp
= input_line_pointer
;
1372 if (lex_reg_name (allowed_reg
, ®
))
1374 if (!lex_force_match (','))
1377 if (! lex_imm (&imm
))
1380 short size
= registers
[reg
].bytes
;
1381 char *f
= s12z_new_insn (insn
->page
+ size
);
1382 if (insn
->page
== 2)
1383 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1385 number_to_chars_bigendian (f
++, insn
->opc
+ reg
, 1);
1386 number_to_chars_bigendian (f
++, imm
, size
);
1391 fail_line_pointer
= input_line_pointer
;
1392 input_line_pointer
= ilp
;
1398 regd_imm (const struct instruction
*insn
)
1400 return reg_imm (insn
, REG_BIT_Dn
);
1404 regdxy_imm (const struct instruction
*insn
)
1406 return reg_imm (insn
, REG_BIT_Dn
| REG_BIT_XY
);
1411 regs_imm (const struct instruction
*insn
)
1413 return reg_imm (insn
, 0x1U
<< REG_S
);
1417 trap_imm (const struct instruction
*insn ATTRIBUTE_UNUSED
)
1420 if (! lex_imm (&imm
))
1423 if (imm
< 0x92 || imm
> 0xFF ||
1424 (imm
>= 0xA0 && imm
<= 0xA7) ||
1425 (imm
>= 0xB0 && imm
<= 0xB7))
1427 as_bad (_("trap value %ld is not valid"), imm
);
1432 char *f
= s12z_new_insn (2);
1433 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1434 number_to_chars_bigendian (f
++, imm
& 0xFF, 1);
1441 fail_line_pointer
= input_line_pointer
;
1447 /* Special one byte instruction CMP X, Y */
1449 regx_regy (const struct instruction
*insn
)
1452 if (lex_reg_name (0x1U
<< REG_X
, ®
))
1454 if (lex_force_match (','))
1456 if (lex_reg_name (0x1U
<< REG_Y
, ®
))
1458 char *f
= s12z_new_insn (1);
1459 number_to_chars_bigendian (f
, insn
->opc
, 1);
1467 /* Special one byte instruction SUB D6, X, Y */
1469 regd6_regx_regy (const struct instruction
*insn
)
1471 char *ilp
= input_line_pointer
;
1473 if (!lex_reg_name (0x1U
<< REG_D6
, ®
))
1476 if (!lex_match (','))
1479 if (!lex_reg_name (0x1U
<< REG_X
, ®
))
1482 if (!lex_match (','))
1485 if (!lex_reg_name (0x1U
<< REG_Y
, ®
))
1488 char *f
= s12z_new_insn (1);
1489 number_to_chars_bigendian (f
, insn
->opc
, 1);
1493 fail_line_pointer
= input_line_pointer
;
1494 input_line_pointer
= ilp
;
1498 /* Special one byte instruction SUB D6, Y, X */
1500 regd6_regy_regx (const struct instruction
*insn
)
1502 char *ilp
= input_line_pointer
;
1504 if (!lex_reg_name (0x1U
<< REG_D6
, ®
))
1507 if (!lex_match (','))
1510 if (!lex_reg_name (0x1U
<< REG_Y
, ®
))
1513 if (!lex_match (','))
1516 if (!lex_reg_name (0x1U
<< REG_X
, ®
))
1519 char *f
= s12z_new_insn (1);
1520 number_to_chars_bigendian (f
, insn
->opc
, 1);
1524 fail_line_pointer
= input_line_pointer
;
1525 input_line_pointer
= ilp
;
1530 reg_opr (const struct instruction
*insn
, int allowed_regs
,
1533 char *ilp
= input_line_pointer
;
1535 if (lex_reg_name (allowed_regs
, ®
))
1537 if (!lex_force_match (','))
1543 if (lex_opr (buffer
, &n_bytes
, &exp
, immediate_ok
))
1545 /* Large constant direct values are more efficiently encoded as ext24 mode.
1546 Otherwise a decision has to be deferred to a relax. */
1547 if (exp
.X_op
== O_constant
1548 && buffer
[0] == 0xFA
1549 && insn
->alt_opc
!= 0)
1551 char *f
= s12z_new_insn (4);
1553 /* I don't think there are any instances of page 2 opcodes in this case */
1554 gas_assert (insn
->page
== 1);
1556 number_to_chars_bigendian (f
++, insn
->alt_opc
+ reg
, 1);
1558 emit_ext24 (f
, exp
.X_add_number
);
1562 char *f
= s12z_new_insn (n_bytes
+ insn
->page
);
1564 if (insn
->page
== 2)
1565 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
1567 number_to_chars_bigendian (f
++, insn
->opc
+ reg
, 1);
1569 emit_opr (f
, buffer
, n_bytes
, &exp
);
1577 fail_line_pointer
= input_line_pointer
;
1578 input_line_pointer
= ilp
;
1584 regdxy_opr_dest (const struct instruction
*insn
)
1586 return reg_opr (insn
, REG_BIT_Dn
| REG_BIT_XY
, false);
1590 regdxy_opr_src (const struct instruction
*insn
)
1592 return reg_opr (insn
, REG_BIT_Dn
| REG_BIT_XY
, true);
1597 regd_opr (const struct instruction
*insn
)
1599 return reg_opr (insn
, REG_BIT_Dn
, true);
1603 /* OP0: S; OP1: destination OPR */
1605 regs_opr_dest (const struct instruction
*insn
)
1607 return reg_opr (insn
, 0x1U
<< REG_S
, false);
1610 /* OP0: S; OP1: source OPR */
1612 regs_opr_src (const struct instruction
*insn
)
1614 return reg_opr (insn
, 0x1U
<< REG_S
, true);
1618 imm_opr (const struct instruction
*insn
)
1620 char *ilp
= input_line_pointer
;
1622 if (!lex_imm (&imm
))
1625 if (!lex_match (','))
1631 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
1634 int size
= size_from_suffix (insn
, 0);
1635 char *f
= s12z_new_insn (1 + n_bytes
+ size
);
1636 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1639 for (i
= 0; i
< size
; ++i
)
1640 number_to_chars_bigendian (f
++, imm
>> (CHAR_BIT
* (size
- i
- 1)), 1);
1642 emit_opr (f
, buffer
, n_bytes
, &exp
);
1647 fail_line_pointer
= input_line_pointer
;
1648 input_line_pointer
= ilp
;
1653 opr_opr (const struct instruction
*insn
)
1655 char *ilp
= input_line_pointer
;
1660 if (!lex_opr (buffer1
, &n_bytes1
, &exp1
, false))
1664 if (!lex_match (','))
1670 if (!lex_opr (buffer2
, &n_bytes2
, &exp2
, false))
1673 char *f
= s12z_new_insn (1 + n_bytes1
+ n_bytes2
);
1674 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1676 f
= emit_opr (f
, buffer1
, n_bytes1
, &exp1
);
1677 f
= emit_opr (f
, buffer2
, n_bytes2
, &exp2
);
1682 fail_line_pointer
= input_line_pointer
;
1683 input_line_pointer
= ilp
;
1688 reg67sxy_opr (const struct instruction
*insn
)
1691 if (!lex_reg_name (REG_BIT_XYS
| (0x1U
<< REG_D6
) | (0x1U
<< REG_D7
), ®
))
1694 if (!lex_match (','))
1700 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
1703 char *f
= s12z_new_insn (1 + n_bytes
);
1704 number_to_chars_bigendian (f
++, insn
->opc
+ reg
- REG_D6
, 1);
1705 emit_opr (f
, buffer
, n_bytes
, &exp
);
1711 rotate (const struct instruction
*insn
, short dir
)
1716 if (lex_opr (buffer
, &n_bytes
, &exp
, false))
1718 char *f
= s12z_new_insn (n_bytes
+ 2);
1719 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1720 int size
= size_from_suffix (insn
, 0);
1727 number_to_chars_bigendian (f
++, sb
, 1);
1728 emit_opr (f
, buffer
, n_bytes
, &exp
);
1737 rol (const struct instruction
*insn
)
1739 return rotate (insn
, 1);
1743 ror (const struct instruction
*insn
)
1745 return rotate (insn
, 0);
1749 /* Shift instruction with a register operand and an immediate #1 or #2
1750 left = 1; right = 0;
1751 logical = 0; arithmetic = 1;
1754 lex_shift_reg_imm1 (const struct instruction
*insn
, short type
, short dir
)
1757 This function is highly unusual and a bit wierd!
1758 It first matches the input against a register {d0, d1, ... d7} followed by an immediate
1760 Then, it rewinds the input and parses it again as a OPR.
1762 char *ilp
= input_line_pointer
;
1765 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1770 if (!lex_match (','))
1774 if (!lex_imm (&imm
))
1777 if (imm
!= 1 && imm
!= 2)
1779 input_line_pointer
= ilp
;
1781 /* Now parse the first operand again */
1787 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
1790 gas_assert (n_bytes
== 1);
1798 char *f
= s12z_new_insn (3);
1799 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1800 number_to_chars_bigendian (f
++, sb
, 1);
1801 emit_opr (f
, buffer
, n_bytes
, &exp
);
1806 fail_line_pointer
= input_line_pointer
;
1807 input_line_pointer
= ilp
;
1811 /* Shift instruction with a register operand.
1812 left = 1; right = 0;
1813 logical = 0; arithmetic = 1; */
1815 lex_shift_reg (const struct instruction
*insn
, short type
, short dir
)
1818 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1823 if (!lex_match (','))
1826 if (!lex_reg_name (REG_BIT_Dn
, &Ds
))
1831 if (!lex_match (','))
1839 if (lex_reg_name (REG_BIT_Dn
, &Dn
))
1841 char *f
= s12z_new_insn (3);
1842 number_to_chars_bigendian (f
++, insn
->opc
| Dd
, 1);
1843 number_to_chars_bigendian (f
++, sb
, 1);
1846 number_to_chars_bigendian (f
++, xb
, 1);
1850 else if (lex_imm (&imm
))
1852 if (imm
< 0 || imm
> 31)
1854 as_bad (_("Shift value should be in the range [0,31]"));
1859 if (imm
== 1 || imm
== 2)
1866 sb
|= (imm
& 0x01) << 3;
1869 char *f
= s12z_new_insn (n_bytes
);
1870 number_to_chars_bigendian (f
++, insn
->opc
| Dd
, 1);
1871 number_to_chars_bigendian (f
++, sb
, 1);
1876 number_to_chars_bigendian (f
++, xb
, 1);
1883 fail_line_pointer
= input_line_pointer
;
1888 impute_shift_dir_and_type (const struct instruction
*insn
, short *type
, short *dir
)
1892 switch (insn
->name
[0])
1901 as_fatal (_("Bad shift mode"));
1905 switch (insn
->name
[2])
1914 as_fatal (_("Bad shift *direction"));
1919 /* Shift instruction with a OPR operand */
1921 shift_two_operand (const struct instruction
*insn
)
1924 char *ilp
= input_line_pointer
;
1928 impute_shift_dir_and_type (insn
, &type
, &dir
);
1932 int size
= size_from_suffix (insn
, 0);
1938 if (!lex_opr (buffer
, &n_opr_bytes
, &exp
, false))
1941 if (!lex_match (','))
1945 if (!lex_imm (&imm
))
1948 if (imm
!= 1 && imm
!= 2)
1954 char *f
= s12z_new_insn (2 + n_opr_bytes
);
1955 number_to_chars_bigendian (f
++, insn
->opc
, 1);
1956 number_to_chars_bigendian (f
++, sb
, 1);
1957 emit_opr (f
, buffer
, n_opr_bytes
, &exp
);
1962 fail_line_pointer
= input_line_pointer
;
1963 input_line_pointer
= ilp
;
1967 /* Shift instruction with a OPR operand */
1969 shift_opr_imm (const struct instruction
*insn
)
1971 char *ilp
= input_line_pointer
;
1975 impute_shift_dir_and_type (insn
, &type
, &dir
);
1978 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
1981 if (!lex_match (','))
1990 if (!lex_opr (buffer1
, &n_opr_bytes1
, &exp1
, false))
1993 n_bytes
+= n_opr_bytes1
;
1994 if (!lex_match (','))
1998 int n_opr_bytes2
= 0;
2001 bool immediate
= false;
2006 else if (!lex_opr (buffer2
, &n_opr_bytes2
, &exp2
, false))
2011 int size
= size_from_suffix (insn
, 0);
2021 if (imm
== 2 || imm
== 1)
2036 n_bytes
+= n_opr_bytes2
;
2040 char *f
= s12z_new_insn (n_bytes
);
2041 number_to_chars_bigendian (f
++, insn
->opc
| Dd
, 1);
2042 number_to_chars_bigendian (f
++, sb
, 1);
2043 f
= emit_opr (f
, buffer1
, n_opr_bytes1
, &exp1
);
2046 if (imm
!= 1 && imm
!= 2)
2048 number_to_chars_bigendian (f
++, 0x70 | (imm
>> 1), 1);
2053 f
= emit_opr (f
, buffer2
, n_opr_bytes2
, &exp2
);
2059 fail_line_pointer
= input_line_pointer
;
2060 input_line_pointer
= ilp
;
2064 /* Shift instruction with a register operand */
2066 shift_reg (const struct instruction
*insn
)
2070 impute_shift_dir_and_type (insn
, &type
, &dir
);
2072 if (lex_shift_reg_imm1 (insn
, type
, dir
))
2075 return lex_shift_reg (insn
, type
, dir
);
2079 bm_regd_imm (const struct instruction
*insn
)
2081 char *ilp
= input_line_pointer
;
2083 if (!lex_reg_name (REG_BIT_Dn
, &Di
))
2086 if (!lex_match (','))
2090 if (!lex_imm (&imm
))
2094 uint8_t bm
= imm
<< 3;
2097 char *f
= s12z_new_insn (2);
2098 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2099 number_to_chars_bigendian (f
++, bm
, 1);
2104 fail_line_pointer
= input_line_pointer
;
2105 input_line_pointer
= ilp
;
2110 bm_opr_reg (const struct instruction
*insn
)
2112 char *ilp
= input_line_pointer
;
2118 if (!lex_opr (buffer
, &n_opr_bytes
, &exp
, false))
2121 if (!lex_match (','))
2125 if (!lex_reg_name (REG_BIT_Dn
, &Dn
))
2128 uint8_t bm
= Dn
<< 4;
2129 int size
= size_from_suffix (insn
, 0);
2130 bm
|= (size
- 1) << 2;
2133 char *f
= s12z_new_insn (2 + n_opr_bytes
);
2134 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2135 number_to_chars_bigendian (f
++, bm
, 1);
2137 emit_opr (f
, buffer
, n_opr_bytes
, &exp
);
2142 fail_line_pointer
= input_line_pointer
;
2143 input_line_pointer
= ilp
;
2149 bm_opr_imm (const struct instruction
*insn
)
2151 char *ilp
= input_line_pointer
;
2157 if (!lex_opr (buffer
, &n_opr_bytes
, &exp
, false))
2160 if (!lex_match (','))
2165 if (!lex_imm (&imm
))
2168 int size
= size_from_suffix (insn
, 0);
2170 if (imm
< 0 || imm
>= size
* 8)
2172 as_bad (_("Immediate operand %ld is inappropriate for size of instruction"), imm
);
2181 bm
|= (imm
& 0x07) << 4;
2185 char *f
= s12z_new_insn (2 + n_opr_bytes
);
2186 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2187 number_to_chars_bigendian (f
++, bm
, 1);
2188 emit_opr (f
, buffer
, n_opr_bytes
, &exp
);
2193 fail_line_pointer
= input_line_pointer
;
2194 input_line_pointer
= ilp
;
2200 bm_regd_reg (const struct instruction
*insn
)
2202 char *ilp
= input_line_pointer
;
2204 if (!lex_reg_name (REG_BIT_Dn
, &Di
))
2207 if (!lex_match (','))
2211 if (!lex_reg_name (REG_BIT_Dn
, &Dn
))
2214 uint8_t bm
= Dn
<< 4;
2217 uint8_t xb
= Di
| 0xb8;
2219 char *f
= s12z_new_insn (3);
2220 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2221 number_to_chars_bigendian (f
++, bm
, 1);
2222 number_to_chars_bigendian (f
++, xb
, 1);
2227 fail_line_pointer
= input_line_pointer
;
2228 input_line_pointer
= ilp
;
2237 bf_reg_opr_imm (const struct instruction
*insn
, short ie
)
2239 char *ilp
= input_line_pointer
;
2241 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
2244 if (!lex_match (','))
2251 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2254 if (!lex_match (','))
2258 if (!lex_imm (&width
))
2261 if (width
< 0 || width
> 31)
2263 as_bad (_("Invalid width value for %s"), insn
->name
);
2267 if (!lex_match (':'))
2271 if (!lex_constant (&offset
))
2274 if (offset
< 0 || offset
> 31)
2276 as_bad (_("Invalid offset value for %s"), insn
->name
);
2280 uint8_t i1
= width
<< 5;
2283 int size
= size_from_suffix (insn
, 0);
2284 uint8_t bb
= ie
? 0x80 : 0x00;
2286 bb
|= (size
- 1) << 2;
2289 char *f
= s12z_new_insn (4 + n_bytes
);
2290 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2291 number_to_chars_bigendian (f
++, 0x08 | Dd
, 1);
2292 number_to_chars_bigendian (f
++, bb
, 1);
2293 number_to_chars_bigendian (f
++, i1
, 1);
2295 emit_opr (f
, buffer
, n_bytes
, &exp
);
2300 fail_line_pointer
= input_line_pointer
;
2301 input_line_pointer
= ilp
;
2307 bf_opr_reg_imm (const struct instruction
*insn
, short ie
)
2309 char *ilp
= input_line_pointer
;
2313 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2316 if (!lex_match (','))
2320 if (!lex_reg_name (REG_BIT_Dn
, &Ds
))
2323 if (!lex_match (','))
2327 if (!lex_imm (&width
))
2330 if (width
< 0 || width
> 31)
2332 as_bad (_("Invalid width value for %s"), insn
->name
);
2336 if (!lex_match (':'))
2340 if (!lex_constant (&offset
))
2343 if (offset
< 0 || offset
> 31)
2345 as_bad (_("Invalid offset value for %s"), insn
->name
);
2349 uint8_t i1
= width
<< 5;
2352 int size
= size_from_suffix (insn
, 0);
2353 uint8_t bb
= ie
? 0x80 : 0x00;
2355 bb
|= (size
- 1) << 2;
2358 char *f
= s12z_new_insn (4 + n_bytes
);
2359 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2360 number_to_chars_bigendian (f
++, 0x08 | Ds
, 1);
2361 number_to_chars_bigendian (f
++, bb
, 1);
2362 number_to_chars_bigendian (f
++, i1
, 1);
2364 emit_opr (f
, buffer
, n_bytes
, &exp
);
2369 fail_line_pointer
= input_line_pointer
;
2370 input_line_pointer
= ilp
;
2377 bf_reg_reg_imm (const struct instruction
*insn
, short ie
)
2379 char *ilp
= input_line_pointer
;
2381 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
2384 if (!lex_match (','))
2388 if (!lex_reg_name (REG_BIT_Dn
, &Ds
))
2391 if (!lex_match (','))
2395 if (!lex_imm (&width
))
2398 if (width
< 0 || width
> 31)
2400 as_bad (_("Invalid width value for %s"), insn
->name
);
2404 if (!lex_match (':'))
2408 if (!lex_constant (&offset
))
2411 if (offset
< 0 || offset
> 31)
2413 as_bad (_("Invalid offset value for %s"), insn
->name
);
2417 uint8_t bb
= ie
? 0x80 : 0x00;
2422 uint8_t i1
= width
<< 5;
2425 char *f
= s12z_new_insn (4);
2426 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2427 number_to_chars_bigendian (f
++, 0x08 | Dd
, 1);
2428 number_to_chars_bigendian (f
++, bb
, 1);
2429 number_to_chars_bigendian (f
++, i1
, 1);
2434 fail_line_pointer
= input_line_pointer
;
2435 input_line_pointer
= ilp
;
2440 bf_reg_reg_reg (const struct instruction
*insn ATTRIBUTE_UNUSED
, 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_reg_name ((0x01u
<< REG_D2
) |
2465 uint8_t bb
= ie
? 0x80 : 0x00;
2469 char *f
= s12z_new_insn (3);
2470 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2471 number_to_chars_bigendian (f
++, 0x08 | Dd
, 1);
2472 number_to_chars_bigendian (f
++, bb
, 1);
2477 fail_line_pointer
= input_line_pointer
;
2478 input_line_pointer
= ilp
;
2483 bf_opr_reg_reg (const struct instruction
*insn
, short ie
)
2485 char *ilp
= input_line_pointer
;
2490 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2493 if (!lex_match (','))
2498 if (!lex_reg_name (REG_BIT_Dn
, &Ds
))
2501 if (!lex_match (','))
2506 if (!lex_reg_name ((0x01u
<< REG_D2
) |
2513 int size
= size_from_suffix (insn
, 0);
2514 uint8_t bb
= ie
? 0x80 : 0x00;
2517 bb
|= (size
- 1) << 2;
2519 char *f
= s12z_new_insn (3 + n_bytes
);
2520 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2521 number_to_chars_bigendian (f
++, 0x08 | Ds
, 1);
2522 number_to_chars_bigendian (f
++, bb
, 1);
2524 emit_opr (f
, buffer
, n_bytes
, &exp
);
2529 fail_line_pointer
= input_line_pointer
;
2530 input_line_pointer
= ilp
;
2536 bf_reg_opr_reg (const struct instruction
*insn
, short ie
)
2538 char *ilp
= input_line_pointer
;
2540 if (!lex_reg_name (REG_BIT_Dn
, &Dd
))
2543 if (!lex_match (','))
2550 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2553 if (!lex_match (','))
2557 if (!lex_reg_name ((0x01u
<< REG_D2
) |
2564 int size
= size_from_suffix (insn
, 0);
2565 uint8_t bb
= ie
? 0x80 : 0x00;
2568 bb
|= (size
- 1) << 2;
2570 char *f
= s12z_new_insn (3 + n_bytes
);
2571 number_to_chars_bigendian (f
++, PAGE2_PREBYTE
, 1);
2572 number_to_chars_bigendian (f
++, 0x08 | Dd
, 1);
2573 number_to_chars_bigendian (f
++, bb
, 1);
2575 emit_opr (f
, buffer
, n_bytes
, &exp
);
2580 fail_line_pointer
= input_line_pointer
;
2581 input_line_pointer
= ilp
;
2588 bfe_reg_reg_reg (const struct instruction
*insn
)
2590 return bf_reg_reg_reg (insn
, 0);
2594 bfi_reg_reg_reg (const struct instruction
*insn
)
2596 return bf_reg_reg_reg (insn
, 1);
2600 bfe_reg_reg_imm (const struct instruction
*insn
)
2602 return bf_reg_reg_imm (insn
, 0);
2606 bfi_reg_reg_imm (const struct instruction
*insn
)
2608 return bf_reg_reg_imm (insn
, 1);
2613 bfe_reg_opr_reg (const struct instruction
*insn
)
2615 return bf_reg_opr_reg (insn
, 0);
2619 bfi_reg_opr_reg (const struct instruction
*insn
)
2621 return bf_reg_opr_reg (insn
, 1);
2626 bfe_opr_reg_reg (const struct instruction
*insn
)
2628 return bf_opr_reg_reg (insn
, 0);
2632 bfi_opr_reg_reg (const struct instruction
*insn
)
2634 return bf_opr_reg_reg (insn
, 1);
2638 bfe_reg_opr_imm (const struct instruction
*insn
)
2640 return bf_reg_opr_imm (insn
, 0);
2644 bfi_reg_opr_imm (const struct instruction
*insn
)
2646 return bf_reg_opr_imm (insn
, 1);
2650 bfe_opr_reg_imm (const struct instruction
*insn
)
2652 return bf_opr_reg_imm (insn
, 0);
2656 bfi_opr_reg_imm (const struct instruction
*insn
)
2658 return bf_opr_reg_imm (insn
, 1);
2665 tb_reg_rel (const struct instruction
*insn
)
2667 char *ilp
= input_line_pointer
;
2670 if (!lex_reg_name (REG_BIT_Dn
| REG_BIT_XY
, ®
))
2673 if (!lex_match (','))
2676 bool long_displacement
;
2678 if (! lex_15_bit_offset (&long_displacement
, &exp
))
2682 if (reg
== REG_X
|| reg
== REG_Y
)
2693 if (0 == strncmp (insn
->name
+ 2, "ne", 2))
2695 else if (0 == strncmp (insn
->name
+ 2, "eq", 2))
2697 else if (0 == strncmp (insn
->name
+ 2, "pl", 2))
2699 else if (0 == strncmp (insn
->name
+ 2, "mi", 2))
2701 else if (0 == strncmp (insn
->name
+ 2, "gt", 2))
2703 else if (0 == strncmp (insn
->name
+ 2, "le", 2))
2706 switch (insn
->name
[0])
2718 char *f
= s12z_new_insn (long_displacement
? 4 : 3);
2719 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2720 number_to_chars_bigendian (f
++, lb
, 1);
2722 emit_15_bit_offset (f
, 4, &exp
);
2727 fail_line_pointer
= input_line_pointer
;
2728 input_line_pointer
= ilp
;
2734 tb_opr_rel (const struct instruction
*insn
)
2736 char *ilp
= input_line_pointer
;
2741 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2744 if (!lex_match (','))
2747 bool long_displacement
;
2749 if (! lex_15_bit_offset (&long_displacement
, &exp2
))
2754 if (0 == strncmp (insn
->name
+ 2, "ne", 2))
2756 else if (0 == strncmp (insn
->name
+ 2, "eq", 2))
2758 else if (0 == strncmp (insn
->name
+ 2, "pl", 2))
2760 else if (0 == strncmp (insn
->name
+ 2, "mi", 2))
2762 else if (0 == strncmp (insn
->name
+ 2, "gt", 2))
2764 else if (0 == strncmp (insn
->name
+ 2, "le", 2))
2767 switch (insn
->name
[0])
2779 int size
= size_from_suffix (insn
, 0);
2783 char *f
= s12z_new_insn (n_bytes
+ (long_displacement
? 4 : 3));
2784 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2785 number_to_chars_bigendian (f
++, lb
, 1);
2786 f
= emit_opr (f
, buffer
, n_bytes
, &exp
);
2788 emit_15_bit_offset (f
, n_bytes
+ 4, &exp2
);
2793 fail_line_pointer
= input_line_pointer
;
2794 input_line_pointer
= ilp
;
2802 test_br_reg_reg_rel (const struct instruction
*insn
)
2804 char *ilp
= input_line_pointer
;
2807 if (!lex_reg_name (REG_BIT_Dn
, &Di
))
2810 if (!lex_match (','))
2815 if (!lex_reg_name (REG_BIT_Dn
, &Dn
))
2818 if (!lex_match (','))
2822 bool long_displacement
;
2824 if (! lex_15_bit_offset (&long_displacement
, &exp
))
2833 char *f
= s12z_new_insn (long_displacement
? 5 : 4);
2834 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2835 number_to_chars_bigendian (f
++, bm
, 1);
2836 number_to_chars_bigendian (f
++, xb
, 1);
2838 emit_15_bit_offset (f
, 5, &exp
);
2843 fail_line_pointer
= input_line_pointer
;
2844 input_line_pointer
= ilp
;
2849 test_br_opr_reg_rel (const struct instruction
*insn
)
2851 char *ilp
= input_line_pointer
;
2856 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2859 if (!lex_match (','))
2863 if (!lex_reg_name (REG_BIT_Dn
, &Dn
))
2866 if (!lex_match (','))
2871 int size
= size_from_suffix (insn
, 0);
2872 bm
|= (size
-1) << 2;
2874 bool long_displacement
;
2877 if (! lex_15_bit_offset (&long_displacement
, &exp2
))
2880 int n
= n_bytes
+ (long_displacement
? 4 : 3);
2881 char *f
= s12z_new_insn (n
);
2882 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2883 number_to_chars_bigendian (f
++, bm
, 1);
2884 f
= emit_opr (f
, buffer
, n_bytes
, &exp
);
2886 emit_15_bit_offset (f
, n
, &exp2
);
2891 fail_line_pointer
= input_line_pointer
;
2892 input_line_pointer
= ilp
;
2898 test_br_opr_imm_rel (const struct instruction
*insn
)
2900 char *ilp
= input_line_pointer
;
2905 if (!lex_opr (buffer
, &n_bytes
, &exp
, false))
2908 if (!lex_match (','))
2912 if (!lex_imm (&imm
))
2915 if (imm
< 0 || imm
> 31)
2918 if (!lex_match (','))
2921 bool long_displacement
;
2923 if (! lex_15_bit_offset (&long_displacement
, &exp2
))
2926 int size
= size_from_suffix (insn
, 0);
2929 bm
|= (imm
& 0x07) << 4;
2930 bm
|= (imm
>> 3) & 0x03;
2936 char *f
= s12z_new_insn (n_bytes
+ (long_displacement
? 4 : 3));
2937 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2938 number_to_chars_bigendian (f
++, bm
, 1);
2939 f
= emit_opr (f
, buffer
, n_bytes
, &exp
);
2941 emit_15_bit_offset (f
, n_bytes
+ 4, &exp2
);
2946 fail_line_pointer
= input_line_pointer
;
2947 input_line_pointer
= ilp
;
2953 test_br_reg_imm_rel (const struct instruction
*insn
)
2955 char *ilp
= input_line_pointer
;
2958 if (!lex_reg_name (REG_BIT_Dn
, &Di
))
2961 if (!lex_match (','))
2965 if (!lex_imm (&imm
))
2968 if (imm
< 0 || imm
> 31)
2972 if (!lex_match (','))
2975 bool long_displacement
;
2977 if (! lex_15_bit_offset (&long_displacement
, &exp
))
2983 char *f
= s12z_new_insn (long_displacement
? 4 : 3);
2984 number_to_chars_bigendian (f
++, insn
->opc
, 1);
2985 number_to_chars_bigendian (f
++, bm
, 1);
2987 emit_15_bit_offset (f
, 4, &exp
);
2992 fail_line_pointer
= input_line_pointer
;
2993 input_line_pointer
= ilp
;
3000 static const struct instruction opcodes
[] = {
3001 {"bgnd", 1, 0x00, no_operands
, 0},
3002 {"nop", 1, 0x01, no_operands
, 0},
3004 {"brclr", 1, 0x02, test_br_reg_reg_rel
, 0},
3005 {"brset", 1, 0x03, test_br_reg_reg_rel
, 0},
3007 {"brclr", 1, 0x02, test_br_reg_imm_rel
, 0},
3008 {"brset", 1, 0x03, test_br_reg_imm_rel
, 0},
3010 {"brclr.b", 1, 0x02, test_br_opr_reg_rel
, 0},
3011 {"brclr.w", 1, 0x02, test_br_opr_reg_rel
, 0},
3012 {"brclr.l", 1, 0x02, test_br_opr_reg_rel
, 0},
3014 {"brset.b", 1, 0x03, test_br_opr_reg_rel
, 0},
3015 {"brset.w", 1, 0x03, test_br_opr_reg_rel
, 0},
3016 {"brset.l", 1, 0x03, test_br_opr_reg_rel
, 0},
3018 {"brclr.b", 1, 0x02, test_br_opr_imm_rel
, 0},
3019 {"brclr.w", 1, 0x02, test_br_opr_imm_rel
, 0},
3020 {"brclr.l", 1, 0x02, test_br_opr_imm_rel
, 0},
3022 {"brset.b", 1, 0x03, test_br_opr_imm_rel
, 0},
3023 {"brset.w", 1, 0x03, test_br_opr_imm_rel
, 0},
3024 {"brset.l", 1, 0x03, test_br_opr_imm_rel
, 0},
3026 {"psh", 1, 0x04, psh_pull
, 0},
3027 {"pul", 1, 0x04, psh_pull
, 0},
3029 {"rts", 1, 0x05, no_operands
, 0},
3030 {"lea", 1, 0x06, reg67sxy_opr
, 0},
3032 {"dbne", 1, 0x0b, tb_reg_rel
, 0},
3033 {"dbeq", 1, 0x0b, tb_reg_rel
, 0},
3034 {"dbpl", 1, 0x0b, tb_reg_rel
, 0},
3035 {"dbmi", 1, 0x0b, tb_reg_rel
, 0},
3036 {"dbgt", 1, 0x0b, tb_reg_rel
, 0},
3037 {"dble", 1, 0x0b, tb_reg_rel
, 0},
3039 {"dbne.b", 1, 0x0b, tb_opr_rel
, 0},
3040 {"dbeq.b", 1, 0x0b, tb_opr_rel
, 0},
3041 {"dbpl.b", 1, 0x0b, tb_opr_rel
, 0},
3042 {"dbmi.b", 1, 0x0b, tb_opr_rel
, 0},
3043 {"dbgt.b", 1, 0x0b, tb_opr_rel
, 0},
3044 {"dble.b", 1, 0x0b, tb_opr_rel
, 0},
3046 {"dbne.w", 1, 0x0b, tb_opr_rel
, 0},
3047 {"dbeq.w", 1, 0x0b, tb_opr_rel
, 0},
3048 {"dbpl.w", 1, 0x0b, tb_opr_rel
, 0},
3049 {"dbmi.w", 1, 0x0b, tb_opr_rel
, 0},
3050 {"dbgt.w", 1, 0x0b, tb_opr_rel
, 0},
3051 {"dble.w", 1, 0x0b, tb_opr_rel
, 0},
3053 {"dbne.p", 1, 0x0b, tb_opr_rel
, 0},
3054 {"dbeq.p", 1, 0x0b, tb_opr_rel
, 0},
3055 {"dbpl.p", 1, 0x0b, tb_opr_rel
, 0},
3056 {"dbmi.p", 1, 0x0b, tb_opr_rel
, 0},
3057 {"dbgt.p", 1, 0x0b, tb_opr_rel
, 0},
3058 {"dble.p", 1, 0x0b, tb_opr_rel
, 0},
3060 {"dbne.l", 1, 0x0b, tb_opr_rel
, 0},
3061 {"dbeq.l", 1, 0x0b, tb_opr_rel
, 0},
3062 {"dbpl.l", 1, 0x0b, tb_opr_rel
, 0},
3063 {"dbmi.l", 1, 0x0b, tb_opr_rel
, 0},
3064 {"dbgt.l", 1, 0x0b, tb_opr_rel
, 0},
3065 {"dble.l", 1, 0x0b, tb_opr_rel
, 0},
3067 {"tbne", 1, 0x0b, tb_reg_rel
, 0},
3068 {"tbeq", 1, 0x0b, tb_reg_rel
, 0},
3069 {"tbpl", 1, 0x0b, tb_reg_rel
, 0},
3070 {"tbmi", 1, 0x0b, tb_reg_rel
, 0},
3071 {"tbgt", 1, 0x0b, tb_reg_rel
, 0},
3072 {"tble", 1, 0x0b, tb_reg_rel
, 0},
3074 {"tbne.b", 1, 0x0b, tb_opr_rel
, 0},
3075 {"tbeq.b", 1, 0x0b, tb_opr_rel
, 0},
3076 {"tbpl.b", 1, 0x0b, tb_opr_rel
, 0},
3077 {"tbmi.b", 1, 0x0b, tb_opr_rel
, 0},
3078 {"tbgt.b", 1, 0x0b, tb_opr_rel
, 0},
3079 {"tble.b", 1, 0x0b, tb_opr_rel
, 0},
3081 {"tbne.w", 1, 0x0b, tb_opr_rel
, 0},
3082 {"tbeq.w", 1, 0x0b, tb_opr_rel
, 0},
3083 {"tbpl.w", 1, 0x0b, tb_opr_rel
, 0},
3084 {"tbmi.w", 1, 0x0b, tb_opr_rel
, 0},
3085 {"tbgt.w", 1, 0x0b, tb_opr_rel
, 0},
3086 {"tble.w", 1, 0x0b, tb_opr_rel
, 0},
3088 {"tbne.p", 1, 0x0b, tb_opr_rel
, 0},
3089 {"tbeq.p", 1, 0x0b, tb_opr_rel
, 0},
3090 {"tbpl.p", 1, 0x0b, tb_opr_rel
, 0},
3091 {"tbmi.p", 1, 0x0b, tb_opr_rel
, 0},
3092 {"tbgt.p", 1, 0x0b, tb_opr_rel
, 0},
3093 {"tble.p", 1, 0x0b, tb_opr_rel
, 0},
3095 {"tbne.l", 1, 0x0b, tb_opr_rel
, 0},
3096 {"tbeq.l", 1, 0x0b, tb_opr_rel
, 0},
3097 {"tbpl.l", 1, 0x0b, tb_opr_rel
, 0},
3098 {"tbmi.l", 1, 0x0b, tb_opr_rel
, 0},
3099 {"tbgt.l", 1, 0x0b, tb_opr_rel
, 0},
3100 {"tble.l", 1, 0x0b, tb_opr_rel
, 0},
3102 {"mov.b", 1, 0x0c, imm_opr
, 0},
3103 {"mov.w", 1, 0x0d, imm_opr
, 0},
3104 {"mov.p", 1, 0x0e, imm_opr
, 0},
3105 {"mov.l", 1, 0x0f, imm_opr
, 0},
3107 {"rol", 1, 0x10, rol
, 0},
3108 {"rol.b", 1, 0x10, rol
, 0},
3109 {"rol.w", 1, 0x10, rol
, 0},
3110 {"rol.p", 1, 0x10, rol
, 0},
3111 {"rol.l", 1, 0x10, rol
, 0},
3113 {"ror", 1, 0x10, ror
, 0},
3114 {"ror.b", 1, 0x10, ror
, 0},
3115 {"ror.w", 1, 0x10, ror
, 0},
3116 {"ror.p", 1, 0x10, ror
, 0},
3117 {"ror.l", 1, 0x10, ror
, 0},
3119 {"lsl", 1, 0x10, shift_reg
, 0},
3120 {"lsr", 1, 0x10, shift_reg
, 0},
3121 {"asl", 1, 0x10, shift_reg
, 0},
3122 {"asr", 1, 0x10, shift_reg
, 0},
3124 {"lsl.b", 1, 0x10, shift_two_operand
, 0},
3125 {"lsl.w", 1, 0x10, shift_two_operand
, 0},
3126 {"lsl.p", 1, 0x10, shift_two_operand
, 0},
3127 {"lsl.l", 1, 0x10, shift_two_operand
, 0},
3128 {"asl.b", 1, 0x10, shift_two_operand
, 0},
3129 {"asl.w", 1, 0x10, shift_two_operand
, 0},
3130 {"asl.p", 1, 0x10, shift_two_operand
, 0},
3131 {"asl.l", 1, 0x10, shift_two_operand
, 0},
3133 {"lsr.b", 1, 0x10, shift_two_operand
, 0},
3134 {"lsr.w", 1, 0x10, shift_two_operand
, 0},
3135 {"lsr.p", 1, 0x10, shift_two_operand
, 0},
3136 {"lsr.l", 1, 0x10, shift_two_operand
, 0},
3137 {"asr.b", 1, 0x10, shift_two_operand
, 0},
3138 {"asr.w", 1, 0x10, shift_two_operand
, 0},
3139 {"asr.p", 1, 0x10, shift_two_operand
, 0},
3140 {"asr.l", 1, 0x10, shift_two_operand
, 0},
3142 {"lsl.b", 1, 0x10, shift_opr_imm
, 0},
3143 {"lsl.w", 1, 0x10, shift_opr_imm
, 0},
3144 {"lsl.p", 1, 0x10, shift_opr_imm
, 0},
3145 {"lsl.l", 1, 0x10, shift_opr_imm
, 0},
3146 {"asl.b", 1, 0x10, shift_opr_imm
, 0},
3147 {"asl.w", 1, 0x10, shift_opr_imm
, 0},
3148 {"asl.p", 1, 0x10, shift_opr_imm
, 0},
3149 {"asl.l", 1, 0x10, shift_opr_imm
, 0},
3151 {"lsr.b", 1, 0x10, shift_opr_imm
, 0},
3152 {"lsr.w", 1, 0x10, shift_opr_imm
, 0},
3153 {"lsr.p", 1, 0x10, shift_opr_imm
, 0},
3154 {"lsr.l", 1, 0x10, shift_opr_imm
, 0},
3155 {"asr.b", 1, 0x10, shift_opr_imm
, 0},
3156 {"asr.w", 1, 0x10, shift_opr_imm
, 0},
3157 {"asr.p", 1, 0x10, shift_opr_imm
, 0},
3158 {"asr.l", 1, 0x10, shift_opr_imm
, 0},
3160 {"mov.b", 1, 0x1c, opr_opr
, 0},
3161 {"mov.w", 1, 0x1d, opr_opr
, 0},
3162 {"mov.p", 1, 0x1e, opr_opr
, 0},
3163 {"mov.l", 1, 0x1f, opr_opr
, 0},
3165 {"bra", 1, 0x20, rel
, 0},
3166 {"bsr", 1, 0x21, rel
, 0},
3167 {"bhi", 1, 0x22, rel
, 0},
3168 {"bls", 1, 0x23, rel
, 0},
3169 {"bcc", 1, 0x24, rel
, 0},
3170 {"bhs", 1, 0x24, rel
, 0}, /* Alias for bcc */
3171 {"bcs", 1, 0x25, rel
, 0},
3172 {"blo", 1, 0x25, rel
, 0}, /* Alias for bcs */
3173 {"bne", 1, 0x26, rel
, 0},
3174 {"beq", 1, 0x27, rel
, 0},
3175 {"bvc", 1, 0x28, rel
, 0},
3176 {"bvs", 1, 0x29, rel
, 0},
3177 {"bpl", 1, 0x2a, rel
, 0},
3178 {"bmi", 1, 0x2b, rel
, 0},
3179 {"bge", 1, 0x2c, rel
, 0},
3180 {"blt", 1, 0x2d, rel
, 0},
3181 {"bgt", 1, 0x2e, rel
, 0},
3182 {"ble", 1, 0x2f, rel
, 0},
3184 {"inc", 1, 0x30, reg_inh
, 0},
3185 {"clr", 1, 0x38, reg_inh
, 0},
3186 {"dec", 1, 0x40, reg_inh
, 0},
3188 {"muls", 1, 0x48, mul_reg_reg_reg
, 0},
3189 {"mulu", 1, 0x48, mul_reg_reg_reg
, 0},
3191 {"muls.b", 1, 0x48, mul_reg_reg_opr
, 0},
3192 {"muls.w", 1, 0x48, mul_reg_reg_opr
, 0},
3193 {"muls.l", 1, 0x48, mul_reg_reg_opr
, 0},
3195 {"mulu.b", 1, 0x48, mul_reg_reg_opr
, 0},
3196 {"mulu.w", 1, 0x48, mul_reg_reg_opr
, 0},
3197 {"mulu.l", 1, 0x48, mul_reg_reg_opr
, 0},
3199 {"muls.b", 1, 0x48, mul_reg_reg_imm
, 0},
3200 {"muls.w", 1, 0x48, mul_reg_reg_imm
, 0},
3201 {"muls.l", 1, 0x48, mul_reg_reg_imm
, 0},
3203 {"mulu.b", 1, 0x48, mul_reg_reg_imm
, 0},
3204 {"mulu.w", 1, 0x48, mul_reg_reg_imm
, 0},
3205 {"mulu.l", 1, 0x48, mul_reg_reg_imm
, 0},
3207 {"muls.bb", 1, 0x48, mul_reg_opr_opr
, 0},
3208 {"muls.bw", 1, 0x48, mul_reg_opr_opr
, 0},
3209 {"muls.bp", 1, 0x48, mul_reg_opr_opr
, 0},
3210 {"muls.bl", 1, 0x48, mul_reg_opr_opr
, 0},
3212 {"muls.wb", 1, 0x48, mul_reg_opr_opr
, 0},
3213 {"muls.ww", 1, 0x48, mul_reg_opr_opr
, 0},
3214 {"muls.wp", 1, 0x48, mul_reg_opr_opr
, 0},
3215 {"muls.wl", 1, 0x48, mul_reg_opr_opr
, 0},
3217 {"muls.pb", 1, 0x48, mul_reg_opr_opr
, 0},
3218 {"muls.pw", 1, 0x48, mul_reg_opr_opr
, 0},
3219 {"muls.pp", 1, 0x48, mul_reg_opr_opr
, 0},
3220 {"muls.pl", 1, 0x48, mul_reg_opr_opr
, 0},
3222 {"muls.lb", 1, 0x48, mul_reg_opr_opr
, 0},
3223 {"muls.lw", 1, 0x48, mul_reg_opr_opr
, 0},
3224 {"muls.lp", 1, 0x48, mul_reg_opr_opr
, 0},
3225 {"muls.ll", 1, 0x48, mul_reg_opr_opr
, 0},
3227 {"mulu.bb", 1, 0x48, mul_reg_opr_opr
, 0},
3228 {"mulu.bw", 1, 0x48, mul_reg_opr_opr
, 0},
3229 {"mulu.bp", 1, 0x48, mul_reg_opr_opr
, 0},
3230 {"mulu.bl", 1, 0x48, mul_reg_opr_opr
, 0},
3232 {"mulu.wb", 1, 0x48, mul_reg_opr_opr
, 0},
3233 {"mulu.ww", 1, 0x48, mul_reg_opr_opr
, 0},
3234 {"mulu.wp", 1, 0x48, mul_reg_opr_opr
, 0},
3235 {"mulu.wl", 1, 0x48, mul_reg_opr_opr
, 0},
3237 {"mulu.pb", 1, 0x48, mul_reg_opr_opr
, 0},
3238 {"mulu.pw", 1, 0x48, mul_reg_opr_opr
, 0},
3239 {"mulu.pp", 1, 0x48, mul_reg_opr_opr
, 0},
3240 {"mulu.pl", 1, 0x48, mul_reg_opr_opr
, 0},
3242 {"mulu.lb", 1, 0x48, mul_reg_opr_opr
, 0},
3243 {"mulu.lw", 1, 0x48, mul_reg_opr_opr
, 0},
3244 {"mulu.lp", 1, 0x48, mul_reg_opr_opr
, 0},
3245 {"mulu.ll", 1, 0x48, mul_reg_opr_opr
, 0},
3247 {"add", 1, 0x50, regd_imm
, 0},
3248 {"and", 1, 0x58, regd_imm
, 0},
3250 {"add", 1, 0x60, regd_opr
, 0},
3251 {"and", 1, 0x68, regd_opr
, 0},
3253 {"sub", 1, 0x70, regd_imm
, 0},
3254 {"or", 1, 0x78, regd_imm
, 0},
3256 {"sub", 1, 0x80, regd_opr
, 0},
3257 {"or", 1, 0x88, regd_opr
, 0},
3259 {"ld", 1, 0x90, regdxy_imm
, 0},
3261 {"clr", 1, 0x9a, clr_xy
, 0},
3262 {"tfr", 1, 0x9e, tfr
, 0},
3263 {"zex", 1, 0x9e, tfr
, 0},
3265 {"ld", 1, 0xa0, regdxy_opr_src
, 0xb0},
3267 {"jmp", 1, 0xaa, opr
, 0xba},
3268 {"jsr", 1, 0xab, opr
, 0xbb},
3270 {"exg", 1, 0xae, tfr
, 0},
3271 {"sex", 1, 0xae, tfr
, 0},
3273 {"st", 1, 0xc0, regdxy_opr_dest
, 0xd0},
3275 {"andcc", 1, 0xce, imm8
, 0},
3276 {"orcc", 1, 0xde, imm8
, 0},
3278 {"inc.b", 1, 0x9c, opr
, 0},
3279 {"inc.w", 1, 0x9d, opr
, 0},
3280 {"inc.l", 1, 0x9f, opr
, 0},
3282 {"dec.b", 1, 0xac, opr
, 0},
3283 {"dec.w", 1, 0xad, opr
, 0},
3284 {"dec.l", 1, 0xaf, opr
, 0},
3286 {"clr.b", 1, 0xbc, opr
, 0},
3287 {"clr.w", 1, 0xbd, opr
, 0},
3288 {"clr.p", 1, 0xbe, opr
, 0},
3289 {"clr.l", 1, 0xbf, opr
, 0},
3291 {"com.b", 1, 0xcc, opr
, 0},
3292 {"com.w", 1, 0xcd, opr
, 0},
3293 {"com.l", 1, 0xcf, opr
, 0},
3295 {"neg.b", 1, 0xdc, opr
, 0},
3296 {"neg.w", 1, 0xdd, opr
, 0},
3297 {"neg.l", 1, 0xdf, opr
, 0},
3299 {"bclr", 1, 0xec, bm_regd_imm
, 0},
3300 {"bset", 1, 0xed, bm_regd_imm
, 0},
3301 {"btgl", 1, 0xee, bm_regd_imm
, 0},
3303 {"bclr", 1, 0xec, bm_regd_reg
, 0},
3304 {"bset", 1, 0xed, bm_regd_reg
, 0},
3305 {"btgl", 1, 0xee, bm_regd_reg
, 0},
3307 {"bclr.b", 1, 0xec, bm_opr_imm
, 0},
3308 {"bclr.w", 1, 0xec, bm_opr_imm
, 0},
3309 {"bclr.l", 1, 0xec, bm_opr_imm
, 0},
3311 {"bset.b", 1, 0xed, bm_opr_imm
, 0},
3312 {"bset.w", 1, 0xed, bm_opr_imm
, 0},
3313 {"bset.l", 1, 0xed, bm_opr_imm
, 0},
3315 {"btgl.b", 1, 0xee, bm_opr_imm
, 0},
3316 {"btgl.w", 1, 0xee, bm_opr_imm
, 0},
3317 {"btgl.l", 1, 0xee, bm_opr_imm
, 0},
3319 {"bclr.b", 1, 0xec, bm_opr_reg
, 0},
3320 {"bclr.w", 1, 0xec, bm_opr_reg
, 0},
3321 {"bclr.l", 1, 0xec, bm_opr_reg
, 0},
3323 {"bset.b", 1, 0xed, bm_opr_reg
, 0},
3324 {"bset.w", 1, 0xed, bm_opr_reg
, 0},
3325 {"bset.l", 1, 0xed, bm_opr_reg
, 0},
3327 {"btgl.b", 1, 0xee, bm_opr_reg
, 0},
3328 {"btgl.w", 1, 0xee, bm_opr_reg
, 0},
3329 {"btgl.l", 1, 0xee, bm_opr_reg
, 0},
3331 {"cmp", 1, 0xe0, regdxy_imm
, 0},
3332 {"cmp", 1, 0xf0, regdxy_opr_src
, 0},
3334 {"cmp", 1, 0xfc, regx_regy
, 0},
3335 {"sub", 1, 0xfd, regd6_regx_regy
, 0},
3336 {"sub", 1, 0xfe, regd6_regy_regx
, 0},
3338 {"swi", 1, 0xff, no_operands
, 0},
3342 /* The -10 below is a kludge. The opcode is in fact 0x00 */
3343 {"ld", 2, -10, regs_opr_src
, 0},
3345 /* The -9 below is a kludge. The opcode is in fact 0x01 */
3346 {"st", 2, -9, regs_opr_dest
, 0},
3348 /* The -8 below is a kludge. The opcode is in fact 0x02 */
3349 {"cmp", 2, -8, regs_opr_src
, 0},
3351 /* The -7 below is a kludge. The opcode is in fact 0x03 */
3352 {"ld", 2, -7, regs_imm
, 0},
3354 /* The -6 below is a kludge. The opcode is in fact 0x04 */
3355 {"cmp", 2, -6, regs_imm
, 0},
3357 {"bfext", 2, 0x08, bfe_reg_reg_reg
, 0},
3358 {"bfext", 2, 0x08, bfe_reg_reg_imm
, 0},
3359 {"bfext.b", 2, 0x08, bfe_reg_opr_reg
, 0},
3360 {"bfext.w", 2, 0x08, bfe_reg_opr_reg
, 0},
3361 {"bfext.p", 2, 0x08, bfe_reg_opr_reg
, 0},
3362 {"bfext.l", 2, 0x08, bfe_reg_opr_reg
, 0},
3363 {"bfext.b", 2, 0x08, bfe_opr_reg_reg
, 0},
3364 {"bfext.w", 2, 0x08, bfe_opr_reg_reg
, 0},
3365 {"bfext.p", 2, 0x08, bfe_opr_reg_reg
, 0},
3366 {"bfext.l", 2, 0x08, bfe_opr_reg_reg
, 0},
3367 {"bfext.b", 2, 0x08, bfe_reg_opr_imm
, 0},
3368 {"bfext.w", 2, 0x08, bfe_reg_opr_imm
, 0},
3369 {"bfext.p", 2, 0x08, bfe_reg_opr_imm
, 0},
3370 {"bfext.l", 2, 0x08, bfe_reg_opr_imm
, 0},
3371 {"bfext.b", 2, 0x08, bfe_opr_reg_imm
, 0},
3372 {"bfext.w", 2, 0x08, bfe_opr_reg_imm
, 0},
3373 {"bfext.p", 2, 0x08, bfe_opr_reg_imm
, 0},
3374 {"bfext.l", 2, 0x08, bfe_opr_reg_imm
, 0},
3377 {"bfins", 2, 0x08, bfi_reg_reg_reg
, 0},
3378 {"bfins", 2, 0x08, bfi_reg_reg_imm
, 0},
3379 {"bfins.b", 2, 0x08, bfi_reg_opr_reg
, 0},
3380 {"bfins.w", 2, 0x08, bfi_reg_opr_reg
, 0},
3381 {"bfins.p", 2, 0x08, bfi_reg_opr_reg
, 0},
3382 {"bfins.l", 2, 0x08, bfi_reg_opr_reg
, 0},
3383 {"bfins.b", 2, 0x08, bfi_opr_reg_reg
, 0},
3384 {"bfins.w", 2, 0x08, bfi_opr_reg_reg
, 0},
3385 {"bfins.p", 2, 0x08, bfi_opr_reg_reg
, 0},
3386 {"bfins.l", 2, 0x08, bfi_opr_reg_reg
, 0},
3387 {"bfins.b", 2, 0x08, bfi_reg_opr_imm
, 0},
3388 {"bfins.w", 2, 0x08, bfi_reg_opr_imm
, 0},
3389 {"bfins.p", 2, 0x08, bfi_reg_opr_imm
, 0},
3390 {"bfins.l", 2, 0x08, bfi_reg_opr_imm
, 0},
3391 {"bfins.b", 2, 0x08, bfi_opr_reg_imm
, 0},
3392 {"bfins.w", 2, 0x08, bfi_opr_reg_imm
, 0},
3393 {"bfins.p", 2, 0x08, bfi_opr_reg_imm
, 0},
3394 {"bfins.l", 2, 0x08, bfi_opr_reg_imm
, 0},
3397 {"minu", 2, 0x10, regd_opr
, 0},
3398 {"maxu", 2, 0x18, regd_opr
, 0},
3399 {"mins", 2, 0x20, regd_opr
, 0},
3400 {"maxs", 2, 0x28, regd_opr
, 0},
3402 {"clb", 2, 0x91, tfr
, 0},
3404 {"trap", 2, 0x00, trap_imm
, 0},
3405 {"abs", 2, 0x40, reg_inh
, 0},
3406 {"sat", 2, 0xa0, reg_inh
, 0},
3408 {"rti", 2, 0x90, no_operands
, 0},
3409 {"stop", 2, 0x05, no_operands
, 0},
3410 {"wai", 2, 0x06, no_operands
, 0},
3411 {"sys", 2, 0x07, no_operands
, 0},
3413 {"bit", 2, 0x58, regd_imm
, 0},
3414 {"bit", 2, 0x68, regd_opr
, 0},
3416 {"adc", 2, 0x50, regd_imm
, 0},
3417 {"adc", 2, 0x60, regd_opr
, 0},
3419 {"sbc", 2, 0x70, regd_imm
, 0},
3420 {"eor", 2, 0x78, regd_imm
, 0},
3422 {"sbc", 2, 0x80, regd_opr
, 0},
3423 {"eor", 2, 0x88, regd_opr
, 0},
3425 {"divs", 2, 0x30, mul_reg_reg_reg
, 0},
3426 {"divu", 2, 0x30, mul_reg_reg_reg
, 0},
3428 {"divs.b", 2, 0x30, mul_reg_reg_opr
, 0},
3429 {"divs.w", 2, 0x30, mul_reg_reg_opr
, 0},
3430 {"divs.l", 2, 0x30, mul_reg_reg_opr
, 0},
3432 {"divu.b", 2, 0x30, mul_reg_reg_opr
, 0},
3433 {"divu.w", 2, 0x30, mul_reg_reg_opr
, 0},
3434 {"divu.l", 2, 0x30, mul_reg_reg_opr
, 0},
3436 {"divs.b", 2, 0x30, mul_reg_reg_imm
, 0},
3437 {"divs.w", 2, 0x30, mul_reg_reg_imm
, 0},
3438 {"divs.l", 2, 0x30, mul_reg_reg_imm
, 0},
3440 {"divu.b", 2, 0x30, mul_reg_reg_imm
, 0},
3441 {"divu.w", 2, 0x30, mul_reg_reg_imm
, 0},
3442 {"divu.l", 2, 0x30, mul_reg_reg_imm
, 0},
3444 {"divs.bb", 2, 0x30, mul_reg_opr_opr
, 0},
3445 {"divs.bw", 2, 0x30, mul_reg_opr_opr
, 0},
3446 {"divs.bp", 2, 0x30, mul_reg_opr_opr
, 0},
3447 {"divs.bl", 2, 0x30, mul_reg_opr_opr
, 0},
3449 {"divs.wb", 2, 0x30, mul_reg_opr_opr
, 0},
3450 {"divs.ww", 2, 0x30, mul_reg_opr_opr
, 0},
3451 {"divs.wp", 2, 0x30, mul_reg_opr_opr
, 0},
3452 {"divs.wl", 2, 0x30, mul_reg_opr_opr
, 0},
3454 {"divs.pb", 2, 0x30, mul_reg_opr_opr
, 0},
3455 {"divs.pw", 2, 0x30, mul_reg_opr_opr
, 0},
3456 {"divs.pp", 2, 0x30, mul_reg_opr_opr
, 0},
3457 {"divs.pl", 2, 0x30, mul_reg_opr_opr
, 0},
3459 {"divs.lb", 2, 0x30, mul_reg_opr_opr
, 0},
3460 {"divs.lw", 2, 0x30, mul_reg_opr_opr
, 0},
3461 {"divs.lp", 2, 0x30, mul_reg_opr_opr
, 0},
3462 {"divs.ll", 2, 0x30, mul_reg_opr_opr
, 0},
3464 {"divu.bb", 2, 0x30, mul_reg_opr_opr
, 0},
3465 {"divu.bw", 2, 0x30, mul_reg_opr_opr
, 0},
3466 {"divu.bp", 2, 0x30, mul_reg_opr_opr
, 0},
3467 {"divu.bl", 2, 0x30, mul_reg_opr_opr
, 0},
3469 {"divu.wb", 2, 0x30, mul_reg_opr_opr
, 0},
3470 {"divu.ww", 2, 0x30, mul_reg_opr_opr
, 0},
3471 {"divu.wp", 2, 0x30, mul_reg_opr_opr
, 0},
3472 {"divu.wl", 2, 0x30, mul_reg_opr_opr
, 0},
3474 {"divu.pb", 2, 0x30, mul_reg_opr_opr
, 0},
3475 {"divu.pw", 2, 0x30, mul_reg_opr_opr
, 0},
3476 {"divu.pp", 2, 0x30, mul_reg_opr_opr
, 0},
3477 {"divu.pl", 2, 0x30, mul_reg_opr_opr
, 0},
3479 {"divu.lb", 2, 0x30, mul_reg_opr_opr
, 0},
3480 {"divu.lw", 2, 0x30, mul_reg_opr_opr
, 0},
3481 {"divu.lp", 2, 0x30, mul_reg_opr_opr
, 0},
3482 {"divu.ll", 2, 0x30, mul_reg_opr_opr
, 0},
3486 {"qmuls", 2, 0xb0, mul_reg_reg_reg
, 0},
3487 {"qmulu", 2, 0xb0, mul_reg_reg_reg
, 0},
3489 {"qmuls.b", 2, 0xb0, mul_reg_reg_opr
, 0},
3490 {"qmuls.w", 2, 0xb0, mul_reg_reg_opr
, 0},
3491 {"qmuls.l", 2, 0xb0, mul_reg_reg_opr
, 0},
3493 {"qmulu.b", 2, 0xb0, mul_reg_reg_opr
, 0},
3494 {"qmulu.w", 2, 0xb0, mul_reg_reg_opr
, 0},
3495 {"qmulu.l", 2, 0xb0, mul_reg_reg_opr
, 0},
3497 {"qmuls.b", 2, 0xb0, mul_reg_reg_imm
, 0},
3498 {"qmuls.w", 2, 0xb0, mul_reg_reg_imm
, 0},
3499 {"qmuls.l", 2, 0xb0, mul_reg_reg_imm
, 0},
3501 {"qmulu.b", 2, 0xb0, mul_reg_reg_imm
, 0},
3502 {"qmulu.w", 2, 0xb0, mul_reg_reg_imm
, 0},
3503 {"qmulu.l", 2, 0xb0, mul_reg_reg_imm
, 0},
3505 {"qmuls.bb", 2, 0xb0, mul_reg_opr_opr
, 0},
3506 {"qmuls.bw", 2, 0xb0, mul_reg_opr_opr
, 0},
3507 {"qmuls.bp", 2, 0xb0, mul_reg_opr_opr
, 0},
3508 {"qmuls.bl", 2, 0xb0, mul_reg_opr_opr
, 0},
3510 {"qmuls.wb", 2, 0xb0, mul_reg_opr_opr
, 0},
3511 {"qmuls.ww", 2, 0xb0, mul_reg_opr_opr
, 0},
3512 {"qmuls.wp", 2, 0xb0, mul_reg_opr_opr
, 0},
3513 {"qmuls.wl", 2, 0xb0, mul_reg_opr_opr
, 0},
3515 {"qmuls.pb", 2, 0xb0, mul_reg_opr_opr
, 0},
3516 {"qmuls.pw", 2, 0xb0, mul_reg_opr_opr
, 0},
3517 {"qmuls.pp", 2, 0xb0, mul_reg_opr_opr
, 0},
3518 {"qmuls.pl", 2, 0xb0, mul_reg_opr_opr
, 0},
3520 {"qmuls.lb", 2, 0xb0, mul_reg_opr_opr
, 0},
3521 {"qmuls.lw", 2, 0xb0, mul_reg_opr_opr
, 0},
3522 {"qmuls.lp", 2, 0xb0, mul_reg_opr_opr
, 0},
3523 {"qmuls.ll", 2, 0xb0, mul_reg_opr_opr
, 0},
3525 {"qmulu.bb", 2, 0xb0, mul_reg_opr_opr
, 0},
3526 {"qmulu.bw", 2, 0xb0, mul_reg_opr_opr
, 0},
3527 {"qmulu.bp", 2, 0xb0, mul_reg_opr_opr
, 0},
3528 {"qmulu.bl", 2, 0xb0, mul_reg_opr_opr
, 0},
3530 {"qmulu.wb", 2, 0xb0, mul_reg_opr_opr
, 0},
3531 {"qmulu.ww", 2, 0xb0, mul_reg_opr_opr
, 0},
3532 {"qmulu.wp", 2, 0xb0, mul_reg_opr_opr
, 0},
3533 {"qmulu.wl", 2, 0xb0, mul_reg_opr_opr
, 0},
3535 {"qmulu.pb", 2, 0xb0, mul_reg_opr_opr
, 0},
3536 {"qmulu.pw", 2, 0xb0, mul_reg_opr_opr
, 0},
3537 {"qmulu.pp", 2, 0xb0, mul_reg_opr_opr
, 0},
3538 {"qmulu.pl", 2, 0xb0, mul_reg_opr_opr
, 0},
3540 {"qmulu.lb", 2, 0xb0, mul_reg_opr_opr
, 0},
3541 {"qmulu.lw", 2, 0xb0, mul_reg_opr_opr
, 0},
3542 {"qmulu.lp", 2, 0xb0, mul_reg_opr_opr
, 0},
3543 {"qmulu.ll", 2, 0xb0, mul_reg_opr_opr
, 0},
3548 {"macs", 2, 0x48, mul_reg_reg_reg
, 0},
3549 {"macu", 2, 0x48, mul_reg_reg_reg
, 0},
3551 {"macs.b", 2, 0x48, mul_reg_reg_opr
, 0},
3552 {"macs.w", 2, 0x48, mul_reg_reg_opr
, 0},
3553 {"macs.l", 2, 0x48, mul_reg_reg_opr
, 0},
3555 {"macu.b", 2, 0x48, mul_reg_reg_opr
, 0},
3556 {"macu.w", 2, 0x48, mul_reg_reg_opr
, 0},
3557 {"macu.l", 2, 0x48, mul_reg_reg_opr
, 0},
3559 {"macs.b", 2, 0x48, mul_reg_reg_imm
, 0},
3560 {"macs.w", 2, 0x48, mul_reg_reg_imm
, 0},
3561 {"macs.l", 2, 0x48, mul_reg_reg_imm
, 0},
3563 {"macu.b", 2, 0x48, mul_reg_reg_imm
, 0},
3564 {"macu.w", 2, 0x48, mul_reg_reg_imm
, 0},
3565 {"macu.l", 2, 0x48, mul_reg_reg_imm
, 0},
3567 {"macs.bb", 2, 0x48, mul_reg_opr_opr
, 0},
3568 {"macs.bw", 2, 0x48, mul_reg_opr_opr
, 0},
3569 {"macs.bp", 2, 0x48, mul_reg_opr_opr
, 0},
3570 {"macs.bl", 2, 0x48, mul_reg_opr_opr
, 0},
3572 {"macs.wb", 2, 0x48, mul_reg_opr_opr
, 0},
3573 {"macs.ww", 2, 0x48, mul_reg_opr_opr
, 0},
3574 {"macs.wp", 2, 0x48, mul_reg_opr_opr
, 0},
3575 {"macs.wl", 2, 0x48, mul_reg_opr_opr
, 0},
3577 {"macs.pb", 2, 0x48, mul_reg_opr_opr
, 0},
3578 {"macs.pw", 2, 0x48, mul_reg_opr_opr
, 0},
3579 {"macs.pp", 2, 0x48, mul_reg_opr_opr
, 0},
3580 {"macs.pl", 2, 0x48, mul_reg_opr_opr
, 0},
3582 {"macs.lb", 2, 0x48, mul_reg_opr_opr
, 0},
3583 {"macs.lw", 2, 0x48, mul_reg_opr_opr
, 0},
3584 {"macs.lp", 2, 0x48, mul_reg_opr_opr
, 0},
3585 {"macs.ll", 2, 0x48, mul_reg_opr_opr
, 0},
3587 {"macu.bb", 2, 0x48, mul_reg_opr_opr
, 0},
3588 {"macu.bw", 2, 0x48, mul_reg_opr_opr
, 0},
3589 {"macu.bp", 2, 0x48, mul_reg_opr_opr
, 0},
3590 {"macu.bl", 2, 0x48, mul_reg_opr_opr
, 0},
3592 {"macu.wb", 2, 0x48, mul_reg_opr_opr
, 0},
3593 {"macu.ww", 2, 0x48, mul_reg_opr_opr
, 0},
3594 {"macu.wp", 2, 0x48, mul_reg_opr_opr
, 0},
3595 {"macu.wl", 2, 0x48, mul_reg_opr_opr
, 0},
3597 {"macu.pb", 2, 0x48, mul_reg_opr_opr
, 0},
3598 {"macu.pw", 2, 0x48, mul_reg_opr_opr
, 0},
3599 {"macu.pp", 2, 0x48, mul_reg_opr_opr
, 0},
3600 {"macu.pl", 2, 0x48, mul_reg_opr_opr
, 0},
3602 {"macu.lb", 2, 0x48, mul_reg_opr_opr
, 0},
3603 {"macu.lw", 2, 0x48, mul_reg_opr_opr
, 0},
3604 {"macu.lp", 2, 0x48, mul_reg_opr_opr
, 0},
3605 {"macu.ll", 2, 0x48, mul_reg_opr_opr
, 0},
3610 {"mods", 2, 0x38, mul_reg_reg_reg
, 0},
3611 {"modu", 2, 0x38, mul_reg_reg_reg
, 0},
3613 {"mods.b", 2, 0x38, mul_reg_reg_opr
, 0},
3614 {"mods.w", 2, 0x38, mul_reg_reg_opr
, 0},
3615 {"mods.l", 2, 0x38, mul_reg_reg_opr
, 0},
3617 {"modu.b", 2, 0x38, mul_reg_reg_opr
, 0},
3618 {"modu.w", 2, 0x38, mul_reg_reg_opr
, 0},
3619 {"modu.l", 2, 0x38, mul_reg_reg_opr
, 0},
3621 {"mods.b", 2, 0x38, mul_reg_reg_imm
, 0},
3622 {"mods.w", 2, 0x38, mul_reg_reg_imm
, 0},
3623 {"mods.l", 2, 0x38, mul_reg_reg_imm
, 0},
3625 {"modu.b", 2, 0x38, mul_reg_reg_imm
, 0},
3626 {"modu.w", 2, 0x38, mul_reg_reg_imm
, 0},
3627 {"modu.l", 2, 0x38, mul_reg_reg_imm
, 0},
3629 {"mods.bb", 2, 0x38, mul_reg_opr_opr
, 0},
3630 {"mods.bw", 2, 0x38, mul_reg_opr_opr
, 0},
3631 {"mods.bp", 2, 0x38, mul_reg_opr_opr
, 0},
3632 {"mods.bl", 2, 0x38, mul_reg_opr_opr
, 0},
3634 {"mods.wb", 2, 0x38, mul_reg_opr_opr
, 0},
3635 {"mods.ww", 2, 0x38, mul_reg_opr_opr
, 0},
3636 {"mods.wp", 2, 0x38, mul_reg_opr_opr
, 0},
3637 {"mods.wl", 2, 0x38, mul_reg_opr_opr
, 0},
3639 {"mods.pb", 2, 0x38, mul_reg_opr_opr
, 0},
3640 {"mods.pw", 2, 0x38, mul_reg_opr_opr
, 0},
3641 {"mods.pp", 2, 0x38, mul_reg_opr_opr
, 0},
3642 {"mods.pl", 2, 0x38, mul_reg_opr_opr
, 0},
3644 {"mods.lb", 2, 0x38, mul_reg_opr_opr
, 0},
3645 {"mods.lw", 2, 0x38, mul_reg_opr_opr
, 0},
3646 {"mods.lp", 2, 0x38, mul_reg_opr_opr
, 0},
3647 {"mods.ll", 2, 0x38, mul_reg_opr_opr
, 0},
3649 {"modu.bb", 2, 0x38, mul_reg_opr_opr
, 0},
3650 {"modu.bw", 2, 0x38, mul_reg_opr_opr
, 0},
3651 {"modu.bp", 2, 0x38, mul_reg_opr_opr
, 0},
3652 {"modu.bl", 2, 0x38, mul_reg_opr_opr
, 0},
3654 {"modu.wb", 2, 0x38, mul_reg_opr_opr
, 0},
3655 {"modu.ww", 2, 0x38, mul_reg_opr_opr
, 0},
3656 {"modu.wp", 2, 0x38, mul_reg_opr_opr
, 0},
3657 {"modu.wl", 2, 0x38, mul_reg_opr_opr
, 0},
3659 {"modu.pb", 2, 0x38, mul_reg_opr_opr
, 0},
3660 {"modu.pw", 2, 0x38, mul_reg_opr_opr
, 0},
3661 {"modu.pp", 2, 0x38, mul_reg_opr_opr
, 0},
3662 {"modu.pl", 2, 0x38, mul_reg_opr_opr
, 0},
3664 {"modu.lb", 2, 0x38, mul_reg_opr_opr
, 0},
3665 {"modu.lw", 2, 0x38, mul_reg_opr_opr
, 0},
3666 {"modu.lp", 2, 0x38, mul_reg_opr_opr
, 0},
3667 {"modu.ll", 2, 0x38, mul_reg_opr_opr
, 0}
3671 /* Gas line assembler entry point. */
3673 /* This is the main entry point for the machine-dependent assembler. str
3674 points to a machine-dependent instruction. This function is supposed to
3675 emit the frags/bytes it assembles to. */
3677 md_assemble (char *str
)
3684 fail_line_pointer
= NULL
;
3686 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
3687 lower case (the opcode table only has lower case op-codes). */
3688 for (op_start
= op_end
= str
;
3689 *op_end
&& !is_end_of_line
[(int)*op_end
] && *op_end
!= ' ';
3692 name
[nlen
] = TOLOWER (op_start
[nlen
]);
3694 gas_assert (nlen
< sizeof (name
) - 1);
3700 as_bad (_("No instruction or missing opcode."));
3704 input_line_pointer
= skip_whites (op_end
);
3707 for (i
= 0; i
< sizeof (opcodes
) / sizeof (opcodes
[0]); ++i
)
3709 const struct instruction
*opc
= opcodes
+ i
;
3710 if (0 == strcmp (name
, opc
->name
))
3712 if (opc
->parse_operands (opc
))
3718 as_bad (_("Invalid instruction: \"%s\""), str
);
3719 as_bad (_("First invalid token: \"%s\""), fail_line_pointer
);
3720 while (*input_line_pointer
++)
3728 /* Relocation, relaxation and frag conversions. */
3730 /* PC-relative offsets are relative to the start of the
3731 next instruction. That is, the address of the offset, plus its
3732 size, since the offset is always the last part of the insn. */
3734 md_pcrel_from (fixS
*fixP
)
3736 long ret
= fixP
->fx_size
+ fixP
->fx_frag
->fr_address
;
3737 if (fixP
->fx_addsy
&& S_IS_DEFINED (fixP
->fx_addsy
))
3738 ret
+= fixP
->fx_where
;
3744 /* We need a port-specific relaxation function to cope with sym2 - sym1
3745 relative expressions with both symbols in the same segment (but not
3746 necessarily in the same frag as this insn), for example:
3747 ldab sym2-(sym1-2),pc
3749 The offset can be 5, 9 or 16 bits long. */
3752 s12z_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
*fragP ATTRIBUTE_UNUSED
,
3753 long stretch ATTRIBUTE_UNUSED
)
3759 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec ATTRIBUTE_UNUSED
,
3760 fragS
*fragP ATTRIBUTE_UNUSED
)
3764 /* On an ELF system, we can't relax a weak symbol. The weak symbol
3765 can be overridden at final link time by a non weak symbol. We can
3766 relax externally visible symbol because there is no shared library
3767 and such symbol can't be overridden (unless they are weak). */
3769 /* Force truly undefined symbols to their maximum size, and generally set up
3770 the frag list to be relaxed. */
3772 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
, asection
*segment ATTRIBUTE_UNUSED
)
3778 /* If while processing a fixup, a reloc really needs to be created
3779 then it is done here. */
3781 tc_gen_reloc (asection
*section
, fixS
*fixp
)
3783 arelent
*reloc
= XNEW (arelent
);
3784 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3785 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3786 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3787 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3788 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3790 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3791 _("Relocation %d is not supported by object file format."),
3792 (int) fixp
->fx_r_type
);
3796 if (0 == (section
->flags
& SEC_CODE
))
3797 reloc
->addend
= fixp
->fx_offset
;
3799 reloc
->addend
= fixp
->fx_addnumber
;
3804 /* See whether we need to force a relocation into the output file. */
3806 tc_s12z_force_relocation (fixS
*fixP
)
3808 return generic_force_reloc (fixP
);
3811 /* Here we decide which fixups can be adjusted to make them relative
3812 to the beginning of the section instead of the symbol. Basically
3813 we need to make sure that the linker relaxation is done
3814 correctly, so in some cases we force the original symbol to be
3817 tc_s12z_fix_adjustable (fixS
*fixP ATTRIBUTE_UNUSED
)
3823 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
3827 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
3830 /* We don't actually support subtracting a symbol. */
3831 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
3832 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
3835 Patch the instruction with the resolved operand. Elf relocation
3836 info will also be generated to take care of linker/loader fixups.
3838 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
3840 switch (fixP
->fx_r_type
)
3843 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
3846 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
3849 case BFD_RELOC_S12Z_OPR
:
3850 bfd_putb24 ((bfd_vma
) value
, (unsigned char *) where
);
3853 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
3855 case BFD_RELOC_16_PCREL
:
3856 if (value
< -0x8000 || value
> 0x7FFF)
3857 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3858 _("Value out of 16-bit range."));
3860 bfd_putb16 ((bfd_vma
) value
| 0x8000, (unsigned char *) where
);
3864 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3865 fixP
->fx_line
, fixP
->fx_r_type
);
3869 /* Set the ELF specific flags. */
3871 s12z_elf_final_processing (void)