1 /* Register names and numbers for i386 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 <string.h>
34 #include <dwarf.h>
35 
36 #define BACKEND i386_
37 #include "libebl_CPU.h"
38 
39 ssize_t
i386_register_info(Ebl * ebl,int regno,char * name,size_t namelen,const char ** prefix,const char ** setname,int * bits,int * type)40 i386_register_info (Ebl *ebl __attribute__ ((unused)),
41 		    int regno, char *name, size_t namelen,
42 		    const char **prefix, const char **setname,
43 		    int *bits, int *type)
44 {
45   if (name == NULL)
46     return 46;
47 
48   if (regno < 0 || regno > 45 || namelen < 6)
49     return -1;
50 
51   *prefix = "%";
52   *bits = 32;
53   *type = DW_ATE_unsigned;
54   if (regno < 11)
55     {
56       *setname = "integer";
57       if (regno < 9)
58 	*type = DW_ATE_signed;
59     }
60   else if (regno < 19)
61     {
62       *setname = "x87";
63       *type = DW_ATE_float;
64       *bits = 80;
65     }
66   else if (regno < 29)
67     {
68       *setname = "SSE";
69       *bits = 128;
70     }
71   else if (regno < 37)
72     {
73       *setname = "MMX";
74       *bits = 64;
75     }
76   else if (regno < 40)
77     *setname = "FPU-control";
78   else
79     {
80       *setname = "segment";
81       *bits = 16;
82     }
83 
84   switch (regno)
85     {
86       static const char baseregs[][2] =
87 	{
88 	  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "ip"
89 	};
90 
91     case 4:
92     case 5:
93     case 8:
94       *type = DW_ATE_address;
95       FALLTHROUGH;
96     case 0 ... 3:
97     case 6 ... 7:
98       name[0] = 'e';
99       name[1] = baseregs[regno][0];
100       name[2] = baseregs[regno][1];
101       namelen = 3;
102       break;
103 
104     case 9:
105       return stpcpy (name, "eflags") + 1 - name;
106     case 10:
107       return stpcpy (name, "trapno") + 1 - name;
108 
109     case 11 ... 18:
110       name[0] = 's';
111       name[1] = 't';
112       name[2] = regno - 11 + '0';
113       namelen = 3;
114       break;
115 
116     case 21 ... 28:
117       name[0] = 'x';
118       name[1] = 'm';
119       name[2] = 'm';
120       name[3] = regno - 21 + '0';
121       namelen = 4;
122       break;
123 
124     case 29 ... 36:
125       name[0] = 'm';
126       name[1] = 'm';
127       name[2] = regno - 29 + '0';
128       namelen = 3;
129       break;
130 
131     case 37:
132       *bits = 16;
133       return stpcpy (name, "fctrl") + 1 - name;
134     case 38:
135       *bits = 16;
136       return stpcpy (name, "fstat") + 1 - name;
137     case 39:
138       return stpcpy (name, "mxcsr") + 1 - name;
139 
140     case 40 ... 45:
141       name[0] = "ecsdfg"[regno - 40];
142       name[1] = 's';
143       namelen = 2;
144       break;
145 
146     default:
147       *setname = NULL;
148       return 0;
149     }
150 
151   name[namelen++] = '\0';
152   return namelen;
153 }
154