[LLVMdev] spilling & restoring registers for EHReturn & return _Unwind_Reason_Code
Robert Lytton
robert at xmos.com
Fri Dec 20 09:33:36 PST 2013
Hi
I'm working on the XCore target and am having difficulty building libgcc.
Background:
If I use a libgcc built by llvm3.0-gcc with my current clang-llvm3.3 compiler, exceptions 'seem' to work.
Trying to rebuild libgcc however breaks exception handling - they aren't caught!
I thus assumed I needed to focus on the unwind code and particularly functions that call @llvm.eh.unwind.init().
I reinforced this assumption by swapping the assembler output from the llvm-gcc lib into my new lib for some such functions - and exceptions 'seem' to work again.
(the critical functions being found in eh_personality.o, unwind-dw2.o, eh_throw.o)
Looking at functions built using the llvm3.0-gcc front end, I noticed that R0 & R1 were spilled/restored (clobbering '_Unwind_Reason_Code') , along with the callee saved regs.
So how are things meant to work?
For example take:
define i32 @_Unwind_RaiseException(%struct._Unwind_Exception* %exc)
This calls:
@llvm.eh.unwind.init()
followed by:
call void @llvm.eh.return()
ret i32 '_Unwind_Reason_Code'
call void @abort()
>From my reading, I need to spill all callee save regs (R4-R10) during the prologue.
(R0-R3, LR & FP are caller saved/argument registers)
BUT
Q: what about exception info (and what is this)?
Q: is it %exc (R0)?
Q: is it 'ExceptionPointerRegister' & 'ExceptionSelectorRegister' (R0&R1)?
Then:
Calling abort, does not restore callee save regs.
For 'return' epilogues, I restore callee save regs (R4-10) & R0 will hold the '_Unwind_Reason_Code'.
However, what must I do for llvm.eh.return() epilogues?
Q: do I restore callee save regs (R4-R10)?
Q: do I restore exception info (R0-R1)?
I have tried only spilling/restoring callee save regs - but this doesn't work, I end up with an uncaught exception.
So I tried spilling R0 & R1 and trying to restore them only for llvm.eh.return() but this will not compile.
viz unwind-dw2.c will report:
BB#0: derived from LLVM BB %entry
Live Ins: %R0 %R0 %R1 %R4 %R5 %R6 %R7 %R8 %R9 %R10 %LR %R0 %R1
ENTSP_lu6 120, %SP<imp-def>, %SP<imp-use>, %LR<imp-use,kill>
PROLOG_LABEL <MCSym=.Ltmp68>
PROLOG_LABEL <MCSym=.Ltmp69>
STWSP_lru6 %R0<kill>, 119, %SP<imp-use>
PROLOG_LABEL <MCSym=.Ltmp59>
STWSP_lru6 %R1<kill>, 118, %SP<imp-use>
PROLOG_LABEL <MCSym=.Ltmp60>
STWSP_lru6 %R4<kill>, 117, %SP<imp-use>
PROLOG_LABEL <MCSym=.Ltmp61>
STWSP_lru6 %R5<kill>, 116, %SP<imp-use>
PROLOG_LABEL <MCSym=.Ltmp62>
STWSP_lru6 %R6<kill>, 115, %SP<imp-use>
PROLOG_LABEL <MCSym=.Ltmp63>
STWSP_lru6 %R7<kill>, 114, %SP<imp-use>
PROLOG_LABEL <MCSym=.Ltmp64>
STWSP_lru6 %R8<kill>, 113, %SP<imp-use>
PROLOG_LABEL <MCSym=.Ltmp65>
STWSP_lru6 %R9<kill>, 112, %SP<imp-use>
PROLOG_LABEL <MCSym=.Ltmp66>
STWSP_lru6 %R10<kill>, 111, %SP<imp-use>
PROLOG_LABEL <MCSym=.Ltmp67>
%R4<def> = COPY %R0
...
*** Bad machine code: Using an undefined physical register ***
- function: _Unwind_RaiseException
- basic block: BB#0 entry (0x33d9f20)
- instruction: %R4<def> = COPY %R0
- operand 1: %R0
To see if I am on the right track I may try to:
1. hack llvm to not kill R0 during the spill
2. manually add spilled/restore R0 & R1 into the assembler output for functions that call llvm.eh.return().
However, I would prefer knowledgeable input at this stage!
Thank you.
Robert
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131220/720e074d/attachment.html>
More information about the llvm-dev
mailing list