[libunwind] Add support for OpenRISC 1000.

This patch makes no assumptions on ABI past the ABI defined in
the OpenRISC 1000 spec except that the DWARF register numbers will
be 0-31 for registers r0-r31, which is true for both gcc and
clang at the moment.

git-svn-id: https://llvm.org/svn/llvm-project/libunwind/trunk@246413 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/src/Registers.hpp b/src/Registers.hpp
index 0269bf7..38ce066 100644
--- a/src/Registers.hpp
+++ b/src/Registers.hpp
@@ -1711,7 +1711,187 @@
 inline void Registers_arm::setVectorRegister(int, v128) {
   _LIBUNWIND_ABORT("ARM vector support not implemented");
 }
+/// Registers_or1k holds the register state of a thread in an OpenRISC1000
+/// process.
+class _LIBUNWIND_HIDDEN Registers_or1k {
+public:
+  Registers_or1k();
+  Registers_or1k(const void *registers);
 
+  bool        validRegister(int num) const;
+  uint32_t    getRegister(int num) const;
+  void        setRegister(int num, uint32_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 31; }
+
+  uint64_t  getSP() const         { return _registers.__r[1]; }
+  void      setSP(uint32_t value) { _registers.__r[1] = value; }
+  uint64_t  getIP() const         { return _registers.__r[9]; }
+  void      setIP(uint32_t value) { _registers.__r[9] = value; }
+
+private:
+  struct or1k_thread_state_t {
+    unsigned int __r[32];
+  };
+
+  or1k_thread_state_t _registers;
+};
+
+inline Registers_or1k::Registers_or1k(const void *registers) {
+  static_assert(sizeof(Registers_or1k) < sizeof(unw_context_t),
+                    "or1k registers do not fit into unw_context_t");
+  memcpy(&_registers, static_cast<const uint8_t *>(registers),
+         sizeof(_registers));
+}
+
+inline Registers_or1k::Registers_or1k() {
+  memset(&_registers, 0, sizeof(_registers));
+}
+
+inline bool Registers_or1k::validRegister(int regNum) const {
+  if (regNum == UNW_REG_IP)
+    return true;
+  if (regNum == UNW_REG_SP)
+    return true;
+  if (regNum < 0)
+    return false;
+  if (regNum <= UNW_OR1K_R31)
+    return true;
+  return false;
+}
+
+inline uint32_t Registers_or1k::getRegister(int regNum) const {
+  if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
+    return _registers.__r[regNum - UNW_OR1K_R0];
+
+  switch (regNum) {
+  case UNW_REG_IP:
+    return _registers.__r[9];
+  case UNW_REG_SP:
+    return _registers.__r[1];
+  }
+  _LIBUNWIND_ABORT("unsupported or1k register");
+}
+
+inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
+  if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
+    _registers.__r[regNum - UNW_OR1K_R0] = value;
+    return;
+  }
+
+  switch (regNum) {
+  case UNW_REG_IP:
+    _registers.__r[9] = value;
+    return;
+  case UNW_REG_SP:
+    _registers.__r[1] = value;
+    return;
+  }
+  _LIBUNWIND_ABORT("unsupported or1k register");
+}
+
+inline bool Registers_or1k::validFloatRegister(int regNum) const {
+  return false;
+}
+
+inline double Registers_or1k::getFloatRegister(int regNum) const {
+  _LIBUNWIND_ABORT("or1k float support not implemented");
+}
+
+inline void Registers_or1k::setFloatRegister(int regNum, double value) {
+  _LIBUNWIND_ABORT("or1k float support not implemented");
+}
+
+inline bool Registers_or1k::validVectorRegister(int regNum) const {
+  return false;
+}
+
+inline v128 Registers_or1k::getVectorRegister(int regNum) const {
+  _LIBUNWIND_ABORT("or1k vector support not implemented");
+}
+
+inline void Registers_or1k::setVectorRegister(int regNum, v128 value) {
+  _LIBUNWIND_ABORT("or1k vector support not implemented");
+}
+
+inline const char *Registers_or1k::getRegisterName(int regNum) {
+  switch (regNum) {
+  case UNW_OR1K_R0:
+    return "r0";
+  case UNW_OR1K_R1:
+    return "r1";
+  case UNW_OR1K_R2:
+    return "r2";
+  case UNW_OR1K_R3:
+    return "r3";
+  case UNW_OR1K_R4:
+    return "r4";
+  case UNW_OR1K_R5:
+    return "r5";
+  case UNW_OR1K_R6:
+    return "r6";
+  case UNW_OR1K_R7:
+    return "r7";
+  case UNW_OR1K_R8:
+    return "r8";
+  case UNW_OR1K_R9:
+    return "r9";
+  case UNW_OR1K_R10:
+    return "r10";
+  case UNW_OR1K_R11:
+    return "r11";
+  case UNW_OR1K_R12:
+    return "r12";
+  case UNW_OR1K_R13:
+    return "r13";
+  case UNW_OR1K_R14:
+    return "r14";
+  case UNW_OR1K_R15:
+    return "r15";
+  case UNW_OR1K_R16:
+    return "r16";
+  case UNW_OR1K_R17:
+    return "r17";
+  case UNW_OR1K_R18:
+    return "r18";
+  case UNW_OR1K_R19:
+    return "r19";
+  case UNW_OR1K_R20:
+    return "r20";
+  case UNW_OR1K_R21:
+    return "r21";
+  case UNW_OR1K_R22:
+    return "r22";
+  case UNW_OR1K_R23:
+    return "r23";
+  case UNW_OR1K_R24:
+    return "r24";
+  case UNW_OR1K_R25:
+    return "r25";
+  case UNW_OR1K_R26:
+    return "r26";
+  case UNW_OR1K_R27:
+    return "r27";
+  case UNW_OR1K_R28:
+    return "r28";
+  case UNW_OR1K_R29:
+    return "r29";
+  case UNW_OR1K_R30:
+    return "r30";
+  case UNW_OR1K_R31:
+    return "r31";
+  default:
+    return "unknown register";
+  }
+
+}
 } // namespace libunwind
 
 #endif // __REGISTERS_HPP__