[libunwind] r332513 - [OR1K] Add the EPCR special-purpose register to register state.

whitequark via cfe-commits cfe-commits at lists.llvm.org
Wed May 16 12:09:49 PDT 2018


Author: whitequark
Date: Wed May 16 12:09:48 2018
New Revision: 332513

URL: http://llvm.org/viewvc/llvm-project?rev=332513&view=rev
Log:
[OR1K] Add the EPCR special-purpose register to register state.

This makes it possible to unwind hardware exception stack frames,
which necessarily save every register and so need an extra column
for storing the return address. CFI for the exception handler could
then look as follows:

.globl exception_vector
exception_vector:
    .cfi_startproc
    .cfi_signal_frame
    .cfi_return_column 32
    l.addi  r1, r1, -0x100
    .cfi_def_cfa_offset 0x100
    l.sw    0x00(r1), r2
    .cfi_offset 2, 0x00-0x100
    l.sw    0x04(r1), r3
    .cfi_offset 3, 0x04-0x100
    l.sw    0x08(r1), r4
    .cfi_offset 4, 0x08-0x100
    l.mfspr r3, r0, SPR_EPCR_BASE
    l.sw    0x78(r1), r3
    .cfi_offset 32, 0x78-0x100
    l.jal   exception_handler
     l.nop
    l.lwz   r2, 0x00(r1)
    l.lwz   r3, 0x04(r1)
    l.lwz   r4, 0x08(r1)
    l.jr    r9
     l.nop
    .cfi_endproc

This register could, of course, also be accessed by the trace
callback or personality function, if so desired.

Modified:
    libunwind/trunk/include/__libunwind_config.h
    libunwind/trunk/include/libunwind.h
    libunwind/trunk/src/Registers.hpp
    libunwind/trunk/src/UnwindRegistersSave.S

Modified: libunwind/trunk/include/__libunwind_config.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/__libunwind_config.h?rev=332513&r1=332512&r2=332513&view=diff
==============================================================================
--- libunwind/trunk/include/__libunwind_config.h (original)
+++ libunwind/trunk/include/__libunwind_config.h Wed May 16 12:09:48 2018
@@ -21,7 +21,7 @@
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64     116
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64     95
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM       287
-#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K      31
+#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K      32
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS      65
 
 #if defined(_LIBUNWIND_IS_NATIVE_ONLY)

Modified: libunwind/trunk/include/libunwind.h
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/libunwind.h?rev=332513&r1=332512&r2=332513&view=diff
==============================================================================
--- libunwind/trunk/include/libunwind.h (original)
+++ libunwind/trunk/include/libunwind.h Wed May 16 12:09:48 2018
@@ -745,6 +745,7 @@ enum {
   UNW_OR1K_R29 = 29,
   UNW_OR1K_R30 = 30,
   UNW_OR1K_R31 = 31,
+  UNW_OR1K_EPCR = 32,
 };
 
 // MIPS registers

Modified: libunwind/trunk/src/Registers.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/Registers.hpp?rev=332513&r1=332512&r2=332513&view=diff
==============================================================================
--- libunwind/trunk/src/Registers.hpp (original)
+++ libunwind/trunk/src/Registers.hpp Wed May 16 12:09:48 2018
@@ -2528,6 +2528,7 @@ private:
   struct or1k_thread_state_t {
     unsigned int __r[32]; // r0-r31
     unsigned int __pc;    // Program counter
+    unsigned int __epcr;  // Program counter at exception
   };
 
   or1k_thread_state_t _registers;
@@ -2553,6 +2554,8 @@ inline bool Registers_or1k::validRegiste
     return false;
   if (regNum <= UNW_OR1K_R31)
     return true;
+  if (regNum == UNW_OR1K_EPCR)
+    return true;
   return false;
 }
 
@@ -2565,6 +2568,8 @@ inline uint32_t Registers_or1k::getRegis
     return _registers.__pc;
   case UNW_REG_SP:
     return _registers.__r[1];
+  case UNW_OR1K_EPCR:
+    return _registers.__epcr;
   }
   _LIBUNWIND_ABORT("unsupported or1k register");
 }
@@ -2582,6 +2587,9 @@ inline void Registers_or1k::setRegister(
   case UNW_REG_SP:
     _registers.__r[1] = value;
     return;
+  case UNW_OR1K_EPCR:
+    _registers.__epcr = value;
+    return;
   }
   _LIBUNWIND_ABORT("unsupported or1k register");
 }
@@ -2677,6 +2685,8 @@ inline const char *Registers_or1k::getRe
     return "r30";
   case UNW_OR1K_R31:
     return "r31";
+  case UNW_OR1K_EPCR:
+    return "EPCR";
   default:
     return "unknown register";
   }

Modified: libunwind/trunk/src/UnwindRegistersSave.S
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersSave.S?rev=332513&r1=332512&r2=332513&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindRegistersSave.S (original)
+++ libunwind/trunk/src/UnwindRegistersSave.S Wed May 16 12:09:48 2018
@@ -940,6 +940,8 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext
   l.sw     124(r3), r31
   # store ra to pc
   l.sw     128(r3), r9
+  # zero epcr
+  l.sw     132(r3), r0
 #endif
 
 #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */




More information about the cfe-commits mailing list