Imported Upstream version 0.155
[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 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
40 ssize_t
41 x86_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     case 0 ... 5:
91       name[0] = 'r';
92       name[1] = baseregs[regno][0];
93       name[2] = baseregs[regno][1];
94       namelen = 3;
95       break;
96
97     case 8 ... 9:
98       name[0] = 'r';
99       name[1] = regno - 8 + '8';
100       namelen = 2;
101       break;
102
103     case 10 ... 15:
104       name[0] = 'r';
105       name[1] = '1';
106       name[2] = regno - 10 + '0';
107       namelen = 3;
108       break;
109
110     case 16:
111       *type = DW_ATE_address;
112       name[0] = 'r';
113       name[1] = 'i';
114       name[2] = 'p';
115       namelen = 3;
116       break;
117
118     case 17 ... 26:
119       name[0] = 'x';
120       name[1] = 'm';
121       name[2] = 'm';
122       name[3] = regno - 17 + '0';
123       namelen = 4;
124       break;
125
126     case 27 ... 32:
127       name[0] = 'x';
128       name[1] = 'm';
129       name[2] = 'm';
130       name[3] = '1';
131       name[4] = regno - 27 + '0';
132       namelen = 5;
133       break;
134
135     case 33 ... 40:
136       name[0] = 's';
137       name[1] = 't';
138       name[2] = regno - 33 + '0';
139       namelen = 3;
140       break;
141
142     case 41 ... 48:
143       name[0] = 'm';
144       name[1] = 'm';
145       name[2] = regno - 41 + '0';
146       namelen = 3;
147       break;
148
149     case 50 ... 55:
150       name[0] = "ecsdfg"[regno - 50];
151       name[1] = 's';
152       namelen = 2;
153       break;
154
155     case 58 ... 59:
156       *type = DW_ATE_address;
157       *bits = 64;
158       name[0] = regno - 58 + 'f';
159       return stpcpy (&name[1], "s.base") + 1 - name;
160
161     case 49:
162       *setname = "integer";
163       return stpcpy (name, "rflags") + 1 - name;
164     case 62:
165       return stpcpy (name, "tr") + 1 - name;
166     case 63:
167       return stpcpy (name, "ldtr") + 1 - name;
168     case 64:
169       return stpcpy (name, "mxcsr") + 1 - name;
170
171     case 65 ... 66:
172       *bits = 16;
173       name[0] = 'f';
174       name[1] = "cs"[regno - 65];
175       name[2] = 'w';
176       namelen = 3;
177       break;
178
179     default:
180       return 0;
181     }
182
183   name[namelen++] = '\0';
184   return namelen;
185 }