2005-06-15 Dave Brolley <brolley@redhat.com>
[deliverable/binutils-gdb.git] / cpu / ms1.opc
1 /* Morpho Technologies mRISC opcode support, for GNU Binutils. -*- C -*-
2 Copyright 2001 Free Software Foundation, Inc.
3
4 Contributed by Red Hat Inc; developed under contract from
5 Morpho Technologies.
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, MA 02110-1301, USA.
22
23 */
24
25 /*
26 Each section is delimited with start and end markers.
27
28 <arch>-opc.h additions use: "-- opc.h"
29 <arch>-opc.c additions use: "-- opc.c"
30 <arch>-asm.c additions use: "-- asm.c"
31 <arch>-dis.c additions use: "-- dis.c"
32 <arch>-ibd.h additions use: "-- ibd.h"
33 */
34 \f
35 /* -- opc.h */
36
37 /* Check applicability of instructions against machines. */
38 #define CGEN_VALIDATE_INSN_SUPPORTED
39
40 /* Allows reason codes to be output when assembler errors occur. */
41 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
42
43 /* Override disassembly hashing - there are variable bits in the top
44 byte of these instructions. */
45 #define CGEN_DIS_HASH_SIZE 8
46 #define CGEN_DIS_HASH(buf, value) (((* (unsigned char *) (buf)) >> 5) % CGEN_DIS_HASH_SIZE)
47
48 #define CGEN_ASM_HASH_SIZE 127
49 #define CGEN_ASM_HASH(insn) ms1_asm_hash (insn)
50
51 extern unsigned int ms1_asm_hash (const char *);
52
53 extern int ms1_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
54
55 \f
56 /* -- opc.c */
57 #include "safe-ctype.h"
58
59 /* Special check to ensure that instruction exists for given machine. */
60
61 int
62 ms1_cgen_insn_supported (CGEN_CPU_DESC cd,
63 const CGEN_INSN *insn)
64 {
65 int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
66
67 /* No mach attribute? Assume it's supported for all machs. */
68 if (machs == 0)
69 return 1;
70
71 return ((machs & cd->machs) != 0);
72 }
73
74 /* A better hash function for instruction mnemonics. */
75
76 unsigned int
77 ms1_asm_hash (const char* insn)
78 {
79 unsigned int hash;
80 const char* m = insn;
81
82 for (hash = 0; *m && ! ISSPACE (*m); m++)
83 hash = (hash * 23) ^ (0x1F & TOLOWER (*m));
84
85 /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */
86
87 return hash % CGEN_ASM_HASH_SIZE;
88 }
89
90 \f
91 /* -- asm.c */
92 static int signed_out_of_bounds (long);
93 static const char * parse_imm16 (CGEN_CPU_DESC, const char **, int, long *);
94 static const char * parse_dup (CGEN_CPU_DESC, const char **, int, long *);
95 static const char * parse_ball (CGEN_CPU_DESC, const char **, int, long *);
96 static const char * parse_xmode (CGEN_CPU_DESC, const char **, int, long *);
97 static const char * parse_rc (CGEN_CPU_DESC, const char **, int, long *);
98 static const char * parse_cbrb (CGEN_CPU_DESC, const char **, int, long *);
99 static const char * parse_rbbc (CGEN_CPU_DESC, const char **, int, long *);
100 static const char * parse_type (CGEN_CPU_DESC, const char **, int, long *);
101
102 /* Range checking for signed numbers. Returns 0 if acceptable
103 and 1 if the value is out of bounds for a signed quantity. */
104
105 static int
106 signed_out_of_bounds (long val)
107 {
108 if ((val < -32768) || (val > 32767))
109 return 1;
110 return 0;
111 }
112
113 static const char *
114 parse_imm16 (CGEN_CPU_DESC cd,
115 const char **strp,
116 int opindex,
117 long *valuep)
118 {
119 const char *errmsg;
120 enum cgen_parse_operand_result result_type;
121 bfd_reloc_code_real_type code = BFD_RELOC_NONE;
122 bfd_vma value;
123
124 /* Is it a control transfer instructions? */
125 if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16O)
126 {
127 code = BFD_RELOC_16_PCREL;
128 errmsg = cgen_parse_address (cd, strp, opindex, code,
129 & result_type, & value);
130 if (errmsg == NULL)
131 {
132 if (signed_out_of_bounds (value))
133 errmsg = _("Operand out of range. Must be between -32768 and 32767.");
134 }
135 *valuep = value;
136 return errmsg;
137 }
138
139 /* If it's not a control transfer instruction, then
140 we have to check for %OP relocating operators. */
141 if (strncmp (*strp, "%hi16", 5) == 0)
142 {
143 *strp += 5;
144 code = BFD_RELOC_HI16;
145 }
146 else if (strncmp (*strp, "%lo16", 5) == 0)
147 {
148 *strp += 5;
149 code = BFD_RELOC_LO16;
150 }
151
152 /* If we found a %OP relocating operator, then parse it as an address.
153 If not, we need to parse it as an integer, either signed or unsigned
154 depending on which operand type we have. */
155 if (code != BFD_RELOC_NONE)
156 {
157 /* %OP relocating operator found. */
158 errmsg = cgen_parse_address (cd, strp, opindex, code,
159 & result_type, & value);
160 if (errmsg == NULL)
161 {
162 switch (result_type)
163 {
164 case (CGEN_PARSE_OPERAND_RESULT_NUMBER):
165 if (code == BFD_RELOC_HI16)
166 value = (value >> 16) & 0xFFFF;
167 else if (code == BFD_RELOC_LO16)
168 value = value & 0xFFFF;
169 else
170 errmsg = _("Biiiig Trouble in parse_imm16!");
171 break;
172
173 case (CGEN_PARSE_OPERAND_RESULT_QUEUED):
174 /* No special processing for this case. */
175 break;
176
177 default:
178 errmsg = _("%operator operand is not a symbol");
179 break;
180 }
181 }
182 *valuep = value;
183 }
184 else
185 {
186 /* Parse hex values like 0xffff as unsigned, and sign extend
187 them manually. */
188 int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MS1_OPERAND_IMM16);
189
190 if ((*strp)[0] == '0'
191 && ((*strp)[1] == 'x' || (*strp)[1] == 'X'))
192 parse_signed = 0;
193
194 /* No relocating operator. Parse as an number. */
195 if (parse_signed)
196 {
197 /* Parse as as signed integer. */
198
199 errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
200
201 if (errmsg == NULL)
202 {
203 #if 0
204 /* Manual range checking is needed for the signed case. */
205 if (*valuep & 0x8000)
206 value = 0xffff0000 | *valuep;
207 else
208 value = *valuep;
209
210 if (signed_out_of_bounds (value))
211 errmsg = _("Operand out of range. Must be between -32768 and 32767.");
212 /* Truncate to 16 bits. This is necessary
213 because cgen will have sign extended *valuep. */
214 *valuep &= 0xFFFF;
215 #endif
216 }
217 }
218 else
219 {
220 /* MS1_OPERAND_IMM16Z. Parse as an unsigned integer. */
221 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
222
223 if (opindex == (CGEN_OPERAND_TYPE)MS1_OPERAND_IMM16
224 && *valuep >= 0x8000
225 && *valuep <= 0xffff)
226 *valuep -= 0x10000;
227 }
228 }
229
230 return errmsg;
231 }
232
233
234 static const char *
235 parse_dup (CGEN_CPU_DESC cd,
236 const char **strp,
237 int opindex,
238 long *valuep)
239 {
240 const char *errmsg = NULL;
241
242 if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0)
243 {
244 *strp += 3;
245 *valuep = 1;
246 }
247 else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0)
248 {
249 *strp += 2;
250 *valuep = 0;
251 }
252 else
253 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
254
255 return errmsg;
256 }
257
258
259 static const char *
260 parse_ball (CGEN_CPU_DESC cd,
261 const char **strp,
262 int opindex,
263 long *valuep)
264 {
265 const char *errmsg = NULL;
266
267 if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0)
268 {
269 *strp += 3;
270 *valuep = 1;
271 }
272 else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0)
273 {
274 *strp += 3;
275 *valuep = 0;
276 }
277 else
278 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
279
280 return errmsg;
281 }
282
283 static const char *
284 parse_xmode (CGEN_CPU_DESC cd,
285 const char **strp,
286 int opindex,
287 long *valuep)
288 {
289 const char *errmsg = NULL;
290
291 if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0)
292 {
293 *strp += 2;
294 *valuep = 1;
295 }
296 else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0)
297 {
298 *strp += 2;
299 *valuep = 0;
300 }
301 else
302 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
303
304 return errmsg;
305 }
306
307 static const char *
308 parse_rc (CGEN_CPU_DESC cd,
309 const char **strp,
310 int opindex,
311 long *valuep)
312 {
313 const char *errmsg = NULL;
314
315 if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0)
316 {
317 *strp += 1;
318 *valuep = 1;
319 }
320 else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0)
321 {
322 *strp += 1;
323 *valuep = 0;
324 }
325 else
326 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
327
328 return errmsg;
329 }
330
331 static const char *
332 parse_cbrb (CGEN_CPU_DESC cd,
333 const char **strp,
334 int opindex,
335 long *valuep)
336 {
337 const char *errmsg = NULL;
338
339 if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0)
340 {
341 *strp += 2;
342 *valuep = 1;
343 }
344 else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0)
345 {
346 *strp += 2;
347 *valuep = 0;
348 }
349 else
350 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
351
352 return errmsg;
353 }
354
355 static const char *
356 parse_rbbc (CGEN_CPU_DESC cd,
357 const char **strp,
358 int opindex,
359 long *valuep)
360 {
361 const char *errmsg = NULL;
362
363 if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0)
364 {
365 *strp += 2;
366 *valuep = 0;
367 }
368 else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0)
369 {
370 *strp += 3;
371 *valuep = 1;
372 }
373 else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0)
374 {
375 *strp += 3;
376 *valuep = 2;
377 }
378 else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0)
379 {
380 *strp += 2;
381 *valuep = 3;
382 }
383 else
384 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
385
386 return errmsg;
387 }
388
389 static const char *
390 parse_type (CGEN_CPU_DESC cd,
391 const char **strp,
392 int opindex,
393 long *valuep)
394 {
395 const char *errmsg = NULL;
396
397 if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0)
398 {
399 *strp += 3;
400 *valuep = 0;
401 }
402 else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0)
403 {
404 *strp += 4;
405 *valuep = 1;
406 }
407 else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0)
408 {
409 *strp += 2;
410 *valuep = 2;
411 }
412 else
413 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
414
415 if ((errmsg == NULL) && (*valuep == 3))
416 errmsg = _("invalid operand. type may have values 0,1,2 only.");
417
418 return errmsg;
419 }
420
421 /* -- dis.c */
422 static void print_dollarhex (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int);
423
424 static void
425 print_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
426 void * dis_info,
427 long value,
428 unsigned int attrs ATTRIBUTE_UNUSED,
429 bfd_vma pc ATTRIBUTE_UNUSED,
430 int length ATTRIBUTE_UNUSED)
431 {
432 disassemble_info *info = (disassemble_info *) dis_info;
433
434 info->fprintf_func (info->stream, "$%x", value);
435
436 if (0)
437 print_normal (cd, dis_info, value, attrs, pc, length);
438 }
439
440
441 /* -- */
442
443
444
445
446
This page took 0.053684 seconds and 5 git commands to generate.