* elf64-ppc.c (ppc64_elf_size_stubs): Don't consider non-ppc64 input.
[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 /* Range checking for signed numbers. Returns 0 if acceptable
93 and 1 if the value is out of bounds for a signed quantity. */
94
95 static int
96 signed_out_of_bounds (long val)
97 {
98 if ((val < -32768) || (val > 32767))
99 return 1;
100 return 0;
101 }
102
103 static const char *
104 parse_loopsize (CGEN_CPU_DESC cd,
105 const char **strp,
106 int opindex,
107 void *arg)
108 {
109 signed long * valuep = (signed long *) arg;
110 const char *errmsg;
111 bfd_reloc_code_real_type code = BFD_RELOC_NONE;
112 enum cgen_parse_operand_result result_type;
113 bfd_vma value;
114
115 /* Is it a control transfer instructions? */
116 if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_LOOPSIZE)
117 {
118 code = BFD_RELOC_MS1_PCINSN8;
119 errmsg = cgen_parse_address (cd, strp, opindex, code,
120 & result_type, & value);
121 *valuep = value;
122 return errmsg;
123 }
124
125 abort ();
126 }
127
128 static const char *
129 parse_imm16 (CGEN_CPU_DESC cd,
130 const char **strp,
131 int opindex,
132 void *arg)
133 {
134 signed long * valuep = (signed long *) arg;
135 const char *errmsg;
136 enum cgen_parse_operand_result result_type;
137 bfd_reloc_code_real_type code = BFD_RELOC_NONE;
138 bfd_vma value;
139
140 /* Is it a control transfer instructions? */
141 if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16O)
142 {
143 code = BFD_RELOC_16_PCREL;
144 errmsg = cgen_parse_address (cd, strp, opindex, code,
145 & result_type, & value);
146 if (errmsg == NULL)
147 {
148 if (signed_out_of_bounds (value))
149 errmsg = _("Operand out of range. Must be between -32768 and 32767.");
150 }
151 *valuep = value;
152 return errmsg;
153 }
154
155 /* If it's not a control transfer instruction, then
156 we have to check for %OP relocating operators. */
157 if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16L)
158 ;
159 else if (strncmp (*strp, "%hi16", 5) == 0)
160 {
161 *strp += 5;
162 code = BFD_RELOC_HI16;
163 }
164 else if (strncmp (*strp, "%lo16", 5) == 0)
165 {
166 *strp += 5;
167 code = BFD_RELOC_LO16;
168 }
169
170 /* If we found a %OP relocating operator, then parse it as an address.
171 If not, we need to parse it as an integer, either signed or unsigned
172 depending on which operand type we have. */
173 if (code != BFD_RELOC_NONE)
174 {
175 /* %OP relocating operator found. */
176 errmsg = cgen_parse_address (cd, strp, opindex, code,
177 & result_type, & value);
178 if (errmsg == NULL)
179 {
180 switch (result_type)
181 {
182 case (CGEN_PARSE_OPERAND_RESULT_NUMBER):
183 if (code == BFD_RELOC_HI16)
184 value = (value >> 16) & 0xFFFF;
185 else if (code == BFD_RELOC_LO16)
186 value = value & 0xFFFF;
187 else
188 errmsg = _("Biiiig Trouble in parse_imm16!");
189 break;
190
191 case (CGEN_PARSE_OPERAND_RESULT_QUEUED):
192 /* No special processing for this case. */
193 break;
194
195 default:
196 errmsg = _("%operator operand is not a symbol");
197 break;
198 }
199 }
200 *valuep = value;
201 }
202 else
203 {
204 /* Parse hex values like 0xffff as unsigned, and sign extend
205 them manually. */
206 int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MS1_OPERAND_IMM16);
207
208 if ((*strp)[0] == '0'
209 && ((*strp)[1] == 'x' || (*strp)[1] == 'X'))
210 parse_signed = 0;
211
212 /* No relocating operator. Parse as an number. */
213 if (parse_signed)
214 {
215 /* Parse as as signed integer. */
216
217 errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
218
219 if (errmsg == NULL)
220 {
221 #if 0
222 /* Manual range checking is needed for the signed case. */
223 if (*valuep & 0x8000)
224 value = 0xffff0000 | *valuep;
225 else
226 value = *valuep;
227
228 if (signed_out_of_bounds (value))
229 errmsg = _("Operand out of range. Must be between -32768 and 32767.");
230 /* Truncate to 16 bits. This is necessary
231 because cgen will have sign extended *valuep. */
232 *valuep &= 0xFFFF;
233 #endif
234 }
235 }
236 else
237 {
238 /* MS1_OPERAND_IMM16Z. Parse as an unsigned integer. */
239 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep);
240
241 if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16
242 && *valuep >= 0x8000
243 && *valuep <= 0xffff)
244 *valuep -= 0x10000;
245 }
246 }
247
248 return errmsg;
249 }
250
251
252 static const char *
253 parse_dup (CGEN_CPU_DESC cd,
254 const char **strp,
255 int opindex,
256 unsigned long *valuep)
257 {
258 const char *errmsg = NULL;
259
260 if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0)
261 {
262 *strp += 3;
263 *valuep = 1;
264 }
265 else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0)
266 {
267 *strp += 2;
268 *valuep = 0;
269 }
270 else
271 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
272
273 return errmsg;
274 }
275
276
277 static const char *
278 parse_ball (CGEN_CPU_DESC cd,
279 const char **strp,
280 int opindex,
281 unsigned long *valuep)
282 {
283 const char *errmsg = NULL;
284
285 if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0)
286 {
287 *strp += 3;
288 *valuep = 1;
289 }
290 else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0)
291 {
292 *strp += 3;
293 *valuep = 0;
294 }
295 else
296 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
297
298 return errmsg;
299 }
300
301 static const char *
302 parse_xmode (CGEN_CPU_DESC cd,
303 const char **strp,
304 int opindex,
305 unsigned long *valuep)
306 {
307 const char *errmsg = NULL;
308
309 if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0)
310 {
311 *strp += 2;
312 *valuep = 1;
313 }
314 else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0)
315 {
316 *strp += 2;
317 *valuep = 0;
318 }
319 else
320 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
321
322 return errmsg;
323 }
324
325 static const char *
326 parse_rc (CGEN_CPU_DESC cd,
327 const char **strp,
328 int opindex,
329 unsigned long *valuep)
330 {
331 const char *errmsg = NULL;
332
333 if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0)
334 {
335 *strp += 1;
336 *valuep = 1;
337 }
338 else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0)
339 {
340 *strp += 1;
341 *valuep = 0;
342 }
343 else
344 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
345
346 return errmsg;
347 }
348
349 static const char *
350 parse_cbrb (CGEN_CPU_DESC cd,
351 const char **strp,
352 int opindex,
353 unsigned long *valuep)
354 {
355 const char *errmsg = NULL;
356
357 if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0)
358 {
359 *strp += 2;
360 *valuep = 1;
361 }
362 else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0)
363 {
364 *strp += 2;
365 *valuep = 0;
366 }
367 else
368 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
369
370 return errmsg;
371 }
372
373 static const char *
374 parse_rbbc (CGEN_CPU_DESC cd,
375 const char **strp,
376 int opindex,
377 unsigned long *valuep)
378 {
379 const char *errmsg = NULL;
380
381 if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0)
382 {
383 *strp += 2;
384 *valuep = 0;
385 }
386 else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0)
387 {
388 *strp += 3;
389 *valuep = 1;
390 }
391 else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0)
392 {
393 *strp += 3;
394 *valuep = 2;
395 }
396 else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0)
397 {
398 *strp += 2;
399 *valuep = 3;
400 }
401 else
402 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
403
404 return errmsg;
405 }
406
407 static const char *
408 parse_type (CGEN_CPU_DESC cd,
409 const char **strp,
410 int opindex,
411 unsigned long *valuep)
412 {
413 const char *errmsg = NULL;
414
415 if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0)
416 {
417 *strp += 3;
418 *valuep = 0;
419 }
420 else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0)
421 {
422 *strp += 4;
423 *valuep = 1;
424 }
425 else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0)
426 {
427 *strp += 2;
428 *valuep = 2;
429 }
430 else
431 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
432
433 if ((errmsg == NULL) && (*valuep == 3))
434 errmsg = _("invalid operand. type may have values 0,1,2 only.");
435
436 return errmsg;
437 }
438
439 /* -- dis.c */
440 static void print_dollarhex (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int);
441 static void print_pcrel (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int);
442
443 static void
444 print_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
445 void * dis_info,
446 long value,
447 unsigned int attrs ATTRIBUTE_UNUSED,
448 bfd_vma pc ATTRIBUTE_UNUSED,
449 int length ATTRIBUTE_UNUSED)
450 {
451 disassemble_info *info = (disassemble_info *) dis_info;
452
453 info->fprintf_func (info->stream, "$%lx", value);
454
455 if (0)
456 print_normal (cd, dis_info, value, attrs, pc, length);
457 }
458
459 static void
460 print_pcrel (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
461 void * dis_info,
462 long value,
463 unsigned int attrs ATTRIBUTE_UNUSED,
464 bfd_vma pc ATTRIBUTE_UNUSED,
465 int length ATTRIBUTE_UNUSED)
466 {
467 print_address (cd, dis_info, value + pc, attrs, pc, length);
468 }
469
470 /* -- */
471
472
473
474
475
This page took 0.047264 seconds and 4 git commands to generate.