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
x86_64_register_info(Ebl * ebl,int regno,char * name,size_t namelen,const char ** prefix,const char ** setname,int * bits,int * type)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       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