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 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 case 0 ... 5: 91 name[0] = 'r'; 92 name[1] = baseregs[regno][0]; 93 name[2] = baseregs[regno][1]; 94 namelen = 3; 95 break; 96 97 case 8 ... 9: 98 name[0] = 'r'; 99 name[1] = regno - 8 + '8'; 100 namelen = 2; 101 break; 102 103 case 10 ... 15: 104 name[0] = 'r'; 105 name[1] = '1'; 106 name[2] = regno - 10 + '0'; 107 namelen = 3; 108 break; 109 110 case 16: 111 *type = DW_ATE_address; 112 name[0] = 'r'; 113 name[1] = 'i'; 114 name[2] = 'p'; 115 namelen = 3; 116 break; 117 118 case 17 ... 26: 119 name[0] = 'x'; 120 name[1] = 'm'; 121 name[2] = 'm'; 122 name[3] = regno - 17 + '0'; 123 namelen = 4; 124 break; 125 126 case 27 ... 32: 127 name[0] = 'x'; 128 name[1] = 'm'; 129 name[2] = 'm'; 130 name[3] = '1'; 131 name[4] = regno - 27 + '0'; 132 namelen = 5; 133 break; 134 135 case 33 ... 40: 136 name[0] = 's'; 137 name[1] = 't'; 138 name[2] = regno - 33 + '0'; 139 namelen = 3; 140 break; 141 142 case 41 ... 48: 143 name[0] = 'm'; 144 name[1] = 'm'; 145 name[2] = regno - 41 + '0'; 146 namelen = 3; 147 break; 148 149 case 50 ... 55: 150 name[0] = "ecsdfg"[regno - 50]; 151 name[1] = 's'; 152 namelen = 2; 153 break; 154 155 case 58 ... 59: 156 *type = DW_ATE_address; 157 *bits = 64; 158 name[0] = regno - 58 + 'f'; 159 return stpcpy (&name[1], "s.base") + 1 - name; 160 161 case 49: 162 *setname = "integer"; 163 return stpcpy (name, "rflags") + 1 - name; 164 case 62: 165 return stpcpy (name, "tr") + 1 - name; 166 case 63: 167 return stpcpy (name, "ldtr") + 1 - name; 168 case 64: 169 return stpcpy (name, "mxcsr") + 1 - name; 170 171 case 65 ... 66: 172 *bits = 16; 173 name[0] = 'f'; 174 name[1] = "cs"[regno - 65]; 175 name[2] = 'w'; 176 namelen = 3; 177 break; 178 179 default: 180 return 0; 181 } 182 183 name[namelen++] = '\0'; 184 return namelen; 185 } 186