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