1/* Register names and numbers for IA64 DWARF.
2   Copyright (C) 2006 Red Hat, Inc.
3   This file is part of Red Hat elfutils.
4
5   Red Hat elfutils is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by the
7   Free Software Foundation; version 2 of the License.
8
9   Red Hat elfutils is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   General Public License for more details.
13
14   You should have received a copy of the GNU General Public License along
15   with Red Hat elfutils; if not, write to the Free Software Foundation,
16   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
17
18   Red Hat elfutils is an included package of the Open Invention Network.
19   An included package of the Open Invention Network is a package for which
20   Open Invention Network licensees cross-license their patents.  No patent
21   license is granted, either expressly or impliedly, by designation as an
22   included package.  Should you wish to participate in the Open Invention
23   Network licensing program, please visit www.openinventionnetwork.com
24   <http://www.openinventionnetwork.com>.  */
25
26#ifdef HAVE_CONFIG_H
27# include <config.h>
28#endif
29
30#include <string.h>
31#include <dwarf.h>
32
33#define BACKEND i386_
34#include "libebl_CPU.h"
35
36ssize_t
37ia64_register_info (Ebl *ebl __attribute__ ((unused)),
38		    int regno, char *name, size_t namelen,
39		    const char **prefix, const char **setname,
40		    int *bits, int *type)
41{
42  if (name == NULL)
43    return 687 + 64;
44
45  if (regno < 0 || regno > 687 + 63 || namelen < 12)
46    return -1;
47
48  *prefix = "ar.";
49  *setname = "application";
50  *bits = 64;
51  *type = DW_ATE_signed;
52  switch (regno)
53    {
54    case 0 ... 9:
55      name[0] = 'r';
56      name[1] = (regno - 0) + '0';
57      namelen = 2;
58      *setname = "integer";
59      *prefix = "";
60      break;
61
62    case 10 ... 99:
63      name[0] = 'r';
64      name[1] = (regno - 0) / 10 + '0';
65      name[2] = (regno - 0) % 10 + '0';
66      namelen = 3;
67      *setname = "integer";
68      *prefix = "";
69      break;
70
71    case 100 ... 127:
72      name[0] = 'r';
73      name[1] = '1';
74      name[2] = (regno - 100) / 10 + '0';
75      name[3] = (regno - 0) % 10 + '0';
76      namelen = 4;
77      *setname = "integer";
78      *prefix = "";
79      break;
80
81    case 128 + 0 ... 128 + 9:
82      name[0] = 'f';
83      name[1] = (regno - 128) + '0';
84      namelen = 2;
85      *type = DW_ATE_float;
86      *bits = 128;
87      *setname = "FPU";
88      *prefix = "";
89      break;
90
91    case 128 + 10 ... 128 + 99:
92      name[0] = 'f';
93      name[1] = (regno - 128) / 10 + '0';
94      name[2] = (regno - 128) % 10 + '0';
95      namelen = 3;
96      *setname = "FPU";
97      *prefix = "";
98      break;
99
100    case 128 + 100 ... 128 + 127:
101      name[0] = 'f';
102      name[1] = '1';
103      name[2] = (regno - 128 - 100) / 10 + '0';
104      name[3] = (regno - 128) % 10 + '0';
105      namelen = 4;
106      *type = DW_ATE_float;
107      *bits = 128;
108      *setname = "FPU";
109      *prefix = "";
110      break;
111
112    case 320 + 0 ... 320 + 7:
113      name[0] = 'b';
114      name[1] = (regno - 320) + '0';
115      namelen = 2;
116      *type = DW_ATE_address;
117      *setname = "branch";
118      *prefix = "";
119      break;
120
121    case 328 ... 333:
122      {
123	static const char named_special[][5] =
124	  {
125	    "vfp", "vrap", "pr", "ip", "psr", "cfm"
126	  };
127	*setname = "special";
128	*prefix = "";
129	*type = regno == 331 ? DW_ATE_address : DW_ATE_unsigned;
130	return stpcpy (name, named_special[regno - 328]) + 1 - name;
131      }
132
133    case 590:
134      *setname = "special";
135      *prefix = "";
136      *type = DW_ATE_unsigned;
137      return stpcpy (name, "bof") + 1 - name;
138
139    case 334 + 0 ... 334 + 7:
140      name[0] = 'k';
141      name[1] = 'r';
142      name[2] = (regno - 334) + '0';
143      namelen = 3;
144      *prefix = "";
145      break;
146
147    case 334 + 8 ... 334 + 127:
148      {
149	static const char named_ar[][9] =
150	  {
151	    [16 - 8] = "rsc",
152	    [17 - 8] = "bsp",
153	    [18 - 8] = "bspstore",
154	    [19 - 8] = "rnat",
155	    [21 - 8] = "fcr",
156	    [24 - 8] = "eflag",
157	    [25 - 8] = "csd",
158	    [26 - 8] = "ssd",
159	    [27 - 8] = "cflg",
160	    [28 - 8] = "fsr",
161	    [29 - 8] = "fir",
162	    [30 - 8] = "fdr",
163	    [32 - 8] = "ccv",
164	    [36 - 8] = "unat",
165	    [40 - 8] = "fpsr",
166	    [44 - 8] = "itc",
167	    [64 - 8] = "pfs",
168	    [65 - 8] = "lc",
169	    [66 - 8] = "ec",
170	  };
171	const size_t idx = regno - (334 + 8);
172	*type = DW_ATE_unsigned;
173	if (idx == 1 || idx == 2)
174	  *type = DW_ATE_address;
175	if (idx < sizeof named_ar / sizeof named_ar[0]
176	    && named_ar[idx][0] != '\0')
177	  return stpcpy (name, named_ar[idx]) + 1 - name;
178
179	name[0] = 'a';
180	name[1] = 'r';
181	switch (regno - 334)
182	  {
183	  case 0 ... 9:
184	    name[2] = (regno - 334) + '0';
185	    namelen = 3;
186	    break;
187	  case 10 ... 99:
188	    name[2] = (regno - 334) / 10 + '0';
189	    name[3] = (regno - 334) % 10 + '0';
190	    namelen = 4;
191	    break;
192	  case 100 ... 127:
193	    name[2] = '1';
194	    name[3] = (regno - 334 - 100) / 10 + '0';
195	    name[4] = (regno - 334) % 10 + '0';
196	    namelen = 5;
197	    break;
198	  }
199	*prefix = "";
200	break;
201      }
202
203    case 462 + 0 ... 462 + 9:
204      name[0] = 'n';
205      name[1] = 'a';
206      name[2] = 't';
207      name[3] = (regno - 462) + '0';
208      namelen = 4;
209      *setname = "NAT";
210      *type = DW_ATE_boolean;
211      *bits = 1;
212      *prefix = "";
213      break;
214
215    case 462 + 10 ... 462 + 99:
216      name[0] = 'n';
217      name[1] = 'a';
218      name[2] = 't';
219      name[3] = (regno - 462) / 10 + '0';
220      name[4] = (regno - 462) % 10 + '0';
221      namelen = 5;
222      *setname = "NAT";
223      *type = DW_ATE_boolean;
224      *bits = 1;
225      *prefix = "";
226      break;
227
228    case 462 + 100 ... 462 + 127:
229      name[0] = 'n';
230      name[1] = 'a';
231      name[2] = 't';
232      name[3] = '1';
233      name[4] = (regno - 462 - 100) / 10 + '0';
234      name[5] = (regno - 462) % 10 + '0';
235      namelen = 6;
236      *setname = "NAT";
237      *type = DW_ATE_boolean;
238      *bits = 1;
239      *prefix = "";
240      break;
241
242    case 687 + 0 ... 687 + 9:
243      name[0] = 'p';
244      name[1] = (regno - 687) + '0';
245      namelen = 2;
246      *setname = "predicate";
247      *type = DW_ATE_boolean;
248      *bits = 1;
249      *prefix = "";
250      break;
251
252    case 687 + 10 ... 687 + 63:
253      name[0] = 'p';
254      name[1] = (regno - 687) / 10 + '0';
255      name[2] = (regno - 687) % 10 + '0';
256      namelen = 3;
257      *setname = "predicate";
258      *type = DW_ATE_boolean;
259      *bits = 1;
260      *prefix = "";
261      break;
262
263    default:
264      *setname = NULL;
265      return 0;
266    }
267
268  name[namelen++] = '\0';
269  return namelen;
270}
271