1/* Register names and numbers for x86-64 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 <assert.h>
34#include <dwarf.h>
35#include <string.h>
36
37#define BACKEND x86_64_
38#include "libebl_CPU.h"
39
40ssize_t
41x86_64_register_info (Ebl *ebl __attribute__ ((unused)),
42		      int regno, char *name, size_t namelen,
43		      const char **prefix, const char **setname,
44		      int *bits, int *type)
45{
46  if (name == NULL)
47    return 67;
48
49  if (regno < 0 || regno > 66 || namelen < 7)
50    return -1;
51
52  *prefix = "%";
53  *bits = 64;
54  *type = DW_ATE_unsigned;
55  if (regno < 17)
56    {
57      *setname = "integer";
58      *type = DW_ATE_signed;
59    }
60  else if (regno < 33)
61    {
62      *setname = "SSE";
63      *bits = 128;
64    }
65  else if (regno < 41)
66    {
67      *setname = "x87";
68      *type = DW_ATE_float;
69      *bits = 80;
70    }
71  else if (regno < 49)
72    *setname = "MMX";
73  else if (regno > 49 && regno < 60)
74    {
75      *setname = "segment";
76      *bits = 16;
77    }
78  else
79    *setname = "control";
80
81  switch (regno)
82    {
83      static const char baseregs[][2] =
84	{
85	  "ax", "dx", "cx", "bx", "si", "di", "bp", "sp"
86	};
87
88    case 6 ... 7:
89      *type = DW_ATE_address;
90      FALLTHROUGH;
91    case 0 ... 5:
92      name[0] = 'r';
93      name[1] = baseregs[regno][0];
94      name[2] = baseregs[regno][1];
95      namelen = 3;
96      break;
97
98    case 8 ... 9:
99      name[0] = 'r';
100      name[1] = regno - 8 + '8';
101      namelen = 2;
102      break;
103
104    case 10 ... 15:
105      name[0] = 'r';
106      name[1] = '1';
107      name[2] = regno - 10 + '0';
108      namelen = 3;
109      break;
110
111    case 16:
112      *type = DW_ATE_address;
113      name[0] = 'r';
114      name[1] = 'i';
115      name[2] = 'p';
116      namelen = 3;
117      break;
118
119    case 17 ... 26:
120      name[0] = 'x';
121      name[1] = 'm';
122      name[2] = 'm';
123      name[3] = regno - 17 + '0';
124      namelen = 4;
125      break;
126
127    case 27 ... 32:
128      name[0] = 'x';
129      name[1] = 'm';
130      name[2] = 'm';
131      name[3] = '1';
132      name[4] = regno - 27 + '0';
133      namelen = 5;
134      break;
135
136    case 33 ... 40:
137      name[0] = 's';
138      name[1] = 't';
139      name[2] = regno - 33 + '0';
140      namelen = 3;
141      break;
142
143    case 41 ... 48:
144      name[0] = 'm';
145      name[1] = 'm';
146      name[2] = regno - 41 + '0';
147      namelen = 3;
148      break;
149
150    case 50 ... 55:
151      name[0] = "ecsdfg"[regno - 50];
152      name[1] = 's';
153      namelen = 2;
154      break;
155
156    case 58 ... 59:
157      *type = DW_ATE_address;
158      *bits = 64;
159      name[0] = regno - 58 + 'f';
160      return stpcpy (&name[1], "s.base") + 1 - name;
161
162    case 49:
163      *setname = "integer";
164      return stpcpy (name, "rflags") + 1 - name;
165    case 62:
166      return stpcpy (name, "tr") + 1 - name;
167    case 63:
168      return stpcpy (name, "ldtr") + 1 - name;
169    case 64:
170      return stpcpy (name, "mxcsr") + 1 - name;
171
172    case 65 ... 66:
173      *bits = 16;
174      name[0] = 'f';
175      name[1] = "cs"[regno - 65];
176      name[2] = 'w';
177      namelen = 3;
178      break;
179
180    default:
181      return 0;
182    }
183
184  name[namelen++] = '\0';
185  return namelen;
186}
187