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