1*440a403fSchristos/* OpenRISC 1000 opcode support.  -*- C -*-
2*440a403fSchristos   Copyright 2000-2014 Free Software Foundation, Inc.
3*440a403fSchristos
4*440a403fSchristos   Originally ontributed for OR32 by Red Hat Inc;
5*440a403fSchristos
6*440a403fSchristos   This file is part of the GNU Binutils.
7*440a403fSchristos
8*440a403fSchristos   This program is free software; you can redistribute it and/or modify
9*440a403fSchristos   it under the terms of the GNU General Public License as published by
10*440a403fSchristos   the Free Software Foundation; either version 3 of the License, or
11*440a403fSchristos   (at your option) any later version.
12*440a403fSchristos
13*440a403fSchristos   This program is distributed in the hope that it will be useful,
14*440a403fSchristos   but WITHOUT ANY WARRANTY; without even the implied warranty of
15*440a403fSchristos   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*440a403fSchristos   GNU General Public License for more details.
17*440a403fSchristos
18*440a403fSchristos   You should have received a copy of the GNU General Public License
19*440a403fSchristos   along with this program; if not, see <http://www.gnu.org/licenses/>. */
20*440a403fSchristos
21*440a403fSchristos/* This file is an addendum to or1k.cpu.  Heavy use of C code isn't
22*440a403fSchristos   appropriate in .cpu files, so it resides here.  This especially applies
23*440a403fSchristos   to assembly/disassembly where parsing/printing can be quite involved.
24*440a403fSchristos   Such things aren't really part of the specification of the cpu, per se,
25*440a403fSchristos   so .cpu files provide the general framework and .opc files handle the
26*440a403fSchristos   nitty-gritty details as necessary.
27*440a403fSchristos
28*440a403fSchristos   Each section is delimited with start and end markers.
29*440a403fSchristos
30*440a403fSchristos   <arch>-opc.h additions use: "-- opc.h"
31*440a403fSchristos   <arch>-opc.c additions use: "-- opc.c"
32*440a403fSchristos   <arch>-asm.c additions use: "-- asm.c"
33*440a403fSchristos   <arch>-dis.c additions use: "-- dis.c"
34*440a403fSchristos   <arch>-ibd.h additions use: "-- ibd.h"  */
35*440a403fSchristos
36*440a403fSchristos/* -- opc.h */
37*440a403fSchristos
38*440a403fSchristos#undef  CGEN_DIS_HASH_SIZE
39*440a403fSchristos#define CGEN_DIS_HASH_SIZE 256
40*440a403fSchristos#undef  CGEN_DIS_HASH
41*440a403fSchristos#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2)
42*440a403fSchristos
43*440a403fSchristos/* -- */
44*440a403fSchristos
45*440a403fSchristos/* -- opc.c */
46*440a403fSchristos/* -- */
47*440a403fSchristos
48*440a403fSchristos/* -- asm.c */
49*440a403fSchristos
50*440a403fSchristosstatic const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
51*440a403fSchristos
52*440a403fSchristos#define CGEN_VERBOSE_ASSEMBLER_ERRORS
53*440a403fSchristos
54*440a403fSchristosstatic const char *
55*440a403fSchristosparse_disp26 (CGEN_CPU_DESC cd,
56*440a403fSchristos	      const char ** strp,
57*440a403fSchristos	      int opindex,
58*440a403fSchristos	      int opinfo,
59*440a403fSchristos	      enum cgen_parse_operand_result * resultp,
60*440a403fSchristos	      bfd_vma * valuep)
61*440a403fSchristos{
62*440a403fSchristos  const char *errmsg = NULL;
63*440a403fSchristos  enum cgen_parse_operand_result result_type;
64*440a403fSchristos
65*440a403fSchristos  if (strncasecmp (*strp, "plt(", 4) == 0)
66*440a403fSchristos    {
67*440a403fSchristos      bfd_vma value;
68*440a403fSchristos
69*440a403fSchristos      *strp += 4;
70*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26,
71*440a403fSchristos				   & result_type, & value);
72*440a403fSchristos      if (**strp != ')')
73*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
74*440a403fSchristos      ++*strp;
75*440a403fSchristos      if (errmsg == NULL
76*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
77*440a403fSchristos	value = (value >> 2) & 0xffff;
78*440a403fSchristos      *valuep = value;
79*440a403fSchristos      return errmsg;
80*440a403fSchristos    }
81*440a403fSchristos  return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
82*440a403fSchristos}
83*440a403fSchristos
84*440a403fSchristosstatic const char *
85*440a403fSchristosparse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep)
86*440a403fSchristos{
87*440a403fSchristos  const char *errmsg;
88*440a403fSchristos  enum cgen_parse_operand_result result_type;
89*440a403fSchristos  long ret;
90*440a403fSchristos
91*440a403fSchristos  if (**strp == '#')
92*440a403fSchristos    ++*strp;
93*440a403fSchristos
94*440a403fSchristos  if (strncasecmp (*strp, "hi(", 3) == 0)
95*440a403fSchristos    {
96*440a403fSchristos      bfd_vma value;
97*440a403fSchristos
98*440a403fSchristos      *strp += 3;
99*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
100*440a403fSchristos				   & result_type, & value);
101*440a403fSchristos      if (**strp != ')')
102*440a403fSchristos	errmsg = MISSING_CLOSING_PARENTHESIS;
103*440a403fSchristos      ++*strp;
104*440a403fSchristos
105*440a403fSchristos      ret = value;
106*440a403fSchristos
107*440a403fSchristos      if (errmsg == NULL
108*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
109*440a403fSchristos	{
110*440a403fSchristos	  ret >>= 16;
111*440a403fSchristos	  ret &= 0xffff;
112*440a403fSchristos	  ret = (ret ^ 0x8000) - 0x8000;
113*440a403fSchristos	}
114*440a403fSchristos    }
115*440a403fSchristos  else if (strncasecmp (*strp, "lo(", 3) == 0)
116*440a403fSchristos    {
117*440a403fSchristos      bfd_vma value;
118*440a403fSchristos
119*440a403fSchristos      *strp += 3;
120*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
121*440a403fSchristos				   & result_type, & value);
122*440a403fSchristos      if (**strp != ')')
123*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
124*440a403fSchristos      ++*strp;
125*440a403fSchristos
126*440a403fSchristos      ret = value;
127*440a403fSchristos
128*440a403fSchristos      if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
129*440a403fSchristos	{
130*440a403fSchristos	  ret &= 0xffff;
131*440a403fSchristos	  ret = (ret ^ 0x8000) - 0x8000;
132*440a403fSchristos	}
133*440a403fSchristos    }
134*440a403fSchristos  else if (strncasecmp (*strp, "got(", 4) == 0)
135*440a403fSchristos    {
136*440a403fSchristos      bfd_vma value;
137*440a403fSchristos
138*440a403fSchristos      *strp += 4;
139*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16,
140*440a403fSchristos				   & result_type, & value);
141*440a403fSchristos      if (**strp != ')')
142*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
143*440a403fSchristos      ++*strp;
144*440a403fSchristos      if (errmsg == NULL
145*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
146*440a403fSchristos	value &= 0xffff;
147*440a403fSchristos      *valuep = value;
148*440a403fSchristos      return errmsg;
149*440a403fSchristos    }
150*440a403fSchristos  else if (strncasecmp (*strp, "gotpchi(", 8) == 0)
151*440a403fSchristos    {
152*440a403fSchristos      bfd_vma value;
153*440a403fSchristos
154*440a403fSchristos      *strp += 8;
155*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
156*440a403fSchristos				   BFD_RELOC_OR1K_GOTPC_HI16,
157*440a403fSchristos				   & result_type, & value);
158*440a403fSchristos      if (**strp != ')')
159*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
160*440a403fSchristos      ++*strp;
161*440a403fSchristos      if (errmsg == NULL
162*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
163*440a403fSchristos	value = (value >> 16) & 0xffff;
164*440a403fSchristos      *valuep = value;
165*440a403fSchristos      return errmsg;
166*440a403fSchristos    }
167*440a403fSchristos  else if (strncasecmp (*strp, "gotpclo(", 8) == 0)
168*440a403fSchristos    {
169*440a403fSchristos      bfd_vma value;
170*440a403fSchristos
171*440a403fSchristos      *strp += 8;
172*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
173*440a403fSchristos				   BFD_RELOC_OR1K_GOTPC_LO16,
174*440a403fSchristos				   &result_type, &value);
175*440a403fSchristos      if (**strp != ')')
176*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
177*440a403fSchristos      ++*strp;
178*440a403fSchristos      if (errmsg == NULL
179*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
180*440a403fSchristos	value &= 0xffff;
181*440a403fSchristos      *valuep = value;
182*440a403fSchristos      return errmsg;
183*440a403fSchristos    }
184*440a403fSchristos  else if (strncasecmp (*strp, "gotoffhi(", 9) == 0)
185*440a403fSchristos    {
186*440a403fSchristos      bfd_vma value;
187*440a403fSchristos
188*440a403fSchristos      *strp += 9;
189*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
190*440a403fSchristos				   BFD_RELOC_OR1K_GOTOFF_HI16,
191*440a403fSchristos				   & result_type, & value);
192*440a403fSchristos
193*440a403fSchristos      if (**strp != ')')
194*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
195*440a403fSchristos      ++*strp;
196*440a403fSchristos      if (errmsg == NULL
197*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
198*440a403fSchristos	value = (value >> 16) & 0xffff;
199*440a403fSchristos      *valuep = value;
200*440a403fSchristos      return errmsg;
201*440a403fSchristos    }
202*440a403fSchristos  else if (strncasecmp (*strp, "gotofflo(", 9) == 0)
203*440a403fSchristos    {
204*440a403fSchristos      bfd_vma value;
205*440a403fSchristos
206*440a403fSchristos      *strp += 9;
207*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
208*440a403fSchristos				   BFD_RELOC_OR1K_GOTOFF_LO16,
209*440a403fSchristos				   &result_type, &value);
210*440a403fSchristos      if (**strp != ')')
211*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
212*440a403fSchristos      ++*strp;
213*440a403fSchristos      if (errmsg == NULL
214*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
215*440a403fSchristos	value &= 0xffff;
216*440a403fSchristos      *valuep = value;
217*440a403fSchristos      return errmsg;
218*440a403fSchristos    }
219*440a403fSchristos  else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0)
220*440a403fSchristos    {
221*440a403fSchristos      bfd_vma value;
222*440a403fSchristos
223*440a403fSchristos      *strp += 8;
224*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
225*440a403fSchristos				   BFD_RELOC_OR1K_TLS_GD_HI16,
226*440a403fSchristos				   & result_type, & value);
227*440a403fSchristos
228*440a403fSchristos      if (**strp != ')')
229*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
230*440a403fSchristos      ++*strp;
231*440a403fSchristos      if (errmsg == NULL
232*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
233*440a403fSchristos	value = (value >> 16) & 0xffff;
234*440a403fSchristos      *valuep = value;
235*440a403fSchristos      return errmsg;
236*440a403fSchristos    }
237*440a403fSchristos  else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0)
238*440a403fSchristos    {
239*440a403fSchristos      bfd_vma value;
240*440a403fSchristos
241*440a403fSchristos      *strp += 8;
242*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
243*440a403fSchristos				   BFD_RELOC_OR1K_TLS_GD_LO16,
244*440a403fSchristos				   &result_type, &value);
245*440a403fSchristos      if (**strp != ')')
246*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
247*440a403fSchristos      ++*strp;
248*440a403fSchristos      if (errmsg == NULL
249*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
250*440a403fSchristos	value &= 0xffff;
251*440a403fSchristos      *valuep = value;
252*440a403fSchristos      return errmsg;
253*440a403fSchristos    }
254*440a403fSchristos  else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0)
255*440a403fSchristos    {
256*440a403fSchristos      bfd_vma value;
257*440a403fSchristos
258*440a403fSchristos      *strp += 9;
259*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
260*440a403fSchristos				   BFD_RELOC_OR1K_TLS_LDM_HI16,
261*440a403fSchristos				   & result_type, & value);
262*440a403fSchristos
263*440a403fSchristos      if (**strp != ')')
264*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
265*440a403fSchristos      ++*strp;
266*440a403fSchristos      if (errmsg == NULL
267*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
268*440a403fSchristos	value = (value >> 16) & 0xffff;
269*440a403fSchristos      *valuep = value;
270*440a403fSchristos      return errmsg;
271*440a403fSchristos    }
272*440a403fSchristos  else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0)
273*440a403fSchristos    {
274*440a403fSchristos      bfd_vma value;
275*440a403fSchristos
276*440a403fSchristos      *strp += 9;
277*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
278*440a403fSchristos				   BFD_RELOC_OR1K_TLS_LDM_LO16,
279*440a403fSchristos				   &result_type, &value);
280*440a403fSchristos      if (**strp != ')')
281*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
282*440a403fSchristos      ++*strp;
283*440a403fSchristos      if (errmsg == NULL
284*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
285*440a403fSchristos	value &= 0xffff;
286*440a403fSchristos      *valuep = value;
287*440a403fSchristos      return errmsg;
288*440a403fSchristos    }
289*440a403fSchristos  else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0)
290*440a403fSchristos    {
291*440a403fSchristos      bfd_vma value;
292*440a403fSchristos
293*440a403fSchristos      *strp += 9;
294*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
295*440a403fSchristos				   BFD_RELOC_OR1K_TLS_LDO_HI16,
296*440a403fSchristos				   & result_type, & value);
297*440a403fSchristos
298*440a403fSchristos      if (**strp != ')')
299*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
300*440a403fSchristos      ++*strp;
301*440a403fSchristos      if (errmsg == NULL
302*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
303*440a403fSchristos	value = (value >> 16) & 0xffff;
304*440a403fSchristos      *valuep = value;
305*440a403fSchristos      return errmsg;
306*440a403fSchristos    }
307*440a403fSchristos  else if (strncasecmp (*strp, "dtpofflo(", 9) == 0)
308*440a403fSchristos    {
309*440a403fSchristos      bfd_vma value;
310*440a403fSchristos
311*440a403fSchristos      *strp += 9;
312*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
313*440a403fSchristos				   BFD_RELOC_OR1K_TLS_LDO_LO16,
314*440a403fSchristos				   &result_type, &value);
315*440a403fSchristos      if (**strp != ')')
316*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
317*440a403fSchristos      ++*strp;
318*440a403fSchristos      if (errmsg == NULL
319*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
320*440a403fSchristos	value &= 0xffff;
321*440a403fSchristos      *valuep = value;
322*440a403fSchristos      return errmsg;
323*440a403fSchristos    }
324*440a403fSchristos  else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0)
325*440a403fSchristos    {
326*440a403fSchristos      bfd_vma value;
327*440a403fSchristos
328*440a403fSchristos      *strp += 11;
329*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
330*440a403fSchristos				   BFD_RELOC_OR1K_TLS_IE_HI16,
331*440a403fSchristos				   & result_type, & value);
332*440a403fSchristos
333*440a403fSchristos      if (**strp != ')')
334*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
335*440a403fSchristos      ++*strp;
336*440a403fSchristos      if (errmsg == NULL
337*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
338*440a403fSchristos	value = (value >> 16) & 0xffff;
339*440a403fSchristos      *valuep = value;
340*440a403fSchristos      return errmsg;
341*440a403fSchristos    }
342*440a403fSchristos  else if (strncasecmp (*strp, "gottpofflo(", 11) == 0)
343*440a403fSchristos    {
344*440a403fSchristos      bfd_vma value;
345*440a403fSchristos
346*440a403fSchristos      *strp += 11;
347*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
348*440a403fSchristos				   BFD_RELOC_OR1K_TLS_IE_LO16,
349*440a403fSchristos				   &result_type, &value);
350*440a403fSchristos      if (**strp != ')')
351*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
352*440a403fSchristos      ++*strp;
353*440a403fSchristos      if (errmsg == NULL
354*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
355*440a403fSchristos	value &= 0xffff;
356*440a403fSchristos      *valuep = value;
357*440a403fSchristos      return errmsg;
358*440a403fSchristos    }
359*440a403fSchristos  else if (strncasecmp (*strp, "tpoffhi(", 8) == 0)
360*440a403fSchristos    {
361*440a403fSchristos      bfd_vma value;
362*440a403fSchristos
363*440a403fSchristos      *strp += 8;
364*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
365*440a403fSchristos				   BFD_RELOC_OR1K_TLS_LE_HI16,
366*440a403fSchristos				   & result_type, & value);
367*440a403fSchristos
368*440a403fSchristos      if (**strp != ')')
369*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
370*440a403fSchristos      ++*strp;
371*440a403fSchristos      if (errmsg == NULL
372*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
373*440a403fSchristos	value = (value >> 16) & 0xffff;
374*440a403fSchristos      *valuep = value;
375*440a403fSchristos      return errmsg;
376*440a403fSchristos    }
377*440a403fSchristos  else if (strncasecmp (*strp, "tpofflo(", 8) == 0)
378*440a403fSchristos    {
379*440a403fSchristos      bfd_vma value;
380*440a403fSchristos
381*440a403fSchristos      *strp += 8;
382*440a403fSchristos      errmsg = cgen_parse_address (cd, strp, opindex,
383*440a403fSchristos				   BFD_RELOC_OR1K_TLS_LE_LO16,
384*440a403fSchristos				   &result_type, &value);
385*440a403fSchristos      if (**strp != ')')
386*440a403fSchristos	return MISSING_CLOSING_PARENTHESIS;
387*440a403fSchristos      ++*strp;
388*440a403fSchristos      if (errmsg == NULL
389*440a403fSchristos	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
390*440a403fSchristos	value &= 0xffff;
391*440a403fSchristos      *valuep = value;
392*440a403fSchristos      return errmsg;
393*440a403fSchristos    }
394*440a403fSchristos  else
395*440a403fSchristos    {
396*440a403fSchristos      long value;
397*440a403fSchristos      errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
398*440a403fSchristos      ret = value;
399*440a403fSchristos    }
400*440a403fSchristos
401*440a403fSchristos  if (errmsg == NULL)
402*440a403fSchristos    *valuep = ret;
403*440a403fSchristos
404*440a403fSchristos  return errmsg;
405*440a403fSchristos}
406*440a403fSchristos
407*440a403fSchristosstatic const char *
408*440a403fSchristosparse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep)
409*440a403fSchristos{
410*440a403fSchristos  const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep);
411*440a403fSchristos
412*440a403fSchristos  if (errmsg == NULL)
413*440a403fSchristos    *valuep &= 0xffff;
414*440a403fSchristos  return errmsg;
415*440a403fSchristos}
416*440a403fSchristos
417*440a403fSchristos/* -- */
418*440a403fSchristos
419*440a403fSchristos/* -- ibd.h */
420*440a403fSchristos
421*440a403fSchristos/* -- */
422