llvm.org GIT mirror llvm / 179856d
ARM: support high registers in __builtin_longjmp on WoA Windows on ARM uses a pure thumb-2 environment. This means that it can select a high register when doing a __builtin_longjmp. We would use a tLDRi which would truncate the register to a low register. Use a t2LDRi12 to get the full register file access. Tweak the code to just load into PC, as that is an interworking branch on all supported cores anyways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274815 91177308-0d34-0410-b5e6-96231b3b80d8 Saleem Abdulrasool 4 years ago
3 changed file(s) with 37 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
18811881 .addReg(0));
18821882 return;
18831883 }
1884 case ARM::tInt_eh_sjlj_longjmp:
1885 case ARM::tInt_WIN_eh_sjlj_longjmp: {
1884 case ARM::tInt_eh_sjlj_longjmp: {
18861885 // ldr $scratch, [$src, #8]
18871886 // mov sp, $scratch
18881887 // ldr $scratch, [$src, #4]
19171916 .addReg(0));
19181917
19191918 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1920 .addReg(Opc == ARM::tInt_WIN_eh_sjlj_longjmp ? ARM::R11 : ARM::R7)
1919 .addReg(ARM::R7)
19211920 .addReg(SrcReg)
19221921 .addImm(0)
19231922 // Predicate.
19291928 // Predicate.
19301929 .addImm(ARMCC::AL)
19311930 .addReg(0));
1931 return;
1932 }
1933 case ARM::tInt_WIN_eh_sjlj_longjmp: {
1934 // ldr.w r11, [$src, #0]
1935 // ldr.w sp, [$src, #8]
1936 // ldr.w pc, [$src, #4]
1937
1938 unsigned SrcReg = MI->getOperand(0).getReg();
1939
1940 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
1941 .addReg(ARM::R11)
1942 .addReg(SrcReg)
1943 .addImm(0)
1944 // Predicate
1945 .addImm(ARMCC::AL)
1946 .addReg(0));
1947 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
1948 .addReg(ARM::SP)
1949 .addReg(SrcReg)
1950 .addImm(8)
1951 // Predicate
1952 .addImm(ARMCC::AL)
1953 .addReg(0));
1954 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
1955 .addReg(ARM::PC)
1956 .addReg(SrcReg)
1957 .addImm(4)
1958 // Predicate
1959 .addImm(ARMCC::AL)
1960 .addReg(0));
19321961 return;
19331962 }
19341963 }
647647 case ARM::Int_eh_sjlj_longjmp:
648648 return 16;
649649 case ARM::tInt_eh_sjlj_longjmp:
650 return 10;
650651 case ARM::tInt_WIN_eh_sjlj_longjmp:
651 return 10;
652 return 12;
652653 case ARM::Int_eh_sjlj_setjmp:
653654 case ARM::Int_eh_sjlj_setjmp_nofp:
654655 return 20;
88 }
99
1010 ; CHECK: push.w {r11, lr}
11 ; CHECK: ldr r[[SP:[0-9]+]], [r0, #8]
12 ; CHECK: mov sp, r[[SP]]
13 ; CHECK: ldr r[[PC:[0-9]+]], [r0, #4]
14 ; CHECK: ldr r11, [r0]
15 ; CHECK: bx r[[PC]]
11 ; CHECK: ldr.w r11, [r0]
12 ; CHECK: ldr.w sp, [r0, #8]
13 ; CHECK: ldr.w pc, [r0, #4]
1614