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