Imported Upstream version 0.153
[platform/upstream/elfutils.git] / backends / x86_64_regs.c
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
37 ssize_t
38 x86_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 }