Skip to content

Commit 205f8fd

Browse files
committedOct 2, 2014
Support Cortex-m0
As the title says... also, fix all the ARM asm return sequences so that they work on processors without the BX instruction. http://reviews.llvm.org/D5314 llvm-svn: 218869
1 parent 254dd7e commit 205f8fd

File tree

3 files changed

+70
-21
lines changed

3 files changed

+70
-21
lines changed
 

‎libcxxabi/src/Unwind/UnwindRegistersRestore.S

+28-10
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
310310

311311
#elif __arm__ && !__APPLE__
312312

313+
#if !defined(__ARM_ARCH_ISA_ARM)
314+
.thumb
315+
#endif
316+
313317
@
314318
@ void libunwind::Registers_arm::restoreCoreAndJumpTo()
315319
@
@@ -318,6 +322,13 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
318322
@
319323
.p2align 2
320324
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv)
325+
#if !defined(__ARM_ARCH_ISA_ARM)
326+
ldr r2, [r0, #52]
327+
ldr r3, [r0, #60]
328+
mov sp, r2
329+
mov lr, r3 @ restore pc into lr
330+
ldm r0, {r0-r7}
331+
#else
321332
@ Use lr as base so that r0 can be restored.
322333
mov lr, r0
323334
@ 32bit thumb-2 restrictions for ldm:
@@ -326,11 +337,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJu
326337
ldm lr, {r0-r12}
327338
ldr sp, [lr, #52]
328339
ldr lr, [lr, #60] @ restore pc into lr
329-
#if __ARM_ARCH > 4
330-
bx lr
331-
#else
332-
mov pc, lr
333340
#endif
341+
JMP(lr)
334342

335343
@
336344
@ static void libunwind::Registers_arm::restoreVFPWithFLDMD(unw_fpreg_t* values)
@@ -340,8 +348,9 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJu
340348
@
341349
.p2align 2
342350
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPy)
351+
#if defined(__ARM_FP)
343352
@ VFP and iwMMX instructions are only available when compiling with the flags
344-
@ that enable them. We don't want to do that in the library (because we don't
353+
@ that enable them. We do not want to do that in the library (because we do not
345354
@ want the compiler to generate instructions that access those) but this is
346355
@ only accessed if the personality routine needs these registers. Use of
347356
@ these registers implies they are, actually, available on the target, so
@@ -352,7 +361,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFL
352361
#else
353362
vldmia r0, {d0-d15}
354363
#endif
355-
mov pc, lr
364+
#endif
365+
JMP(lr)
356366

357367
@
358368
@ static void libunwind::Registers_arm::restoreVFPWithFLDMX(unw_fpreg_t* values)
@@ -362,12 +372,14 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFL
362372
@
363373
.p2align 2
364374
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPy)
375+
#if defined(__ARM_FP)
365376
#if __ARM_ARCH < 7
366377
ldc p11, cr0, [r0], {0x21} @ fldmiax r0, {d0-d15}
367378
#else
368379
vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia
369380
#endif
370-
mov pc, lr
381+
#endif
382+
JMP(lr)
371383

372384
@
373385
@ static void libunwind::Registers_arm::restoreVFPv3(unw_fpreg_t* values)
@@ -377,12 +389,14 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFL
377389
@
378390
.p2align 2
379391
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy)
392+
#if defined(__ARM_FP)
380393
#if __ARM_ARCH < 7
381394
ldcl p11, cr0, [r0], {0x20} @ vldm r0, {d16-d31}
382395
#else
383396
vldmia r0, {d16-d31}
384397
#endif
385-
mov pc, lr
398+
#endif
399+
JMP(lr)
386400

387401
@
388402
@ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values)
@@ -392,6 +406,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy)
392406
@
393407
.p2align 2
394408
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
409+
#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
395410
ldcl p1, cr0, [r0], #8 @ wldrd wR0, [r0], #8
396411
ldcl p1, cr1, [r0], #8 @ wldrd wR1, [r0], #8
397412
ldcl p1, cr2, [r0], #8 @ wldrd wR2, [r0], #8
@@ -408,7 +423,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
408423
ldcl p1, cr13, [r0], #8 @ wldrd wR13, [r0], #8
409424
ldcl p1, cr14, [r0], #8 @ wldrd wR14, [r0], #8
410425
ldcl p1, cr15, [r0], #8 @ wldrd wR15, [r0], #8
411-
mov pc, lr
426+
#endif
427+
JMP(lr)
412428

