[libunwind] r321667 - [PPC64] Port to ppc64le - initial version

Martin Storsjo via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 2 12:10:54 PST 2018


Author: mstorsjo
Date: Tue Jan  2 12:10:54 2018
New Revision: 321667

URL: http://llvm.org/viewvc/llvm-project?rev=321667&view=rev
Log:
[PPC64] Port to ppc64le - initial version

Initial working version of libunwind for PowerPC 64. Tested on
little-endian ppc64 host only.
Based on the existing PowerPC 32 code.

It supports:

- context save/restore (unw_getcontext, unw_init_local, unw_resume)
- read/write from/to saved registers
- backtrace (unw_step)

Patch by Leandro Lupori!

Differential Revision: https://reviews.llvm.org/D41386

Modified:
    libunwind/trunk/include/__libunwind_config.h
    libunwind/trunk/include/libunwind.h
    libunwind/trunk/src/AddressSpace.hpp
    libunwind/trunk/src/Registers.hpp
    libunwind/trunk/src/UnwindCursor.hpp
    libunwind/trunk/src/UnwindRegistersRestore.S
    libunwind/trunk/src/UnwindRegistersSave.S
    libunwind/trunk/src/assembly.h
    libunwind/trunk/src/config.h
    libunwind/trunk/src/libunwind.cpp

Modified: libunwind/trunk/include/__libunwind_config.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/__libunwind_config.h?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/include/__libunwind_config.h (original)
+++ libunwind/trunk/include/__libunwind_config.h Tue Jan  2 12:10:54 2018
@@ -18,6 +18,7 @@
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86       8
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64    32
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC       112
+#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64     110
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64     95
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM       287
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K      31
@@ -39,6 +40,11 @@
 #    define _LIBUNWIND_CURSOR_SIZE 33
 #  endif
 #  define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64
+# elif defined(__powerpc64__)
+#  define _LIBUNWIND_TARGET_PPC64 1
+#  define _LIBUNWIND_CONTEXT_SIZE 136
+#  define _LIBUNWIND_CURSOR_SIZE 148
+#  define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64
 # elif defined(__ppc__)
 #  define _LIBUNWIND_TARGET_PPC 1
 #  define _LIBUNWIND_CONTEXT_SIZE 117
@@ -84,13 +90,14 @@
 # define _LIBUNWIND_TARGET_I386
 # define _LIBUNWIND_TARGET_X86_64 1
 # define _LIBUNWIND_TARGET_PPC 1
+# define _LIBUNWIND_TARGET_PPC64 1
 # define _LIBUNWIND_TARGET_AARCH64 1
 # define _LIBUNWIND_TARGET_ARM 1
 # define _LIBUNWIND_TARGET_OR1K 1
 # define _LIBUNWIND_TARGET_MIPS_O32 1
 # define _LIBUNWIND_TARGET_MIPS_N64 1
-# define _LIBUNWIND_CONTEXT_SIZE 128
-# define _LIBUNWIND_CURSOR_SIZE 140
+# define _LIBUNWIND_CONTEXT_SIZE 136
+# define _LIBUNWIND_CURSOR_SIZE 148
 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
 #endif // _LIBUNWIND_IS_NATIVE_ONLY
 

Modified: libunwind/trunk/include/libunwind.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/libunwind.h?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/include/libunwind.h (original)
+++ libunwind/trunk/include/libunwind.h Tue Jan  2 12:10:54 2018
@@ -325,6 +325,120 @@ enum {
   UNW_PPC_SPEFSCR = 112
 };
 
