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