[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-05-15 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL332414: [libunwind][MIPS] Support MIPS floating-point 
registers for hard-float ABIs. (authored by jhb, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D41968

Files:
  libunwind/trunk/include/__libunwind_config.h
  libunwind/trunk/include/libunwind.h
  libunwind/trunk/src/Registers.hpp
  libunwind/trunk/src/UnwindRegistersRestore.S
  libunwind/trunk/src/UnwindRegistersSave.S
  libunwind/trunk/src/libunwind.cpp

Index: libunwind/trunk/src/Registers.hpp
===
--- libunwind/trunk/src/Registers.hpp
+++ libunwind/trunk/src/Registers.hpp
@@ -2718,6 +2718,14 @@
   };
 
   mips_o32_thread_state_t _registers;
+#ifdef __mips_hard_float
+  /// O32 with 32-bit floating point registers only uses half of this
+  /// space.  However, using the same layout for 32-bit vs 64-bit
+  /// floating point registers results in a single context size for
+  /// O32 with hard float.
+  uint32_t _padding;
+  double _floats[32];
+#endif
 };
 
 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
@@ -2744,13 +2752,28 @@
 return true;
   if (regNum == UNW_MIPS_LO)
 return true;
-  // FIXME: Hard float, DSP accumulator registers, MSA registers
+#if defined(__mips_hard_float) && __mips_fpr == 32
+  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
+return true;
+#endif
+  // FIXME: DSP accumulator registers, MSA registers
   return false;
 }
 
 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
 return _registers.__r[regNum - UNW_MIPS_R0];
+#if defined(__mips_hard_float) && __mips_fpr == 32
+  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
+uint32_t *p;
+
+if (regNum % 2 == 0)
+  p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
+else
+  p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
+return *p;
+  }
+#endif
 
   switch (regNum) {
   case UNW_REG_IP:
@@ -2770,6 +2793,18 @@
 _registers.__r[regNum - UNW_MIPS_R0] = value;
 return;
   }
+#if defined(__mips_hard_float) && __mips_fpr == 32
+  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
+uint32_t *p;
+
+if (regNum % 2 == 0)
+  p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
+else
+  p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
+*p = value;
+return;
+  }
+#endif
 
   switch (regNum) {
   case UNW_REG_IP:
@@ -2788,17 +2823,31 @@
   _LIBUNWIND_ABORT("unsupported mips_o32 register");
 }
 
-inline bool Registers_mips_o32::validFloatRegister(int /* regNum */) const {
+inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
+#if defined(__mips_hard_float) && __mips_fpr == 64
+  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
+return true;
+#endif
   return false;
 }
 
