1/* Register names and numbers for PowerPC DWARF.
2   Copyright (C) 2005, 2006, 2007 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 ppc_
34#include "libebl_CPU.h"
35
36ssize_t
37ppc_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 1156;
44
45  if (regno < 0 || regno > 1155 || namelen < 8)
46    return -1;
47
48  *prefix = NULL;
49  *bits = ebl->machine == EM_PPC64 ? 64 : 32;
50  *type = (regno < 32 ? DW_ATE_signed
51	   : regno < 64 ? DW_ATE_float : DW_ATE_unsigned);
52
53  if (regno < 32 || regno == 64 || regno == 66)
54    *setname = "integer";
55  else if (regno < 64 || regno == 65)
56    {
57      *setname = "FPU";
58      if (ebl->machine != EM_PPC64 && regno < 64)
59	*bits = 64;
60    }
61  else if (regno == 67 || regno == 356 || regno == 612 || regno >= 1124)
62    {
63      *setname = "vector";
64      *bits = regno >= 1124 ? 128 : 32;
65    }
66  else
67    *setname = "privileged";
68
69  switch (regno)
70    {
71    case 0 ... 9:
72      name[0] = 'r';
73      name[1] = regno + '0';
74      namelen = 2;
75      break;
76
77    case 10 ... 31:
78      name[0] = 'r';
79      name[1] = regno / 10 + '0';
80      name[2] = regno % 10 + '0';
81      namelen = 3;
82      break;
83
84    case 32 + 0 ... 32 + 9:
85      name[0] = 'f';
86      name[1] = (regno - 32) + '0';
87      namelen = 2;
88      break;
89
90    case 32 + 10 ... 32 + 31:
91      name[0] = 'f';
92      name[1] = (regno - 32) / 10 + '0';
93      name[2] = (regno - 32) % 10 + '0';
94      namelen = 3;
95      break;
96
97    case 64:
98      return stpcpy (name, "cr") + 1 - name;
99    case 65:
100      return stpcpy (name, "fpscr") + 1 - name;
101    case 66:
102      return stpcpy (name, "msr") + 1 - name;
103    case 67:			/* XXX unofficial assignment */
104      return stpcpy (name, "vscr") + 1 - name;
105
106    case 70 + 0 ... 70 + 9:
107      name[0] = 's';
108      name[1] = 'r';
109      name[2] = (regno - 70) + '0';
110      namelen = 3;
111      break;
112
113    case 70 + 10 ... 70 + 15:
114      name[0] = 's';
115      name[1] = 'r';
116      name[2] = (regno - 70) / 10 + '0';
117      name[3] = (regno - 70) % 10 + '0';
118      namelen = 4;
119      break;
120
121    case 101:
122      return stpcpy (name, "xer") + 1 - name;
123    case 108:
124      return stpcpy (name, "lr") + 1 - name;
125    case 109:
126      return stpcpy (name, "ctr") + 1 - name;
127    case 118:
128      return stpcpy (name, "dsisr") + 1 - name;
129    case 119:
130      return stpcpy (name, "dar") + 1 - name;
131    case 122:
132      return stpcpy (name, "dec") + 1 - name;
133    case 356:
134      return stpcpy (name, "vrsave") + 1 - name;
135    case 612:
136      return stpcpy (name, "spefscr") + 1 - name;
137    case 100:
138      if (*bits == 32)
139	return stpcpy (name, "mq") + 1 - name;
140
141    case 102 ... 107:
142      name[0] = 's';
143      name[1] = 'p';
144      name[2] = 'r';
145      name[3] = (regno - 100) + '0';
146      namelen = 4;
147      break;
148
149    case 110 ... 117:
150    case 120 ... 121:
151    case 123 ... 199:
152      name[0] = 's';
153      name[1] = 'p';
154      name[2] = 'r';
155      name[3] = (regno - 100) / 10 + '0';
156      name[4] = (regno - 100) % 10 + '0';
157      namelen = 5;
158      break;
159
160    case 200 ... 355:
161    case 357 ... 611:
162    case 613 ... 999:
163      name[0] = 's';
164      name[1] = 'p';
165      name[2] = 'r';
166      name[3] = (regno - 100) / 100 + '0';
167      name[4] = ((regno - 100) % 100 / 10) + '0';
168      name[5] = (regno - 100) % 10 + '0';
169      namelen = 6;
170      break;
171
172    case 1124 + 0 ... 1124 + 9:
173      name[0] = 'v';
174      name[1] = 'r';
175      name[2] = (regno - 1124) + '0';
176      namelen = 3;
177      break;
178
179    case 1124 + 10 ... 1124 + 31:
180      name[0] = 'v';
181      name[1] = 'r';
182      name[2] = (regno - 1124) / 10 + '0';
183      name[3] = (regno - 1124) % 10 + '0';
184      namelen = 4;
185      break;
186
187    default:
188      *setname = NULL;
189      return 0;
190    }
191
192  name[namelen++] = '\0';
193  return namelen;
194}
195
196__typeof (ppc_register_info)
197     ppc64_register_info __attribute__ ((alias ("ppc_register_info")));
198