llvm.org GIT mirror llvm / 27934da
Load / store multiple pass fixes for Thumb2. Not enabled yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78031 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 11 years ago
2 changed file(s) with 88 addition(s) and 77 deletion(s). Raw diff Collapse all Expand all
142142 return 0;
143143 }
144144
145 static bool isT2i32Load(unsigned Opc) {
146 return Opc == ARM::t2LDRi12 || Opc == ARM::t2LDRi8;
147 }
148
145149 static bool isi32Load(unsigned Opc) {
146 return Opc == ARM::LDR || Opc == ARM::t2LDRi12 || Opc == ARM::t2LDRi8;
150 return Opc == ARM::LDR || isT2i32Load(Opc);
151 }
152
153 static bool isT2i32Store(unsigned Opc) {
154 return Opc == ARM::t2STRi12 || Opc == ARM::t2STRi8;
147155 }
148156
149157 static bool isi32Store(unsigned Opc) {
150 return Opc == ARM::STR || Opc == ARM::t2STRi12 || Opc == ARM::t2STRi8;
158 return Opc == ARM::STR || isT2i32Store(Opc);
151159 }
152160
153161 /// MergeOps - Create and insert a LDM or STM with Base as base register and
210218 }
211219
212220 bool isDPR = Opcode == ARM::FLDD || Opcode == ARM::FSTD;
213 bool isDef = Opcode == ARM::LDR || Opcode == ARM::FLDS || Opcode == ARM::FLDD;
221 bool isDef = isi32Load(Opcode) || Opcode == ARM::FLDS || Opcode == ARM::FLDD;
214222 Opcode = getLoadStoreMultipleOpcode(Opcode);
215223 MachineInstrBuilder MIB = (isAM4)
216224 ? BuildMI(MBB, MBBI, dl, TII->get(Opcode))
308316 }
309317
310318 static inline bool isMatchingDecrement(MachineInstr *MI, unsigned Base,
311 unsigned Bytes, ARMCC::CondCodes Pred,
312 unsigned PredReg, bool isThumb2) {
319 unsigned Bytes, unsigned Limit,
320 ARMCC::CondCodes Pred, unsigned PredReg){
313321 unsigned MyPredReg = 0;
314322 if (!MI)
315323 return false;
316 if (isThumb2) {
317 if (MI->getOpcode() != ARM::t2SUBri)
318 return false;
319 // Make sure the offset fits in 8 bits.
320 if (Bytes <= 0 || Bytes >= 0x100)
321 return false;
322 } else {
323 if (MI->getOpcode() != ARM::SUBri)
324 return false;
325 // Make sure the offset fits in 12 bits.
326 if (Bytes <= 0 || Bytes >= 0x1000)
327 return false;
328 }
324 if (MI->getOpcode() != ARM::t2SUBri &&
325 MI->getOpcode() != ARM::SUBri)
326 return false;
327
328 // Make sure the offset fits in 8 bits.
329 if (Bytes <= 0 || (Limit && Bytes >= Limit))
330 return false;
329331
330332 return (MI->getOperand(0).getReg() == Base &&
331333 MI->getOperand(1).getReg() == Base &&
335337 }
336338
337339 static inline bool isMatchingIncrement(MachineInstr *MI, unsigned Base,
338 unsigned Bytes, ARMCC::CondCodes Pred,
339 unsigned PredReg, bool isThumb2) {
340 unsigned Bytes, unsigned Limit,
341 ARMCC::CondCodes Pred, unsigned PredReg){
340342 unsigned MyPredReg = 0;
341343 if (!MI)
342344 return false;
343 if (isThumb2) {
344 if (MI->getOpcode() != ARM::t2ADDri)
345 return false;
345 if (MI->getOpcode() != ARM::t2ADDri &&
346 MI->getOpcode() != ARM::ADDri)
347 return false;
348
349 if (Bytes <= 0 || (Limit && Bytes >= Limit))
346350 // Make sure the offset fits in 8 bits.
347 if (Bytes <= 0 || Bytes >= 0x100)
348 return false;
349 } else {
350 if (MI->getOpcode() != ARM::ADDri)
351 return false;
352 // Make sure the offset fits in 12 bits.
353 if (Bytes <= 0 || Bytes >= 0x1000)
354 return false;
355 }
351 return false;
356352
357353 return (MI->getOperand(0).getReg() == Base &&
358354 MI->getOperand(1).getReg() == Base &&
378374 return 8;
379375 case ARM::LDM:
380376 case ARM::STM:
377 case ARM::t2LDM:
378 case ARM::t2STM:
381379 return (MI->getNumOperands() - 4) * 4;
382380 case ARM::FLDMS:
383381 case ARM::FSTMS:
427425 if (MBBI != MBB.begin()) {
428426 MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
429427 if (Mode == ARM_AM::ia &&
430 isMatchingDecrement(PrevMBBI, Base, Bytes, Pred, PredReg, isThumb2)) {
428 isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
431429 MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::db, true));
432430 MBB.erase(PrevMBBI);
433431 return true;
434432 } else if (Mode == ARM_AM::ib &&
435 isMatchingDecrement(PrevMBBI, Base, Bytes, Pred, PredReg,
436 isThumb2)) {
433 isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
437434 MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::da, true));
438435 MBB.erase(PrevMBBI);
439436 return true;
443440 if (MBBI != MBB.end()) {
444441 MachineBasicBlock::iterator NextMBBI = next(MBBI);
445442 if ((Mode == ARM_AM::ia || Mode == ARM_AM::ib) &&
446 isMatchingIncrement(NextMBBI, Base, Bytes, Pred, PredReg, isThumb2)) {
443 isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
447444 MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true));
448445 if (NextMBBI == I) {
449446 Advance = true;
452449 MBB.erase(NextMBBI);
453450 return true;
454451 } else if ((Mode == ARM_AM::da || Mode == ARM_AM::db) &&
455 isMatchingDecrement(NextMBBI, Base, Bytes, Pred, PredReg,
456 isThumb2)) {
452 isMatchingDecrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
457453 MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true));
458454 if (NextMBBI == I) {
459455 Advance = true;
473469 if (MBBI != MBB.begin()) {
474470 MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
475471 if (Mode == ARM_AM::ia &&
476 isMatchingDecrement(PrevMBBI, Base, Bytes, Pred, PredReg, isThumb2)) {
472 isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
477473 MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::db, true, Offset));
478474 MBB.erase(PrevMBBI);
479475 return true;
483479 if (MBBI != MBB.end()) {
484480 MachineBasicBlock::iterator NextMBBI = next(MBBI);
485481 if (Mode == ARM_AM::ia &&
486 isMatchingIncrement(NextMBBI, Base, Bytes, Pred, PredReg, isThumb2)) {
482 isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
487483 MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::ia, true, Offset));
488484 if (NextMBBI == I) {
489485 Advance = true;
549545 unsigned Bytes = getLSMultipleTransferSize(MI);
550546 int Opcode = MI->getOpcode();
551547 DebugLoc dl = MI->getDebugLoc();
548 bool isAM5 = Opcode == ARM::FLDD || Opcode == ARM::FLDS ||
549 Opcode == ARM::FSTD || Opcode == ARM::FSTS;
552550 bool isAM2 = Opcode == ARM::LDR || Opcode == ARM::STR;
553551 if (isAM2 && ARM_AM::getAM2Offset(MI->getOperand(3).getImm()) != 0)
554552 return false;
555 else if (!isAM2 && !isThumb2 &&
556 ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0)
553 else if (isAM5 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0)
557554 return false;
558 else if (isThumb2 && MI->getOperand(2).getImm() != 0)
559 return false;
555 else if (isT2i32Load(Opcode) || isT2i32Store(Opcode))
556 if (MI->getOperand(2).getImm() != 0)
557 return false;
560558
561559 bool isLd = isi32Load(Opcode) || Opcode == ARM::FLDS || Opcode == ARM::FLDD;
562560 // Can't do the merge if the destination register is the same as the would-be
569567 bool DoMerge = false;
570568 ARM_AM::AddrOpc AddSub = ARM_AM::add;
571569 unsigned NewOpc = 0;
570 // AM2 - 12 bits, thumb2 - 8 bits.
571 unsigned Limit = isAM5 ? 0 : (isAM2 ? 0x1000 : 0x100);
572572 if (MBBI != MBB.begin()) {
573573 MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
574 if (isMatchingDecrement(PrevMBBI, Base, Bytes, Pred, PredReg, isThumb2)) {
574 if (isMatchingDecrement(PrevMBBI, Base, Bytes, Limit, Pred, PredReg)) {
575575 DoMerge = true;
576576 AddSub = ARM_AM::sub;
577577 NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
578 } else if (isAM2 && isMatchingIncrement(PrevMBBI, Base, Bytes,
579 Pred, PredReg, isThumb2)) {
578 } else if (!isAM5 &&
579 isMatchingIncrement(PrevMBBI, Base, Bytes, Limit,Pred,PredReg)) {
580580 DoMerge = true;
581581 NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
582582 }
586586
587587 if (!DoMerge && MBBI != MBB.end()) {
588588 MachineBasicBlock::iterator NextMBBI = next(MBBI);
589 if (isAM2 && isMatchingDecrement(NextMBBI, Base, Bytes, Pred, PredReg,
590 isThumb2)) {
589 if (!isAM5 &&
590 isMatchingDecrement(NextMBBI, Base, Bytes, Limit, Pred, PredReg)) {
591591 DoMerge = true;
592592 AddSub = ARM_AM::sub;
593593 NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
594 } else if (isMatchingIncrement(NextMBBI, Base, Bytes, Pred, PredReg,
595 isThumb2)) {
594 } else if (isMatchingIncrement(NextMBBI, Base, Bytes, Limit,Pred,PredReg)) {
596595 DoMerge = true;
597596 NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
598597 }
609608 return false;
610609
611610 bool isDPR = NewOpc == ARM::FLDMD || NewOpc == ARM::FSTMD;
612 unsigned Offset = isAM2
613 ? ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift)
614 : (isThumb2
615 ? Bytes
616 : ARM_AM::getAM5Opc((AddSub == ARM_AM::sub) ? ARM_AM::db : ARM_AM::ia,
617 true, isDPR ? 2 : 1));
611 unsigned Offset = isAM5
612 ? ARM_AM::getAM5Opc((AddSub == ARM_AM::sub) ? ARM_AM::db : ARM_AM::ia,
613 true, isDPR ? 2 : 1)
614 : (isAM2
615 ? ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift)
616 : Bytes);
618617 if (isLd) {
619 if (isAM2 || isThumb2)
620 // LDR_PRE, LDR_POST, t2LDR_PRE, t2LDR_POST
621 BuildMI(MBB, MBBI, dl, TII->get(NewOpc), MI->getOperand(0).getReg())
622 .addReg(Base, RegState::Define)
623 .addReg(Base).addReg(0).addImm(Offset).addImm(Pred).addReg(PredReg);
624 else if (!isThumb2)
618 if (isAM5)
625619 // FLDMS, FLDMD
626620 BuildMI(MBB, MBBI, dl, TII->get(NewOpc))
627621 .addReg(Base, getKillRegState(BaseKill))
628622 .addImm(Offset).addImm(Pred).addReg(PredReg)
629623 .addReg(MI->getOperand(0).getReg(), RegState::Define);
624 else if (isAM2)
625 // LDR_PRE, LDR_POST,
626 BuildMI(MBB, MBBI, dl, TII->get(NewOpc), MI->getOperand(0).getReg())
627 .addReg(Base, RegState::Define)
628 .addReg(Base).addReg(0).addImm(Offset).addImm(Pred).addReg(PredReg);
629 else
630 // t2LDR_PRE, t2LDR_POST
631 BuildMI(MBB, MBBI, dl, TII->get(NewOpc), MI->getOperand(0).getReg())
632 .addReg(Base, RegState::Define)
633 .addReg(Base).addImm(Offset).addImm(Pred).addReg(PredReg);
630634 } else {
631635 MachineOperand &MO = MI->getOperand(0);
632 if (isAM2 || isThumb2)
633 // STR_PRE, STR_POST, t2STR_PRE, t2STR_POST
636 if (isAM5)
637 // FSTMS, FSTMD
638 BuildMI(MBB, MBBI, dl, TII->get(NewOpc)).addReg(Base).addImm(Offset)
639 .addImm(Pred).addReg(PredReg)
640 .addReg(MO.getReg(), getKillRegState(MO.isKill()));
641 else if (isAM2)
642 // STR_PRE, STR_POST
634643 BuildMI(MBB, MBBI, dl, TII->get(NewOpc), Base)
635644 .addReg(MO.getReg(), getKillRegState(MO.isKill()))
636645 .addReg(Base).addReg(0).addImm(Offset).addImm(Pred).addReg(PredReg);
637646 else
638 // FSTMS, FSTMD
639 BuildMI(MBB, MBBI, dl, TII->get(NewOpc)).addReg(Base).addImm(Offset)
640 .addImm(Pred).addReg(PredReg)
641 .addReg(MO.getReg(), getKillRegState(MO.isKill()));
647 // t2STR_PRE, t2STR_POST
648 BuildMI(MBB, MBBI, dl, TII->get(NewOpc), Base)
649 .addReg(MO.getReg(), getKillRegState(MO.isKill()))
650 .addReg(Base).addImm(Offset).addImm(Pred).addReg(PredReg);
642651 }
643652 MBB.erase(MBBI);
644653
10091018 MachineInstr *PrevMI = prior(MBBI);
10101019 if (PrevMI->getOpcode() == ARM::LDM || PrevMI->getOpcode() == ARM::t2LDM) {
10111020 MachineOperand &MO = PrevMI->getOperand(PrevMI->getNumOperands()-1);
1012 if (MO.getReg() == ARM::LR) {
1013 unsigned NewOpc = isThumb2 ? ARM::t2LDM_RET : ARM::LDM_RET;
1014 PrevMI->setDesc(TII->get(NewOpc));
1015 MO.setReg(ARM::PC);
1016 MBB.erase(MBBI);
1017 return true;
1018 }
1021 if (MO.getReg() != ARM::LR)
1022 return false;
1023 unsigned NewOpc = isThumb2 ? ARM::t2LDM_RET : ARM::LDM_RET;
1024 PrevMI->setDesc(TII->get(NewOpc));
1025 MO.setReg(ARM::PC);
1026 MBB.erase(MBBI);
1027 return true;
10191028 }
10201029 }
10211030 return false;
595595 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
596596 if (Modifier && strcmp(Modifier, "submode") == 0) {
597597 if (MO1.getReg() == ARM::SP) {
598 // FIXME
598599 bool isLDM = (MI->getOpcode() == ARM::LDM ||
599 MI->getOpcode() == ARM::LDM_RET);
600 MI->getOpcode() == ARM::LDM_RET ||
601 MI->getOpcode() == ARM::t2LDM_RET);
600602 O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
601603 } else
602604 O << ARM_AM::getAMSubModeStr(Mode);