xref: /netbsd-src/external/gpl3/binutils/dist/cpu/mt.opc (revision 4f645668ed707e1f969c546666f8c8e45e6f8888)
12a6b7db3Sskrll/* Morpho Technologies mRISC opcode support, for GNU Binutils.  -*- C -*-
2*883529b6Schristos   Copyright 2001, 2007, 2008, 2009, 2012 Free Software Foundation, Inc.
32a6b7db3Sskrll
42a6b7db3Sskrll   Contributed by Red Hat Inc; developed under contract from
52a6b7db3Sskrll   Morpho Technologies.
62a6b7db3Sskrll
72a6b7db3Sskrll   This file is part of the GNU Binutils.
82a6b7db3Sskrll
92a6b7db3Sskrll   This program is free software; you can redistribute it and/or modify
102a6b7db3Sskrll   it under the terms of the GNU General Public License as published by
112a6b7db3Sskrll   the Free Software Foundation; either version 3 of the License, or
122a6b7db3Sskrll   (at your option) any later version.
132a6b7db3Sskrll
142a6b7db3Sskrll   This program is distributed in the hope that it will be useful,
152a6b7db3Sskrll   but WITHOUT ANY WARRANTY; without even the implied warranty of
162a6b7db3Sskrll   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
172a6b7db3Sskrll   GNU General Public License for more details.
182a6b7db3Sskrll
192a6b7db3Sskrll   You should have received a copy of the GNU General Public License
202a6b7db3Sskrll   along with this program; if not, write to the Free Software
212a6b7db3Sskrll   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
222a6b7db3Sskrll   MA 02110-1301, USA.  */
232a6b7db3Sskrll
242a6b7db3Sskrll
252a6b7db3Sskrll/* Each section is delimited with start and end markers.
262a6b7db3Sskrll
272a6b7db3Sskrll   <arch>-opc.h additions use: "-- opc.h"
282a6b7db3Sskrll   <arch>-opc.c additions use: "-- opc.c"
292a6b7db3Sskrll   <arch>-asm.c additions use: "-- asm.c"
302a6b7db3Sskrll   <arch>-dis.c additions use: "-- dis.c"
312a6b7db3Sskrll   <arch>-ibd.h additions use: "-- ibd.h"  */
322a6b7db3Sskrll
332a6b7db3Sskrll/* -- opc.h */
342a6b7db3Sskrll
352a6b7db3Sskrll/* Check applicability of instructions against machines.  */
362a6b7db3Sskrll#define CGEN_VALIDATE_INSN_SUPPORTED
372a6b7db3Sskrll
382a6b7db3Sskrll/* Allows reason codes to be output when assembler errors occur.  */
392a6b7db3Sskrll#define CGEN_VERBOSE_ASSEMBLER_ERRORS
402a6b7db3Sskrll
412a6b7db3Sskrll/* Override disassembly hashing - there are variable bits in the top
422a6b7db3Sskrll   byte of these instructions.  */
432a6b7db3Sskrll#define CGEN_DIS_HASH_SIZE 8
442a6b7db3Sskrll#define CGEN_DIS_HASH(buf, value) (((* (unsigned char *) (buf)) >> 5) % CGEN_DIS_HASH_SIZE)
452a6b7db3Sskrll
462a6b7db3Sskrll#define CGEN_ASM_HASH_SIZE 127
472a6b7db3Sskrll#define CGEN_ASM_HASH(insn) mt_asm_hash (insn)
482a6b7db3Sskrll
492a6b7db3Sskrllextern unsigned int mt_asm_hash (const char *);
502a6b7db3Sskrll
512a6b7db3Sskrllextern int mt_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
522a6b7db3Sskrll
532a6b7db3Sskrll
542a6b7db3Sskrll/* -- opc.c */
552a6b7db3Sskrll#include "safe-ctype.h"
562a6b7db3Sskrll
572a6b7db3Sskrll/* Special check to ensure that instruction exists for given machine.  */
582a6b7db3Sskrll
592a6b7db3Sskrllint
602a6b7db3Sskrllmt_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
612a6b7db3Sskrll{
622a6b7db3Sskrll  int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
632a6b7db3Sskrll
642a6b7db3Sskrll  /* No mach attribute?  Assume it's supported for all machs.  */
652a6b7db3Sskrll  if (machs == 0)
662a6b7db3Sskrll    return 1;
672a6b7db3Sskrll
682a6b7db3Sskrll  return ((machs & cd->machs) != 0);
692a6b7db3Sskrll}
702a6b7db3Sskrll
712a6b7db3Sskrll/* A better hash function for instruction mnemonics.  */
722a6b7db3Sskrll
732a6b7db3Sskrllunsigned int
742a6b7db3Sskrllmt_asm_hash (const char* insn)
752a6b7db3Sskrll{
762a6b7db3Sskrll  unsigned int hash;
772a6b7db3Sskrll  const char* m = insn;
782a6b7db3Sskrll
792a6b7db3Sskrll  for (hash = 0; *m && ! ISSPACE (*m); m++)
802a6b7db3Sskrll    hash = (hash * 23) ^ (0x1F & TOLOWER (*m));
812a6b7db3Sskrll
822a6b7db3Sskrll  /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */
832a6b7db3Sskrll
842a6b7db3Sskrll  return hash % CGEN_ASM_HASH_SIZE;
852a6b7db3Sskrll}
862a6b7db3Sskrll
872a6b7db3Sskrll
882a6b7db3Sskrll/* -- asm.c */
892a6b7db3Sskrll/* Range checking for signed numbers.  Returns 0 if acceptable
902a6b7db3Sskrll   and 1 if the value is out of bounds for a signed quantity.  */
912a6b7db3Sskrll
922a6b7db3Sskrllstatic int
932a6b7db3Sskrllsigned_out_of_bounds (long val)
942a6b7db3Sskrll{
952a6b7db3Sskrll  if ((val < -32768) || (val > 32767))
962a6b7db3Sskrll    return 1;
972a6b7db3Sskrll  return 0;
982a6b7db3Sskrll}
992a6b7db3Sskrll
1002a6b7db3Sskrllstatic const char *
1012a6b7db3Sskrllparse_loopsize (CGEN_CPU_DESC cd,
1022a6b7db3Sskrll		const char **strp,
1032a6b7db3Sskrll		int opindex,
1042a6b7db3Sskrll		void *arg)
1052a6b7db3Sskrll{
1062a6b7db3Sskrll  signed long * valuep = (signed long *) arg;
1072a6b7db3Sskrll  const char *errmsg;
1082a6b7db3Sskrll  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
1092a6b7db3Sskrll  enum cgen_parse_operand_result result_type;
1102a6b7db3Sskrll  bfd_vma value;
1112a6b7db3Sskrll
1122a6b7db3Sskrll  /* Is it a control transfer instructions?  */
1132a6b7db3Sskrll  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_LOOPSIZE)
1142a6b7db3Sskrll    {
1152a6b7db3Sskrll      code = BFD_RELOC_MT_PCINSN8;
1162a6b7db3Sskrll      errmsg = cgen_parse_address (cd, strp, opindex, code,
1172a6b7db3Sskrll                                   & result_type, & value);
1182a6b7db3Sskrll      *valuep = value;
1192a6b7db3Sskrll      return errmsg;
1202a6b7db3Sskrll    }
1212a6b7db3Sskrll
1222a6b7db3Sskrll  abort ();
1232a6b7db3Sskrll}
1242a6b7db3Sskrll
1252a6b7db3Sskrllstatic const char *
1262a6b7db3Sskrllparse_imm16 (CGEN_CPU_DESC cd,
1272a6b7db3Sskrll	     const char **strp,
1282a6b7db3Sskrll	     int opindex,
1292a6b7db3Sskrll	     void *arg)
1302a6b7db3Sskrll{
1312a6b7db3Sskrll  signed long * valuep = (signed long *) arg;
1322a6b7db3Sskrll  const char *errmsg;
1332a6b7db3Sskrll  enum cgen_parse_operand_result result_type;
1342a6b7db3Sskrll  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
1352a6b7db3Sskrll  bfd_vma value;
1362a6b7db3Sskrll
1372a6b7db3Sskrll  /* Is it a control transfer instructions?  */
1382a6b7db3Sskrll  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16O)
1392a6b7db3Sskrll    {
1402a6b7db3Sskrll      code = BFD_RELOC_16_PCREL;
1412a6b7db3Sskrll      errmsg = cgen_parse_address (cd, strp, opindex, code,
1422a6b7db3Sskrll                                   & result_type, & value);
1432a6b7db3Sskrll      if (errmsg == NULL)
1442a6b7db3Sskrll	{
1452a6b7db3Sskrll	  if (signed_out_of_bounds (value))
1462a6b7db3Sskrll	    errmsg = _("Operand out of range. Must be between -32768 and 32767.");
1472a6b7db3Sskrll	}
1482a6b7db3Sskrll      *valuep = value;
1492a6b7db3Sskrll      return errmsg;
1502a6b7db3Sskrll    }
1512a6b7db3Sskrll
1522a6b7db3Sskrll  /* If it's not a control transfer instruction, then
1532a6b7db3Sskrll     we have to check for %OP relocating operators.  */
1542a6b7db3Sskrll  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16L)
1552a6b7db3Sskrll    ;
1562a6b7db3Sskrll  else if (strncmp (*strp, "%hi16", 5) == 0)
1572a6b7db3Sskrll    {
1582a6b7db3Sskrll      *strp += 5;
1592a6b7db3Sskrll      code = BFD_RELOC_HI16;
1602a6b7db3Sskrll    }
1612a6b7db3Sskrll  else if (strncmp (*strp, "%lo16", 5) == 0)
1622a6b7db3Sskrll    {
1632a6b7db3Sskrll      *strp += 5;
1642a6b7db3Sskrll      code = BFD_RELOC_LO16;
1652a6b7db3Sskrll    }
1662a6b7db3Sskrll
1672a6b7db3Sskrll  /* If we found a %OP relocating operator, then parse it as an address.
1682a6b7db3Sskrll     If not, we need to parse it as an integer, either signed or unsigned
1692a6b7db3Sskrll     depending on which operand type we have.  */
1702a6b7db3Sskrll  if (code != BFD_RELOC_NONE)
1712a6b7db3Sskrll    {
1722a6b7db3Sskrll       /* %OP relocating operator found.  */
1732a6b7db3Sskrll       errmsg = cgen_parse_address (cd, strp, opindex, code,
1742a6b7db3Sskrll                                   & result_type, & value);
1752a6b7db3Sskrll       if (errmsg == NULL)
1762a6b7db3Sskrll	 {
1772a6b7db3Sskrll           switch (result_type)
1782a6b7db3Sskrll	     {
1792a6b7db3Sskrll	     case (CGEN_PARSE_OPERAND_RESULT_NUMBER):
1802a6b7db3Sskrll	       if (code == BFD_RELOC_HI16)
1812a6b7db3Sskrll		 value = (value >> 16) & 0xFFFF;
1822a6b7db3Sskrll	       else if (code == BFD_RELOC_LO16)
1832a6b7db3Sskrll		 value = value  & 0xFFFF;
1842a6b7db3Sskrll	       else
1852a6b7db3Sskrll		 errmsg = _("Biiiig Trouble in parse_imm16!");
1862a6b7db3Sskrll	       break;
1872a6b7db3Sskrll
1882a6b7db3Sskrll	     case (CGEN_PARSE_OPERAND_RESULT_QUEUED):
1892a6b7db3Sskrll	       /* No special processing for this case.  */
1902a6b7db3Sskrll	       break;
1912a6b7db3Sskrll
1922a6b7db3Sskrll	     default:
1932a6b7db3Sskrll	       errmsg = _("The percent-operator's operand is not a symbol");
1942a6b7db3Sskrll	       break;
1952a6b7db3Sskrll             }
1962a6b7db3Sskrll	 }
1972a6b7db3Sskrll       *valuep = value;
1982a6b7db3Sskrll    }
1992a6b7db3Sskrll  else
2002a6b7db3Sskrll    {
2012a6b7db3Sskrll      /* Parse hex values like 0xffff as unsigned, and sign extend
2022a6b7db3Sskrll	 them manually.  */
2032a6b7db3Sskrll      int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MT_OPERAND_IMM16);
2042a6b7db3Sskrll
2052a6b7db3Sskrll      if ((*strp)[0] == '0'
2062a6b7db3Sskrll	  && ((*strp)[1] == 'x' || (*strp)[1] == 'X'))
2072a6b7db3Sskrll	parse_signed = 0;
2082a6b7db3Sskrll
2092a6b7db3Sskrll      /* No relocating operator.  Parse as an number.  */
2102a6b7db3Sskrll      if (parse_signed)
2112a6b7db3Sskrll	{
2122a6b7db3Sskrll          /* Parse as as signed integer.  */
2132a6b7db3Sskrll
2142a6b7db3Sskrll          errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
2152a6b7db3Sskrll
2162a6b7db3Sskrll          if (errmsg == NULL)
2172a6b7db3Sskrll	    {
2182a6b7db3Sskrll#if 0
2192a6b7db3Sskrll	      /* Manual range checking is needed for the signed case.  */
2202a6b7db3Sskrll	      if (*valuep & 0x8000)
2212a6b7db3Sskrll                value = 0xffff0000 | *valuep;
2222a6b7db3Sskrll	      else
2232a6b7db3Sskrll                value = *valuep;
2242a6b7db3Sskrll
2252a6b7db3Sskrll	      if (signed_out_of_bounds (value))
2262a6b7db3Sskrll	        errmsg = _("Operand out of range. Must be between -32768 and 32767.");
2272a6b7db3Sskrll	      /* Truncate to 16 bits. This is necessary
2282a6b7db3Sskrll		 because cgen will have sign extended *valuep.  */
2292a6b7db3Sskrll	      *valuep &= 0xFFFF;
2302a6b7db3Sskrll#endif
2312a6b7db3Sskrll	    }
2322a6b7db3Sskrll	}
2332a6b7db3Sskrll      else
2342a6b7db3Sskrll	{
2352a6b7db3Sskrll          /* MT_OPERAND_IMM16Z.  Parse as an unsigned integer.  */
2362a6b7db3Sskrll          errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep);
2372a6b7db3Sskrll
2382a6b7db3Sskrll	  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16
2392a6b7db3Sskrll	      && *valuep >= 0x8000
2402a6b7db3Sskrll	      && *valuep <= 0xffff)
2412a6b7db3Sskrll	    *valuep -= 0x10000;
2422a6b7db3Sskrll	}
2432a6b7db3Sskrll    }
2442a6b7db3Sskrll
2452a6b7db3Sskrll  return errmsg;
2462a6b7db3Sskrll}
2472a6b7db3Sskrll
2482a6b7db3Sskrll
2492a6b7db3Sskrllstatic const char *
2502a6b7db3Sskrllparse_dup (CGEN_CPU_DESC cd,
2512a6b7db3Sskrll	   const char **strp,
2522a6b7db3Sskrll	   int opindex,
2532a6b7db3Sskrll	   unsigned long *valuep)
2542a6b7db3Sskrll{
2552a6b7db3Sskrll  const char *errmsg = NULL;
2562a6b7db3Sskrll
2572a6b7db3Sskrll  if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0)
2582a6b7db3Sskrll    {
2592a6b7db3Sskrll      *strp += 3;
2602a6b7db3Sskrll      *valuep = 1;
2612a6b7db3Sskrll    }
2622a6b7db3Sskrll  else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0)
2632a6b7db3Sskrll    {
2642a6b7db3Sskrll      *strp += 2;
2652a6b7db3Sskrll      *valuep = 0;
2662a6b7db3Sskrll    }
2672a6b7db3Sskrll  else
2682a6b7db3Sskrll    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
2692a6b7db3Sskrll
2702a6b7db3Sskrll  return errmsg;
2712a6b7db3Sskrll}
2722a6b7db3Sskrll
2732a6b7db3Sskrll
2742a6b7db3Sskrllstatic const char *
2752a6b7db3Sskrllparse_ball (CGEN_CPU_DESC cd,
2762a6b7db3Sskrll	    const char **strp,
2772a6b7db3Sskrll	    int opindex,
2782a6b7db3Sskrll	    unsigned long *valuep)
2792a6b7db3Sskrll{
2802a6b7db3Sskrll  const char *errmsg = NULL;
2812a6b7db3Sskrll
2822a6b7db3Sskrll  if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0)
2832a6b7db3Sskrll    {
2842a6b7db3Sskrll      *strp += 3;
2852a6b7db3Sskrll      *valuep = 1;
2862a6b7db3Sskrll    }
2872a6b7db3Sskrll  else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0)
2882a6b7db3Sskrll    {
2892a6b7db3Sskrll      *strp += 3;
2902a6b7db3Sskrll      *valuep = 0;
2912a6b7db3Sskrll    }
2922a6b7db3Sskrll  else
2932a6b7db3Sskrll    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
2942a6b7db3Sskrll
2952a6b7db3Sskrll  return errmsg;
2962a6b7db3Sskrll}
2972a6b7db3Sskrll
2982a6b7db3Sskrllstatic const char *
2992a6b7db3Sskrllparse_xmode (CGEN_CPU_DESC cd,
3002a6b7db3Sskrll	     const char **strp,
3012a6b7db3Sskrll	     int opindex,
3022a6b7db3Sskrll	     unsigned long *valuep)
3032a6b7db3Sskrll{
3042a6b7db3Sskrll  const char *errmsg = NULL;
3052a6b7db3Sskrll
3062a6b7db3Sskrll  if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0)
3072a6b7db3Sskrll    {
3082a6b7db3Sskrll      *strp += 2;
3092a6b7db3Sskrll      *valuep = 1;
3102a6b7db3Sskrll    }
3112a6b7db3Sskrll  else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0)
3122a6b7db3Sskrll    {
3132a6b7db3Sskrll      *strp += 2;
3142a6b7db3Sskrll      *valuep = 0;
3152a6b7db3Sskrll    }
3162a6b7db3Sskrll  else
3172a6b7db3Sskrll    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
3182a6b7db3Sskrll
3192a6b7db3Sskrll  return errmsg;
3202a6b7db3Sskrll}
3212a6b7db3Sskrll
3222a6b7db3Sskrllstatic const char *
3232a6b7db3Sskrllparse_rc (CGEN_CPU_DESC cd,
3242a6b7db3Sskrll	  const char **strp,
3252a6b7db3Sskrll	  int opindex,
3262a6b7db3Sskrll	  unsigned long *valuep)
3272a6b7db3Sskrll{
3282a6b7db3Sskrll  const char *errmsg = NULL;
3292a6b7db3Sskrll
3302a6b7db3Sskrll  if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0)
3312a6b7db3Sskrll    {
3322a6b7db3Sskrll      *strp += 1;
3332a6b7db3Sskrll      *valuep = 1;
3342a6b7db3Sskrll    }
3352a6b7db3Sskrll  else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0)
3362a6b7db3Sskrll    {
3372a6b7db3Sskrll      *strp += 1;
3382a6b7db3Sskrll      *valuep = 0;
3392a6b7db3Sskrll    }
3402a6b7db3Sskrll  else
3412a6b7db3Sskrll    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
3422a6b7db3Sskrll
3432a6b7db3Sskrll  return errmsg;
3442a6b7db3Sskrll}
3452a6b7db3Sskrll
3462a6b7db3Sskrllstatic const char *
3472a6b7db3Sskrllparse_cbrb (CGEN_CPU_DESC cd,
3482a6b7db3Sskrll	    const char **strp,
3492a6b7db3Sskrll	    int opindex,
3502a6b7db3Sskrll	    unsigned long *valuep)
3512a6b7db3Sskrll{
3522a6b7db3Sskrll  const char *errmsg = NULL;
3532a6b7db3Sskrll
3542a6b7db3Sskrll  if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0)
3552a6b7db3Sskrll    {
3562a6b7db3Sskrll      *strp += 2;
3572a6b7db3Sskrll      *valuep = 1;
3582a6b7db3Sskrll    }
3592a6b7db3Sskrll  else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0)
3602a6b7db3Sskrll    {
3612a6b7db3Sskrll      *strp += 2;
3622a6b7db3Sskrll      *valuep = 0;
3632a6b7db3Sskrll    }
3642a6b7db3Sskrll  else
3652a6b7db3Sskrll    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
3662a6b7db3Sskrll
3672a6b7db3Sskrll  return errmsg;
3682a6b7db3Sskrll}
3692a6b7db3Sskrll
3702a6b7db3Sskrllstatic const char *
3712a6b7db3Sskrllparse_rbbc (CGEN_CPU_DESC cd,
3722a6b7db3Sskrll	    const char **strp,
3732a6b7db3Sskrll	    int opindex,
3742a6b7db3Sskrll	    unsigned long *valuep)
3752a6b7db3Sskrll{
3762a6b7db3Sskrll  const char *errmsg = NULL;
3772a6b7db3Sskrll
3782a6b7db3Sskrll  if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0)
3792a6b7db3Sskrll    {
3802a6b7db3Sskrll      *strp += 2;
3812a6b7db3Sskrll      *valuep = 0;
3822a6b7db3Sskrll    }
3832a6b7db3Sskrll  else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0)
3842a6b7db3Sskrll    {
3852a6b7db3Sskrll      *strp += 3;
3862a6b7db3Sskrll      *valuep = 1;
3872a6b7db3Sskrll    }
3882a6b7db3Sskrll  else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0)
3892a6b7db3Sskrll    {
3902a6b7db3Sskrll      *strp += 3;
3912a6b7db3Sskrll      *valuep = 2;
3922a6b7db3Sskrll    }
3932a6b7db3Sskrll  else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0)
3942a6b7db3Sskrll    {
3952a6b7db3Sskrll      *strp += 2;
3962a6b7db3Sskrll      *valuep = 3;
3972a6b7db3Sskrll    }
3982a6b7db3Sskrll  else
3992a6b7db3Sskrll    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
4002a6b7db3Sskrll
4012a6b7db3Sskrll  return errmsg;
4022a6b7db3Sskrll}
4032a6b7db3Sskrll
4042a6b7db3Sskrllstatic const char *
4052a6b7db3Sskrllparse_type (CGEN_CPU_DESC cd,
4062a6b7db3Sskrll	    const char **strp,
4072a6b7db3Sskrll	    int opindex,
4082a6b7db3Sskrll	    unsigned long *valuep)
4092a6b7db3Sskrll{
4102a6b7db3Sskrll  const char *errmsg = NULL;
4112a6b7db3Sskrll
4122a6b7db3Sskrll  if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0)
4132a6b7db3Sskrll    {
4142a6b7db3Sskrll      *strp += 3;
4152a6b7db3Sskrll      *valuep = 0;
4162a6b7db3Sskrll    }
4172a6b7db3Sskrll  else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0)
4182a6b7db3Sskrll    {
4192a6b7db3Sskrll      *strp += 4;
4202a6b7db3Sskrll      *valuep = 1;
4212a6b7db3Sskrll    }
4222a6b7db3Sskrll  else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0)
4232a6b7db3Sskrll    {
4242a6b7db3Sskrll      *strp += 2;
4252a6b7db3Sskrll      *valuep = 2;
4262a6b7db3Sskrll    }
4272a6b7db3Sskrll  else
4282a6b7db3Sskrll    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
4292a6b7db3Sskrll
4302a6b7db3Sskrll if ((errmsg == NULL) && (*valuep == 3))
4312a6b7db3Sskrll    errmsg = _("invalid operand.  type may have values 0,1,2 only.");
4322a6b7db3Sskrll
4332a6b7db3Sskrll  return errmsg;
4342a6b7db3Sskrll}
4352a6b7db3Sskrll
4362a6b7db3Sskrll/* -- dis.c */
4372a6b7db3Sskrllstatic void
4382a6b7db3Sskrllprint_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
4392a6b7db3Sskrll		 void * dis_info,
4402a6b7db3Sskrll		 long value,
4412a6b7db3Sskrll		 unsigned int attrs ATTRIBUTE_UNUSED,
4422a6b7db3Sskrll		 bfd_vma pc ATTRIBUTE_UNUSED,
4432a6b7db3Sskrll		 int length ATTRIBUTE_UNUSED)
4442a6b7db3Sskrll{
4452a6b7db3Sskrll  disassemble_info *info = (disassemble_info *) dis_info;
4462a6b7db3Sskrll
447*883529b6Schristos  info->fprintf_func (info->stream, "$%lx", value & 0xffffffff);
4482a6b7db3Sskrll
4492a6b7db3Sskrll  if (0)
4502a6b7db3Sskrll    print_normal (cd, dis_info, value, attrs, pc, length);
4512a6b7db3Sskrll}
4522a6b7db3Sskrll
4532a6b7db3Sskrllstatic void
4542a6b7db3Sskrllprint_pcrel (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
4552a6b7db3Sskrll	     void * dis_info,
4562a6b7db3Sskrll	     long value,
4572a6b7db3Sskrll	     unsigned int attrs ATTRIBUTE_UNUSED,
4582a6b7db3Sskrll	     bfd_vma pc ATTRIBUTE_UNUSED,
4592a6b7db3Sskrll	     int length ATTRIBUTE_UNUSED)
4602a6b7db3Sskrll{
4612a6b7db3Sskrll  print_address (cd, dis_info, value + pc, attrs, pc, length);
4622a6b7db3Sskrll}
4632a6b7db3Sskrll
4642a6b7db3Sskrll/* -- */
4652a6b7db3Sskrll
4662a6b7db3Sskrll
4672a6b7db3Sskrll
4682a6b7db3Sskrll
4692a6b7db3Sskrll
470