413429
@
414430
@ static void libunwind::Registers_arm::restoreiWMMXControl(unw_uint32_t* values)
@@ -418,10 +434,12 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
418434
@
419435
.p2align 2
420436
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj)
437+
#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
421438
ldc2 p1, cr8, [r0], #4 @ wldrw wCGR0, [r0], #4
422439
ldc2 p1, cr9, [r0], #4 @ wldrw wCGR1, [r0], #4
423440
ldc2 p1, cr10, [r0], #4 @ wldrw wCGR2, [r0], #4
424441
ldc2 p1, cr11, [r0], #4 @ wldrw wCGR3, [r0], #4
425-
mov pc, lr
442+
#endif
443+
JMP(lr)
426444

427445
#endif

‎libcxxabi/src/Unwind/UnwindRegistersSave.S

+30-11
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
282282

283283
#elif __arm__ && !__APPLE__
284284

285+
#if !defined(__ARM_ARCH_ISA_ARM)
286+
.thumb
287+
#endif
288+
285289
@
286290
@ extern int unw_getcontext(unw_context_t* thread_state)
287291
@
@@ -296,19 +300,24 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
296300
@
297301
.p2align 2
298302
DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
303+
#if !defined(__ARM_ARCH_ISA_ARM)
304+
stm r0!, {r0-r7}
305+
mov r2, sp
306+
mov r3, lr
307+
str r2, [r0, #52]
308+
str r3, [r0, #56]
309+
str r3, [r0, #60] @ store return address as pc
310+
#else
299311
@ 32bit thumb-2 restrictions for stm:
300312
@ . the sp (r13) cannot be in the list
301313
@ . the pc (r15) cannot be in the list in an STM instruction
302314
stm r0, {r0-r12}
303315
str sp, [r0, #52]
304316
str lr, [r0, #56]
305317
str lr, [r0, #60] @ store return address as pc
306-
mov r0, #0 @ return UNW_ESUCCESS
307-
#if __ARM_ARCH > 4
308-
bx lr
309-
#else
310-
mov pc, lr
311318
#endif
319+
mov r0, #0 @ return UNW_ESUCCESS
320+
JMP(lr)
312321

313322
@
314323
@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values)
@@ -318,12 +327,14 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
318327
@
319328
.p2align 2
320329
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy)
330+
#if defined(__ARM_FP)
321331
#if __ARM_ARCH < 7
322332
stc p11, cr0, [r0], {0x20} @ fstmiad r0, {d0-d15}
323333
#else
324334
vstmia r0, {d0-d15}
325335
#endif
326-
mov pc, lr
336+
#endif
337+
JMP(lr)
327338

328339
@
329340
@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values)
@@ -333,12 +344,14 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMD
333344
@
334345
.p2align 2
335346
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy)
347+
#if defined(__ARM_FP)
336348
#if __ARM_ARCH < 7
337349
stc p11, cr0, [r0], {0x21} @ fstmiax r0, {d0-d15}
338350
#else
339351
vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia
340352
#endif
341-
mov pc, lr
353+
#endif
354+
JMP(lr)
342355

343356
@
344357
@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values)
@@ -348,8 +361,9 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMX
348361
@
349362
.p2align 2
350363
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
364+
#if defined(__ARM_FP)
351365
@ VFP and iwMMX instructions are only available when compiling with the flags
352-
@ that enable them. We don't want to do that in the library (because we don't
366+
@ that enable them. We do not want to do that in the library (because we do not
353367
@ want the compiler to generate instructions that access those) but this is
354368
@ only accessed if the personality routine needs these registers. Use of
355369
@ these registers implies they are, actually, available on the target, so
@@ -360,7 +374,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
360374
#else
361375
vstmia r0, {d16-d31}
362376
#endif
363-
mov pc, lr
377+
#endif
378+
JMP(lr)
364379

365380
@
366381
@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)
@@ -370,6 +385,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
370385
@
371386
.p2align 2
372387
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
388+
#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
373389
stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8
374390
stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8
375391
stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8
@@ -386,7 +402,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
386402
stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8
387403
stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8
388404
stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8
389-
mov pc, lr
405+
#endif
406+
JMP(lr)
390407

391408
@
392409
@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values)
@@ -396,10 +413,12 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
396413
@
397414
.p2align 2
398415
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
416+
#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
399417
stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4
400418
stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4
401419
stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4
402420
stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4
403-
mov pc, lr
421+
#endif
422+
JMP(lr)
404423

405424
#endif

‎libcxxabi/src/Unwind/assembly.h

+12
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,16 @@
6161
SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
6262
SYMBOL_NAME(name):
6363

64+
#if defined(__arm__)
65+
#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
66+
#define ARM_HAS_BX
67+
#endif
68+
69+
#ifdef ARM_HAS_BX
70+
#define JMP(r) bx r
71+
#else
72+
#define JMP(r) mov pc, r
73+
#endif
74+
#endif /* __arm__ */
75+
6476
#endif /* UNWIND_ASSEMBLY_H */

0 commit comments

Comments
 (0)
Please sign in to comment.