forked from OSchip/llvm-project
[libunwind][ARM] Improve unwinder stack usage - Make WMMX support optional
These registers are only available on a limited set of ARM targets (those based on XScale). Other targets should not have to pay the cost of these. This patch shaves off about ~300 bytes of stack usage and ~1KB of code-size. Differential revision: http://reviews.llvm.org/D21991 Reviewers: bcraig, compnerd Change-Id: I2d7a1911a193bd70b123e78747e1a7d1482463c7 llvm-svn: 274744
This commit is contained in:
parent
130802b339
commit
f33c3423ec
|
@ -105,6 +105,7 @@ option(LIBUNWIND_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
|
|||
option(LIBUNWIND_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
|
||||
option(LIBUNWIND_ENABLE_SHARED "Build libunwind as a shared library." ON)
|
||||
option(LIBUNWIND_ENABLE_CROSS_UNWINDING "Enable cross-platform unwinding support." OFF)
|
||||
option(LIBUNWIND_ENABLE_ARM_WMMX "Enable unwinding support for ARM WMMX registers." OFF)
|
||||
|
||||
set(LIBUNWIND_TARGET_TRIPLE "" CACHE STRING "Target triple for cross compiling.")
|
||||
set(LIBUNWIND_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.")
|
||||
|
@ -237,6 +238,15 @@ if (NOT LIBUNWIND_ENABLE_CROSS_UNWINDING)
|
|||
list(APPEND LIBUNWIND_COMPILE_FLAGS -D_LIBUNWIND_IS_NATIVE_ONLY)
|
||||
endif ()
|
||||
|
||||
# ARM WMMX register support
|
||||
if (LIBUNWIND_ENABLE_ARM_WMMX)
|
||||
# __ARM_WMMX is a compiler pre-define (as per the ACLE 2.0). Clang does not
|
||||
# define this macro for any supported target at present. Therefore, here we
|
||||
# provide the option to explicitly enable support for WMMX registers in the
|
||||
# unwinder.
|
||||
list(APPEND LIBUNWIND_COMPILE_FLAGS -D__ARM_WMMX)
|
||||
endif ()
|
||||
|
||||
# This is the _ONLY_ place where add_definitions is called.
|
||||
if (MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
|
|
|
@ -36,8 +36,13 @@
|
|||
# define _LIBUNWIND_CURSOR_SIZE 78
|
||||
# elif defined(__arm__)
|
||||
# define _LIBUNWIND_TARGET_ARM 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 60
|
||||
# define _LIBUNWIND_CURSOR_SIZE 67
|
||||
# if defined(__ARM_WMMX)
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 60
|
||||
# define _LIBUNWIND_CURSOR_SIZE 67
|
||||
# else
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 42
|
||||
# define _LIBUNWIND_CURSOR_SIZE 49
|
||||
# endif
|
||||
# elif defined(__or1k__)
|
||||
# define _LIBUNWIND_TARGET_OR1K 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 16
|
||||
|
|
|
@ -1343,10 +1343,12 @@ public:
|
|||
}
|
||||
if (_saved_vfp_d16_d31)
|
||||
restoreVFPv3(_vfp_d16_d31);
|
||||
#if defined(__ARM_WMMX)
|
||||
if (_saved_iwmmx)
|
||||
restoreiWMMX(_iwmmx);
|
||||
if (_saved_iwmmx_control)
|
||||
restoreiWMMXControl(_iwmmx_control);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -1360,13 +1362,15 @@ private:
|
|||
static void saveVFPWithFSTMD(unw_fpreg_t*);
|
||||
static void saveVFPWithFSTMX(unw_fpreg_t*);
|
||||
static void saveVFPv3(unw_fpreg_t*);
|
||||
static void saveiWMMX(unw_fpreg_t*);
|
||||
static void saveiWMMXControl(uint32_t*);
|
||||
static void restoreVFPWithFLDMD(unw_fpreg_t*);
|
||||
static void restoreVFPWithFLDMX(unw_fpreg_t*);
|
||||
static void restoreVFPv3(unw_fpreg_t*);
|
||||
#if defined(__ARM_WMMX)
|
||||
static void saveiWMMX(unw_fpreg_t*);
|
||||
static void saveiWMMXControl(uint32_t*);
|
||||
static void restoreiWMMX(unw_fpreg_t*);
|
||||
static void restoreiWMMXControl(uint32_t*);
|
||||
#endif
|
||||
void restoreCoreAndJumpTo();
|
||||
|
||||
// ARM registers
|
||||
|
@ -1384,47 +1388,53 @@ private:
|
|||
bool _saved_vfp_d0_d15;
|
||||
// Whether VFPv3 D16-D31 are saved.
|
||||
bool _saved_vfp_d16_d31;
|
||||
// Whether iWMMX data registers are saved.
|
||||
bool _saved_iwmmx;
|
||||
// Whether iWMMX control registers are saved.
|
||||
bool _saved_iwmmx_control;
|
||||
// VFP registers D0-D15, + padding if saved using FSTMX
|
||||
unw_fpreg_t _vfp_d0_d15_pad[17];
|
||||
// VFPv3 registers D16-D31, always saved using FSTMD
|
||||
unw_fpreg_t _vfp_d16_d31[16];
|
||||
#if defined(__ARM_WMMX)
|
||||
// Whether iWMMX data registers are saved.
|
||||
bool _saved_iwmmx;
|
||||
// Whether iWMMX control registers are saved.
|
||||
bool _saved_iwmmx_control;
|
||||
// iWMMX registers
|
||||
unw_fpreg_t _iwmmx[16];
|
||||
// iWMMX control registers
|
||||
uint32_t _iwmmx_control[4];
|
||||
#endif
|
||||
};
|
||||
|
||||
inline Registers_arm::Registers_arm(const void *registers)
|
||||
: _use_X_for_vfp_save(false),
|
||||
_saved_vfp_d0_d15(false),
|
||||
_saved_vfp_d16_d31(false),
|
||||
_saved_iwmmx(false),
|
||||
_saved_iwmmx_control(false) {
|
||||
_saved_vfp_d16_d31(false) {
|
||||
static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
|
||||
"arm registers do not fit into unw_context_t");
|
||||
// See unw_getcontext() note about data.
|
||||
memcpy(&_registers, registers, sizeof(_registers));
|
||||
memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
|
||||
memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
|
||||
#if defined(__ARM_WMMX)
|
||||
_saved_iwmmx = false;
|
||||
_saved_iwmmx_control = false;
|
||||
memset(&_iwmmx, 0, sizeof(_iwmmx));
|
||||
memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Registers_arm::Registers_arm()
|
||||
: _use_X_for_vfp_save(false),
|
||||
_saved_vfp_d0_d15(false),
|
||||
_saved_vfp_d16_d31(false),
|
||||
_saved_iwmmx(false),
|
||||
_saved_iwmmx_control(false) {
|
||||
_saved_vfp_d16_d31(false) {
|
||||
memset(&_registers, 0, sizeof(_registers));
|
||||
memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
|
||||
memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
|
||||
#if defined(__ARM_WMMX)
|
||||
_saved_iwmmx = false;
|
||||
_saved_iwmmx_control = false;
|
||||
memset(&_iwmmx, 0, sizeof(_iwmmx));
|
||||
memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool Registers_arm::validRegister(int regNum) const {
|
||||
|
@ -1436,8 +1446,10 @@ inline bool Registers_arm::validRegister(int regNum) const {
|
|||
return true;
|
||||
if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
|
||||
return true;
|
||||
#if defined(__ARM_WMMX)
|
||||
if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1450,6 +1462,7 @@ inline uint32_t Registers_arm::getRegister(int regNum) {
|
|||
return _registers.__pc;
|
||||
if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
|
||||
return _registers.__r[regNum];
|
||||
#if defined(__ARM_WMMX)
|
||||
if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
|
||||
if (!_saved_iwmmx_control) {
|
||||
_saved_iwmmx_control = true;
|
||||
|
@ -1457,6 +1470,7 @@ inline uint32_t Registers_arm::getRegister(int regNum) {
|
|||
}
|
||||
return _iwmmx_control[regNum - UNW_ARM_WC0];
|
||||
}
|
||||
#endif
|
||||
_LIBUNWIND_ABORT("unsupported arm register");
|
||||
}
|
||||
|
||||
|
@ -1469,13 +1483,16 @@ inline void Registers_arm::setRegister(int regNum, uint32_t value) {
|
|||
_registers.__pc = value;
|
||||
else if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
|
||||
_registers.__r[regNum] = value;
|
||||
#if defined(__ARM_WMMX)
|
||||
else if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
|
||||
if (!_saved_iwmmx_control) {
|
||||
_saved_iwmmx_control = true;
|
||||
saveiWMMXControl(_iwmmx_control);
|
||||
}
|
||||
_iwmmx_control[regNum - UNW_ARM_WC0] = value;
|
||||
} else
|
||||
}
|
||||
#endif
|
||||
else
|
||||
_LIBUNWIND_ABORT("unsupported arm register");
|
||||
}
|
||||
|
||||
|
@ -1652,7 +1669,10 @@ inline bool Registers_arm::validFloatRegister(int regNum) const {
|
|||
// NOTE: Consider the intel MMX registers floating points so the
|
||||
// unw_get_fpreg can be used to transmit the 64-bit data back.
|
||||
return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
|
||||
|| ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15));
|
||||
#if defined(__ARM_WMMX)
|
||||
|| ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
|
||||
|
@ -1671,15 +1691,18 @@ inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
|
|||
saveVFPv3(_vfp_d16_d31);
|
||||
}
|
||||
return _vfp_d16_d31[regNum - UNW_ARM_D16];
|
||||
} else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
|
||||
}
|
||||
#if defined(__ARM_WMMX)
|
||||
else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
|
||||
if (!_saved_iwmmx) {
|
||||
_saved_iwmmx = true;
|
||||
saveiWMMX(_iwmmx);
|
||||
}
|
||||
return _iwmmx[regNum - UNW_ARM_WR0];
|
||||
} else {
|
||||
_LIBUNWIND_ABORT("Unknown ARM float register");
|
||||
}
|
||||
#endif
|
||||
else
|
||||
_LIBUNWIND_ABORT("Unknown ARM float register");
|
||||
}
|
||||
|
||||
inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
|
||||
|
@ -1698,15 +1721,18 @@ inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
|
|||
saveVFPv3(_vfp_d16_d31);
|
||||
}
|
||||
_vfp_d16_d31[regNum - UNW_ARM_D16] = value;
|
||||
} else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
|
||||
}
|
||||
#if defined(__ARM_WMMX)
|
||||
else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
|
||||
if (!_saved_iwmmx) {
|
||||
_saved_iwmmx = true;
|
||||
saveiWMMX(_iwmmx);
|
||||
}
|
||||
_iwmmx[regNum - UNW_ARM_WR0] = value;
|
||||
} else {
|
||||
_LIBUNWIND_ABORT("Unknown ARM float register");
|
||||
}
|
||||
#endif
|
||||
else
|
||||
_LIBUNWIND_ABORT("Unknown ARM float register");
|
||||
}
|
||||
|
||||
inline bool Registers_arm::validVectorRegister(int) const {
|
||||
|
|
|
@ -351,6 +351,7 @@ _Unwind_Reason_Code _Unwind_VRS_Interpret(
|
|||
}
|
||||
case 0xc0: {
|
||||
switch (byte) {
|
||||
#if defined(__ARM_WMMX)
|
||||
case 0xc0:
|
||||
case 0xc1:
|
||||
case 0xc2:
|
||||
|
@ -378,6 +379,7 @@ _Unwind_Reason_Code _Unwind_VRS_Interpret(
|
|||
_Unwind_VRS_Pop(context, _UVRSC_WMMXC, v, _UVRSD_DOUBLE);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case 0xc8:
|
||||
case 0xc9: {
|
||||
uint8_t v = getByte(data, offset++);
|
||||
|
@ -771,13 +773,6 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
|
|||
*(unw_word_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
case _UVRSC_WMMXC:
|
||||
if (representation != _UVRSD_UINT32 || regno > 3)
|
||||
return _UVRSR_FAILED;
|
||||
return unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno),
|
||||
*(unw_word_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
case _UVRSC_VFP:
|
||||
if (representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE)
|
||||
return _UVRSR_FAILED;
|
||||
|
@ -794,6 +789,14 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
|
|||
*(unw_fpreg_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
#if defined(__ARM_WMMX)
|
||||
case _UVRSC_WMMXC:
|
||||
if (representation != _UVRSD_UINT32 || regno > 3)
|
||||
return _UVRSR_FAILED;
|
||||
return unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno),
|
||||
*(unw_word_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
case _UVRSC_WMMXD:
|
||||
if (representation != _UVRSD_DOUBLE || regno > 31)
|
||||
return _UVRSR_FAILED;
|
||||
|
@ -801,6 +804,7 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
|
|||
*(unw_fpreg_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
#endif
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported register class");
|
||||
}
|
||||
|
@ -819,13 +823,6 @@ _Unwind_VRS_Get_Internal(_Unwind_Context *context,
|
|||
(unw_word_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
case _UVRSC_WMMXC:
|
||||
if (representation != _UVRSD_UINT32 || regno > 3)
|
||||
return _UVRSR_FAILED;
|
||||
return unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno),
|
||||
(unw_word_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
case _UVRSC_VFP:
|
||||
if (representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE)
|
||||
return _UVRSR_FAILED;
|
||||
|
@ -842,6 +839,14 @@ _Unwind_VRS_Get_Internal(_Unwind_Context *context,
|
|||
(unw_fpreg_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
#if defined(__ARM_WMMX)
|
||||
case _UVRSC_WMMXC:
|
||||
if (representation != _UVRSD_UINT32 || regno > 3)
|
||||
return _UVRSR_FAILED;
|
||||
return unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno),
|
||||
(unw_word_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
case _UVRSC_WMMXD:
|
||||
if (representation != _UVRSD_DOUBLE || regno > 31)
|
||||
return _UVRSR_FAILED;
|
||||
|
@ -849,6 +854,7 @@ _Unwind_VRS_Get_Internal(_Unwind_Context *context,
|
|||
(unw_fpreg_t *)valuep) == UNW_ESUCCESS
|
||||
? _UVRSR_OK
|
||||
: _UVRSR_FAILED;
|
||||
#endif
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported register class");
|
||||
}
|
||||
|
|
|
@ -383,6 +383,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy)
|
|||
vldmia r0, {d16-d31}
|
||||
JMP(lr)
|
||||
|
||||
#if defined(__ARM_WMMX)
|
||||
|
||||
@
|
||||
@ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values)
|
||||
@
|
||||
|
@ -391,7 +393,6 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy)
|
|||
@
|
||||
.p2align 2
|
||||
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
|
||||
#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
|
||||
ldcl p1, cr0, [r0], #8 @ wldrd wR0, [r0], #8
|
||||
ldcl p1, cr1, [r0], #8 @ wldrd wR1, [r0], #8
|
||||
ldcl p1, cr2, [r0], #8 @ wldrd wR2, [r0], #8
|
||||
|
@ -408,7 +409,6 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
|
|||
ldcl p1, cr13, [r0], #8 @ wldrd wR13, [r0], #8
|
||||
ldcl p1, cr14, [r0], #8 @ wldrd wR14, [r0], #8
|
||||
ldcl p1, cr15, [r0], #8 @ wldrd wR15, [r0], #8
|
||||
#endif
|
||||
JMP(lr)
|
||||
|
||||
@
|
||||
|
@ -419,14 +419,14 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
|
|||
@
|
||||
.p2align 2
|
||||
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj)
|
||||
#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
|
||||
ldc2 p1, cr8, [r0], #4 @ wldrw wCGR0, [r0], #4
|
||||
ldc2 p1, cr9, [r0], #4 @ wldrw wCGR1, [r0], #4
|
||||
ldc2 p1, cr10, [r0], #4 @ wldrw wCGR2, [r0], #4
|
||||
ldc2 p1, cr11, [r0], #4 @ wldrw wCGR3, [r0], #4
|
||||
#endif
|
||||
JMP(lr)
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined(__or1k__)
|
||||
|
||||
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
|
||||
|
|
|
@ -378,6 +378,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
|
|||
vstmia r0, {d16-d31}
|
||||
JMP(lr)
|
||||
|
||||
#if defined(_LIBUNWIND_ARM_WMMX)
|
||||
|
||||
@
|
||||
@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)
|
||||
@
|
||||
|
@ -386,7 +388,6 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
|
|||
@
|
||||
.p2align 2
|
||||
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
|
||||
#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
|
||||
stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8
|
||||
stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8
|
||||
stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8
|
||||
|
@ -403,7 +404,6 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
|
|||
stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8
|
||||
stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8
|
||||
stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8
|
||||
#endif
|
||||
JMP(lr)
|
||||
|
||||
@
|
||||
|
@ -414,14 +414,14 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
|
|||
@
|
||||
.p2align 2
|
||||
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
|
||||
#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
|
||||
stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4
|
||||
stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4
|
||||
stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4
|
||||
stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4
|
||||
#endif
|
||||
JMP(lr)
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined(__or1k__)
|
||||
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue