delve/pkg/dwarf/regnum/ppc64le.go
Álex Sáez 71f1220717
*: add ppc64le support (#2963)
* Add vendor/golang.org/x/arch/ppc64

* Add ppc64le support
2023-07-07 09:30:38 -07:00

116 lines
3.1 KiB
Go

package regnum
import "fmt"
// The mapping between hardware registers and DWARF registers is specified
// in the 64-Bit ELF V2 ABI Specification of the Power Architecture in section
// 2.4 DWARF Definition
// https://openpowerfoundation.org/specifications/64bitelfabi/
const (
// General Purpose Registers: from R0 to R31
PPC64LE_FIRST_GPR = 0
PPC64LE_R0 = PPC64LE_FIRST_GPR
PPC64LE_LAST_GPR = 31
// Floating point registers: from F0 to F31
PPC64LE_FIRST_FPR = 32
PPC64LE_F0 = PPC64LE_FIRST_FPR
PPC64LE_LAST_FPR = 63
// Vector (Altivec/VMX) registers: from V0 to V31
PPC64LE_FIRST_VMX = 64
PPC64LE_V0 = PPC64LE_FIRST_VMX
PPC64LE_LAST_VMX = 95
// Vector Scalar (VSX) registers: from VS0 to VS63
PPC64LE_FIRST_VSX = 96
PPC64LE_VS0 = PPC64LE_FIRST_VSX
PPC64LE_LAST_VSX = 160
// Condition Registers: from CR0 to CR7
PPC64LE_CR0 = 0
// Special registers
PPC64LE_SP = 1 // Stack frame pointer: Gpr[1]
PPC64LE_PC = 12 // The documentation refers to this as the CIA (Current Instruction Address)
PPC64LE_LR = 65 // Link register
)
func PPC64LEToName(num uint64) string {
switch {
case num == PPC64LE_SP:
return "SP"
case num == PPC64LE_PC:
return "PC"
case num == PPC64LE_LR:
return "LR"
case isGPR(num):
return fmt.Sprintf("r%d", int(num-PPC64LE_FIRST_GPR))
case isFPR(num):
return fmt.Sprintf("f%d", int(num-PPC64LE_FIRST_FPR))
case isVMX(num):
return fmt.Sprintf("v%d", int(num-PPC64LE_FIRST_VMX))
case isVSX(num):
return fmt.Sprintf("vs%d", int(num-PPC64LE_FIRST_VSX))
default:
return fmt.Sprintf("unknown%d", num)
}
}
// PPC64LEMaxRegNum is 172 registers in total, across 4 categories:
// General Purpose Registers or GPR (32 GPR + 9 special registers)
// Floating Point Registers or FPR (32 FPR + 1 special register)
// Altivec/VMX Registers or VMX (32 VMX + 2 special registers)
// VSX Registers or VSX (64 VSX)
// Documentation: https://lldb.llvm.org/cpp_reference/RegisterContextPOSIX__ppc64le_8cpp_source.html
func PPC64LEMaxRegNum() uint64 {
return 172
}
func isGPR(num uint64) bool {
return num < PPC64LE_LAST_GPR
}
func isFPR(num uint64) bool {
return num >= PPC64LE_FIRST_FPR && num <= PPC64LE_LAST_FPR
}
func isVMX(num uint64) bool {
return num >= PPC64LE_FIRST_VMX && num <= PPC64LE_LAST_VMX
}
func isVSX(num uint64) bool {
return num >= PPC64LE_FIRST_VSX && num <= PPC64LE_LAST_VSX
}
var PPC64LENameToDwarf = func() map[string]int {
r := make(map[string]int)
r["nip"] = PPC64LE_PC
r["sp"] = PPC64LE_SP
r["bp"] = PPC64LE_SP
r["link"] = PPC64LE_LR
// General Purpose Registers: from R0 to R31
for i := 0; i <= 31; i++ {
r[fmt.Sprintf("r%d", i)] = PPC64LE_R0 + i
}
// Floating point registers: from F0 to F31
for i := 0; i <= 31; i++ {
r[fmt.Sprintf("f%d", i)] = PPC64LE_F0 + i
}
// Vector (Altivec/VMX) registers: from V0 to V31
for i := 0; i <= 31; i++ {
r[fmt.Sprintf("v%d", i)] = PPC64LE_V0 + i
}
// Vector Scalar (VSX) registers: from VS0 to VS63
for i := 0; i <= 63; i++ {
r[fmt.Sprintf("vs%d", i)] = PPC64LE_VS0 + i
}
// Condition Registers: from CR0 to CR7
for i := 0; i <= 7; i++ {
r[fmt.Sprintf("cr%d", i)] = PPC64LE_CR0 + i
}
return r
}()