xref: /third_party/elfutils/backends/i386_regs.c (revision da0c48c4)
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
39ssize_t
40i386_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