1 1.1 joerg //===----------------------------- Registers.hpp --------------------------===// 2 1.1 joerg // 3 1.1 joerg // The LLVM Compiler Infrastructure 4 1.1 joerg // 5 1.1 joerg // This file is dual licensed under the MIT and the University of Illinois Open 6 1.1 joerg // Source Licenses. See LICENSE.TXT for details. 7 1.1 joerg // 8 1.1 joerg // 9 1.1 joerg // Models register sets for supported processors. 10 1.1 joerg // 11 1.1 joerg //===----------------------------------------------------------------------===// 12 1.1 joerg #ifndef __REGISTERS_HPP__ 13 1.1 joerg #define __REGISTERS_HPP__ 14 1.1 joerg 15 1.20 joerg #include <sys/endian.h> 16 1.1 joerg #include <cassert> 17 1.1 joerg #include <cstdint> 18 1.1 joerg 19 1.1 joerg namespace _Unwind { 20 1.1 joerg 21 1.1 joerg enum { 22 1.1 joerg REGNO_X86_EAX = 0, 23 1.1 joerg REGNO_X86_ECX = 1, 24 1.1 joerg REGNO_X86_EDX = 2, 25 1.1 joerg REGNO_X86_EBX = 3, 26 1.1 joerg REGNO_X86_ESP = 4, 27 1.1 joerg REGNO_X86_EBP = 5, 28 1.1 joerg REGNO_X86_ESI = 6, 29 1.1 joerg REGNO_X86_EDI = 7, 30 1.1 joerg REGNO_X86_EIP = 8, 31 1.1 joerg }; 32 1.1 joerg 33 1.1 joerg class Registers_x86 { 34 1.1 joerg public: 35 1.1 joerg enum { 36 1.3 joerg LAST_REGISTER = REGNO_X86_EIP, 37 1.1 joerg LAST_RESTORE_REG = REGNO_X86_EIP, 38 1.10 joerg RETURN_OFFSET = 0, 39 1.19 joerg RETURN_MASK = 0, 40 1.1 joerg }; 41 1.1 joerg 42 1.1 joerg __dso_hidden Registers_x86(); 43 1.1 joerg 44 1.1 joerg static int dwarf2regno(int num) { return num; } 45 1.1 joerg 46 1.1 joerg bool validRegister(int num) const { 47 1.1 joerg return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI; 48 1.1 joerg } 49 1.1 joerg 50 1.1 joerg uint32_t getRegister(int num) const { 51 1.1 joerg assert(validRegister(num)); 52 1.1 joerg return reg[num]; 53 1.1 joerg } 54 1.1 joerg 55 1.1 joerg void setRegister(int num, uint32_t value) { 56 1.1 joerg assert(validRegister(num)); 57 1.1 joerg reg[num] = value; 58 1.1 joerg } 59 1.1 joerg 60 1.1 joerg uint32_t getIP() const { return reg[REGNO_X86_EIP]; } 61 1.1 joerg 62 1.1 joerg void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; } 63 1.1 joerg 64 1.1 joerg uint32_t getSP() const { return reg[REGNO_X86_ESP]; } 65 1.1 joerg 66 1.1 joerg void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; } 67 1.1 joerg 68 1.1 joerg bool validFloatVectorRegister(int num) const { return false; } 69 1.1 joerg 70 1.1 joerg void copyFloatVectorRegister(int num, uint32_t addr) { 71 1.1 joerg } 72 1.1 joerg 73 1.1 joerg __dso_hidden void jumpto() const __dead; 74 1.1 joerg 75 1.1 joerg private: 76 1.1 joerg uint32_t reg[REGNO_X86_EIP + 1]; 77 1.1 joerg }; 78 1.1 joerg 79 1.1 joerg enum { 80 1.1 joerg REGNO_X86_64_RAX = 0, 81 1.1 joerg REGNO_X86_64_RDX = 1, 82 1.1 joerg REGNO_X86_64_RCX = 2, 83 1.1 joerg REGNO_X86_64_RBX = 3, 84 1.1 joerg REGNO_X86_64_RSI = 4, 85 1.1 joerg REGNO_X86_64_RDI = 5, 86 1.1 joerg REGNO_X86_64_RBP = 6, 87 1.1 joerg REGNO_X86_64_RSP = 7, 88 1.1 joerg REGNO_X86_64_R8 = 8, 89 1.1 joerg REGNO_X86_64_R9 = 9, 90 1.1 joerg REGNO_X86_64_R10 = 10, 91 1.1 joerg REGNO_X86_64_R11 = 11, 92 1.1 joerg REGNO_X86_64_R12 = 12, 93 1.1 joerg REGNO_X86_64_R13 = 13, 94 1.1 joerg REGNO_X86_64_R14 = 14, 95 1.1 joerg REGNO_X86_64_R15 = 15, 96 1.1 joerg REGNO_X86_64_RIP = 16, 97 1.1 joerg }; 98 1.1 joerg 99 1.1 joerg class Registers_x86_64 { 100 1.1 joerg public: 101 1.1 joerg enum { 102 1.3 joerg LAST_REGISTER = REGNO_X86_64_RIP, 103 1.1 joerg LAST_RESTORE_REG = REGNO_X86_64_RIP, 104 1.10 joerg RETURN_OFFSET = 0, 105 1.19 joerg RETURN_MASK = 0, 106 1.1 joerg }; 107 1.1 joerg 108 1.1 joerg __dso_hidden Registers_x86_64(); 109 1.1 joerg 110 1.1 joerg static int dwarf2regno(int num) { return num; } 111 1.1 joerg 112 1.1 joerg bool validRegister(int num) const { 113 1.1 joerg return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15; 114 1.1 joerg } 115 1.1 joerg 116 1.1 joerg uint64_t getRegister(int num) const { 117 1.1 joerg assert(validRegister(num)); 118 1.1 joerg return reg[num]; 119 1.1 joerg } 120 1.1 joerg 121 1.1 joerg void setRegister(int num, uint64_t value) { 122 1.1 joerg assert(validRegister(num)); 123 1.1 joerg reg[num] = value; 124 1.1 joerg } 125 1.1 joerg 126 1.1 joerg uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; } 127 1.1 joerg 128 1.1 joerg void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; } 129 1.1 joerg 130 1.1 joerg uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; } 131 1.1 joerg 132 1.1 joerg void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; } 133 1.1 joerg 134 1.1 joerg bool validFloatVectorRegister(int num) const { return false; } 135 1.1 joerg 136 1.1 joerg void copyFloatVectorRegister(int num, uint64_t addr) { 137 1.1 joerg } 138 1.1 joerg 139 1.1 joerg __dso_hidden void jumpto() const __dead; 140 1.1 joerg 141 1.1 joerg private: 142 1.1 joerg uint64_t reg[REGNO_X86_64_RIP + 1]; 143 1.1 joerg }; 144 1.1 joerg 145 1.1 joerg enum { 146 1.1 joerg DWARF_PPC32_R0 = 0, 147 1.1 joerg DWARF_PPC32_R31 = 31, 148 1.1 joerg DWARF_PPC32_F0 = 32, 149 1.1 joerg DWARF_PPC32_F31 = 63, 150 1.1 joerg DWARF_PPC32_LR = 65, 151 1.33 thorpej DWARF_PPC32_CTR = 66, 152 1.4 joerg DWARF_PPC32_CR = 70, 153 1.33 thorpej DWARF_PPC32_XER = 76, 154 1.4 joerg DWARF_PPC32_V0 = 77, 155 1.33 thorpej DWARF_PPC32_SIGRETURN = 99, 156 1.4 joerg DWARF_PPC32_V31 = 108, 157 1.4 joerg 158 1.1 joerg REGNO_PPC32_R0 = 0, 159 1.4 joerg REGNO_PPC32_R1 = 1, 160 1.1 joerg REGNO_PPC32_R31 = 31, 161 1.4 joerg REGNO_PPC32_LR = 32, 162 1.4 joerg REGNO_PPC32_CR = 33, 163 1.4 joerg REGNO_PPC32_SRR0 = 34, 164 1.4 joerg 165 1.1 joerg REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1, 166 1.1 joerg REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31, 167 1.1 joerg REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1, 168 1.1 joerg REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31, 169 1.33 thorpej 170 1.33 thorpej REGNO_PPC32_CTR = REGNO_PPC32_V31 + 1, 171 1.33 thorpej REGNO_PPC32_XER = REGNO_PPC32_CTR + 1, 172 1.33 thorpej REGNO_PPC32_SIGRETURN = REGNO_PPC32_XER + 1 173 1.1 joerg }; 174 1.1 joerg 175 1.1 joerg class Registers_ppc32 { 176 1.1 joerg public: 177 1.1 joerg enum { 178 1.33 thorpej LAST_REGISTER = REGNO_PPC32_SIGRETURN, 179 1.33 thorpej LAST_RESTORE_REG = REGNO_PPC32_SIGRETURN, 180 1.10 joerg RETURN_OFFSET = 0, 181 1.19 joerg RETURN_MASK = 0, 182 1.1 joerg }; 183 1.1 joerg 184 1.1 joerg __dso_hidden Registers_ppc32(); 185 1.1 joerg 186 1.1 joerg static int dwarf2regno(int num) { 187 1.1 joerg if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31) 188 1.1 joerg return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0); 189 1.1 joerg if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31) 190 1.1 joerg return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0); 191 1.1 joerg if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31) 192 1.1 joerg return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0); 193 1.4 joerg switch (num) { 194 1.4 joerg case DWARF_PPC32_LR: 195 1.4 joerg return REGNO_PPC32_LR; 196 1.4 joerg case DWARF_PPC32_CR: 197 1.4 joerg return REGNO_PPC32_CR; 198 1.33 thorpej case DWARF_PPC32_CTR: 199 1.33 thorpej return REGNO_PPC32_CTR; 200 1.33 thorpej case DWARF_PPC32_XER: 201 1.33 thorpej return REGNO_PPC32_XER; 202 1.33 thorpej case DWARF_PPC32_SIGRETURN: 203 1.33 thorpej return REGNO_PPC32_SIGRETURN; 204 1.4 joerg default: 205 1.4 joerg return LAST_REGISTER + 1; 206 1.4 joerg } 207 1.1 joerg } 208 1.1 joerg 209 1.1 joerg bool validRegister(int num) const { 210 1.33 thorpej return (num >= 0 && num <= REGNO_PPC32_SRR0) || 211 1.33 thorpej (num >= REGNO_PPC32_CTR && num <= REGNO_PPC32_SIGRETURN); 212 1.1 joerg } 213 1.1 joerg 214 1.1 joerg uint64_t getRegister(int num) const { 215 1.1 joerg assert(validRegister(num)); 216 1.33 thorpej switch (num) { 217 1.33 thorpej case REGNO_PPC32_CTR: 218 1.33 thorpej return ctr_reg; 219 1.33 thorpej case REGNO_PPC32_XER: 220 1.33 thorpej return xer_reg; 221 1.33 thorpej case REGNO_PPC32_SIGRETURN: 222 1.33 thorpej return sigreturn_reg; 223 1.33 thorpej default: 224 1.33 thorpej return reg[num]; 225 1.33 thorpej } 226 1.1 joerg } 227 1.1 joerg 228 1.1 joerg void setRegister(int num, uint64_t value) { 229 1.1 joerg assert(validRegister(num)); 230 1.33 thorpej switch (num) { 231 1.33 thorpej case REGNO_PPC32_CTR: 232 1.33 thorpej ctr_reg = value; 233 1.33 thorpej break; 234 1.33 thorpej case REGNO_PPC32_XER: 235 1.33 thorpej xer_reg = value; 236 1.33 thorpej break; 237 1.33 thorpej case REGNO_PPC32_SIGRETURN: 238 1.33 thorpej sigreturn_reg = value; 239 1.33 thorpej break; 240 1.33 thorpej default: 241 1.33 thorpej reg[num] = value; 242 1.33 thorpej } 243 1.1 joerg } 244 1.1 joerg 245 1.1 joerg uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 246 1.1 joerg 247 1.1 joerg void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 248 1.1 joerg 249 1.1 joerg uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 250 1.1 joerg 251 1.1 joerg void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 252 1.1 joerg 253 1.1 joerg bool validFloatVectorRegister(int num) const { 254 1.1 joerg return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) || 255 1.1 joerg (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31); 256 1.1 joerg } 257 1.1 joerg 258 1.1 joerg void copyFloatVectorRegister(int num, uint64_t addr_) { 259 1.1 joerg const void *addr = reinterpret_cast<const void *>(addr_); 260 1.1 joerg if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) 261 1.1 joerg memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0])); 262 1.1 joerg else 263 1.1 joerg memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0])); 264 1.1 joerg } 265 1.1 joerg 266 1.1 joerg __dso_hidden void jumpto() const __dead; 267 1.1 joerg 268 1.1 joerg private: 269 1.1 joerg struct vecreg_t { 270 1.1 joerg uint64_t low, high; 271 1.1 joerg }; 272 1.1 joerg uint32_t reg[REGNO_PPC32_SRR0 + 1]; 273 1.4 joerg uint32_t dummy; 274 1.1 joerg uint64_t fpreg[32]; 275 1.1 joerg vecreg_t vecreg[64]; 276 1.33 thorpej uint32_t ctr_reg; 277 1.33 thorpej uint32_t xer_reg; 278 1.33 thorpej uint32_t sigreturn_reg; 279 1.1 joerg }; 280 1.1 joerg 281 1.2 matt enum { 282 1.17 matt DWARF_AARCH64_X0 = 0, 283 1.17 matt DWARF_AARCH64_X30 = 30, 284 1.17 matt DWARF_AARCH64_SP = 31, 285 1.17 matt DWARF_AARCH64_V0 = 64, 286 1.17 matt DWARF_AARCH64_V31 = 95, 287 1.35 thorpej DWARF_AARCH64_SIGRETURN = 96, 288 1.17 matt 289 1.17 matt REGNO_AARCH64_X0 = 0, 290 1.17 matt REGNO_AARCH64_X30 = 30, 291 1.17 matt REGNO_AARCH64_SP = 31, 292 1.21 joerg REGNO_AARCH64_V0 = 32, 293 1.21 joerg REGNO_AARCH64_V31 = 63, 294 1.35 thorpej REGNO_AARCH64_SIGRETURN = 64, 295 1.17 matt }; 296 1.17 matt 297 1.17 matt class Registers_aarch64 { 298 1.17 matt public: 299 1.17 matt enum { 300 1.35 thorpej LAST_RESTORE_REG = REGNO_AARCH64_SIGRETURN, 301 1.35 thorpej LAST_REGISTER = REGNO_AARCH64_SIGRETURN, 302 1.17 matt RETURN_OFFSET = 0, 303 1.19 joerg RETURN_MASK = 0, 304 1.17 matt }; 305 1.17 matt 306 1.17 matt __dso_hidden Registers_aarch64(); 307 1.17 matt 308 1.17 matt static int dwarf2regno(int num) { 309 1.17 matt if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30) 310 1.17 matt return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0); 311 1.17 matt if (num == DWARF_AARCH64_SP) 312 1.17 matt return REGNO_AARCH64_SP; 313 1.17 matt if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31) 314 1.17 matt return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0); 315 1.35 thorpej if (num == DWARF_AARCH64_SIGRETURN) 316 1.35 thorpej return REGNO_AARCH64_SIGRETURN; 317 1.17 matt return LAST_REGISTER + 1; 318 1.17 matt } 319 1.17 matt 320 1.17 matt bool validRegister(int num) const { 321 1.35 thorpej return (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_SP) || 322 1.35 thorpej num == DWARF_AARCH64_SIGRETURN; 323 1.17 matt } 324 1.17 matt 325 1.17 matt uint64_t getRegister(int num) const { 326 1.17 matt assert(validRegister(num)); 327 1.36 thorpej if (num == REGNO_AARCH64_SIGRETURN) 328 1.35 thorpej return sigreturn_reg; 329 1.17 matt return reg[num]; 330 1.17 matt } 331 1.17 matt 332 1.17 matt void setRegister(int num, uint64_t value) { 333 1.17 matt assert(validRegister(num)); 334 1.36 thorpej if (num == REGNO_AARCH64_SIGRETURN) 335 1.35 thorpej sigreturn_reg = value; 336 1.35 thorpej else 337 1.35 thorpej reg[num] = value; 338 1.17 matt } 339 1.17 matt 340 1.17 matt uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; } 341 1.17 matt 342 1.17 matt void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; } 343 1.17 matt 344 1.17 matt uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; } 345 1.17 matt 346 1.17 matt void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; } 347 1.17 matt 348 1.17 matt bool validFloatVectorRegister(int num) const { 349 1.17 matt return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31); 350 1.17 matt } 351 1.17 matt 352 1.17 matt void copyFloatVectorRegister(int num, uint64_t addr_) { 353 1.17 matt const void *addr = reinterpret_cast<const void *>(addr_); 354 1.21 joerg memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, 16); 355 1.17 matt } 356 1.17 matt 357 1.17 matt __dso_hidden void jumpto() const __dead; 358 1.17 matt 359 1.17 matt private: 360 1.21 joerg uint64_t reg[REGNO_AARCH64_SP + 1]; 361 1.21 joerg uint64_t vecreg[64]; 362 1.35 thorpej uint64_t sigreturn_reg; 363 1.17 matt }; 364 1.17 matt 365 1.17 matt enum { 366 1.2 matt DWARF_ARM32_R0 = 0, 367 1.2 matt DWARF_ARM32_R15 = 15, 368 1.2 matt DWARF_ARM32_SPSR = 128, 369 1.20 joerg DWARF_ARM32_S0 = 64, 370 1.24 rin DWARF_ARM32_S31 = 95, 371 1.16 joerg DWARF_ARM32_D0 = 256, 372 1.2 matt DWARF_ARM32_D31 = 287, 373 1.2 matt REGNO_ARM32_R0 = 0, 374 1.2 matt REGNO_ARM32_SP = 13, 375 1.2 matt REGNO_ARM32_R15 = 15, 376 1.2 matt REGNO_ARM32_SPSR = 16, 377 1.16 joerg REGNO_ARM32_D0 = 17, 378 1.16 joerg REGNO_ARM32_D15 = 32, 379 1.16 joerg REGNO_ARM32_D31 = 48, 380 1.20 joerg REGNO_ARM32_S0 = 49, 381 1.24 rin REGNO_ARM32_S31 = 80, 382 1.2 matt }; 383 1.2 matt 384 1.28 rin #define FLAGS_VFPV2_USED 0x1 385 1.28 rin #define FLAGS_VFPV3_USED 0x2 386 1.28 rin #define FLAGS_LEGACY_VFPV2_REGNO 0x4 387 1.28 rin #define FLAGS_EXTENDED_VFPV2_REGNO 0x8 388 1.28 rin 389 1.2 matt class Registers_arm32 { 390 1.2 matt public: 391 1.2 matt enum { 392 1.27 rin LAST_REGISTER = REGNO_ARM32_S31, 393 1.27 rin LAST_RESTORE_REG = REGNO_ARM32_S31, 394 1.10 joerg RETURN_OFFSET = 0, 395 1.19 joerg RETURN_MASK = 0, 396 1.2 matt }; 397 1.2 matt 398 1.2 matt __dso_hidden Registers_arm32(); 399 1.2 matt 400 1.2 matt static int dwarf2regno(int num) { 401 1.2 matt if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) 402 1.2 matt return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); 403 1.16 joerg if (num == DWARF_ARM32_SPSR) 404 1.16 joerg return REGNO_ARM32_SPSR; 405 1.2 matt if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) 406 1.2 matt return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); 407 1.22 rin if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) 408 1.20 joerg return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0); 409 1.2 matt return LAST_REGISTER + 1; 410 1.2 matt } 411 1.2 matt 412 1.2 matt bool validRegister(int num) const { 413 1.16 joerg return num >= 0 && num <= REGNO_ARM32_SPSR; 414 1.2 matt } 415 1.2 matt 416 1.2 matt uint64_t getRegister(int num) const { 417 1.2 matt assert(validRegister(num)); 418 1.2 matt return reg[num]; 419 1.2 matt } 420 1.2 matt 421 1.2 matt void setRegister(int num, uint64_t value) { 422 1.2 matt assert(validRegister(num)); 423 1.2 matt reg[num] = value; 424 1.2 matt } 425 1.2 matt 426 1.2 matt uint64_t getIP() const { return reg[REGNO_ARM32_R15]; } 427 1.2 matt 428 1.2 matt void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; } 429 1.2 matt 430 1.2 matt uint64_t getSP() const { return reg[REGNO_ARM32_SP]; } 431 1.2 matt 432 1.2 matt void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; } 433 1.2 matt 434 1.2 matt bool validFloatVectorRegister(int num) const { 435 1.20 joerg return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31); 436 1.2 matt } 437 1.2 matt 438 1.2 matt void copyFloatVectorRegister(int num, uint64_t addr_) { 439 1.23 rin assert(validFloatVectorRegister(num)); 440 1.20 joerg const void *addr = reinterpret_cast<const void *>(addr_); 441 1.20 joerg if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) { 442 1.27 rin /* 443 1.27 rin * XXX 444 1.27 rin * There are two numbering schemes for VFPv2 registers: s0-s31 445 1.27 rin * (used by GCC) and d0-d15 (used by LLVM). We won't support both 446 1.27 rin * schemes simultaneously in a same frame. 447 1.27 rin */ 448 1.27 rin assert((flags & FLAGS_EXTENDED_VFPV2_REGNO) == 0); 449 1.27 rin flags |= FLAGS_LEGACY_VFPV2_REGNO; 450 1.22 rin if ((flags & FLAGS_VFPV2_USED) == 0) { 451 1.22 rin lazyVFPv2(); 452 1.22 rin flags |= FLAGS_VFPV2_USED; 453 1.20 joerg } 454 1.20 joerg /* 455 1.20 joerg * Emulate single precision register as half of the 456 1.20 joerg * corresponding double register. 457 1.20 joerg */ 458 1.20 joerg int dnum = (num - REGNO_ARM32_S0) / 2; 459 1.20 joerg int part = (num - REGNO_ARM32_S0) % 2; 460 1.20 joerg #if _BYTE_ORDER == _BIG_ENDIAN 461 1.20 joerg part = 1 - part; 462 1.20 joerg #endif 463 1.25 rin memcpy((uint8_t *)(fpreg + dnum) + part * sizeof(fpreg[0]) / 2, 464 1.20 joerg addr, sizeof(fpreg[0]) / 2); 465 1.16 joerg } else { 466 1.26 rin if (num <= REGNO_ARM32_D15) { 467 1.27 rin /* 468 1.27 rin * XXX 469 1.27 rin * See XXX comment above. 470 1.27 rin */ 471 1.27 rin assert((flags & FLAGS_LEGACY_VFPV2_REGNO) == 0); 472 1.27 rin flags |= FLAGS_EXTENDED_VFPV2_REGNO; 473 1.26 rin if ((flags & FLAGS_VFPV2_USED) == 0) { 474 1.26 rin lazyVFPv2(); 475 1.26 rin flags |= FLAGS_VFPV2_USED; 476 1.26 rin } 477 1.26 rin } else { 478 1.26 rin if ((flags & FLAGS_VFPV3_USED) == 0) { 479 1.26 rin lazyVFPv3(); 480 1.26 rin flags |= FLAGS_VFPV3_USED; 481 1.26 rin } 482 1.16 joerg } 483 1.26 rin memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); 484 1.16 joerg } 485 1.2 matt } 486 1.2 matt 487 1.22 rin __dso_hidden void lazyVFPv2(); 488 1.22 rin __dso_hidden void lazyVFPv3(); 489 1.2 matt __dso_hidden void jumpto() const __dead; 490 1.2 matt 491 1.2 matt private: 492 1.2 matt uint32_t reg[REGNO_ARM32_SPSR + 1]; 493 1.16 joerg uint32_t flags; 494 1.2 matt uint64_t fpreg[32]; 495 1.28 rin }; 496 1.22 rin 497 1.28 rin #undef FLAGS_VFPV2_USED 498 1.28 rin #undef FLAGS_VFPV3_USED 499 1.28 rin #undef FLAGS_LEGACY_VFPV2_REGNO 500 1.28 rin #undef FLAGS_EXTENDED_VFPV2_REGNO 501 1.2 matt 502 1.5 joerg enum { 503 1.5 joerg DWARF_VAX_R0 = 0, 504 1.5 joerg DWARF_VAX_R15 = 15, 505 1.5 joerg DWARF_VAX_PSW = 16, 506 1.5 joerg 507 1.5 joerg REGNO_VAX_R0 = 0, 508 1.5 joerg REGNO_VAX_R14 = 14, 509 1.5 joerg REGNO_VAX_R15 = 15, 510 1.5 joerg REGNO_VAX_PSW = 16, 511 1.5 joerg }; 512 1.5 joerg 513 1.5 joerg class Registers_vax { 514 1.5 joerg public: 515 1.5 joerg enum { 516 1.5 joerg LAST_REGISTER = REGNO_VAX_PSW, 517 1.5 joerg LAST_RESTORE_REG = REGNO_VAX_PSW, 518 1.10 joerg RETURN_OFFSET = 0, 519 1.19 joerg RETURN_MASK = 0, 520 1.5 joerg }; 521 1.5 joerg 522 1.5 joerg __dso_hidden Registers_vax(); 523 1.5 joerg 524 1.5 joerg static int dwarf2regno(int num) { 525 1.5 joerg if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15) 526 1.5 joerg return REGNO_VAX_R0 + (num - DWARF_VAX_R0); 527 1.5 joerg if (num == DWARF_VAX_PSW) 528 1.5 joerg return REGNO_VAX_PSW; 529 1.5 joerg return LAST_REGISTER + 1; 530 1.5 joerg } 531 1.5 joerg 532 1.5 joerg bool validRegister(int num) const { 533 1.5 joerg return num >= 0 && num <= LAST_RESTORE_REG; 534 1.5 joerg } 535 1.5 joerg 536 1.5 joerg uint64_t getRegister(int num) const { 537 1.5 joerg assert(validRegister(num)); 538 1.5 joerg return reg[num]; 539 1.5 joerg } 540 1.5 joerg 541 1.5 joerg void setRegister(int num, uint64_t value) { 542 1.5 joerg assert(validRegister(num)); 543 1.5 joerg reg[num] = value; 544 1.5 joerg } 545 1.5 joerg 546 1.5 joerg uint64_t getIP() const { return reg[REGNO_VAX_R15]; } 547 1.5 joerg 548 1.5 joerg void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; } 549 1.5 joerg 550 1.5 joerg uint64_t getSP() const { return reg[REGNO_VAX_R14]; } 551 1.5 joerg 552 1.5 joerg void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; } 553 1.5 joerg 554 1.5 joerg bool validFloatVectorRegister(int num) const { 555 1.5 joerg return false; 556 1.5 joerg } 557 1.5 joerg 558 1.5 joerg void copyFloatVectorRegister(int num, uint64_t addr_) { 559 1.5 joerg } 560 1.5 joerg 561 1.5 joerg __dso_hidden void jumpto() const __dead; 562 1.5 joerg 563 1.5 joerg private: 564 1.5 joerg uint32_t reg[REGNO_VAX_PSW + 1]; 565 1.5 joerg }; 566 1.5 joerg 567 1.6 joerg enum { 568 1.6 joerg DWARF_M68K_A0 = 0, 569 1.6 joerg DWARF_M68K_A7 = 7, 570 1.6 joerg DWARF_M68K_D0 = 8, 571 1.6 joerg DWARF_M68K_D7 = 15, 572 1.7 joerg DWARF_M68K_FP0 = 16, 573 1.7 joerg DWARF_M68K_FP7 = 23, 574 1.6 joerg DWARF_M68K_PC = 24, 575 1.34 thorpej // DWARF pseudo-register that is an alternate that may be used 576 1.34 thorpej // for the return address. 577 1.34 thorpej DWARF_M68K_ALT_PC = 25, 578 1.6 joerg 579 1.6 joerg REGNO_M68K_A0 = 0, 580 1.6 joerg REGNO_M68K_A7 = 7, 581 1.6 joerg REGNO_M68K_D0 = 8, 582 1.6 joerg REGNO_M68K_D7 = 15, 583 1.6 joerg REGNO_M68K_PC = 16, 584 1.7 joerg REGNO_M68K_FP0 = 17, 585 1.7 joerg REGNO_M68K_FP7 = 24, 586 1.6 joerg }; 587 1.6 joerg 588 1.6 joerg class Registers_M68K { 589 1.6 joerg public: 590 1.6 joerg enum { 591 1.7 joerg LAST_REGISTER = REGNO_M68K_FP7, 592 1.7 joerg LAST_RESTORE_REG = REGNO_M68K_FP7, 593 1.10 joerg RETURN_OFFSET = 0, 594 1.19 joerg RETURN_MASK = 0, 595 1.6 joerg }; 596 1.6 joerg 597 1.6 joerg __dso_hidden Registers_M68K(); 598 1.6 joerg 599 1.6 joerg static int dwarf2regno(int num) { 600 1.6 joerg if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7) 601 1.6 joerg return REGNO_M68K_A0 + (num - DWARF_M68K_A0); 602 1.6 joerg if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7) 603 1.6 joerg return REGNO_M68K_D0 + (num - DWARF_M68K_D0); 604 1.7 joerg if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7) 605 1.7 joerg return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0); 606 1.34 thorpej if (num == DWARF_M68K_PC || num == DWARF_M68K_ALT_PC) 607 1.6 joerg return REGNO_M68K_PC; 608 1.6 joerg return LAST_REGISTER + 1; 609 1.6 joerg } 610 1.6 joerg 611 1.6 joerg bool validRegister(int num) const { 612 1.7 joerg return num >= 0 && num <= REGNO_M68K_PC; 613 1.6 joerg } 614 1.6 joerg 615 1.6 joerg uint64_t getRegister(int num) const { 616 1.6 joerg assert(validRegister(num)); 617 1.6 joerg return reg[num]; 618 1.6 joerg } 619 1.6 joerg 620 1.6 joerg void setRegister(int num, uint64_t value) { 621 1.6 joerg assert(validRegister(num)); 622 1.6 joerg reg[num] = value; 623 1.6 joerg } 624 1.6 joerg 625 1.6 joerg uint64_t getIP() const { return reg[REGNO_M68K_PC]; } 626 1.6 joerg 627 1.6 joerg void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; } 628 1.6 joerg 629 1.6 joerg uint64_t getSP() const { return reg[REGNO_M68K_A7]; } 630 1.6 joerg 631 1.6 joerg void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; } 632 1.6 joerg 633 1.6 joerg bool validFloatVectorRegister(int num) const { 634 1.7 joerg return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7; 635 1.6 joerg } 636 1.6 joerg 637 1.6 joerg void copyFloatVectorRegister(int num, uint64_t addr_) { 638 1.7 joerg assert(validFloatVectorRegister(num)); 639 1.7 joerg const void *addr = reinterpret_cast<const void *>(addr_); 640 1.7 joerg memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0])); 641 1.6 joerg } 642 1.6 joerg 643 1.6 joerg __dso_hidden void jumpto() const __dead; 644 1.6 joerg 645 1.6 joerg private: 646 1.7 joerg typedef uint32_t fpreg_t[3]; 647 1.7 joerg 648 1.6 joerg uint32_t reg[REGNO_M68K_PC + 1]; 649 1.7 joerg uint32_t dummy; 650 1.7 joerg fpreg_t fpreg[8]; 651 1.6 joerg }; 652 1.6 joerg 653 1.8 joerg enum { 654 1.8 joerg DWARF_SH3_R0 = 0, 655 1.8 joerg DWARF_SH3_R15 = 15, 656 1.8 joerg DWARF_SH3_PC = 16, 657 1.8 joerg DWARF_SH3_PR = 17, 658 1.37 thorpej DWARF_SH3_GBR = 18, 659 1.37 thorpej DWARF_SH3_MACH = 20, 660 1.37 thorpej DWARF_SH3_MACL = 21, 661 1.37 thorpej DWARF_SH3_SR = 22, 662 1.8 joerg 663 1.8 joerg REGNO_SH3_R0 = 0, 664 1.8 joerg REGNO_SH3_R15 = 15, 665 1.8 joerg REGNO_SH3_PC = 16, 666 1.8 joerg REGNO_SH3_PR = 17, 667 1.37 thorpej REGNO_SH3_GBR = 18, 668 1.37 thorpej REGNO_SH3_MACH = 20, 669 1.37 thorpej REGNO_SH3_MACL = 21, 670 1.37 thorpej REGNO_SH3_SR = 22, 671 1.8 joerg }; 672 1.8 joerg 673 1.8 joerg class Registers_SH3 { 674 1.8 joerg public: 675 1.8 joerg enum { 676 1.37 thorpej LAST_REGISTER = REGNO_SH3_SR, 677 1.37 thorpej LAST_RESTORE_REG = REGNO_SH3_SR, 678 1.10 joerg RETURN_OFFSET = 0, 679 1.19 joerg RETURN_MASK = 0, 680 1.8 joerg }; 681 1.8 joerg 682 1.8 joerg __dso_hidden Registers_SH3(); 683 1.8 joerg 684 1.8 joerg static int dwarf2regno(int num) { 685 1.8 joerg if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15) 686 1.8 joerg return REGNO_SH3_R0 + (num - DWARF_SH3_R0); 687 1.37 thorpej switch (num) { 688 1.37 thorpej case DWARF_SH3_PC: 689 1.8 joerg return REGNO_SH3_PC; 690 1.37 thorpej case DWARF_SH3_PR: 691 1.8 joerg return REGNO_SH3_PR; 692 1.37 thorpej case DWARF_SH3_GBR: 693 1.37 thorpej return REGNO_SH3_GBR; 694 1.37 thorpej case DWARF_SH3_MACH: 695 1.37 thorpej return REGNO_SH3_MACH; 696 1.37 thorpej case DWARF_SH3_MACL: 697 1.37 thorpej return REGNO_SH3_MACL; 698 1.37 thorpej case DWARF_SH3_SR: 699 1.37 thorpej return REGNO_SH3_SR; 700 1.37 thorpej default: 701 1.37 thorpej return LAST_REGISTER + 1; 702 1.37 thorpej } 703 1.8 joerg } 704 1.8 joerg 705 1.8 joerg bool validRegister(int num) const { 706 1.37 thorpej return (num >= 0 && num <= REGNO_SH3_GBR) || 707 1.37 thorpej (num >= REGNO_SH3_MACH && num <= REGNO_SH3_SR); 708 1.8 joerg } 709 1.8 joerg 710 1.8 joerg uint64_t getRegister(int num) const { 711 1.8 joerg assert(validRegister(num)); 712 1.8 joerg return reg[num]; 713 1.8 joerg } 714 1.8 joerg 715 1.8 joerg void setRegister(int num, uint64_t value) { 716 1.8 joerg assert(validRegister(num)); 717 1.8 joerg reg[num] = value; 718 1.8 joerg } 719 1.8 joerg 720 1.8 joerg uint64_t getIP() const { return reg[REGNO_SH3_PC]; } 721 1.8 joerg 722 1.8 joerg void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } 723 1.8 joerg 724 1.8 joerg uint64_t getSP() const { return reg[REGNO_SH3_R15]; } 725 1.8 joerg 726 1.8 joerg void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } 727 1.8 joerg 728 1.8 joerg bool validFloatVectorRegister(int num) const { return false; } 729 1.8 joerg 730 1.8 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 731 1.8 joerg 732 1.8 joerg __dso_hidden void jumpto() const __dead; 733 1.8 joerg 734 1.8 joerg private: 735 1.37 thorpej uint32_t reg[REGNO_SH3_SR + 1]; 736 1.8 joerg }; 737 1.8 joerg 738 1.11 joerg enum { 739 1.11 joerg DWARF_SPARC64_R0 = 0, 740 1.11 joerg DWARF_SPARC64_R31 = 31, 741 1.11 joerg DWARF_SPARC64_PC = 32, 742 1.11 joerg 743 1.11 joerg REGNO_SPARC64_R0 = 0, 744 1.11 joerg REGNO_SPARC64_R14 = 14, 745 1.11 joerg REGNO_SPARC64_R15 = 15, 746 1.11 joerg REGNO_SPARC64_R31 = 31, 747 1.11 joerg REGNO_SPARC64_PC = 32, 748 1.11 joerg }; 749 1.11 joerg 750 1.11 joerg class Registers_SPARC64 { 751 1.11 joerg public: 752 1.11 joerg enum { 753 1.11 joerg LAST_REGISTER = REGNO_SPARC64_PC, 754 1.11 joerg LAST_RESTORE_REG = REGNO_SPARC64_PC, 755 1.11 joerg RETURN_OFFSET = 8, 756 1.19 joerg RETURN_MASK = 0, 757 1.11 joerg }; 758 1.11 joerg typedef uint64_t reg_t; 759 1.11 joerg 760 1.11 joerg __dso_hidden Registers_SPARC64(); 761 1.11 joerg 762 1.11 joerg static int dwarf2regno(int num) { 763 1.11 joerg if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31) 764 1.11 joerg return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0); 765 1.11 joerg if (num == DWARF_SPARC64_PC) 766 1.11 joerg return REGNO_SPARC64_PC; 767 1.11 joerg return LAST_REGISTER + 1; 768 1.11 joerg } 769 1.11 joerg 770 1.11 joerg bool validRegister(int num) const { 771 1.11 joerg return num >= 0 && num <= REGNO_SPARC64_PC; 772 1.11 joerg } 773 1.11 joerg 774 1.11 joerg uint64_t getRegister(int num) const { 775 1.11 joerg assert(validRegister(num)); 776 1.11 joerg return reg[num]; 777 1.11 joerg } 778 1.11 joerg 779 1.11 joerg void setRegister(int num, uint64_t value) { 780 1.11 joerg assert(validRegister(num)); 781 1.11 joerg reg[num] = value; 782 1.11 joerg } 783 1.11 joerg 784 1.11 joerg uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; } 785 1.11 joerg 786 1.11 joerg void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; } 787 1.11 joerg 788 1.11 joerg uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; } 789 1.11 joerg 790 1.11 joerg void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; } 791 1.11 joerg 792 1.11 joerg bool validFloatVectorRegister(int num) const { return false; } 793 1.11 joerg 794 1.11 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 795 1.11 joerg 796 1.11 joerg __dso_hidden void jumpto() const __dead; 797 1.11 joerg 798 1.11 joerg private: 799 1.11 joerg uint64_t reg[REGNO_SPARC64_PC + 1]; 800 1.11 joerg }; 801 1.11 joerg 802 1.11 joerg enum { 803 1.11 joerg DWARF_SPARC_R0 = 0, 804 1.11 joerg DWARF_SPARC_R31 = 31, 805 1.11 joerg DWARF_SPARC_PC = 32, 806 1.11 joerg 807 1.11 joerg REGNO_SPARC_R0 = 0, 808 1.11 joerg REGNO_SPARC_R14 = 14, 809 1.11 joerg REGNO_SPARC_R15 = 15, 810 1.11 joerg REGNO_SPARC_R31 = 31, 811 1.11 joerg REGNO_SPARC_PC = 32, 812 1.11 joerg }; 813 1.11 joerg 814 1.11 joerg class Registers_SPARC { 815 1.11 joerg public: 816 1.11 joerg enum { 817 1.11 joerg LAST_REGISTER = REGNO_SPARC_PC, 818 1.11 joerg LAST_RESTORE_REG = REGNO_SPARC_PC, 819 1.11 joerg RETURN_OFFSET = 8, 820 1.19 joerg RETURN_MASK = 0, 821 1.11 joerg }; 822 1.11 joerg typedef uint32_t reg_t; 823 1.11 joerg 824 1.11 joerg __dso_hidden Registers_SPARC(); 825 1.11 joerg 826 1.11 joerg static int dwarf2regno(int num) { 827 1.11 joerg if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31) 828 1.11 joerg return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0); 829 1.11 joerg if (num == DWARF_SPARC_PC) 830 1.11 joerg return REGNO_SPARC_PC; 831 1.11 joerg return LAST_REGISTER + 1; 832 1.11 joerg } 833 1.11 joerg 834 1.11 joerg bool validRegister(int num) const { 835 1.11 joerg return num >= 0 && num <= REGNO_SPARC_PC; 836 1.11 joerg } 837 1.11 joerg 838 1.11 joerg uint64_t getRegister(int num) const { 839 1.11 joerg assert(validRegister(num)); 840 1.11 joerg return reg[num]; 841 1.11 joerg } 842 1.11 joerg 843 1.11 joerg void setRegister(int num, uint64_t value) { 844 1.11 joerg assert(validRegister(num)); 845 1.11 joerg reg[num] = value; 846 1.11 joerg } 847 1.11 joerg 848 1.11 joerg uint64_t getIP() const { return reg[REGNO_SPARC_PC]; } 849 1.11 joerg 850 1.11 joerg void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; } 851 1.11 joerg 852 1.11 joerg uint64_t getSP() const { return reg[REGNO_SPARC_R14]; } 853 1.11 joerg 854 1.11 joerg void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; } 855 1.11 joerg 856 1.11 joerg bool validFloatVectorRegister(int num) const { return false; } 857 1.11 joerg 858 1.11 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 859 1.11 joerg 860 1.11 joerg __dso_hidden void jumpto() const __dead; 861 1.11 joerg 862 1.11 joerg private: 863 1.11 joerg uint32_t reg[REGNO_SPARC_PC + 1]; 864 1.11 joerg }; 865 1.11 joerg 866 1.12 joerg enum { 867 1.12 joerg DWARF_ALPHA_R0 = 0, 868 1.12 joerg DWARF_ALPHA_R30 = 30, 869 1.12 joerg DWARF_ALPHA_F0 = 32, 870 1.12 joerg DWARF_ALPHA_F30 = 62, 871 1.31 thorpej DWARF_ALPHA_SIGRETURN = 64, 872 1.12 joerg 873 1.12 joerg REGNO_ALPHA_R0 = 0, 874 1.12 joerg REGNO_ALPHA_R26 = 26, 875 1.12 joerg REGNO_ALPHA_R30 = 30, 876 1.12 joerg REGNO_ALPHA_PC = 31, 877 1.12 joerg REGNO_ALPHA_F0 = 32, 878 1.12 joerg REGNO_ALPHA_F30 = 62, 879 1.31 thorpej REGNO_ALPHA_SIGRETURN = 64, 880 1.12 joerg }; 881 1.12 joerg 882 1.12 joerg class Registers_Alpha { 883 1.12 joerg public: 884 1.12 joerg enum { 885 1.31 thorpej LAST_REGISTER = REGNO_ALPHA_SIGRETURN, 886 1.31 thorpej LAST_RESTORE_REG = REGNO_ALPHA_SIGRETURN, 887 1.12 joerg RETURN_OFFSET = 0, 888 1.19 joerg RETURN_MASK = 0, 889 1.12 joerg }; 890 1.12 joerg 891 1.12 joerg __dso_hidden Registers_Alpha(); 892 1.12 joerg 893 1.12 joerg static int dwarf2regno(int num) { return num; } 894 1.12 joerg 895 1.12 joerg bool validRegister(int num) const { 896 1.31 thorpej return (num >= 0 && num <= REGNO_ALPHA_PC) || 897 1.31 thorpej num == REGNO_ALPHA_SIGRETURN; 898 1.12 joerg } 899 1.12 joerg 900 1.12 joerg uint64_t getRegister(int num) const { 901 1.12 joerg assert(validRegister(num)); 902 1.31 thorpej if (num == REGNO_ALPHA_SIGRETURN) 903 1.31 thorpej return sigreturn_reg; 904 1.31 thorpej else 905 1.31 thorpej return reg[num]; 906 1.12 joerg } 907 1.12 joerg 908 1.12 joerg void setRegister(int num, uint64_t value) { 909 1.12 joerg assert(validRegister(num)); 910 1.31 thorpej if (num == REGNO_ALPHA_SIGRETURN) 911 1.31 thorpej sigreturn_reg = value; 912 1.31 thorpej else 913 1.31 thorpej reg[num] = value; 914 1.12 joerg } 915 1.12 joerg 916 1.12 joerg uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; } 917 1.12 joerg 918 1.12 joerg void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; } 919 1.12 joerg 920 1.12 joerg uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; } 921 1.12 joerg 922 1.12 joerg void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; } 923 1.12 joerg 924 1.12 joerg bool validFloatVectorRegister(int num) const { 925 1.12 joerg return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30; 926 1.12 joerg } 927 1.12 joerg 928 1.12 joerg void copyFloatVectorRegister(int num, uint64_t addr_) { 929 1.12 joerg assert(validFloatVectorRegister(num)); 930 1.12 joerg const void *addr = reinterpret_cast<const void *>(addr_); 931 1.12 joerg memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0])); 932 1.12 joerg } 933 1.12 joerg 934 1.12 joerg __dso_hidden void jumpto() const __dead; 935 1.12 joerg 936 1.12 joerg private: 937 1.12 joerg uint64_t reg[REGNO_ALPHA_PC + 1]; 938 1.12 joerg uint64_t fpreg[31]; 939 1.31 thorpej uint64_t sigreturn_reg; 940 1.12 joerg }; 941 1.12 joerg 942 1.13 joerg enum { 943 1.13 joerg DWARF_HPPA_R1 = 1, 944 1.13 joerg DWARF_HPPA_R31 = 31, 945 1.13 joerg DWARF_HPPA_FR4L = 32, 946 1.13 joerg DWARF_HPPA_FR31H = 87, 947 1.38 skrll DWARF_HPPA_SIGRETURN = 89, 948 1.13 joerg 949 1.13 joerg REGNO_HPPA_PC = 0, 950 1.13 joerg REGNO_HPPA_R1 = 1, 951 1.13 joerg REGNO_HPPA_R2 = 2, 952 1.13 joerg REGNO_HPPA_R30 = 30, 953 1.13 joerg REGNO_HPPA_R31 = 31, 954 1.13 joerg REGNO_HPPA_FR4L = 32, 955 1.13 joerg REGNO_HPPA_FR31H = 87, 956 1.38 skrll REGNO_HPPA_SIGRETURN = 89, 957 1.13 joerg }; 958 1.13 joerg 959 1.13 joerg class Registers_HPPA { 960 1.13 joerg public: 961 1.13 joerg enum { 962 1.13 joerg LAST_REGISTER = REGNO_HPPA_FR31H, 963 1.38 skrll LAST_RESTORE_REG = REGNO_HPPA_SIGRETURN, 964 1.19 joerg RETURN_OFFSET = 0, 965 1.19 joerg RETURN_MASK = 3, 966 1.13 joerg }; 967 1.13 joerg 968 1.13 joerg __dso_hidden Registers_HPPA(); 969 1.13 joerg 970 1.13 joerg static int dwarf2regno(int num) { 971 1.13 joerg if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31) 972 1.13 joerg return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1); 973 1.13 joerg if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H) 974 1.13 joerg return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H); 975 1.38 skrll if (num == DWARF_HPPA_SIGRETURN) 976 1.38 skrll return REGNO_HPPA_SIGRETURN; 977 1.13 joerg return LAST_REGISTER + 1; 978 1.13 joerg } 979 1.13 joerg 980 1.13 joerg bool validRegister(int num) const { 981 1.39 martin return (num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31) || 982 1.38 skrll num == REGNO_HPPA_SIGRETURN; 983 1.13 joerg } 984 1.13 joerg 985 1.13 joerg uint64_t getRegister(int num) const { 986 1.13 joerg assert(validRegister(num)); 987 1.38 skrll if (num == REGNO_HPPA_SIGRETURN) 988 1.38 skrll return sigreturn_reg; 989 1.38 skrll else 990 1.38 skrll return reg[num]; 991 1.13 joerg } 992 1.13 joerg 993 1.13 joerg void setRegister(int num, uint64_t value) { 994 1.13 joerg assert(validRegister(num)); 995 1.38 skrll if (num == REGNO_HPPA_SIGRETURN) 996 1.38 skrll sigreturn_reg = value; 997 1.38 skrll else 998 1.38 skrll reg[num] = value; 999 1.13 joerg } 1000 1.13 joerg 1001 1.13 joerg uint64_t getIP() const { return reg[REGNO_HPPA_PC]; } 1002 1.13 joerg 1003 1.13 joerg void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; } 1004 1.13 joerg 1005 1.13 joerg uint64_t getSP() const { return reg[REGNO_HPPA_R30]; } 1006 1.13 joerg 1007 1.13 joerg void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; } 1008 1.13 joerg 1009 1.13 joerg bool validFloatVectorRegister(int num) const { 1010 1.13 joerg return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H; 1011 1.13 joerg } 1012 1.13 joerg 1013 1.13 joerg void copyFloatVectorRegister(int num, uint64_t addr_) { 1014 1.13 joerg assert(validFloatVectorRegister(num)); 1015 1.13 joerg const void *addr = reinterpret_cast<const void *>(addr_); 1016 1.13 joerg memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0])); 1017 1.13 joerg } 1018 1.13 joerg 1019 1.13 joerg __dso_hidden void jumpto() const __dead; 1020 1.13 joerg 1021 1.13 joerg private: 1022 1.13 joerg uint32_t reg[REGNO_HPPA_R31 + 1]; 1023 1.13 joerg uint32_t fpreg[56]; 1024 1.38 skrll uint32_t sigreturn_reg; 1025 1.13 joerg }; 1026 1.13 joerg 1027 1.14 joerg enum { 1028 1.14 joerg DWARF_MIPS_R1 = 0, 1029 1.14 joerg DWARF_MIPS_R31 = 31, 1030 1.14 joerg DWARF_MIPS_F0 = 32, 1031 1.14 joerg DWARF_MIPS_F31 = 63, 1032 1.29 thorpej // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 1033 1.29 thorpej // signal handler return address. 1034 1.29 thorpej DWARF_MIPS_MDHI = 64, 1035 1.29 thorpej DWARF_MIPS_MDLO = 65, 1036 1.29 thorpej DWARF_MIPS_SIGRETURN = 66, 1037 1.14 joerg 1038 1.14 joerg REGNO_MIPS_PC = 0, 1039 1.14 joerg REGNO_MIPS_R1 = 0, 1040 1.14 joerg REGNO_MIPS_R29 = 29, 1041 1.14 joerg REGNO_MIPS_R31 = 31, 1042 1.14 joerg REGNO_MIPS_F0 = 33, 1043 1.29 thorpej REGNO_MIPS_F31 = 64, 1044 1.29 thorpej // these live in other_reg[] 1045 1.29 thorpej REGNO_MIPS_MDHI = 65, 1046 1.29 thorpej REGNO_MIPS_MDLO = 66, 1047 1.29 thorpej REGNO_MIPS_SIGRETURN = 67 1048 1.14 joerg }; 1049 1.14 joerg 1050 1.14 joerg class Registers_MIPS { 1051 1.14 joerg public: 1052 1.14 joerg enum { 1053 1.29 thorpej LAST_REGISTER = REGNO_MIPS_SIGRETURN, 1054 1.29 thorpej LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1055 1.14 joerg RETURN_OFFSET = 0, 1056 1.19 joerg RETURN_MASK = 0, 1057 1.14 joerg }; 1058 1.14 joerg 1059 1.14 joerg __dso_hidden Registers_MIPS(); 1060 1.14 joerg 1061 1.14 joerg static int dwarf2regno(int num) { 1062 1.14 joerg if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31) 1063 1.14 joerg return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1); 1064 1.14 joerg if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31) 1065 1.14 joerg return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0); 1066 1.29 thorpej if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN) 1067 1.29 thorpej return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI); 1068 1.14 joerg return LAST_REGISTER + 1; 1069 1.14 joerg } 1070 1.14 joerg 1071 1.14 joerg bool validRegister(int num) const { 1072 1.29 thorpej return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) || 1073 1.29 thorpej (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN); 1074 1.14 joerg } 1075 1.14 joerg 1076 1.14 joerg uint64_t getRegister(int num) const { 1077 1.14 joerg assert(validRegister(num)); 1078 1.29 thorpej if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 1079 1.29 thorpej return other_reg[num - REGNO_MIPS_MDHI]; 1080 1.14 joerg return reg[num]; 1081 1.14 joerg } 1082 1.14 joerg 1083 1.14 joerg void setRegister(int num, uint64_t value) { 1084 1.14 joerg assert(validRegister(num)); 1085 1.29 thorpej if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 1086 1.29 thorpej other_reg[num - REGNO_MIPS_MDHI] = value; 1087 1.29 thorpej else 1088 1.29 thorpej reg[num] = value; 1089 1.14 joerg } 1090 1.14 joerg 1091 1.14 joerg uint64_t getIP() const { return reg[REGNO_MIPS_PC]; } 1092 1.14 joerg 1093 1.14 joerg void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; } 1094 1.14 joerg 1095 1.14 joerg uint64_t getSP() const { return reg[REGNO_MIPS_R29]; } 1096 1.14 joerg 1097 1.14 joerg void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; } 1098 1.14 joerg 1099 1.14 joerg bool validFloatVectorRegister(int num) const { 1100 1.29 thorpej return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31; 1101 1.14 joerg } 1102 1.14 joerg 1103 1.14 joerg void copyFloatVectorRegister(int num, uint64_t addr_) { 1104 1.14 joerg assert(validFloatVectorRegister(num)); 1105 1.14 joerg const void *addr = reinterpret_cast<const void *>(addr_); 1106 1.14 joerg memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0])); 1107 1.14 joerg } 1108 1.14 joerg 1109 1.14 joerg __dso_hidden void jumpto() const __dead; 1110 1.14 joerg 1111 1.14 joerg private: 1112 1.14 joerg uint32_t reg[REGNO_MIPS_R31 + 1]; 1113 1.14 joerg uint64_t fpreg[32]; 1114 1.29 thorpej uint32_t other_reg[3]; 1115 1.14 joerg }; 1116 1.14 joerg 1117 1.14 joerg enum { 1118 1.14 joerg DWARF_MIPS64_R1 = 0, 1119 1.14 joerg DWARF_MIPS64_R31 = 31, 1120 1.14 joerg DWARF_MIPS64_F0 = 32, 1121 1.14 joerg DWARF_MIPS64_F31 = 63, 1122 1.30 thorpej // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 1123 1.30 thorpej // signal handler return address. 1124 1.30 thorpej DWARF_MIPS64_MDHI = 64, 1125 1.30 thorpej DWARF_MIPS64_MDLO = 65, 1126 1.30 thorpej DWARF_MIPS64_SIGRETURN = 66, 1127 1.14 joerg 1128 1.14 joerg REGNO_MIPS64_PC = 0, 1129 1.14 joerg REGNO_MIPS64_R1 = 0, 1130 1.14 joerg REGNO_MIPS64_R29 = 29, 1131 1.14 joerg REGNO_MIPS64_R31 = 31, 1132 1.14 joerg REGNO_MIPS64_F0 = 33, 1133 1.30 thorpej REGNO_MIPS64_F31 = 64, 1134 1.30 thorpej // these live in other_reg[] 1135 1.30 thorpej REGNO_MIPS64_MDHI = 65, 1136 1.30 thorpej REGNO_MIPS64_MDLO = 66, 1137 1.30 thorpej REGNO_MIPS64_SIGRETURN = 67 1138 1.14 joerg }; 1139 1.14 joerg 1140 1.14 joerg class Registers_MIPS64 { 1141 1.14 joerg public: 1142 1.14 joerg enum { 1143 1.30 thorpej LAST_REGISTER = REGNO_MIPS_SIGRETURN, 1144 1.30 thorpej LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1145 1.14 joerg RETURN_OFFSET = 0, 1146 1.19 joerg RETURN_MASK = 0, 1147 1.14 joerg }; 1148 1.14 joerg 1149 1.14 joerg __dso_hidden Registers_MIPS64(); 1150 1.14 joerg 1151 1.14 joerg static int dwarf2regno(int num) { 1152 1.14 joerg if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31) 1153 1.14 joerg return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1); 1154 1.14 joerg if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31) 1155 1.14 joerg return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0); 1156 1.30 thorpej if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN) 1157 1.30 thorpej return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI); 1158 1.14 joerg return LAST_REGISTER + 1; 1159 1.14 joerg } 1160 1.14 joerg 1161 1.14 joerg bool validRegister(int num) const { 1162 1.32 skrll return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) || 1163 1.30 thorpej (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN); 1164 1.14 joerg } 1165 1.14 joerg 1166 1.14 joerg uint64_t getRegister(int num) const { 1167 1.14 joerg assert(validRegister(num)); 1168 1.30 thorpej if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1169 1.30 thorpej return other_reg[num - REGNO_MIPS64_MDHI]; 1170 1.14 joerg return reg[num]; 1171 1.14 joerg } 1172 1.14 joerg 1173 1.14 joerg void setRegister(int num, uint64_t value) { 1174 1.14 joerg assert(validRegister(num)); 1175 1.30 thorpej if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1176 1.30 thorpej other_reg[num - REGNO_MIPS64_MDHI] = value; 1177 1.30 thorpej else 1178 1.30 thorpej reg[num] = value; 1179 1.14 joerg } 1180 1.14 joerg 1181 1.14 joerg uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } 1182 1.14 joerg 1183 1.14 joerg void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; } 1184 1.14 joerg 1185 1.14 joerg uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; } 1186 1.14 joerg 1187 1.14 joerg void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } 1188 1.14 joerg 1189 1.14 joerg bool validFloatVectorRegister(int num) const { 1190 1.30 thorpej return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31; 1191 1.14 joerg } 1192 1.14 joerg 1193 1.14 joerg void copyFloatVectorRegister(int num, uint64_t addr_) { 1194 1.14 joerg assert(validFloatVectorRegister(num)); 1195 1.14 joerg const void *addr = reinterpret_cast<const void *>(addr_); 1196 1.14 joerg memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0])); 1197 1.14 joerg } 1198 1.14 joerg 1199 1.14 joerg __dso_hidden void jumpto() const __dead; 1200 1.14 joerg 1201 1.14 joerg private: 1202 1.14 joerg uint64_t reg[REGNO_MIPS64_R31 + 1]; 1203 1.14 joerg uint64_t fpreg[32]; 1204 1.30 thorpej uint64_t other_reg[3]; 1205 1.14 joerg }; 1206 1.14 joerg 1207 1.18 matt enum { 1208 1.18 matt DWARF_OR1K_R0 = 0, 1209 1.18 matt DWARF_OR1K_SP = 1, 1210 1.18 matt DWARF_OR1K_LR = 9, 1211 1.18 matt DWARF_OR1K_R31 = 31, 1212 1.18 matt DWARF_OR1K_FPCSR = 32, 1213 1.18 matt 1214 1.18 matt REGNO_OR1K_R0 = 0, 1215 1.18 matt REGNO_OR1K_SP = 1, 1216 1.18 matt REGNO_OR1K_LR = 9, 1217 1.18 matt REGNO_OR1K_R31 = 31, 1218 1.18 matt REGNO_OR1K_FPCSR = 32, 1219 1.18 matt }; 1220 1.18 matt 1221 1.18 matt class Registers_or1k { 1222 1.18 matt public: 1223 1.18 matt enum { 1224 1.18 matt LAST_REGISTER = REGNO_OR1K_FPCSR, 1225 1.18 matt LAST_RESTORE_REG = REGNO_OR1K_FPCSR, 1226 1.18 matt RETURN_OFFSET = 0, 1227 1.19 joerg RETURN_MASK = 0, 1228 1.18 matt }; 1229 1.18 matt 1230 1.18 matt __dso_hidden Registers_or1k(); 1231 1.18 matt 1232 1.18 matt static int dwarf2regno(int num) { 1233 1.18 matt if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31) 1234 1.18 matt return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0); 1235 1.18 matt if (num == DWARF_OR1K_FPCSR) 1236 1.18 matt return REGNO_OR1K_FPCSR; 1237 1.18 matt return LAST_REGISTER + 1; 1238 1.18 matt } 1239 1.18 matt 1240 1.18 matt bool validRegister(int num) const { 1241 1.18 matt return num >= 0 && num <= LAST_RESTORE_REG; 1242 1.18 matt } 1243 1.18 matt 1244 1.18 matt uint64_t getRegister(int num) const { 1245 1.18 matt assert(validRegister(num)); 1246 1.18 matt return reg[num]; 1247 1.18 matt } 1248 1.18 matt 1249 1.18 matt void setRegister(int num, uint64_t value) { 1250 1.18 matt assert(validRegister(num)); 1251 1.18 matt reg[num] = value; 1252 1.18 matt } 1253 1.18 matt 1254 1.18 matt uint64_t getIP() const { return reg[REGNO_OR1K_LR]; } 1255 1.18 matt 1256 1.18 matt void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; } 1257 1.18 matt 1258 1.18 matt uint64_t getSP() const { return reg[REGNO_OR1K_SP]; } 1259 1.18 matt 1260 1.18 matt void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; } 1261 1.18 matt 1262 1.18 matt bool validFloatVectorRegister(int num) const { 1263 1.18 matt return false; 1264 1.18 matt } 1265 1.18 matt 1266 1.18 matt void copyFloatVectorRegister(int num, uint64_t addr_) { 1267 1.18 matt } 1268 1.18 matt 1269 1.18 matt __dso_hidden void jumpto() const __dead; 1270 1.18 matt 1271 1.18 matt private: 1272 1.18 matt uint32_t reg[REGNO_OR1K_FPCSR + 1]; 1273 1.18 matt }; 1274 1.18 matt 1275 1.9 joerg #if __i386__ 1276 1.9 joerg typedef Registers_x86 NativeUnwindRegisters; 1277 1.9 joerg #elif __x86_64__ 1278 1.9 joerg typedef Registers_x86_64 NativeUnwindRegisters; 1279 1.9 joerg #elif __powerpc__ 1280 1.9 joerg typedef Registers_ppc32 NativeUnwindRegisters; 1281 1.17 matt #elif __aarch64__ 1282 1.17 matt typedef Registers_aarch64 NativeUnwindRegisters; 1283 1.16 joerg #elif __arm__ 1284 1.9 joerg typedef Registers_arm32 NativeUnwindRegisters; 1285 1.9 joerg #elif __vax__ 1286 1.9 joerg typedef Registers_vax NativeUnwindRegisters; 1287 1.9 joerg #elif __m68k__ 1288 1.9 joerg typedef Registers_M68K NativeUnwindRegisters; 1289 1.14 joerg #elif __mips_n64 || __mips_n32 1290 1.14 joerg typedef Registers_MIPS64 NativeUnwindRegisters; 1291 1.14 joerg #elif __mips__ 1292 1.14 joerg typedef Registers_MIPS NativeUnwindRegisters; 1293 1.9 joerg #elif __sh3__ 1294 1.9 joerg typedef Registers_SH3 NativeUnwindRegisters; 1295 1.11 joerg #elif __sparc64__ 1296 1.11 joerg typedef Registers_SPARC64 NativeUnwindRegisters; 1297 1.11 joerg #elif __sparc__ 1298 1.11 joerg typedef Registers_SPARC NativeUnwindRegisters; 1299 1.12 joerg #elif __alpha__ 1300 1.12 joerg typedef Registers_Alpha NativeUnwindRegisters; 1301 1.13 joerg #elif __hppa__ 1302 1.13 joerg typedef Registers_HPPA NativeUnwindRegisters; 1303 1.18 matt #elif __or1k__ 1304 1.18 matt typedef Registers_or1k NativeUnwindRegisters; 1305 1.9 joerg #endif 1306 1.1 joerg } // namespace _Unwind 1307 1.1 joerg 1308 1.1 joerg #endif // __REGISTERS_HPP__ 1309