1/* Register names and numbers for PowerPC DWARF.
2   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
3   This file is part of elfutils.
4
5   This file is free software; you can redistribute it and/or modify
6   it under the terms of either
7
8     * the GNU Lesser General Public License as published by the Free
9       Software Foundation; either version 3 of the License, or (at
10       your option) any later version
11
12   or
13
14     * the GNU General Public License as published by the Free
15       Software Foundation; either version 2 of the License, or (at
16       your option) any later version
17
18   or both in parallel, as here.
19
20   elfutils is distributed in the hope that it will be useful, but
21   WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   General Public License for more details.
24
25   You should have received copies of the GNU General Public License and
26   the GNU Lesser General Public License along with this program.  If
27   not, see <http://www.gnu.org/licenses/>.  */
28
29#ifdef HAVE_CONFIG_H
30# include <config.h>
31#endif
32
33#include <string.h>
34#include <dwarf.h>
35
36#define BACKEND ppc_
37#include "libebl_CPU.h"
38
39ssize_t
40ppc_register_info (Ebl *ebl __attribute__ ((unused)),
41		   int regno, char *name, size_t namelen,
42		   const char **prefix, const char **setname,
43		   int *bits, int *type)
44{
45  if (name == NULL)
46    return 1156;
47
48  if (regno < 0 || regno > 1155 || namelen < 8)
49    return -1;
50
51  *prefix = "";
52  *bits = ebl->machine == EM_PPC64 ? 64 : 32;
53  *type = (regno < 32 ? DW_ATE_signed
54	   : regno < 64 ? DW_ATE_float : DW_ATE_unsigned);
55
56  if (regno < 32 || regno == 64 || regno == 66)
57    *setname = "integer";
58  else if (regno < 64 || regno == 65)
59    {
60      *setname = "FPU";
61      if (ebl->machine != EM_PPC64 && regno < 64)
62	*bits = 64;
63    }
64  else if (regno == 67 || regno == 356 || regno == 612 || regno >= 1124)
65    {
66      *setname = "vector";
67      *bits = regno >= 1124 ? 128 : 32;
68    }
69  else
70    *setname = "privileged";
71
72  switch (regno)
73    {
74    case 0 ... 9:
75      name[0] = 'r';
76      name[1] = regno + '0';
77      namelen = 2;
78      break;
79
80    case 10 ... 31:
81      name[0] = 'r';
82      name[1] = regno / 10 + '0';
83      name[2] = regno % 10 + '0';
84      namelen = 3;
85      break;
86
87    case 32 + 0 ... 32 + 9:
88      name[0] = 'f';
89      name[1] = (regno - 32) + '0';
90      namelen = 2;
91      break;
92
93    case 32 + 10 ... 32 + 31:
94      name[0] = 'f';
95      name[1] = (regno - 32) / 10 + '0';
96      name[2] = (regno - 32) % 10 + '0';
97      namelen = 3;
98      break;
99
100    case 64:
101      return stpcpy (name, "cr") + 1 - name;
102    case 65:
103      return stpcpy (name, "fpscr") + 1 - name;
104    case 66:
105      return stpcpy (name, "msr") + 1 - name;
106    case 67:			/* XXX unofficial assignment */
107      return stpcpy (name, "vscr") + 1 - name;
108
109    case 70 + 0 ... 70 + 9:
110      name[0] = 's';
111      name[1] = 'r';
112      name[2] = (regno - 70) + '0';
113      namelen = 3;
114      break;
115
116    case 70 + 10 ... 70 + 15:
117      name[0] = 's';
118      name[1] = 'r';
119      name[2] = (regno - 70) / 10 + '0';
120      name[3] = (regno - 70) % 10 + '0';
121      namelen = 4;
122      break;
123
124    case 101:
125      return stpcpy (name, "xer") + 1 - name;
126    case 108:
127      return stpcpy (name, "lr") + 1 - name;
128    case 109:
129      return stpcpy (name, "ctr") + 1 - name;
130    case 118:
131      return stpcpy (name, "dsisr") + 1 - name;
132    case 119:
133      return stpcpy (name, "dar") + 1 - name;
134    case 122:
135      return stpcpy (name, "dec") + 1 - name;
136    case 356:
137      return stpcpy (name, "vrsave") + 1 - name;
138    case 612:
139      return stpcpy (name, "spefscr") + 1 - name;
140    case 100:
141      if (*bits == 32)
142	return stpcpy (name, "mq") + 1 - name;
143
144    case 102 ... 107:
145      name[0] = 's';
146      name[1] = 'p';
147      name[2] = 'r';
148      name[3] = (regno - 100) + '0';
149      namelen = 4;
150      break;
151
152    case 110 ... 117:
153    case 120 ... 121:
154    case 123 ... 199:
155      name[0] = 's';
156      name[1] = 'p';
157      name[2] = 'r';
158      name[3] = (regno - 100) / 10 + '0';
159      name[4] = (regno - 100) % 10 + '0';
160      namelen = 5;
161      break;
162
163    case 200 ... 355:
164    case 357 ... 611:
165    case 613 ... 999:
166      name[0] = 's';
167      name[1] = 'p';
168      name[2] = 'r';
169      name[3] = (regno - 100) / 100 + '0';
170      name[4] = ((regno - 100) % 100 / 10) + '0';
171      name[5] = (regno - 100) % 10 + '0';
172      namelen = 6;
173      break;
174
175    case 1124 + 0 ... 1124 + 9:
176      name[0] = 'v';
177      name[1] = 'r';
178      name[2] = (regno - 1124) + '0';
179      namelen = 3;
180      break;
181
182    case 1124 + 10 ... 1124 + 31:
183      name[0] = 'v';
184      name[1] = 'r';
185      name[2] = (regno - 1124) / 10 + '0';
186      name[3] = (regno - 1124) % 10 + '0';
187      namelen = 4;
188      break;
189
190    default:
191      *setname = NULL;
192      return 0;
193    }
194
195  name[namelen++] = '\0';
196  return namelen;
197}
198
199__typeof (ppc_register_info)
200     ppc64_register_info __attribute__ ((alias ("ppc_register_info")));
201