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