Imported Upstream version 0.155
[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 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
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     case 0 ... 3:
96     case 6 ... 7:
97       name[0] = 'e';
98       name[1] = baseregs[regno][0];
99       name[2] = baseregs[regno][1];
100       namelen = 3;
101       break;
102
103     case 9:
104       return stpcpy (name, "eflags") + 1 - name;
105     case 10:
106       return stpcpy (name, "trapno") + 1 - name;
107
108     case 11 ... 18:
109       name[0] = 's';
110       name[1] = 't';
111       name[2] = regno - 11 + '0';
112       namelen = 3;
113       break;
114
115     case 21 ... 28:
116       name[0] = 'x';
117       name[1] = 'm';
118       name[2] = 'm';
119       name[3] = regno - 21 + '0';
120       namelen = 4;
121       break;
122
123     case 29 ... 36:
124       name[0] = 'm';
125       name[1] = 'm';
126       name[2] = regno - 29 + '0';
127       namelen = 3;
128       break;
129
130     case 37:
131       *bits = 16;
132       return stpcpy (name, "fctrl") + 1 - name;
133     case 38:
134       *bits = 16;
135       return stpcpy (name, "fstat") + 1 - name;
136     case 39:
137       return stpcpy (name, "mxcsr") + 1 - name;
138
139     case 40 ... 45:
140       name[0] = "ecsdfg"[regno - 40];
141       name[1] = 's';
142       namelen = 2;
143       break;
144
145     default:
146       *setname = NULL;
147       return 0;
148     }
149
150   name[namelen++] = '\0';
151   return namelen;
152 }