+// 64-bit ppc register numbers
+enum {
+  UNW_PPC64_R0  = 0,
+  UNW_PPC64_R1  = 1,
+  UNW_PPC64_R2  = 2,
+  UNW_PPC64_R3  = 3,
+  UNW_PPC64_R4  = 4,
+  UNW_PPC64_R5  = 5,
+  UNW_PPC64_R6  = 6,
+  UNW_PPC64_R7  = 7,
+  UNW_PPC64_R8  = 8,
+  UNW_PPC64_R9  = 9,
+  UNW_PPC64_R10 = 10,
+  UNW_PPC64_R11 = 11,
+  UNW_PPC64_R12 = 12,
+  UNW_PPC64_R13 = 13,
+  UNW_PPC64_R14 = 14,
+  UNW_PPC64_R15 = 15,
+  UNW_PPC64_R16 = 16,
+  UNW_PPC64_R17 = 17,
+  UNW_PPC64_R18 = 18,
+  UNW_PPC64_R19 = 19,
+  UNW_PPC64_R20 = 20,
+  UNW_PPC64_R21 = 21,
+  UNW_PPC64_R22 = 22,
+  UNW_PPC64_R23 = 23,
+  UNW_PPC64_R24 = 24,
+  UNW_PPC64_R25 = 25,
+  UNW_PPC64_R26 = 26,
+  UNW_PPC64_R27 = 27,
+  UNW_PPC64_R28 = 28,
+  UNW_PPC64_R29 = 29,
+  UNW_PPC64_R30 = 30,
+  UNW_PPC64_R31 = 31,
+  UNW_PPC64_F0  = 32,
+  UNW_PPC64_F1  = 33,
+  UNW_PPC64_F2  = 34,
+  UNW_PPC64_F3  = 35,
+  UNW_PPC64_F4  = 36,
+  UNW_PPC64_F5  = 37,
+  UNW_PPC64_F6  = 38,
+  UNW_PPC64_F7  = 39,
+  UNW_PPC64_F8  = 40,
+  UNW_PPC64_F9  = 41,
+  UNW_PPC64_F10 = 42,
+  UNW_PPC64_F11 = 43,
+  UNW_PPC64_F12 = 44,
+  UNW_PPC64_F13 = 45,
+  UNW_PPC64_F14 = 46,
+  UNW_PPC64_F15 = 47,
+  UNW_PPC64_F16 = 48,
+  UNW_PPC64_F17 = 49,
+  UNW_PPC64_F18 = 50,
+  UNW_PPC64_F19 = 51,
+  UNW_PPC64_F20 = 52,
+  UNW_PPC64_F21 = 53,
+  UNW_PPC64_F22 = 54,
+  UNW_PPC64_F23 = 55,
+  UNW_PPC64_F24 = 56,
+  UNW_PPC64_F25 = 57,
+  UNW_PPC64_F26 = 58,
+  UNW_PPC64_F27 = 59,
+  UNW_PPC64_F28 = 60,
+  UNW_PPC64_F29 = 61,
+  UNW_PPC64_F30 = 62,
+  UNW_PPC64_F31 = 63,
+  UNW_PPC64_LR  = 64,
+  UNW_PPC64_CTR = 65,
+  UNW_PPC64_CR0 = 66,
+  UNW_PPC64_CR1 = 67,
+  UNW_PPC64_CR2 = 68,
+  UNW_PPC64_CR3 = 69,
+  UNW_PPC64_CR4 = 70,
+  UNW_PPC64_CR5 = 71,
+  UNW_PPC64_CR6 = 72,
+  UNW_PPC64_CR7 = 73,
+  UNW_PPC64_XER = 74,
+  UNW_PPC64_V0  = 75,
+  UNW_PPC64_V1  = 76,
+  UNW_PPC64_V2  = 77,
+  UNW_PPC64_V3  = 78,
+  UNW_PPC64_V4  = 79,
+  UNW_PPC64_V5  = 80,
+  UNW_PPC64_V6  = 81,
+  UNW_PPC64_V7  = 82,
+  UNW_PPC64_V8  = 83,
+  UNW_PPC64_V9  = 84,
+  UNW_PPC64_V10 = 85,
+  UNW_PPC64_V11 = 86,
+  UNW_PPC64_V12 = 87,
+  UNW_PPC64_V13 = 88,
+  UNW_PPC64_V14 = 89,
+  UNW_PPC64_V15 = 90,
+  UNW_PPC64_V16 = 91,
+  UNW_PPC64_V17 = 92,
+  UNW_PPC64_V18 = 93,
+  UNW_PPC64_V19 = 94,
+  UNW_PPC64_V20 = 95,
+  UNW_PPC64_V21 = 96,
+  UNW_PPC64_V22 = 97,
+  UNW_PPC64_V23 = 98,
+  UNW_PPC64_V24 = 99,
+  UNW_PPC64_V25 = 100,
+  UNW_PPC64_V26 = 101,
+  UNW_PPC64_V27 = 102,
+  UNW_PPC64_V28 = 103,
+  UNW_PPC64_V29 = 104,
+  UNW_PPC64_V30 = 105,
+  UNW_PPC64_V31 = 106,
+  UNW_PPC64_VRSAVE  = 107,
+  UNW_PPC64_VSCR    = 108,
+  UNW_PPC64_FPSCR   = 109
+};
+
 // 64-bit ARM64 registers
 enum {
   UNW_ARM64_X0  = 0,

Modified: libunwind/trunk/src/AddressSpace.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/AddressSpace.hpp?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/src/AddressSpace.hpp (original)
+++ libunwind/trunk/src/AddressSpace.hpp Tue Jan  2 12:10:54 2018
@@ -697,6 +697,13 @@ struct unw_addr_space_ppc : public unw_a
   RemoteAddressSpace<Pointer32<BigEndian>> oas;
 };
 
+/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points
+/// to when examining a 64-bit PowerPC process.
+struct unw_addr_space_ppc64 : public unw_addr_space {
+  unw_addr_space_ppc64(task_t task) : oas(task) {}
+  RemoteAddressSpace<Pointer64<LittleEndian>> oas;
+};
+
 #endif // UNW_REMOTE
 
 } // namespace libunwind

Modified: libunwind/trunk/src/Registers.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/Registers.hpp?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/src/Registers.hpp (original)
+++ libunwind/trunk/src/Registers.hpp Tue Jan  2 12:10:54 2018
@@ -1106,6 +1106,583 @@ inline const char *Registers_ppc::getReg
 }
 #endif // _LIBUNWIND_TARGET_PPC
 
