Rename ms1 files to mt files (part 1 -- renames only)
[deliverable/binutils-gdb.git] / cpu / iq2000.opc
1 /* IQ2000 opcode support. -*- C -*-
2
3 Copyright 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
4
5 Contributed by Red Hat Inc; developed under contract from Fujitsu.
6
7 This file is part of the GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
23
24 /* This file is an addendum to iq2000.cpu. Heavy use of C code isn't
25 appropriate in .cpu files, so it resides here. This especially applies
26 to assembly/disassembly where parsing/printing can be quite involved.
27 Such things aren't really part of the specification of the cpu, per se,
28 so .cpu files provide the general framework and .opc files handle the
29 nitty-gritty details as necessary.
30
31 Each section is delimited with start and end markers.
32
33 <arch>-opc.h additions use: "-- opc.h"
34 <arch>-opc.c additions use: "-- opc.c"
35 <arch>-asm.c additions use: "-- asm.c"
36 <arch>-dis.c additions use: "-- dis.c"
37 <arch>-ibd.h additions use: "-- ibd.h". */
38 \f
39 /* -- opc.h */
40
41 /* Allows reason codes to be output when assembler errors occur. */
42 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
43
44 /* Override disassembly hashing - there are variable bits in the top
45 byte of these instructions. */
46 #define CGEN_DIS_HASH_SIZE 8
47 #define CGEN_DIS_HASH(buf,value) (((* (unsigned char*) (buf)) >> 6) % CGEN_DIS_HASH_SIZE)
48
49 /* following activates check beyond hashing since some iq2000 and iq10
50 instructions have same mnemonics but different functionality. */
51 #define CGEN_VALIDATE_INSN_SUPPORTED
52
53 extern int iq2000_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
54
55 /* -- asm.c */
56
57 #include "safe-ctype.h"
58
59 static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
60
61 /* Special check to ensure that instruction exists for given machine. */
62
63 int
64 iq2000_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
65 {
66 int machs = cd->machs;
67
68 return (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH) & machs) != 0;
69 }
70
71 static int
72 iq2000_cgen_isa_register (const char **strp)
73 {
74 int len;
75 int ch1, ch2;
76
77 if (**strp == 'r' || **strp == 'R')
78 {
79 len = strlen (*strp);
80 if (len == 2)
81 {
82 ch1 = (*strp)[1];
83 if ('0' <= ch1 && ch1 <= '9')
84 return 1;
85 }
86 else if (len == 3)
87 {
88 ch1 = (*strp)[1];
89 ch2 = (*strp)[2];
90 if (('1' <= ch1 && ch1 <= '2') && ('0' <= ch2 && ch2 <= '9'))
91 return 1;
92 if ('3' == ch1 && (ch2 == '0' || ch2 == '1'))
93 return 1;
94 }
95 }
96 if (**strp == '%'
97 && TOLOWER ((*strp)[1]) != 'l'
98 && TOLOWER ((*strp)[1]) != 'h')
99 return 1;
100 return 0;
101 }
102
103 /* Handle negated literal. */
104
105 static const char *
106 parse_mimm (CGEN_CPU_DESC cd,
107 const char **strp,
108 int opindex,
109 unsigned long *valuep)
110 {
111 const char *errmsg;
112
113 /* Verify this isn't a register. */
114 if (iq2000_cgen_isa_register (strp))
115 errmsg = _("immediate value cannot be register");
116 else
117 {
118 long value;
119
120 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
121 if (errmsg == NULL)
122 {
123 long x = (-value) & 0xFFFF0000;
124
125 if (x != 0 && x != (long) 0xFFFF0000)
126 errmsg = _("immediate value out of range");
127 else
128 *valuep = (-value & 0xFFFF);
129 }
130 }
131 return errmsg;
132 }
133
134 /* Handle signed/unsigned literal. */
135
136 static const char *
137 parse_imm (CGEN_CPU_DESC cd,
138 const char **strp,
139 int opindex,
140 unsigned long *valuep)
141 {
142 const char *errmsg;
143
144 if (iq2000_cgen_isa_register (strp))
145 errmsg = _("immediate value cannot be register");
146 else
147 {
148 long value;
149
150 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
151 if (errmsg == NULL)
152 {
153 long x = value & 0xFFFF0000;
154
155 if (x != 0 && x != (long) 0xFFFF0000)
156 errmsg = _("immediate value out of range");
157 else
158 *valuep = (value & 0xFFFF);
159 }
160 }
161 return errmsg;
162 }
163
164 /* Handle iq10 21-bit jmp offset. */
165
166 static const char *
167 parse_jtargq10 (CGEN_CPU_DESC cd,
168 const char **strp,
169 int opindex,
170 int reloc ATTRIBUTE_UNUSED,
171 enum cgen_parse_operand_result *type_addr ATTRIBUTE_UNUSED,
172 bfd_vma *valuep)
173 {
174 const char *errmsg;
175 bfd_vma value;
176 enum cgen_parse_operand_result result_type = CGEN_PARSE_OPERAND_RESULT_NUMBER;
177
178 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_OFFSET_21,
179 & result_type, & value);
180 if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
181 {
182 /* Check value is within 23-bits
183 (remembering that 2-bit shift right will occur). */
184 if (value > 0x7fffff)
185 return _("21-bit offset out of range");
186 }
187 *valuep = (value & 0x7FFFFF);
188 return errmsg;
189 }
190
191 /* Handle high(). */
192
193 static const char *
194 parse_hi16 (CGEN_CPU_DESC cd,
195 const char **strp,
196 int opindex,
197 unsigned long *valuep)
198 {
199 if (strncasecmp (*strp, "%hi(", 4) == 0)
200 {
201 enum cgen_parse_operand_result result_type;
202 bfd_vma value;
203 const char *errmsg;
204
205 *strp += 4;
206 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
207 & result_type, & value);
208 if (**strp != ')')
209 return MISSING_CLOSING_PARENTHESIS;
210
211 ++*strp;
212 if (errmsg == NULL
213 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
214 {
215 /* If value has top-bit of %lo on, then it will
216 sign-propagate and so we compensate by adding
217 1 to the resultant %hi value. */
218 if (value & 0x8000)
219 value += 0x10000;
220 value >>= 16;
221 }
222 *valuep = value;
223
224 return errmsg;
225 }
226
227 /* We add %uhi in case a user just wants the high 16-bits or is using
228 an insn like ori for %lo which does not sign-propagate. */
229 if (strncasecmp (*strp, "%uhi(", 5) == 0)
230 {
231 enum cgen_parse_operand_result result_type;
232 bfd_vma value;
233 const char *errmsg;
234
235 *strp += 5;
236 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_UHI16,
237 & result_type, & value);
238 if (**strp != ')')
239 return MISSING_CLOSING_PARENTHESIS;
240
241 ++*strp;
242 if (errmsg == NULL
243 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
244 value >>= 16;
245
246 *valuep = value;
247
248 return errmsg;
249 }
250
251 return parse_imm (cd, strp, opindex, valuep);
252 }
253
254 /* Handle %lo in a signed context.
255 The signedness of the value doesn't matter to %lo(), but this also
256 handles the case where %lo() isn't present. */
257
258 static const char *
259 parse_lo16 (CGEN_CPU_DESC cd,
260 const char **strp,
261 int opindex,
262 unsigned long *valuep)
263 {
264 if (strncasecmp (*strp, "%lo(", 4) == 0)
265 {
266 const char *errmsg;
267 enum cgen_parse_operand_result result_type;
268 bfd_vma value;
269
270 *strp += 4;
271 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
272 & result_type, & value);
273 if (**strp != ')')
274 return MISSING_CLOSING_PARENTHESIS;
275 ++*strp;
276 if (errmsg == NULL
277 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
278 value &= 0xffff;
279 *valuep = value;
280 return errmsg;
281 }
282
283 return parse_imm (cd, strp, opindex, valuep);
284 }
285
286 /* Handle %lo in a negated signed context.
287 The signedness of the value doesn't matter to %lo(), but this also
288 handles the case where %lo() isn't present. */
289
290 static const char *
291 parse_mlo16 (CGEN_CPU_DESC cd,
292 const char **strp,
293 int opindex,
294 unsigned long *valuep)
295 {
296 if (strncasecmp (*strp, "%lo(", 4) == 0)
297 {
298 const char *errmsg;
299 enum cgen_parse_operand_result result_type;
300 bfd_vma value;
301
302 *strp += 4;
303 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
304 & result_type, & value);
305 if (**strp != ')')
306 return MISSING_CLOSING_PARENTHESIS;
307 ++*strp;
308 if (errmsg == NULL
309 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
310 value = (-value) & 0xffff;
311 *valuep = value;
312 return errmsg;
313 }
314
315 return parse_mimm (cd, strp, opindex, valuep);
316 }
317
318 /* -- */
This page took 0.035906 seconds and 4 git commands to generate.