xref: /netbsd-src/external/gpl3/binutils/dist/cpu/lm32.opc (revision be12b8bcaf6171e22ce54bb82a70fb1a78be9ab5)
1*be12b8bcSchristos/* Lattice Mico32 opcode support.  -*- C -*-
2*be12b8bcSchristos   Copyright 2008, 2009  Free Software Foundation, Inc.
3*be12b8bcSchristos   Contributed by Jon Beniston <jon@beniston.com>
4*be12b8bcSchristos
5*be12b8bcSchristos   This file is part of the GNU Binutils.
6*be12b8bcSchristos
7*be12b8bcSchristos   This program is free software; you can redistribute it and/or modify
8*be12b8bcSchristos   it under the terms of the GNU General Public License as published by
9*be12b8bcSchristos   the Free Software Foundation; either version 3 of the License, or
10*be12b8bcSchristos   (at your option) any later version.
11*be12b8bcSchristos
12*be12b8bcSchristos   This program is distributed in the hope that it will be useful,
13*be12b8bcSchristos   but WITHOUT ANY WARRANTY; without even the implied warranty of
14*be12b8bcSchristos   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*be12b8bcSchristos   GNU General Public License for more details.
16*be12b8bcSchristos
17*be12b8bcSchristos   You should have received a copy of the GNU General Public License
18*be12b8bcSchristos   along with this program; if not, write to the Free Software
19*be12b8bcSchristos   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20*be12b8bcSchristos   MA 02110-1301, USA.  */
21*be12b8bcSchristos
22*be12b8bcSchristos/* -- opc.h */
23*be12b8bcSchristos
24*be12b8bcSchristos/* Allows reason codes to be output when assembler errors occur.  */
25*be12b8bcSchristos#define CGEN_VERBOSE_ASSEMBLER_ERRORS
26*be12b8bcSchristos
27*be12b8bcSchristos#define CGEN_DIS_HASH_SIZE 64
28*be12b8bcSchristos#define CGEN_DIS_HASH(buf,value) ((value >> 26) & 0x3f)
29*be12b8bcSchristos
30*be12b8bcSchristos/* -- asm.c */
31*be12b8bcSchristos
32*be12b8bcSchristos/* Handle signed/unsigned literal.  */
33*be12b8bcSchristos
34*be12b8bcSchristosstatic const char *
35*be12b8bcSchristosparse_imm (CGEN_CPU_DESC cd,
36*be12b8bcSchristos	   const char **strp,
37*be12b8bcSchristos	   int opindex,
38*be12b8bcSchristos	   unsigned long *valuep)
39*be12b8bcSchristos{
40*be12b8bcSchristos  const char *errmsg;
41*be12b8bcSchristos  signed long value;
42*be12b8bcSchristos
43*be12b8bcSchristos  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
44*be12b8bcSchristos  if (errmsg == NULL)
45*be12b8bcSchristos    {
46*be12b8bcSchristos      unsigned long x = value & 0xFFFF0000;
47*be12b8bcSchristos      if (x != 0 && x != 0xFFFF0000)
48*be12b8bcSchristos        errmsg = _("immediate value out of range");
49*be12b8bcSchristos      else
50*be12b8bcSchristos        *valuep = (value & 0xFFFF);
51*be12b8bcSchristos    }
52*be12b8bcSchristos  return errmsg;
53*be12b8bcSchristos}
54*be12b8bcSchristos
55*be12b8bcSchristos/* Handle hi() */
56*be12b8bcSchristos
57*be12b8bcSchristosstatic const char *
58*be12b8bcSchristosparse_hi16 (CGEN_CPU_DESC cd,
59*be12b8bcSchristos	    const char **strp,
60*be12b8bcSchristos	    int opindex,
61*be12b8bcSchristos	    unsigned long *valuep)
62*be12b8bcSchristos{
63*be12b8bcSchristos  if (strncasecmp (*strp, "hi(", 3) == 0)
64*be12b8bcSchristos    {
65*be12b8bcSchristos      enum cgen_parse_operand_result result_type;
66*be12b8bcSchristos      bfd_vma value;
67*be12b8bcSchristos      const char *errmsg;
68*be12b8bcSchristos
69*be12b8bcSchristos      *strp += 3;
70*be12b8bcSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
71*be12b8bcSchristos                                   &result_type, &value);
72*be12b8bcSchristos      if (**strp != ')')
73*be12b8bcSchristos        return _("missing `)'");
74*be12b8bcSchristos
75*be12b8bcSchristos      ++*strp;
76*be12b8bcSchristos      if (errmsg == NULL
77*be12b8bcSchristos          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
78*be12b8bcSchristos        value = (value >> 16) & 0xffff;
79*be12b8bcSchristos      *valuep = value;
80*be12b8bcSchristos
81*be12b8bcSchristos      return errmsg;
82*be12b8bcSchristos    }
83*be12b8bcSchristos
84*be12b8bcSchristos  return parse_imm (cd, strp, opindex, valuep);
85*be12b8bcSchristos}
86*be12b8bcSchristos
87*be12b8bcSchristos/* Handle lo() */
88*be12b8bcSchristos
89*be12b8bcSchristosstatic const char *
90*be12b8bcSchristosparse_lo16 (CGEN_CPU_DESC cd,
91*be12b8bcSchristos	    const char **strp,
92*be12b8bcSchristos	    int opindex,
93*be12b8bcSchristos	    unsigned long *valuep)
94*be12b8bcSchristos{
95*be12b8bcSchristos  if (strncasecmp (*strp, "lo(", 3) == 0)
96*be12b8bcSchristos    {
97*be12b8bcSchristos      const char *errmsg;
98*be12b8bcSchristos      enum cgen_parse_operand_result result_type;
99*be12b8bcSchristos      bfd_vma value;
100*be12b8bcSchristos
101*be12b8bcSchristos      *strp += 3;
102*be12b8bcSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
103*be12b8bcSchristos                                   &result_type, &value);
104*be12b8bcSchristos      if (**strp != ')')
105*be12b8bcSchristos        return _("missing `)'");
106*be12b8bcSchristos      ++*strp;
107*be12b8bcSchristos      if (errmsg == NULL
108*be12b8bcSchristos          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
109*be12b8bcSchristos        value &= 0xffff;
110*be12b8bcSchristos      *valuep = value;
111*be12b8bcSchristos      return errmsg;
112*be12b8bcSchristos    }
113*be12b8bcSchristos
114*be12b8bcSchristos  return parse_imm (cd, strp, opindex, valuep);
115*be12b8bcSchristos}
116*be12b8bcSchristos
117*be12b8bcSchristos/* Handle gp() */
118*be12b8bcSchristos
119*be12b8bcSchristosstatic const char *
120*be12b8bcSchristosparse_gp16 (CGEN_CPU_DESC cd,
121*be12b8bcSchristos	    const char **strp,
122*be12b8bcSchristos	    int opindex,
123*be12b8bcSchristos	    long *valuep)
124*be12b8bcSchristos{
125*be12b8bcSchristos  if (strncasecmp (*strp, "gp(", 3) == 0)
126*be12b8bcSchristos    {
127*be12b8bcSchristos      const char *errmsg;
128*be12b8bcSchristos      enum cgen_parse_operand_result result_type;
129*be12b8bcSchristos      bfd_vma value;
130*be12b8bcSchristos
131*be12b8bcSchristos      *strp += 3;
132*be12b8bcSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_GPREL16,
133*be12b8bcSchristos                                   & result_type, & value);
134*be12b8bcSchristos      if (**strp != ')')
135*be12b8bcSchristos        return _("missing `)'");
136*be12b8bcSchristos      ++*strp;
137*be12b8bcSchristos      if (errmsg == NULL
138*be12b8bcSchristos          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
139*be12b8bcSchristos        value &= 0xffff;
140*be12b8bcSchristos      *valuep = value;
141*be12b8bcSchristos      return errmsg;
142*be12b8bcSchristos    }
143*be12b8bcSchristos
144*be12b8bcSchristos  return _("expecting gp relative address: gp(symbol)");
145*be12b8bcSchristos}
146*be12b8bcSchristos
147*be12b8bcSchristos/* Handle got() */
148*be12b8bcSchristos
149*be12b8bcSchristosstatic const char *
150*be12b8bcSchristosparse_got16 (CGEN_CPU_DESC cd,
151*be12b8bcSchristos	     const char **strp,
152*be12b8bcSchristos	     int opindex,
153*be12b8bcSchristos	     long *valuep)
154*be12b8bcSchristos{
155*be12b8bcSchristos  if (strncasecmp (*strp, "got(", 4) == 0)
156*be12b8bcSchristos    {
157*be12b8bcSchristos      const char *errmsg;
158*be12b8bcSchristos      enum cgen_parse_operand_result result_type;
159*be12b8bcSchristos      bfd_vma value;
160*be12b8bcSchristos
161*be12b8bcSchristos      *strp += 4;
162*be12b8bcSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_16_GOT,
163*be12b8bcSchristos                                   & result_type, & value);
164*be12b8bcSchristos      if (**strp != ')')
165*be12b8bcSchristos        return _("missing `)'");
166*be12b8bcSchristos      ++*strp;
167*be12b8bcSchristos      if (errmsg == NULL
168*be12b8bcSchristos          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
169*be12b8bcSchristos        value &= 0xffff;
170*be12b8bcSchristos      *valuep = value;
171*be12b8bcSchristos      return errmsg;
172*be12b8bcSchristos    }
173*be12b8bcSchristos
174*be12b8bcSchristos  return _("expecting got relative address: got(symbol)");
175*be12b8bcSchristos}
176*be12b8bcSchristos
177*be12b8bcSchristos/* Handle gotoffhi16() */
178*be12b8bcSchristos
179*be12b8bcSchristosstatic const char *
180*be12b8bcSchristosparse_gotoff_hi16 (CGEN_CPU_DESC cd,
181*be12b8bcSchristos		   const char **strp,
182*be12b8bcSchristos		   int opindex,
183*be12b8bcSchristos		   long *valuep)
184*be12b8bcSchristos{
185*be12b8bcSchristos  if (strncasecmp (*strp, "gotoffhi16(", 11) == 0)
186*be12b8bcSchristos    {
187*be12b8bcSchristos      const char *errmsg;
188*be12b8bcSchristos      enum cgen_parse_operand_result result_type;
189*be12b8bcSchristos      bfd_vma value;
190*be12b8bcSchristos
191*be12b8bcSchristos      *strp += 11;
192*be12b8bcSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_HI16,
193*be12b8bcSchristos                                   & result_type, & value);
194*be12b8bcSchristos      if (**strp != ')')
195*be12b8bcSchristos        return _("missing `)'");
196*be12b8bcSchristos      ++*strp;
197*be12b8bcSchristos      if (errmsg == NULL
198*be12b8bcSchristos          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
199*be12b8bcSchristos        value &= 0xffff;
200*be12b8bcSchristos      *valuep = value;
201*be12b8bcSchristos      return errmsg;
202*be12b8bcSchristos    }
203*be12b8bcSchristos
204*be12b8bcSchristos  return _("expecting got relative address: gotoffhi16(symbol)");
205*be12b8bcSchristos}
206*be12b8bcSchristos
207*be12b8bcSchristos/* Handle gotofflo16() */
208*be12b8bcSchristos
209*be12b8bcSchristosstatic const char *
210*be12b8bcSchristosparse_gotoff_lo16 (CGEN_CPU_DESC cd,
211*be12b8bcSchristos		   const char **strp,
212*be12b8bcSchristos		   int opindex,
213*be12b8bcSchristos		   long *valuep)
214*be12b8bcSchristos{
215*be12b8bcSchristos  if (strncasecmp (*strp, "gotofflo16(", 11) == 0)
216*be12b8bcSchristos    {
217*be12b8bcSchristos      const char *errmsg;
218*be12b8bcSchristos      enum cgen_parse_operand_result result_type;
219*be12b8bcSchristos      bfd_vma value;
220*be12b8bcSchristos
221*be12b8bcSchristos      *strp += 11;
222*be12b8bcSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_LO16,
223*be12b8bcSchristos                                   &result_type, &value);
224*be12b8bcSchristos      if (**strp != ')')
225*be12b8bcSchristos        return _("missing `)'");
226*be12b8bcSchristos      ++*strp;
227*be12b8bcSchristos      if (errmsg == NULL
228*be12b8bcSchristos          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
229*be12b8bcSchristos        value &= 0xffff;
230*be12b8bcSchristos      *valuep = value;
231*be12b8bcSchristos      return errmsg;
232*be12b8bcSchristos    }
233*be12b8bcSchristos
234*be12b8bcSchristos  return _("expecting got relative address: gotofflo16(symbol)");
235*be12b8bcSchristos}
236