+#if defined(_LIBUNWIND_TARGET_PPC64)
+/// Registers_ppc holds the register state of a thread in a 64-bit PowerPC
+/// process.
+class _LIBUNWIND_HIDDEN Registers_ppc64 {
+public:
+  Registers_ppc64();
+  Registers_ppc64(const void *registers);
+
+  bool        validRegister(int num) const;
+  uint64_t    getRegister(int num) const;
+  void        setRegister(int num, uint64_t value);
+  bool        validFloatRegister(int num) const;
+  double      getFloatRegister(int num) const;
+  void        setFloatRegister(int num, double value);
+  bool        validVectorRegister(int num) const;
+  v128        getVectorRegister(int num) const;
+  void        setVectorRegister(int num, v128 value);
+  const char *getRegisterName(int num);
+  void        jumpto();
+  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
+
+  uint64_t  getSP() const         { return _registers.__r1; }
+  void      setSP(uint64_t value) { _registers.__r1 = value; }
+  uint64_t  getIP() const         { return _registers.__srr0; }
+  void      setIP(uint64_t value) { _registers.__srr0 = value; }
+
+private:
+  struct ppc64_thread_state_t {
+    uint64_t __srr0; /* Instruction address register (PC) */
+    uint64_t __srr1; /* Machine state register (supervisor) */
+    uint64_t __r0;
+    uint64_t __r1;
+    uint64_t __r2;
+    uint64_t __r3;
+    uint64_t __r4;
+    uint64_t __r5;
+    uint64_t __r6;
+    uint64_t __r7;
+    uint64_t __r8;
+    uint64_t __r9;
+    uint64_t __r10;
+    uint64_t __r11;
+    uint64_t __r12;
+    uint64_t __r13;
+    uint64_t __r14;
+    uint64_t __r15;
+    uint64_t __r16;
+    uint64_t __r17;
+    uint64_t __r18;
+    uint64_t __r19;
+    uint64_t __r20;
+    uint64_t __r21;
+    uint64_t __r22;
+    uint64_t __r23;
+    uint64_t __r24;
+    uint64_t __r25;
+    uint64_t __r26;
+    uint64_t __r27;
+    uint64_t __r28;
+    uint64_t __r29;
+    uint64_t __r30;
+    uint64_t __r31;
+    uint64_t __cr;     /* Condition register */
+    uint64_t __xer;    /* User's integer exception register */
+    uint64_t __lr;     /* Link register */
+    uint64_t __ctr;    /* Count register */
+    uint64_t __vrsave; /* Vector Save Register */
+  };
+
+  struct ppc64_float_state_t {
+    double __fpregs[32];
+    uint64_t __fpscr;     /* floating point status register */
+  };
+
+  ppc64_thread_state_t _registers;
+  ppc64_float_state_t  _floatRegisters;
+  v128                 _vectorRegisters[32];
+};
+
+inline Registers_ppc64::Registers_ppc64(const void *registers) {
+  static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
+                "ppc64 registers do not fit into unw_context_t");
+  memcpy(&_registers, static_cast<const uint8_t *>(registers),
+         sizeof(_registers));
+  static_assert(sizeof(ppc64_thread_state_t) == 312,
+                "expected float register offset to be 312");
+  memcpy(&_floatRegisters,
+         static_cast<const uint8_t *>(registers) + sizeof(ppc64_thread_state_t),
+         sizeof(_floatRegisters));
+  static_assert(sizeof(ppc64_thread_state_t) + sizeof(ppc64_float_state_t) == 576,
+                "expected vector register offset to be 576 bytes");
+  memcpy(_vectorRegisters,
+         static_cast<const uint8_t *>(registers) + sizeof(ppc64_thread_state_t) +
+             sizeof(ppc64_float_state_t),
+         sizeof(_vectorRegisters));
+}
+
+inline Registers_ppc64::Registers_ppc64() {
+  memset(&_registers, 0, sizeof(_registers));
+  memset(&_floatRegisters, 0, sizeof(_floatRegisters));
+  memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
+}
+
+inline bool Registers_ppc64::validRegister(int regNum) const {
+  switch (regNum) {
+  case UNW_REG_IP:
+  case UNW_REG_SP:
+  case UNW_PPC64_VRSAVE:
+  case UNW_PPC64_LR:
+  case UNW_PPC64_CTR:
+      return true;
+  }
+
+  if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
+    return true;
+  if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
+    return true;
+
+  return false;
+}
+
+inline uint64_t Registers_ppc64::getRegister(int regNum) const {
+  switch (regNum) {
+  case UNW_REG_IP:
+    return _registers.__srr0;
+  case UNW_REG_SP:
+    return _registers.__r1;
+  case UNW_PPC64_R0:
+    return _registers.__r0;
+  case UNW_PPC64_R1:
+    return _registers.__r1;
+  case UNW_PPC64_R2:
+    return _registers.__r2;
+  case UNW_PPC64_R3:
+    return _registers.__r3;
+  case UNW_PPC64_R4:
+    return _registers.__r4;
+  case UNW_PPC64_R5:
+    return _registers.__r5;
+  case UNW_PPC64_R6:
+    return _registers.__r6;
+  case UNW_PPC64_R7:
+    return _registers.__r7;
+  case UNW_PPC64_R8:
+    return _registers.__r8;
+  case UNW_PPC64_R9:
+    return _registers.__r9;
+  case UNW_PPC64_R10:
+    return _registers.__r10;
+  case UNW_PPC64_R11:
+    return _registers.__r11;
+  case UNW_PPC64_R12:
+    return _registers.__r12;
+  case UNW_PPC64_R13:
+    return _registers.__r13;
+  case UNW_PPC64_R14:
+    return _registers.__r14;
+  case UNW_PPC64_R15:
+    return _registers.__r15;
+  case UNW_PPC64_R16:
+    return _registers.__r16;
+  case UNW_PPC64_R17:
+    return _registers.__r17;
+  case UNW_PPC64_R18:
+    return _registers.__r18;
+  case UNW_PPC64_R19:
+    return _registers.__r19;
+  case UNW_PPC64_R20:
+    return _registers.__r20;
+  case UNW_PPC64_R21:
+    return _registers.__r21;
+  case UNW_PPC64_R22:
+    return _registers.__r22;
+  case UNW_PPC64_R23:
+    return _registers.__r23;
+  case UNW_PPC64_R24:
+    return _registers.__r24;
+  case UNW_PPC64_R25:
+    return _registers.__r25;
+  case UNW_PPC64_R26:
+    return _registers.__r26;
+  case UNW_PPC64_R27:
+    return _registers.__r27;
+  case UNW_PPC64_R28:
+    return _registers.__r28;
+  case UNW_PPC64_R29:
+    return _registers.__r29;
+  case UNW_PPC64_R30:
+    return _registers.__r30;
+  case UNW_PPC64_R31:
+    return _registers.__r31;
+  case UNW_PPC64_LR:
+    return _registers.__lr;
+  case UNW_PPC64_CTR:
+    return _registers.__ctr;
+  case UNW_PPC64_CR0:
+    return (_registers.__cr & 0xF0000000);
+  case UNW_PPC64_CR1:
+    return (_registers.__cr & 0x0F000000);
+  case UNW_PPC64_CR2:
+    return (_registers.__cr & 0x00F00000);
+  case UNW_PPC64_CR3:
+    return (_registers.__cr & 0x000F0000);
+  case UNW_PPC64_CR4:
+    return (_registers.__cr & 0x0000F000);
+  case UNW_PPC64_CR5:
+    return (_registers.__cr & 0x00000F00);
+  case UNW_PPC64_CR6:
+    return (_registers.__cr & 0x000000F0);
+  case UNW_PPC64_CR7:
+    return (_registers.__cr & 0x0000000F);
+  case UNW_PPC64_VRSAVE:
+    return _registers.__vrsave;
+  case UNW_PPC64_FPSCR:
+    return _floatRegisters.__fpscr;
+  }
+  _LIBUNWIND_ABORT("unsupported ppc64 register");
+}
+
+inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
+  switch (regNum) {
+  case UNW_REG_IP:
+    _registers.__srr0 = value;
+    return;
+  case UNW_REG_SP:
+    _registers.__r1 = value;
+    return;
+  case UNW_PPC64_R0:
+    _registers.__r0 = value;
+    return;
+  case UNW_PPC64_R1:
+    _registers.__r1 = value;
+    return;
+  case UNW_PPC64_R2:
+    _registers.__r2 = value;
+    return;
+  case UNW_PPC64_R3:
+    _registers.__r3 = value;
+    return;
+  case UNW_PPC64_R4:
+    _registers.__r4 = value;
+    return;
+  case UNW_PPC64_R5:
+    _registers.__r5 = value;
+    return;
+  case UNW_PPC64_R6:
+    _registers.__r6 = value;
+    return;
+  case UNW_PPC64_R7:
+    _registers.__r7 = value;
+    return;
+  case UNW_PPC64_R8:
+    _registers.__r8 = value;
+    return;
+  case UNW_PPC64_R9:
+    _registers.__r9 = value;
+    return;
+  case UNW_PPC64_R10:
+    _registers.__r10 = value;
+    return;
+  case UNW_PPC64_R11:
+    _registers.__r11 = value;
+    return;
+  case UNW_PPC64_R12:
+    _registers.__r12 = value;
+    return;
+  case UNW_PPC64_R13:
+    _registers.__r13 = value;
+    return;
+  case UNW_PPC64_R14:
+    _registers.__r14 = value;
+    return;
+  case UNW_PPC64_R15:
+    _registers.__r15 = value;
+    return;
+  case UNW_PPC64_R16:
+    _registers.__r16 = value;
+    return;
+  case UNW_PPC64_R17:
+    _registers.__r17 = value;
+    return;
+  case UNW_PPC64_R18:
+    _registers.__r18 = value;
+    return;
+  case UNW_PPC64_R19:
+    _registers.__r19 = value;
+    return;
+  case UNW_PPC64_R20:
+    _registers.__r20 = value;
+    return;
+  case UNW_PPC64_R21:
+    _registers.__r21 = value;
+    return;
+  case UNW_PPC64_R22:
+    _registers.__r22 = value;
+    return;
+  case UNW_PPC64_R23:
+    _registers.__r23 = value;
+    return;
+  case UNW_PPC64_R24:
+    _registers.__r24 = value;
+    return;
+  case UNW_PPC64_R25:
+    _registers.__r25 = value;
+    return;
+  case UNW_PPC64_R26:
+    _registers.__r26 = value;
+    return;
+  case UNW_PPC64_R27:
+    _registers.__r27 = value;
+    return;
+  case UNW_PPC64_R28:
+    _registers.__r28 = value;
+    return;
+  case UNW_PPC64_R29:
+    _registers.__r29 = value;
+    return;
+  case UNW_PPC64_R30:
+    _registers.__r30 = value;
+    return;
+  case UNW_PPC64_R31:
+    _registers.__r31 = value;
+    return;
+  case UNW_PPC64_LR:
+    _registers.__lr = value;
+    return;
+  case UNW_PPC64_CTR:
+    _registers.__ctr = value;
+    return;
+  case UNW_PPC64_CR0:
+    _registers.__cr &= 0x0FFFFFFF;
+    _registers.__cr |= (value & 0xF0000000);
+    return;
+  case UNW_PPC64_CR1:
+    _registers.__cr &= 0xF0FFFFFF;
+    _registers.__cr |= (value & 0x0F000000);
+    return;
+  case UNW_PPC64_CR2:
+    _registers.__cr &= 0xFF0FFFFF;
+    _registers.__cr |= (value & 0x00F00000);
+    return;
+  case UNW_PPC64_CR3:
+    _registers.__cr &= 0xFFF0FFFF;
+    _registers.__cr |= (value & 0x000F0000);
+    return;
+  case UNW_PPC64_CR4:
+    _registers.__cr &= 0xFFFF0FFF;
+    _registers.__cr |= (value & 0x0000F000);
+    return;
+  case UNW_PPC64_CR5:
+    _registers.__cr &= 0xFFFFF0FF;
+    _registers.__cr |= (value & 0x00000F00);
+    return;
+  case UNW_PPC64_CR6:
+    _registers.__cr &= 0xFFFFFF0F;
+    _registers.__cr |= (value & 0x000000F0);
+    return;
+  case UNW_PPC64_CR7:
+    _registers.__cr &= 0xFFFFFFF0;
+    _registers.__cr |= (value & 0x0000000F);
+    return;
+  case UNW_PPC64_VRSAVE:
+    _registers.__vrsave = value;
+    return;
+  case UNW_PPC64_XER:
+    _registers.__xer = value;
+    return;
+  case UNW_PPC64_VSCR:
+    // not saved
+    return;
+  }
+  _LIBUNWIND_ABORT("unsupported ppc64 register");
+}
+
+inline bool Registers_ppc64::validFloatRegister(int regNum) const {
+  if (regNum < UNW_PPC64_F0)
+    return false;
+  if (regNum > UNW_PPC64_F31)
+    return false;
+  return true;
+}
+
+inline double Registers_ppc64::getFloatRegister(int regNum) const {
+  assert(validFloatRegister(regNum));
+  return _floatRegisters.__fpregs[regNum - UNW_PPC64_F0];
+}
+
+inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
+  assert(validFloatRegister(regNum));
+  _floatRegisters.__fpregs[regNum - UNW_PPC64_F0] = value;
+}
+
+inline bool Registers_ppc64::validVectorRegister(int regNum) const {
+  if (regNum < UNW_PPC64_V0)
+    return false;
+  if (regNum > UNW_PPC64_V31)
+    return false;
+  return true;
+}
+
+inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
+  assert(validVectorRegister(regNum));
+  v128 result = _vectorRegisters[regNum - UNW_PPC64_V0];
+  return result;
+}
+
+inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
+  assert(validVectorRegister(regNum));
+  _vectorRegisters[regNum - UNW_PPC64_V0] = value;
+}
+
+inline const char *Registers_ppc64::getRegisterName(int regNum) {
+  switch (regNum) {
+  case UNW_REG_IP:
+    return "ip";
+  case UNW_REG_SP:
+    return "sp";
+  case UNW_PPC64_R0:
+    return "r0";
+  case UNW_PPC64_R1:
+    return "r1";
+  case UNW_PPC64_R2:
+    return "r2";
+  case UNW_PPC64_R3:
+    return "r3";
+  case UNW_PPC64_R4:
+    return "r4";
+  case UNW_PPC64_R5:
+    return "r5";
+  case UNW_PPC64_R6:
+    return "r6";
+  case UNW_PPC64_R7:
+    return "r7";
+  case UNW_PPC64_R8:
+    return "r8";
+  case UNW_PPC64_R9:
+    return "r9";
+  case UNW_PPC64_R10:
+    return "r10";
+  case UNW_PPC64_R11:
+    return "r11";
+  case UNW_PPC64_R12:
+    return "r12";
+  case UNW_PPC64_R13:
+    return "r13";
+  case UNW_PPC64_R14:
+    return "r14";
+  case UNW_PPC64_R15:
+    return "r15";
+  case UNW_PPC64_R16:
+    return "r16";
+  case UNW_PPC64_R17:
+    return "r17";
+  case UNW_PPC64_R18:
+    return "r18";
+  case UNW_PPC64_R19:
+    return "r19";
+  case UNW_PPC64_R20:
+    return "r20";
+  case UNW_PPC64_R21:
+    return "r21";
+  case UNW_PPC64_R22:
+    return "r22";
+  case UNW_PPC64_R23:
+    return "r23";
+  case UNW_PPC64_R24:
+    return "r24";
+  case UNW_PPC64_R25:
+    return "r25";
+  case UNW_PPC64_R26:
+    return "r26";
+  case UNW_PPC64_R27:
+    return "r27";
+  case UNW_PPC64_R28:
+    return "r28";
+  case UNW_PPC64_R29:
+    return "r29";
+  case UNW_PPC64_R30:
+    return "r30";
+  case UNW_PPC64_R31:
+    return "r31";
+  case UNW_PPC64_F0:
+    return "fp0";
+  case UNW_PPC64_F1:
+    return "fp1";
+  case UNW_PPC64_F2:
+    return "fp2";
+  case UNW_PPC64_F3:
+    return "fp3";
+  case UNW_PPC64_F4:
+    return "fp4";
+  case UNW_PPC64_F5:
+    return "fp5";
+  case UNW_PPC64_F6:
+    return "fp6";
+  case UNW_PPC64_F7:
+    return "fp7";
+  case UNW_PPC64_F8:
+    return "fp8";
+  case UNW_PPC64_F9:
+    return "fp9";
+  case UNW_PPC64_F10:
+    return "fp10";
+  case UNW_PPC64_F11:
+    return "fp11";
+  case UNW_PPC64_F12:
+    return "fp12";
+  case UNW_PPC64_F13:
+    return "fp13";
+  case UNW_PPC64_F14:
+    return "fp14";
+  case UNW_PPC64_F15:
+    return "fp15";
+  case UNW_PPC64_F16:
+    return "fp16";
+  case UNW_PPC64_F17:
+    return "fp17";
+  case UNW_PPC64_F18:
+    return "fp18";
+  case UNW_PPC64_F19:
+    return "fp19";
+  case UNW_PPC64_F20:
+    return "fp20";
+  case UNW_PPC64_F21:
+    return "fp21";
+  case UNW_PPC64_F22:
+    return "fp22";
+  case UNW_PPC64_F23:
+    return "fp23";
+  case UNW_PPC64_F24:
+    return "fp24";
+  case UNW_PPC64_F25:
+    return "fp25";
+  case UNW_PPC64_F26:
+    return "fp26";
+  case UNW_PPC64_F27:
+    return "fp27";
+  case UNW_PPC64_F28:
+    return "fp28";
+  case UNW_PPC64_F29:
+    return "fp29";
+  case UNW_PPC64_F30:
+    return "fp30";
+  case UNW_PPC64_F31:
+    return "fp31";
+  case UNW_PPC64_LR:
+    return "lr";
+  case UNW_PPC64_CTR:
+    return "ctr";
+  case UNW_PPC64_CR0:
+    return "cr0";
+  case UNW_PPC64_CR1:
+    return "cr1";
+  case UNW_PPC64_CR2:
+    return "cr2";
+  case UNW_PPC64_CR3:
+    return "cr3";
+  case UNW_PPC64_CR4:
+    return "cr4";
+  case UNW_PPC64_CR5:
+    return "cr5";
+  case UNW_PPC64_CR6:
+    return "cr6";
+  case UNW_PPC64_CR7:
+    return "cr7";
+  case UNW_PPC64_XER:
+    return "xer";
+  case UNW_PPC64_VRSAVE:
+    return "vrsave";
+  case UNW_PPC64_FPSCR:
+    return "fpscr";
+  default:
+    return "unknown register";
+  }
+}
+#endif // _LIBUNWIND_TARGET_PPC64
+
 
 #if defined(_LIBUNWIND_TARGET_AARCH64)
 /// Registers_arm64  holds the register state of a thread in a 64-bit arm