-inline double Registers_mips_o32::getFloatRegister(int /* regNum */) const {
+inline double Registers_mips_o32::getFloatRegister(int regNum) const {
+#if defined(__mips_hard_float) && __mips_fpr == 64
+  assert(validFloatRegister(regNum));
+  return _floats[regNum - UNW_MIPS_F0];
+#else
   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
+#endif
 }
 
-inline void Registers_mips_o32::setFloatRegister(int /* regNum */,
- double /* value */) {
+inline void Registers_mips_o32::setFloatRegister(int regNum,
+ double value) {
+#if defined(__mips_hard_float) && __mips_fpr == 64
+  assert(validFloatRegister(regNum));
+  _floats[regNum - UNW_MIPS_F0] = value;
+#else
   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
+#endif
 }
 
 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
@@ -2879,6 +2928,70 @@
 return "$30";
   case UNW_MIPS_R31:
 return "$31";
+  case UNW_MIPS_F0:
+return "$f0";
+  case UNW_MIPS_F1:
+return "$f1";
+  case UNW_MIPS_F2:
+return "$f2";
+  case UNW_MIPS_F3:
+return "$f3";
+  case UNW_MIPS_F4:
+return "$f4";
+  case UNW_MIPS_F5:
+return "$f5";
+  case UNW_MIPS_F6:
+return "$f6";
+  case UNW_MIPS_F7:
+return "$f7";
+  case UNW_MIPS_F8:
+return "$f8";
+  case UNW_MIPS_F9:
+return "$f9";
+  case UNW_MIPS_F10:
+return "$f10";
+  case UNW_MIPS_F11:
+return "$f11";
+  case UNW_MIPS_F12:
+return "$f12";
+  case UNW_MIPS_F13:
+return "$f13";
+  case UNW_MIPS_F14:
+return "$f14";
+  case UNW_MIPS_F15:
+return "$f15";
+  case UNW_MIPS_F16:
+return "$f16";
+  case UNW_MIPS_F17:
+return "$f17";
+  case UNW_MIPS_F18:
+return "$f18";
+  case UNW_MIPS_F19:
+return "$f19";
+  case UNW_MIPS_F20:
+return "$f20";
+  case UNW_MIPS_F21:
+return "$f21";
+  case UNW_MIPS_F22:
+return "$f22";
+  case UNW_MIPS_F23:
+return "$f23";
+  case UNW_MIPS_F24:
+return 

[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-05-03 Thread Simon Dardis via Phabricator via cfe-commits
sdardis accepted this revision.
sdardis added a comment.
This revision is now accepted and ready to land.
Herald added a subscriber: chrib.

Sorry for the delay.

LGTM.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D41968



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-04-06 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb added a comment.

Ping @sdardis @compnerd


Repository:
  rUNW libunwind

https://reviews.llvm.org/D41968



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-03-14 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb added a comment.

@sdardis ping.  I think the approach I've used for O32 is probably the right 
one in that it matches what DWARF expects (DWARF doesn't treat the 32-bit 
floating point registers as pairs but as individual registers).  I think the 
question is if I O32 with 32-bit FP registers should use an array of float[]s 
instead of an array of double[]s though (which adds an extra #ifdef for context 
size) vs keeping the current layout.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D41968



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-03-05 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb marked 2 inline comments as done.
bsdjhb added a comment.

This version follows the suggestion I made earlier of treating 32-bit floating 
point registers as a "plain" register for O32 rather than a floating-point 
register.  It seems to work for me though for O32 I've only tested with 32-bit 
floating point registers.  If we stick with this approach for 32-bit floating 
point it might be simpler and/or more readable to make _floats[] an array of 
uint32_t for that case and just use different context sizes for the O32 with 
32-bit fp vs O32 with 64-bit fp.  This version works in my testing on FreeBSD 
for O32 with 32-bit FPR, N32, and N64.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D41968



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-03-05 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb updated this revision to Diff 137085.
bsdjhb added a comment.

- Add a comment about using a single FP layout for O32.
- Treat 32-bit floating point registers on O32 as plain registers.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D41968

Files:
  include/__libunwind_config.h
  include/libunwind.h
  src/Registers.hpp
  src/UnwindRegistersRestore.S
  src/UnwindRegistersSave.S
  src/libunwind.cpp

Index: src/libunwind.cpp
===
--- src/libunwind.cpp
+++ src/libunwind.cpp
@@ -61,10 +61,9 @@
 # define REGISTER_KIND Registers_arm
 #elif defined(__or1k__)
 # define REGISTER_KIND Registers_or1k
-#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
-defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
 # define REGISTER_KIND Registers_mips_o32
-#elif defined(__mips64) && defined(__mips_soft_float)
+#elif defined(__mips64)
 # define REGISTER_KIND Registers_mips_newabi
 #elif defined(__mips__)
 # warning The MIPS architecture is not supported with this ABI and environment!
Index: src/UnwindRegistersSave.S
===
--- src/UnwindRegistersSave.S
+++ src/UnwindRegistersSave.S
@@ -116,8 +116,7 @@
   xorl  %eax, %eax# return UNW_ESUCCESS
   ret
 
-#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
-defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -168,12 +167,65 @@
   sw$8,  (4 * 33)($4)
   mflo  $8
   sw$8,  (4 * 34)($4)
+#ifdef __mips_hard_float
+#if __mips_fpr == 32
+  sdc1  $f0, (4 * 36 + 8 * 0)($4)
+  sdc1  $f2, (4 * 36 + 8 * 2)($4)
+  sdc1  $f4, (4 * 36 + 8 * 4)($4)
+  sdc1  $f6, (4 * 36 + 8 * 6)($4)
+  sdc1  $f8, (4 * 36 + 8 * 8)($4)
+  sdc1  $f10, (4 * 36 + 8 * 10)($4)
+  sdc1  $f12, (4 * 36 + 8 * 12)($4)
+  sdc1  $f14, (4 * 36 + 8 * 14)($4)
+  sdc1  $f16, (4 * 36 + 8 * 16)($4)
+  sdc1  $f18, (4 * 36 + 8 * 18)($4)
+  sdc1  $f20, (4 * 36 + 8 * 20)($4)
+  sdc1  $f22, (4 * 36 + 8 * 22)($4)
+  sdc1  $f24, (4 * 36 + 8 * 24)($4)
+  sdc1  $f26, (4 * 36 + 8 * 26)($4)
+  sdc1  $f28, (4 * 36 + 8 * 28)($4)
+  sdc1  $f30, (4 * 36 + 8 * 30)($4)
+#else
+  sdc1  $f0, (4 * 36 + 8 * 0)($4)
+  sdc1  $f1, (4 * 36 + 8 * 1)($4)
+  sdc1  $f2, (4 * 36 + 8 * 2)($4)
+  sdc1  $f3, (4 * 36 + 8 * 3)($4)
+  sdc1  $f4, (4 * 36 + 8 * 4)($4)
+  sdc1  $f5, (4 * 36 + 8 * 5)($4)
+  sdc1  $f6, (4 * 36 + 8 * 6)($4)
+  sdc1  $f7, (4 * 36 + 8 * 7)($4)
+  sdc1  $f8, (4 * 36 + 8 * 8)($4)
+  sdc1  $f9, (4 * 36 + 8 * 9)($4)
+  sdc1  $f10, (4 * 36 + 8 * 10)($4)
+  sdc1  $f11, (4 * 36 + 8 * 11)($4)
+  sdc1  $f12, (4 * 36 + 8 * 12)($4)
+  sdc1  $f13, (4 * 36 + 8 * 13)($4)
+  sdc1  $f14, (4 * 36 + 8 * 14)($4)
+  sdc1  $f15, (4 * 36 + 8 * 15)($4)
+  sdc1  $f16, (4 * 36 + 8 * 16)($4)
+  sdc1  $f17, (4 * 36 + 8 * 17)($4)
+  sdc1  $f18, (4 * 36 + 8 * 18)($4)
+  sdc1  $f19, (4 * 36 + 8 * 19)($4)
+  sdc1  $f20, (4 * 36 + 8 * 20)($4)
+  sdc1  $f21, (4 * 36 + 8 * 21)($4)
+  sdc1  $f22, (4 * 36 + 8 * 22)($4)
+  sdc1  $f23, (4 * 36 + 8 * 23)($4)
+  sdc1  $f24, (4 * 36 + 8 * 24)($4)
+  sdc1  $f25, (4 * 36 + 8 * 25)($4)
+  sdc1  $f26, (4 * 36 + 8 * 26)($4)
+  sdc1  $f27, (4 * 36 + 8 * 27)($4)
+  sdc1  $f28, (4 * 36 + 8 * 28)($4)
+  sdc1  $f29, (4 * 36 + 8 * 29)($4)
+  sdc1  $f30, (4 * 36 + 8 * 30)($4)
+  sdc1  $f31, (4 * 36 + 8 * 31)($4)
+#endif
+#endif
   jr	$31
   # return UNW_ESUCCESS
   or$2, $0, $0
   .set pop
 
-#elif defined(__mips64) && defined(__mips_soft_float)
+#elif defined(__mips64)
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -224,6 +276,40 @@
   sd$8,  (8 * 33)($4)
   mflo  $8
   sd$8,  (8 * 34)($4)
+#ifdef __mips_hard_float
+  sdc1  $f0, (8 * 35)($4)
+  sdc1  $f1, (8 * 36)($4)
+  sdc1  $f2, (8 * 37)($4)
+  sdc1  $f3, (8 * 38)($4)
+  sdc1  $f4, (8 * 39)($4)
+  sdc1  $f5, (8 * 40)($4)
+  sdc1  $f6, (8 * 41)($4)
+  sdc1  $f7, (8 * 42)($4)
+  sdc1  $f8, (8 * 43)($4)
+  sdc1  $f9, (8 * 44)($4)
+  sdc1  $f10, (8 * 45)($4)
+  sdc1  $f11, (8 * 46)($4)
+  sdc1  $f12, (8 * 47)($4)
+  sdc1  $f13, (8 * 48)($4)
+  sdc1  $f14, (8 * 49)($4)
+  sdc1  $f15, (8 * 50)($4)
+  sdc1  $f16, (8 * 51)($4)
+  sdc1  $f17, (8 * 52)($4)
+  sdc1  $f18, (8 * 53)($4)
+  sdc1  $f19, (8 * 54)($4)
+  sdc1  $f20, (8 * 55)($4)
+  sdc1  $f21, (8 * 56)($4)
+  sdc1  $f22, (8 * 57)($4)
+  sdc1  $f23, (8 * 58)($4)
+  sdc1  $f24, (8 * 59)($4)
+  sdc1  $f25, (8 * 60)($4)
+  sdc1  $f26, (8 * 61)($4)
+  sdc1  $f27, (8 * 62)($4)
+  sdc1  $f28, (8 * 63)($4)
+  sdc1  $f29, (8 * 64)($4)
+  sdc1  $f30, (8 * 65)($4)
+  sdc1  $f31, (8 * 66)($4)
+#endif
   jr	$31
   # return UNW_ESUCCESS
   or$2, $0, $0
Index: src/UnwindRegistersRestore.S
===
--- src/UnwindRegistersRestore.S
+++ src/UnwindRegistersRestore.S
@@ -799,8 +799,7 @@
   l.jr r9

[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-02-27 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb updated this revision to Diff 136164.
bsdjhb added a comment.
Herald added a subscriber: christof.

- Rebase after N32 commit.
- Use ldc1/sdc1 rather than l.d and s.d.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D41968

Files:
  include/__libunwind_config.h
  include/libunwind.h
  src/Registers.hpp
  src/UnwindRegistersRestore.S
  src/UnwindRegistersSave.S
  src/libunwind.cpp

Index: src/libunwind.cpp
===
--- src/libunwind.cpp
+++ src/libunwind.cpp
@@ -61,10 +61,9 @@
 # define REGISTER_KIND Registers_arm
 #elif defined(__or1k__)
 # define REGISTER_KIND Registers_or1k
-#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
-defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
 # define REGISTER_KIND Registers_mips_o32
-#elif defined(__mips64) && defined(__mips_soft_float)
+#elif defined(__mips64)
 # define REGISTER_KIND Registers_mips_newabi
 #elif defined(__mips__)
 # warning The MIPS architecture is not supported with this ABI and environment!
Index: src/UnwindRegistersSave.S
===
--- src/UnwindRegistersSave.S
+++ src/UnwindRegistersSave.S
@@ -116,8 +116,7 @@
   xorl  %eax, %eax# return UNW_ESUCCESS
   ret
 
-#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
-defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -168,12 +167,65 @@
   sw$8,  (4 * 33)($4)
   mflo  $8
   sw$8,  (4 * 34)($4)
+#ifdef __mips_hard_float
+#if __mips_fpr == 32
+  sdc1  $f0, (4 * 36 + 8 * 0)($4)
+  sdc1  $f2, (4 * 36 + 8 * 2)($4)
+  sdc1  $f4, (4 * 36 + 8 * 4)($4)
+  sdc1  $f6, (4 * 36 + 8 * 6)($4)
+  sdc1  $f8, (4 * 36 + 8 * 8)($4)
+  sdc1  $f10, (4 * 36 + 8 * 10)($4)
+  sdc1  $f12, (4 * 36 + 8 * 12)($4)
+  sdc1  $f14, (4 * 36 + 8 * 14)($4)
+  sdc1  $f16, (4 * 36 + 8 * 16)($4)
+  sdc1  $f18, (4 * 36 + 8 * 18)($4)
+  sdc1  $f20, (4 * 36 + 8 * 20)($4)
+  sdc1  $f22, (4 * 36 + 8 * 22)($4)
+  sdc1  $f24, (4 * 36 + 8 * 24)($4)
+  sdc1  $f26, (4 * 36 + 8 * 26)($4)
+  sdc1  $f28, (4 * 36 + 8 * 28)($4)
+  sdc1  $f30, (4 * 36 + 8 * 30)($4)
+#else
+  sdc1  $f0, (4 * 36 + 8 * 0)($4)
+  sdc1  $f1, (4 * 36 + 8 * 1)($4)
+  sdc1  $f2, (4 * 36 + 8 * 2)($4)
+  sdc1  $f3, (4 * 36 + 8 * 3)($4)
+  sdc1  $f4, (4 * 36 + 8 * 4)($4)
+  sdc1  $f5, (4 * 36 + 8 * 5)($4)
+  sdc1  $f6, (4 * 36 + 8 * 6)($4)
+  sdc1  $f7, (4 * 36 + 8 * 7)($4)
+  sdc1  $f8, (4 * 36 + 8 * 8)($4)
+  sdc1  $f9, (4 * 36 + 8 * 9)($4)
+  sdc1  $f10, (4 * 36 + 8 * 10)($4)
+  sdc1  $f11, (4 * 36 + 8 * 11)($4)
+  sdc1  $f12, (4 * 36 + 8 * 12)($4)
+  sdc1  $f13, (4 * 36 + 8 * 13)($4)
+  sdc1  $f14, (4 * 36 + 8 * 14)($4)
+  sdc1  $f15, (4 * 36 + 8 * 15)($4)
+  sdc1  $f16, (4 * 36 + 8 * 16)($4)
+  sdc1  $f17, (4 * 36 + 8 * 17)($4)
+  sdc1  $f18, (4 * 36 + 8 * 18)($4)
+  sdc1  $f19, (4 * 36 + 8 * 19)($4)
+  sdc1  $f20, (4 * 36 + 8 * 20)($4)
+  sdc1  $f21, (4 * 36 + 8 * 21)($4)
+  sdc1  $f22, (4 * 36 + 8 * 22)($4)
+  sdc1  $f23, (4 * 36 + 8 * 23)($4)
+  sdc1  $f24, (4 * 36 + 8 * 24)($4)
+  sdc1  $f25, (4 * 36 + 8 * 25)($4)
+  sdc1  $f26, (4 * 36 + 8 * 26)($4)
+  sdc1  $f27, (4 * 36 + 8 * 27)($4)
+  sdc1  $f28, (4 * 36 + 8 * 28)($4)
+  sdc1  $f29, (4 * 36 + 8 * 29)($4)
+  sdc1  $f30, (4 * 36 + 8 * 30)($4)
+  sdc1  $f31, (4 * 36 + 8 * 31)($4)
+#endif
+#endif
   jr	$31
   # return UNW_ESUCCESS
   or$2, $0, $0
   .set pop
 
-#elif defined(__mips64) && defined(__mips_soft_float)
+#elif defined(__mips64)
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -224,6 +276,40 @@
   sd$8,  (8 * 33)($4)
   mflo  $8
   sd$8,  (8 * 34)($4)
+#ifdef __mips_hard_float
+  sdc1  $f0, (8 * 35)($4)
+  sdc1  $f1, (8 * 36)($4)
+  sdc1  $f2, (8 * 37)($4)
+  sdc1  $f3, (8 * 38)($4)
+  sdc1  $f4, (8 * 39)($4)
+  sdc1  $f5, (8 * 40)($4)
+  sdc1  $f6, (8 * 41)($4)
+  sdc1  $f7, (8 * 42)($4)
+  sdc1  $f8, (8 * 43)($4)
+  sdc1  $f9, (8 * 44)($4)
+  sdc1  $f10, (8 * 45)($4)
+  sdc1  $f11, (8 * 46)($4)
+  sdc1  $f12, (8 * 47)($4)
+  sdc1  $f13, (8 * 48)($4)
+  sdc1  $f14, (8 * 49)($4)
+  sdc1  $f15, (8 * 50)($4)
+  sdc1  $f16, (8 * 51)($4)
+  sdc1  $f17, (8 * 52)($4)
+  sdc1  $f18, (8 * 53)($4)
+  sdc1  $f19, (8 * 54)($4)
+  sdc1  $f20, (8 * 55)($4)
+  sdc1  $f21, (8 * 56)($4)
+  sdc1  $f22, (8 * 57)($4)
+  sdc1  $f23, (8 * 58)($4)
+  sdc1  $f24, (8 * 59)($4)
+  sdc1  $f25, (8 * 60)($4)
+  sdc1  $f26, (8 * 61)($4)
+  sdc1  $f27, (8 * 62)($4)
+  sdc1  $f28, (8 * 63)($4)
+  sdc1  $f29, (8 * 64)($4)
+  sdc1  $f30, (8 * 65)($4)
+  sdc1  $f31, (8 * 66)($4)
+#endif
   jr	$31
   # return UNW_ESUCCESS
   or$2, $0, $0
Index: src/UnwindRegistersRestore.S
===
--- src/UnwindRegistersRestore.S
+++ src/UnwindRegistersRestore.S
@@ -799,8 +799,7 @@
   l.jr r9
l.nop
 

[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-02-27 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb added a comment.

Hmmm, so I was somewhat mistaken as DwarfInstructions.hpp::stepWithDwarf() does 
use the Register class's setFloatRegister(), however, it assumes that the 
floating point register is always a double 
(DwarfInstructions.hpp::getSavedFloatRegister() uses AddressSpace::getDouble() 
to read a double from memory).  So I think that means that the NEWABI cases 
work as-is.  O32 with 64-bit FP registers should also work as-is.  However, O32 
with 32-bit FP registers will not quite work.  The DWARF info for O32 with 
32-bit registers does save/restore individual 32-bit registers:

  06dc 0034 06e0 FDE cie= pc=d384..d46c
DW_CFA_advance_loc4: 16 to d394
DW_CFA_def_cfa_offset: 56
DW_CFA_advance_loc4: 20 to d3a8
DW_CFA_offset: r31 at cfa-12
DW_CFA_offset: r17 at cfa-16
DW_CFA_offset: r16 at cfa-20
DW_CFA_offset: r52 at cfa-4
DW_CFA_offset: r53 at cfa-8
  ...

If the compiler happens to always save and restore them in pairs then the 
current approach will work.  If we don't want to assume that they are saved and 
restored in pairs, then we could instead perhaps claim that 32-bit FP registers 
aren't really floating point but are just plain 32-bit registers.  This would 
make unwinding work (I believe), but would mean that one would need to use 
unw_get_reg() instead of unw_get_fpreg() to fetch individual 32-bit FP 
registers.


https://reviews.llvm.org/D41968



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-02-27 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb added a comment.

After thinking about this some more, I need to rework this a bit.  The choice 
of how to expose the floating point registers via getFloatingPointRegister / 
setFloatingPointRegister only affects consumers of the libunwind 
unw_get_fpreg/unw_set_fpreg.  I think a bigger factor is that we need to honor 
unwind rules in frames that describe the saved location of FP registers on the 
stack (which this patchset doesn't do).  I think that's fairly trivial for the 
case where an FP register is the same size as a GP register, and it probably 
argues for storing 32-bit FP registers as individual 'float' if that is how the 
unwind information is encoded.  I haven't yet looked to see what the 
implications would be for O32 MIPS with 64-bit FP registers.  It may be that I 
punt on that configuration for now.


https://reviews.llvm.org/D41968



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-02-08 Thread Simon Dardis via Phabricator via cfe-commits
sdardis added a reviewer: compnerd.
sdardis added a comment.

I am not sure what the answer is. There's a slightly different issue in that 
returning the contents of a floating point register on MIPS and expecting it to 
be a double is not necessarily correct. For a 64bit FPU, the result of 
lwc1/mtc1 leaves the upper 32bits of an floating point register as 
**UNPREDICTABLE** by the architecture definition. It's entirely possible for 
the application being unwound to be operating on single precision values, but 
the contents of the register in it's entirety are a signalling nan.

I think the least worst option for registers is to always present the data as 
double values and to only permit access to the sets of double registers for 
O32, and leave the API user to determine how to proceed.

Unfortunately this complicates unwinding in the case of 
https://reviews.llvm.org/source/compiler-rt/ in strict fp32 mode as that 
doesn't have double precision at all. But there's more work to be done for 
https://reviews.llvm.org/source/compiler-rt/ support anyway, so it can be 
deferred. Some nits inlined. Also, watch out for ABI guards such as 
(defined(_ABIN32) || defined(_ABI64), these can be replaced with __mips64.




Comment at: src/Registers.hpp:2659
+  uint32_t _padding;
+  double _floats[32];
+#endif

bsdjhb wrote:
> I chose to always use double here to avoid having different context sizes for 
> the 32-bit vs 64-bit FPR cases.
Add a comment highlighting that design choice.



Comment at: src/UnwindRegistersRestore.S:647
+#if __mips_fpr == 32
+  l.d   $f0, (4 * 36 + 8 * 0)($4)
+  l.d   $f2, (4 * 36 + 8 * 2)($4)

Use ldc1 instead of l.d . l.d is an alias of ldc1.



Comment at: src/UnwindRegistersRestore.S:755
+#ifdef __mips_hard_float
+  l.d   $f0, (8 * 35)($4)
+  l.d   $f1, (8 * 36)($4)

ldc1 here too.



Comment at: src/UnwindRegistersSave.S:119
 
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32)
 

&& _MIPS_SIM == _ABIO32



Comment at: src/UnwindRegistersSave.S:172
+#if __mips_fpr == 32
+  s.d   $f0, (4 * 36 + 8 * 0)($4)
+  s.d   $f2, (4 * 36 + 8 * 2)($4)

Use sdc1 rather than s.d.



Comment at: src/UnwindRegistersSave.S:228
 
-#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&
\
-defined(__mips_soft_float)
+#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32))
 

defined(__mips64) rather than the checking if the ABI names are defined.



Comment at: src/UnwindRegistersSave.S:280
+#ifdef __mips_hard_float
+  s.d   $f0, (8 * 35)($4)
+  s.d   $f1, (8 * 36)($4)

sdc1 rather s.d



Comment at: src/libunwind.cpp:64
 # define REGISTER_KIND Registers_or1k
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32)
 # define REGISTER_KIND Registers_mips_o32

Check for that _MIPS_SIM == _ABIO32 as well.



Comment at: src/libunwind.cpp:66
 # define REGISTER_KIND Registers_mips_o32
-#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64)) &&
\
-defined(__mips_soft_float)
+#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64))
 # define REGISTER_KIND Registers_mips_newabi

Check for __mips64 rather than defined(_ABIXXX).


https://reviews.llvm.org/D41968



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-01-11 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb added inline comments.



Comment at: src/Registers.hpp:2659
+  uint32_t _padding;
+  double _floats[32];
+#endif

I chose to always use double here to avoid having different context sizes for 
the 32-bit vs 64-bit FPR cases.


https://reviews.llvm.org/D41968



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-01-11 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb created this revision.
bsdjhb added a reviewer: sdardis.
Herald added a subscriber: arichardson.

For newabi this is fairly simple as we just save/restore the 32
floating-point registers as doubles.  For O32 MIPS provides a variety
of floating-point ABIs.  For O32 MIPS with 64-bit floating-point
registers, save/restore the 32 floating-point registers as doubles.
For O32 MIPS with 32-bit floating-point registers, save/restore the 16
even registers as doubles.  This probably isn't correct but does match
the existing libunwind ABI that expects to save/restore floating point
registers as doubles.

For O32 with 32-bit FPRs the sticky point is trying to distinguish if
a user of unw_get_fpreg() or unw_set_fpreg() is trying to operate on a
float or a double.  It's not clear to me what the right thing here is.
If the goal is just to save/restore individual registers then perhaps
the FPRs should always be stored as floats that get converted to doubles
when returned from unw_get_fpreg() and vice versa?


https://reviews.llvm.org/D41968

Files:
  include/__libunwind_config.h
  include/libunwind.h
  src/Registers.hpp
  src/UnwindRegistersRestore.S
  src/UnwindRegistersSave.S
  src/libunwind.cpp

Index: src/libunwind.cpp
===
--- src/libunwind.cpp
+++ src/libunwind.cpp
@@ -61,10 +61,9 @@
 # define REGISTER_KIND Registers_arm
 #elif defined(__or1k__)
 # define REGISTER_KIND Registers_or1k
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32)
 # define REGISTER_KIND Registers_mips_o32
-#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64)) &&\
-defined(__mips_soft_float)
+#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64))
 # define REGISTER_KIND Registers_mips_newabi
 #elif defined(__mips__)
 # warning The MIPS architecture is not supported with this ABI and environment!
Index: src/UnwindRegistersSave.S
===
--- src/UnwindRegistersSave.S
+++ src/UnwindRegistersSave.S
@@ -116,7 +116,7 @@
   xorl  %eax, %eax# return UNW_ESUCCESS
   ret
 
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32)
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -167,13 +167,65 @@
   sw$8,  (4 * 33)($4)
   mflo  $8
   sw$8,  (4 * 34)($4)
+#ifdef __mips_hard_float
+#if __mips_fpr == 32
+  s.d   $f0, (4 * 36 + 8 * 0)($4)
+  s.d   $f2, (4 * 36 + 8 * 2)($4)
+  s.d   $f4, (4 * 36 + 8 * 4)($4)
+  s.d   $f6, (4 * 36 + 8 * 6)($4)
+  s.d   $f8, (4 * 36 + 8 * 8)($4)
+  s.d   $f10, (4 * 36 + 8 * 10)($4)
+  s.d   $f12, (4 * 36 + 8 * 12)($4)
+  s.d   $f14, (4 * 36 + 8 * 14)($4)
+  s.d   $f16, (4 * 36 + 8 * 16)($4)
+  s.d   $f18, (4 * 36 + 8 * 18)($4)
+  s.d   $f20, (4 * 36 + 8 * 20)($4)
+  s.d   $f22, (4 * 36 + 8 * 22)($4)
+  s.d   $f24, (4 * 36 + 8 * 24)($4)
+  s.d   $f26, (4 * 36 + 8 * 26)($4)
+  s.d   $f28, (4 * 36 + 8 * 28)($4)
+  s.d   $f30, (4 * 36 + 8 * 30)($4)
+#else
+  s.d   $f0, (4 * 36 + 8 * 0)($4)
+  s.d   $f1, (4 * 36 + 8 * 1)($4)
+  s.d   $f2, (4 * 36 + 8 * 2)($4)
+  s.d   $f3, (4 * 36 + 8 * 3)($4)
+  s.d   $f4, (4 * 36 + 8 * 4)($4)
+  s.d   $f5, (4 * 36 + 8 * 5)($4)
+  s.d   $f6, (4 * 36 + 8 * 6)($4)
+  s.d   $f7, (4 * 36 + 8 * 7)($4)
+  s.d   $f8, (4 * 36 + 8 * 8)($4)
+  s.d   $f9, (4 * 36 + 8 * 9)($4)
+  s.d   $f10, (4 * 36 + 8 * 10)($4)
+  s.d   $f11, (4 * 36 + 8 * 11)($4)
+  s.d   $f12, (4 * 36 + 8 * 12)($4)
+  s.d   $f13, (4 * 36 + 8 * 13)($4)
+  s.d   $f14, (4 * 36 + 8 * 14)($4)
+  s.d   $f15, (4 * 36 + 8 * 15)($4)
+  s.d   $f16, (4 * 36 + 8 * 16)($4)
+  s.d   $f17, (4 * 36 + 8 * 17)($4)
+  s.d   $f18, (4 * 36 + 8 * 18)($4)
+  s.d   $f19, (4 * 36 + 8 * 19)($4)
+  s.d   $f20, (4 * 36 + 8 * 20)($4)
+  s.d   $f21, (4 * 36 + 8 * 21)($4)
+  s.d   $f22, (4 * 36 + 8 * 22)($4)
+  s.d   $f23, (4 * 36 + 8 * 23)($4)
+  s.d   $f24, (4 * 36 + 8 * 24)($4)
+  s.d   $f25, (4 * 36 + 8 * 25)($4)
+  s.d   $f26, (4 * 36 + 8 * 26)($4)
+  s.d   $f27, (4 * 36 + 8 * 27)($4)
+  s.d   $f28, (4 * 36 + 8 * 28)($4)
+  s.d   $f29, (4 * 36 + 8 * 29)($4)
+  s.d   $f30, (4 * 36 + 8 * 30)($4)
+  s.d   $f31, (4 * 36 + 8 * 31)($4)
+#endif
+#endif
   jr	$31
   # return UNW_ESUCCESS
   or$2, $0, $0
   .set pop
 
-#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) &&\
-defined(__mips_soft_float)
+#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32))
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -224,6 +276,40 @@
   sd$8,  (8 * 33)($4)
   mflo  $8
   sd$8,  (8 * 34)($4)
+#ifdef __mips_hard_float
+  s.d   $f0, (8 * 35)($4)
+  s.d   $f1, (8 * 36)($4)
+  s.d   $f2, (8 * 37)($4)
+  s.d   $f3, (8 * 38)($4)
+  s.d   $f4, (8 * 39)($4)
+  s.d   $f5, (8 * 40)($4)
+  s.d   $f6, (8 * 41)($4)
+  s.d   $f7, (8 * 42)($4)
+  s.d   $f8, (8 * 43)($4)
+  s.d   $f9, (8 * 44)($4)
+  s.d   $f10, (8