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