Modified: libunwind/trunk/src/UnwindCursor.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindCursor.hpp?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindCursor.hpp (original)
+++ libunwind/trunk/src/UnwindCursor.hpp Tue Jan  2 12:10:54 2018
@@ -501,6 +501,13 @@ private:
   }
 #endif
 
+#if defined(_LIBUNWIND_TARGET_PPC64)
+  int stepWithCompactEncoding(Registers_ppc64 &) {
+    return UNW_EINVAL;
+  }
+#endif
+
+
 #if defined(_LIBUNWIND_TARGET_AARCH64)
   int stepWithCompactEncoding(Registers_arm64 &) {
     return CompactUnwinder_arm64<A>::stepWithCompactEncoding(
@@ -553,6 +560,12 @@ private:
   }
 #endif
 
+#if defined(_LIBUNWIND_TARGET_PPC64)
+  bool compactSaysUseDwarf(Registers_ppc64 &, uint32_t *) const {
+    return true;
+  }
+#endif
+
 #if defined(_LIBUNWIND_TARGET_AARCH64)
   bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const {
     if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) {
@@ -600,6 +613,12 @@ private:
     return 0;
   }
 #endif
+
+#if defined(_LIBUNWIND_TARGET_PPC64)
+  compact_unwind_encoding_t dwarfEncoding(Registers_ppc64 &) const {
+    return 0;
+  }
+#endif
 
 #if defined(_LIBUNWIND_TARGET_AARCH64)
   compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {

Modified: libunwind/trunk/src/UnwindRegistersRestore.S
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersRestore.S?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindRegistersRestore.S (original)
+++ libunwind/trunk/src/UnwindRegistersRestore.S Tue Jan  2 12:10:54 2018
@@ -128,6 +128,101 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li
   ret            # rip was saved here
 
 
+#elif defined(__powerpc64__)
+
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
+//
+// void libunwind::Registers_ppc64::jumpto()
+//
+// On entry:
+//  thread_state pointer is in r3
+//
+
+  // restore integral registers
+  // skip r0 for now
+  // skip r1 for now
+  ld    %r2,   32(%r3)
+  // skip r3 for now
+  // skip r4 for now
+  // skip r5 for now
+  ld    %r6,   64(%r3)
+  ld    %r7,   72(%r3)
+  ld    %r8,   80(%r3)
+  ld    %r9,   88(%r3)
+  ld    %r10,  96(%r3)
+  ld    %r11, 104(%r3)
+  ld    %r12, 112(%r3)
+  ld    %r13, 120(%r3)
+  ld    %r14, 128(%r3)
+  ld    %r15, 136(%r3)
+  ld    %r16, 144(%r3)
+  ld    %r17, 152(%r3)
+  ld    %r18, 160(%r3)
+  ld    %r19, 168(%r3)
+  ld    %r20, 176(%r3)
+  ld    %r21, 184(%r3)
+  ld    %r22, 192(%r3)
+  ld    %r23, 200(%r3)
+  ld    %r24, 208(%r3)
+  ld    %r25, 216(%r3)
+  ld    %r26, 224(%r3)
+  ld    %r27, 232(%r3)
+  ld    %r28, 240(%r3)
+  ld    %r29, 248(%r3)
+  ld    %r30, 256(%r3)
+  ld    %r31, 264(%r3)
+
+  //restore float registers
+  lfd   %f0,  312(%r3)
+  lfd   %f1,  320(%r3)
+  lfd   %f2,  328(%r3)
+  lfd   %f3,  336(%r3)
+  lfd   %f4,  344(%r3)
+  lfd   %f5,  352(%r3)
+  lfd   %f6,  360(%r3)
+  lfd   %f7,  368(%r3)
+  lfd   %f8,  376(%r3)
+  lfd   %f9,  384(%r3)
+  lfd   %f10, 392(%r3)
+  lfd   %f11, 400(%r3)
+  lfd   %f12, 408(%r3)
+  lfd   %f13, 416(%r3)
+  lfd   %f14, 424(%r3)
+  lfd   %f15, 432(%r3)
+  lfd   %f16, 440(%r3)
+  lfd   %f17, 448(%r3)
+  lfd   %f18, 456(%r3)
+  lfd   %f19, 464(%r3)
+  lfd   %f20, 472(%r3)
+  lfd   %f21, 480(%r3)
+  lfd   %f22, 488(%r3)
+  lfd   %f23, 496(%r3)
+  lfd   %f24, 504(%r3)
+  lfd   %f25, 512(%r3)
+  lfd   %f26, 520(%r3)
+  lfd   %f27, 528(%r3)
+  lfd   %f28, 536(%r3)
+  lfd   %f29, 544(%r3)
+  lfd   %f30, 552(%r3)
+  lfd   %f31, 560(%r3)
+
+  //TODO: restore vector registers
+
+  // Lnovec:
+  ld    %r0, 272(%r3) // __cr
+  mtcr  %r0
+  ld    %r0, 296(%r3) // __ctr
+  mtctr %r0
+  ld    %r0,   0(%r3) // __ssr0
+  mtctr %r0
+
+  ld    %r0,   16(%r3)
+  ld    %r5,   56(%r3)
+  ld    %r4,   48(%r3)
+  ld    %r1,   24(%r3)
+  ld    %r3,   40(%r3)
+  bctr
+
 #elif defined(__ppc__)
 
 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)

Modified: libunwind/trunk/src/UnwindRegistersSave.S
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersSave.S?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindRegistersSave.S (original)
+++ libunwind/trunk/src/UnwindRegistersSave.S Tue Jan  2 12:10:54 2018
@@ -237,6 +237,109 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext
 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
   teq $0, $0
 
+#elif defined(__powerpc64__)
+
+//
+// extern int unw_getcontext(unw_context_t* thread_state)
+//
+// On entry:
+//  thread_state pointer is in r3
+//
+DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+  std   %r0,   16(%r3)
+  mflr  %r0
+  std   %r0,    0(%r3)  // store lr as ssr0
+  std   %r1,   24(%r3)
+  std   %r2,   32(%r3)
+  std   %r3,   40(%r3)
+  std   %r4,   48(%r3)
+  std   %r5,   56(%r3)
+  std   %r6,   64(%r3)
+  std   %r7,   72(%r3)
+  std   %r8,   80(%r3)
+  std   %r9,   88(%r3)
+  std   %r10,  96(%r3)
+  std   %r11, 104(%r3)
+  std   %r12, 112(%r3)
+  std   %r13, 120(%r3)
+  std   %r14, 128(%r3)
+  std   %r15, 136(%r3)
+  std   %r16, 144(%r3)
+  std   %r17, 152(%r3)
+  std   %r18, 160(%r3)
+  std   %r19, 168(%r3)
+  std   %r20, 176(%r3)
+  std   %r21, 184(%r3)
+  std   %r22, 192(%r3)
+  std   %r23, 200(%r3)
+  std   %r24, 208(%r3)
+  std   %r25, 216(%r3)
+  std   %r26, 224(%r3)
+  std   %r27, 232(%r3)
+  std   %r28, 240(%r3)
+  std   %r29, 248(%r3)
+  std   %r30, 256(%r3)
+  std   %r31, 264(%r3)
+
+  mfcr  %r0
+  std   %r0,  272(%r3)
+
+  mfxer %r0
+  std   %r0,  280(%r3)
+
+  mflr  %r0
+  std   %r0,  288(%r3)
+
+  mfctr %r0
+  std   %r0,  296(%r3)
+
+  mfvrsave    %r0
+  std   %r0,  304(%r3)
+
+  // save float registers
+  stfd  %f0,  312(%r3)
+  stfd  %f1,  320(%r3)
+  stfd  %f2,  328(%r3)
+  stfd  %f3,  336(%r3)
+  stfd  %f4,  344(%r3)
+  stfd  %f5,  352(%r3)
+  stfd  %f6,  360(%r3)
+  stfd  %f7,  368(%r3)
+  stfd  %f8,  376(%r3)
+  stfd  %f9,  384(%r3)
+  stfd  %f10, 392(%r3)
+  stfd  %f11, 400(%r3)
+  stfd  %f12, 408(%r3)
+  stfd  %f13, 416(%r3)
+  stfd  %f14, 424(%r3)
+  stfd  %f15, 432(%r3)
+  stfd  %f16, 440(%r3)
+  stfd  %f17, 448(%r3)
+  stfd  %f18, 456(%r3)
+  stfd  %f19, 464(%r3)
+  stfd  %f20, 472(%r3)
+  stfd  %f21, 480(%r3)
+  stfd  %f22, 488(%r3)
+  stfd  %f23, 496(%r3)
+  stfd  %f24, 504(%r3)
+  stfd  %f25, 512(%r3)
+  stfd  %f26, 520(%r3)
+  stfd  %f27, 528(%r3)
+  stfd  %f28, 536(%r3)
+  stfd  %f29, 544(%r3)
+  stfd  %f30, 552(%r3)
+  stfd  %f31, 560(%r3)
+
+  mffs  %f0
+  stfd  %f0,  568(%r3)
+
+  //TODO: save vector registers
+
+
+  li    %r3,  0   // return UNW_ESUCCESS
+  blr
+
+
 #elif defined(__ppc__)
 
 ;

Modified: libunwind/trunk/src/assembly.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/assembly.h?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/src/assembly.h (original)
+++ libunwind/trunk/src/assembly.h Tue Jan  2 12:10:54 2018
@@ -16,7 +16,9 @@
 #ifndef UNWIND_ASSEMBLY_H
 #define UNWIND_ASSEMBLY_H
 
-#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
+#if defined(__powerpc64__)
+#define SEPARATOR ;
+#elif defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
 #define SEPARATOR @
 #elif defined(__arm64__)
 #define SEPARATOR %%

Modified: libunwind/trunk/src/config.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/config.h?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/src/config.h (original)
+++ libunwind/trunk/src/config.h Tue Jan  2 12:10:54 2018
@@ -63,12 +63,12 @@
 #define _LIBUNWIND_BUILD_SJLJ_APIS
 #endif
 
-#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__)
 #define _LIBUNWIND_SUPPORT_FRAME_APIS
 #endif
 
 #if defined(__i386__) || defined(__x86_64__) ||                                \
-    defined(__ppc__) || defined(__ppc64__) ||                                  \
+    defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) ||        \
     (!defined(__APPLE__) && defined(__arm__)) ||                               \
     (defined(__arm64__) || defined(__aarch64__)) ||                            \
     defined(__mips__)

Modified: libunwind/trunk/src/libunwind.cpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/libunwind.cpp?rev=321667&r1=321666&r2=321667&view=diff
==============================================================================
--- libunwind/trunk/src/libunwind.cpp (original)
+++ libunwind/trunk/src/libunwind.cpp Tue Jan  2 12:10:54 2018
@@ -51,6 +51,8 @@ _LIBUNWIND_EXPORT int unw_init_local(unw
 # define REGISTER_KIND Registers_x86
 #elif defined(__x86_64__)
 # define REGISTER_KIND Registers_x86_64
+#elif defined(__powerpc64__)
+# define REGISTER_KIND Registers_ppc64
 #elif defined(__ppc__)
 # define REGISTER_KIND Registers_ppc
 #elif defined(__aarch64__)




More information about the cfe-commits mailing list