llvm.org GIT mirror llvm / 54fc124
For Darwin on ARMv6 and newer, make register r9 available for use as a caller-saved register. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73901 91177308-0d34-0410-b5e6-96231b3b80d8 Bob Wilson 11 years ago
5 changed file(s) with 91 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
9595 def IsThumb : Predicate<"Subtarget->isThumb()">;
9696 def HasThumb2 : Predicate<"Subtarget->hasThumb2()">;
9797 def IsARM : Predicate<"!Subtarget->isThumb()">;
98 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
99 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
98100
99101 //===----------------------------------------------------------------------===//
100102 // ARM Flag Definitions.
538540 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
539541 []>;
540542
543 // On non-Darwin platforms R9 is callee-saved.
541544 let isCall = 1, Itinerary = IIC_Br,
542545 Defs = [R0, R1, R2, R3, R12, LR,
543546 D0, D1, D2, D3, D4, D5, D6, D7, CPSR] in {
544547 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
545548 "bl ${func:call}",
546 [(ARMcall tglobaladdr:$func)]>;
549 [(ARMcall tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
547550
548551 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
549552 "bl", " ${func:call}",
550 [(ARMcall_pred tglobaladdr:$func)]>;
553 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
551554
552555 // ARMv5T and above
553556 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
554557 "blx $func",
555 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T]> {
558 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsNotDarwin]> {
556559 let Inst{7-4} = 0b0011;
557560 let Inst{19-8} = 0b111111111111;
558561 let Inst{27-20} = 0b00010010;
562565 // ARMv4T
563566 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
564567 "mov lr, pc\n\tbx $func",
565 [(ARMcall_nolink GPR:$func)]>;
568 [(ARMcall_nolink GPR:$func)]>, Requires<[IsNotDarwin]>;
569 }
570 }
571
572 // On Darwin R9 is call-clobbered.
573 let isCall = 1, Itinerary = IIC_Br,
574 Defs = [R0, R1, R2, R3, R9, R12, LR,
575 D0, D1, D2, D3, D4, D5, D6, D7, CPSR] in {
576 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
577 "bl ${func:call}",
578 [(ARMcall tglobaladdr:$func)]>, Requires<[IsDarwin]>;
579
580 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
581 "bl", " ${func:call}",
582 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsDarwin]>;
583
584 // ARMv5T and above
585 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
586 "blx $func",
587 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
588 let Inst{7-4} = 0b0011;
589 let Inst{19-8} = 0b111111111111;
590 let Inst{27-20} = 0b00010010;
591 }
592
593 let Uses = [LR] in {
594 // ARMv4T
595 def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
596 "mov lr, pc\n\tbx $func",
597 [(ARMcall_nolink GPR:$func)]>, Requires<[IsDarwin]>;
566598 }
567599 }
568600
13201352
13211353
13221354 // Direct calls
1323 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>;
1355 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1356 Requires<[IsNotDarwin]>;
1357 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1358 Requires<[IsDarwin]>;
13241359
13251360 // zextload i1 -> zextload i8
13261361 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
234234 };
235235
236236 static const unsigned DarwinCalleeSavedRegs[] = {
237 // Darwin ABI deviates from ARM standard ABI. R9 is not a callee-saved
238 // register.
237239 ARM::LR, ARM::R7, ARM::R6, ARM::R5, ARM::R4,
238 ARM::R11, ARM::R10, ARM::R9, ARM::R8,
240 ARM::R11, ARM::R10, ARM::R8,
239241
240242 ARM::D15, ARM::D14, ARM::D13, ARM::D12,
241243 ARM::D11, ARM::D10, ARM::D9, ARM::D8,
255257 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
256258 0
257259 };
260
258261 static const TargetRegisterClass * const ThumbCalleeSavedRegClasses[] = {
259262 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
260263 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::tGPRRegClass,
264267 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
265268 0
266269 };
267 return STI.isThumb() ? ThumbCalleeSavedRegClasses : CalleeSavedRegClasses;
270
271 static const TargetRegisterClass * const DarwinCalleeSavedRegClasses[] = {
272 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
273 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
274 &ARM::GPRRegClass, &ARM::GPRRegClass,
275
276 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
277 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
278 0
279 };
280
281 static const TargetRegisterClass * const DarwinThumbCalleeSavedRegClasses[] ={
282 &ARM::GPRRegClass, &ARM::tGPRRegClass, &ARM::tGPRRegClass,
283 &ARM::tGPRRegClass, &ARM::tGPRRegClass, &ARM::GPRRegClass,
284 &ARM::GPRRegClass, &ARM::GPRRegClass,
285
286 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
287 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
288 0
289 };
290
291 if (STI.isThumb()) {
292 return STI.isTargetDarwin()
293 ? DarwinThumbCalleeSavedRegClasses : ThumbCalleeSavedRegClasses;
294 }
295 return STI.isTargetDarwin()
296 ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses;
268297 }
269298
270299 BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
8686 // sp == Stack Pointer
8787 // r12 == ip (scratch)
8888 // r7 == Frame Pointer (thumb-style backtraces)
89 // r9 == May be reserved as Thread Register
8990 // r11 == Frame Pointer (arm-style backtraces)
9091 // r10 == Stack Limit
9192 //
114115 ARM::R4, ARM::R5, ARM::R6, ARM::R7,
115116 ARM::R8, ARM::R10,
116117 ARM::R11 };
117 // FP is R7, R9 is available.
118 // FP is R7, R9 is available as non-callee-saved register.
119 // This is used by Darwin.
118120 static const unsigned ARM_GPR_AO_3[] = {
119121 ARM::R0, ARM::R1, ARM::R2, ARM::R3,
120 ARM::R12,ARM::LR,
122 ARM::R9, ARM::R12,ARM::LR,
121123 ARM::R4, ARM::R5, ARM::R6,
122 ARM::R8, ARM::R9, ARM::R10,ARM::R11,
123 ARM::R7 };
124 ARM::R8, ARM::R10,ARM::R11,ARM::R7 };
124125 // FP is R7, R9 is not available.
125126 static const unsigned ARM_GPR_AO_4[] = {
126127 ARM::R0, ARM::R1, ARM::R2, ARM::R3,
154155 GPRClass::iterator I;
155156
156157 if (Subtarget.isTargetDarwin()) {
157 if (Subtarget.isR9Reserved()) {
158 if (Subtarget.isR9Reserved())
158159 I = ARM_GPR_AO_4 + (sizeof(ARM_GPR_AO_4)/sizeof(unsigned));
159 } else {
160 else
160161 I = ARM_GPR_AO_3 + (sizeof(ARM_GPR_AO_3)/sizeof(unsigned));
161 }
162162 } else {
163 if (Subtarget.isR9Reserved()) {
163 if (Subtarget.isR9Reserved())
164164 I = ARM_GPR_AO_2 + (sizeof(ARM_GPR_AO_2)/sizeof(unsigned));
165 } else {
165 else
166166 I = ARM_GPR_AO_1 + (sizeof(ARM_GPR_AO_1)/sizeof(unsigned));
167 }
168167 }
169168
170169 // Mac OS X requires FP not to be clobbered for backtracing purpose.
1515 #include "llvm/Module.h"
1616 #include "llvm/Target/TargetMachine.h"
1717 #include "llvm/Target/TargetOptions.h"
18 #include "llvm/Support/CommandLine.h"
1819 using namespace llvm;
20
21 static cl::opt
22 ReserveR9("arm-reserve-r9", cl::Hidden,
23 cl::desc("Reserve R9, making it unavailable as GPR"));
1924
2025 ARMSubtarget::ARMSubtarget(const Module &M, const std::string &FS,
2126 bool isThumb)
2328 , ARMFPUType(None)
2429 , IsThumb(isThumb)
2530 , ThumbMode(Thumb1)
26 , IsR9Reserved(false)
31 , IsR9Reserved(ReserveR9)
2732 , stackAlignment(4)
2833 , CPUString("generic")
2934 , TargetType(isELF) // Default to ELF unless otherwise specified.
8287 stackAlignment = 8;
8388
8489 if (isTargetDarwin())
85 IsR9Reserved = true;
90 IsR9Reserved = ReserveR9 | (ARMArchVersion < V6);
8691 }
0 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -relocation-model=pic \
1 ; RUN: -mattr=+v6 -ifcvt-limit=0 -stats |& grep asm-printer | grep 35
1 ; RUN: -mattr=+v6 | grep r9
2 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -relocation-model=pic \
3 ; RUN: -mattr=+v6 -arm-reserve-r9 -ifcvt-limit=0 -stats |& grep asm-printer
4 ; | grep 35
25
36 define void @test(i32 %tmp56222, i32 %tmp36224, i32 %tmp46223, i32 %i.0196.0.ph, i32 %tmp8, i32* %tmp1011, i32** %tmp1, i32* %d2.1.out, i32* %d3.1.out, i32* %d0.1.out, i32* %d1.1.out) {
47 newFuncRoot: