llvm.org GIT mirror llvm / 3664090
During PEI, if the immediate value of sp + offset is too large (i.e. something that would require > 3 instructions to materialize), load the immediate from a constpool entry. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33667 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
1 changed file(s) with 102 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
1717 #include "ARMMachineFunctionInfo.h"
1818 #include "ARMRegisterInfo.h"
1919 #include "ARMSubtarget.h"
20 #include "llvm/Constants.h"
21 #include "llvm/DerivedTypes.h"
22 #include "llvm/CodeGen/MachineConstantPool.h"
23 #include "llvm/CodeGen/MachineFrameInfo.h"
24 #include "llvm/CodeGen/MachineFunction.h"
2025 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
2326 #include "llvm/CodeGen/MachineLocation.h"
2427 #include "llvm/Target/TargetFrameInfo.h"
2528 #include "llvm/Target/TargetMachine.h"
2629 #include "llvm/Target/TargetOptions.h"
27 #include "llvm/Type.h"
2830 #include "llvm/ADT/SmallVector.h"
2931 #include "llvm/ADT/STLExtras.h"
3032 #include
280282 return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects();
281283 }
282284
283 /// emitARMRegPlusImmediate - Emit a series of instructions to materialize
285 /// emitARMRegPlusImmediate - Emits a series of instructions to materialize
284286 /// a destreg = basereg + immediate in ARM code.
285287 static
286288 void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
322324 }
323325 }
324326
325 /// emitThumbRegPlusImmediate - Emit a series of instructions to materialize
327 /// calcNumMI - Returns the number of instructions required to materialize
328 /// the specific add / sub r, c instruction.
329 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
330 unsigned NumBits, unsigned Scale) {
331 unsigned NumMIs = 0;
332 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
333
334 if (Opc == ARM::tADDrSPi) {
335 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
336 Bytes -= ThisVal;
337 NumMIs++;
338 NumBits = 8;
339 Scale = 1;
340 Chunk = ((1 << NumBits) - 1) * Scale;
341 }
342
343 NumMIs += Bytes / Chunk;
344 if ((Bytes % Chunk) != 0)
345 NumMIs++;
346 if (ExtraOpc)
347 NumMIs++;
348 return NumMIs;
349 }
350
351 /// emitThumbRegPlusConstPool - Emits a series of instructions to materialize
352 /// a destreg = basereg + immediate in Thumb code. Load the immediate from a
353 /// constpool entry.
354 static
355 void emitThumbRegPlusConstPool(MachineBasicBlock &MBB,
356 MachineBasicBlock::iterator &MBBI,
357 unsigned DestReg, unsigned BaseReg,
358 int NumBytes, const TargetInstrInfo &TII) {
359 MachineFunction &MF = *MBB.getParent();
360 MachineConstantPool *ConstantPool = MF.getConstantPool();
361 bool isHigh = !isLowRegister(DestReg) || !isLowRegister(BaseReg);
362 bool isSub = false;
363 // Subtract doesn't have high register version. Load the negative value
364 // if either base or dest register is a high register.
365 if (NumBytes < 0 && !isHigh) {
366 isSub = true;
367 NumBytes = -NumBytes;
368 }
369 Constant *C = ConstantInt::get(Type::Int32Ty, NumBytes);
370 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2);
371 unsigned LdReg = DestReg;
372 if (DestReg == ARM::SP) {
373 assert(BaseReg == ARM::SP && "Unexpected!");
374 LdReg = ARM::R3;
375 BuildMI(MBB, MBBI, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R3);
376 }
377 // Load the constant.
378 BuildMI(MBB, MBBI, TII.get(ARM::tLDRpci), LdReg).addConstantPoolIndex(Idx);
379 // Emit add / sub.
380 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
381 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(Opc), DestReg);
382 if (DestReg == ARM::SP)
383 MIB.addReg(BaseReg).addReg(LdReg);
384 else
385 MIB.addReg(LdReg).addReg(BaseReg);
386 if (DestReg == ARM::SP)
387 BuildMI(MBB, MBBI, TII.get(ARM::tMOVrr), ARM::R3).addReg(ARM::R12);
388 }
389
390 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
326391 /// a destreg = basereg + immediate in Thumb code.
327392 static
328393 void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
334399 if (isSub) Bytes = -NumBytes;
335400 bool isMul4 = (Bytes & 3) == 0;
336401 bool isTwoAddr = false;
402 bool DstNeBase = false;
337403 unsigned NumBits = 1;
338404 unsigned Scale = 1;
339 unsigned Opc = 0;
340 unsigned ExtraOpc = 0;
405 int Opc = 0;
406 int ExtraOpc = 0;
341407
342408 if (DestReg == BaseReg && BaseReg == ARM::SP) {
343409 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
358424 Scale = 4;
359425 Opc = ARM::tADDrSPi;
360426 } else {
361 if (DestReg != BaseReg) {
362 if (isLowRegister(DestReg) && isLowRegister(BaseReg)) {
363 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
364 unsigned Chunk = (1 << 3) - 1;
365 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
366 Bytes -= ThisVal;
367 BuildMI(MBB, MBBI, TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
368 .addReg(BaseReg).addImm(ThisVal);
369 } else {
370 BuildMI(MBB, MBBI, TII.get(ARM::tMOVrr), DestReg).addReg(BaseReg);
371 }
372 BaseReg = DestReg;
373 }
427 // sp = sub sp, c
428 // r1 = sub sp, c
429 // r8 = sub sp, c
430 if (DestReg != BaseReg)
431 DstNeBase = true;
374432 NumBits = 8;
375433 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
376434 isTwoAddr = true;
435 }
436
437 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
438 unsigned Threshold = (DestReg == ARM::SP) ? 4 : 3;
439 if (NumMIs > Threshold) {
440 // This will expand into too many instructions. Load the immediate from a
441 // constpool entry.
442 emitThumbRegPlusConstPool(MBB, MBBI, DestReg, BaseReg, NumBytes, TII);
443 return;
444 }
445
446 if (DstNeBase) {
447 if (isLowRegister(DestReg) && isLowRegister(BaseReg)) {
448 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
449 unsigned Chunk = (1 << 3) - 1;
450 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
451 Bytes -= ThisVal;
452 BuildMI(MBB, MBBI, TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
453 .addReg(BaseReg).addImm(ThisVal);
454 } else {
455 BuildMI(MBB, MBBI, TII.get(ARM::tMOVrr), DestReg).addReg(BaseReg);
456 }
457 BaseReg = DestReg;
377458 }
378459
379460 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
642723 return;
643724 }
644725
645 // Otherwise, it didn't fit. Pull in what we can to simplify the immediate.
726 // Otherwise, it didn't fit. Pull in what we can to simplify the immediate.
646727 if (AddrMode == ARMII::AddrModeTs) {
647728 // Thumb tLDRspi, tSTRspi. These will change to instructions that use a
648729 // different base register.