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