llvm.org GIT mirror llvm / 5ff58b5
Correctly handle the Thumb-2 imm8 addrmode. Specialize frame index elimination more exactly for Thumb-2 to get better code gen. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76919 91177308-0d34-0410-b5e6-96231b3b80d8 David Goodwin 11 years ago
16 changed file(s) with 424 addition(s) and 265 deletion(s). Raw diff Collapse all Expand all
512512 ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
513513 int &FrameIndex) const {
514514 unsigned oc = MI->getOpcode();
515 if (oc == getOpcode(ARMII::LDR)) {
515 if (oc == getOpcode(ARMII::LDRrr)) {
516516 if (MI->getOperand(1).isFI() &&
517517 MI->getOperand(2).isReg() &&
518518 MI->getOperand(3).isImm() &&
522522 return MI->getOperand(0).getReg();
523523 }
524524 }
525 else if (oc == getOpcode(ARMII::LDRri)) {
526 if (MI->getOperand(1).isFI() &&
527 MI->getOperand(2).isImm() &&
528 MI->getOperand(2).getImm() == 0) {
529 FrameIndex = MI->getOperand(1).getIndex();
530 return MI->getOperand(0).getReg();
531 }
532 }
525533 else if ((oc == getOpcode(ARMII::FLDD)) ||
526534 (oc == getOpcode(ARMII::FLDS))) {
527535 if (MI->getOperand(1).isFI() &&
539547 ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
540548 int &FrameIndex) const {
541549 unsigned oc = MI->getOpcode();
542 if (oc == getOpcode(ARMII::STR)) {
550 if (oc == getOpcode(ARMII::STRrr)) {
543551 if (MI->getOperand(1).isFI() &&
544552 MI->getOperand(2).isReg() &&
545553 MI->getOperand(3).isImm() &&
546554 MI->getOperand(2).getReg() == 0 &&
547555 MI->getOperand(3).getImm() == 0) {
556 FrameIndex = MI->getOperand(1).getIndex();
557 return MI->getOperand(0).getReg();
558 }
559 }
560 else if (oc == getOpcode(ARMII::STRri)) {
561 if (MI->getOperand(1).isFI() &&
562 MI->getOperand(2).isImm() &&
563 MI->getOperand(2).getImm() == 0) {
548564 FrameIndex = MI->getOperand(1).getIndex();
549565 return MI->getOperand(0).getReg();
550566 }
601617 if (I != MBB.end()) DL = I->getDebugLoc();
602618
603619 if (RC == ARM::GPRRegisterClass) {
604 AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::STR)))
620 AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::STRrr)))
605621 .addReg(SrcReg, getKillRegState(isKill))
606622 .addFrameIndex(FI).addReg(0).addImm(0));
607623 } else if (RC == ARM::DPRRegisterClass) {
625641 DebugLoc DL = DebugLoc::getUnknownLoc();
626642 unsigned Opc = 0;
627643 if (RC == ARM::GPRRegisterClass) {
628 Opc = getOpcode(ARMII::STR);
644 if ((Addr.size() > 1) && Addr[1].isImm())
645 Opc = getOpcode(ARMII::STRri);
646 else
647 Opc = getOpcode(ARMII::STRrr);
629648 } else if (RC == ARM::DPRRegisterClass) {
630649 Opc = getOpcode(ARMII::FSTD);
631650 } else {
650669 if (I != MBB.end()) DL = I->getDebugLoc();
651670
652671 if (RC == ARM::GPRRegisterClass) {
653 AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::LDR)), DestReg)
672 AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::LDRrr)), DestReg)
654673 .addFrameIndex(FI).addReg(0).addImm(0));
655674 } else if (RC == ARM::DPRRegisterClass) {
656675 AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::FLDD)), DestReg)
670689 DebugLoc DL = DebugLoc::getUnknownLoc();
671690 unsigned Opc = 0;
672691 if (RC == ARM::GPRRegisterClass) {
673 Opc = getOpcode(ARMII::LDR);
692 if ((Addr.size() > 1) && Addr[1].isImm())
693 Opc = getOpcode(ARMII::LDRri);
694 else
695 Opc = getOpcode(ARMII::LDRrr);
674696 } else if (RC == ARM::DPRRegisterClass) {
675697 Opc = getOpcode(ARMII::FLDD);
676698 } else {
703725 unsigned SrcReg = MI->getOperand(1).getReg();
704726 bool isKill = MI->getOperand(1).isKill();
705727 bool isUndef = MI->getOperand(1).isUndef();
706 NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::STR)))
728 NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::STRrr)))
707729 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
708730 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
709731 } else { // move -> load
710732 unsigned DstReg = MI->getOperand(0).getReg();
711733 bool isDead = MI->getOperand(0).isDead();
712734 bool isUndef = MI->getOperand(0).isUndef();
713 NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::LDR)))
735 NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::LDRrr)))
714736 .addReg(DstReg,
715737 RegState::Define |
716738 getDeadRegState(isDead) |
176176 FLDS,
177177 FSTD,
178178 FSTS,
179 LDR,
179 LDRrr,
180 LDRri,
180181 MOVr,
181 STR,
182 STRrr,
183 STRri,
182184 SUBri,
183185 SUBrs,
184186 SUBrr,
213215
214216 // Return the opcode that implements 'Op', or 0 if no opcode
215217 virtual unsigned getOpcode(ARMII::Op Op) const =0;
216
217 // If 'opcode' is an instruction with an unsigned offset that also
218 // has a version with a signed offset, return the opcode for the
219 // version with the signed offset. In 'NumBits' return the number of
220 // bits for the signed offset.
221 virtual unsigned unsignedOffsetOpcodeToSigned(unsigned opcode,
222 unsigned *NumBits) const = 0;
223218
224219 // Return true if the block does not fall through.
225220 virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const =0;
139139 unsigned ARMBaseRegisterInfo::
140140 getOpcode(int Op) const {
141141 return TII.getOpcode((ARMII::Op)Op);
142 }
143
144 unsigned ARMBaseRegisterInfo::
145 unsignedOffsetOpcodeToSigned(unsigned opcode, unsigned *NumBits) const {
146 return TII.unsignedOffsetOpcodeToSigned(opcode, NumBits);
147142 }
148143
149144 const unsigned*
10301025 return Reg;
10311026 }
10321027
1028 int ARMBaseRegisterInfo::
1029 rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
1030 unsigned FrameReg, int Offset) const
1031 {
1032 unsigned Opcode = MI.getOpcode();
1033 const TargetInstrDesc &Desc = MI.getDesc();
1034 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
1035 bool isSub = false;
1036
1037 // Memory operands in inline assembly always use AddrMode2.
1038 if (Opcode == ARM::INLINEASM)
1039 AddrMode = ARMII::AddrMode2;
1040
1041 if (Opcode == getOpcode(ARMII::ADDri)) {
1042 Offset += MI.getOperand(FrameRegIdx+1).getImm();
1043 if (Offset == 0) {
1044 // Turn it into a move.
1045 MI.setDesc(TII.get(getOpcode(ARMII::MOVr)));
1046 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
1047 MI.RemoveOperand(FrameRegIdx+1);
1048 return 0;
1049 } else if (Offset < 0) {
1050 Offset = -Offset;
1051 isSub = true;
1052 MI.setDesc(TII.get(getOpcode(ARMII::SUBri)));
1053 }
1054
1055 // Common case: small offset, fits into instruction.
1056 if (ARM_AM::getSOImmVal(Offset) != -1) {
1057 // Replace the FrameIndex with sp / fp
1058 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
1059 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
1060 return 0;
1061 }
1062
1063 // Otherwise, pull as much of the immedidate into this ADDri/SUBri
1064 // as possible.
1065 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
1066 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt);
1067
1068 // We will handle these bits from offset, clear them.
1069 Offset &= ~ThisImmVal;
1070
1071 // Get the properly encoded SOImmVal field.
1072 assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 &&
1073 "Bit extraction didn't work?");
1074 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
1075 } else {
1076 unsigned ImmIdx = 0;
1077 int InstrOffs = 0;
1078 unsigned NumBits = 0;
1079 unsigned Scale = 1;
1080 switch (AddrMode) {
1081 case ARMII::AddrMode2: {
1082 ImmIdx = FrameRegIdx+2;
1083 InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm());
1084 if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1085 InstrOffs *= -1;
1086 NumBits = 12;
1087 break;
1088 }
1089 case ARMII::AddrMode3: {
1090 ImmIdx = FrameRegIdx+2;
1091 InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm());
1092 if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1093 InstrOffs *= -1;
1094 NumBits = 8;
1095 break;
1096 }
1097 case ARMII::AddrMode5: {
1098 ImmIdx = FrameRegIdx+1;
1099 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
1100 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1101 InstrOffs *= -1;
1102 NumBits = 8;
1103 Scale = 4;
1104 break;
1105 }
1106 default:
1107 llvm_unreachable("Unsupported addressing mode!");
1108 break;
1109 }
1110
1111 Offset += InstrOffs * Scale;
1112 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
1113 if (Offset < 0) {
1114 Offset = -Offset;
1115 isSub = true;
1116 }
1117
1118 // Attempt to fold address comp. if opcode has offset bits
1119 if (NumBits > 0) {
1120 // Common case: small offset, fits into instruction.
1121 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
1122 int ImmedOffset = Offset / Scale;
1123 unsigned Mask = (1 << NumBits) - 1;
1124 if ((unsigned)Offset <= Mask * Scale) {
1125 // Replace the FrameIndex with sp
1126 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
1127 if (isSub)
1128 ImmedOffset |= 1 << NumBits;
1129 ImmOp.ChangeToImmediate(ImmedOffset);
1130 return 0;
1131 }
1132
1133 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
1134 ImmedOffset = ImmedOffset & Mask;
1135 if (isSub)
1136 ImmedOffset |= 1 << NumBits;
1137 ImmOp.ChangeToImmediate(ImmedOffset);
1138 Offset &= ~(Mask*Scale);
1139 }
1140 }
1141
1142 return (isSub) ? -Offset : Offset;
1143 }
1144
10331145 void ARMBaseRegisterInfo::
10341146 eliminateFrameIndex(MachineBasicBlock::iterator II,
1035 int SPAdj, RegScavenger *RS) const{
1147 int SPAdj, RegScavenger *RS) const {
10361148 unsigned i = 0;
10371149 MachineInstr &MI = *II;
10381150 MachineBasicBlock &MBB = *MI.getParent();
10641176 Offset -= AFI->getFramePtrSpillOffset();
10651177 }
10661178
1067 unsigned Opcode = MI.getOpcode();
1068 const TargetInstrDesc &Desc = MI.getDesc();
1069 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
1070 bool isSub = false;
1071
1072 // Memory operands in inline assembly always use AddrMode2.
1073 if (Opcode == ARM::INLINEASM)
1074 AddrMode = ARMII::AddrMode2;
1075
1076 if (Opcode == getOpcode(ARMII::ADDri)) {
1077 Offset += MI.getOperand(i+1).getImm();
1078 if (Offset == 0) {
1079 // Turn it into a move.
1080 MI.setDesc(TII.get(getOpcode(ARMII::MOVr)));
1081 MI.getOperand(i).ChangeToRegister(FrameReg, false);
1082 MI.RemoveOperand(i+1);
1083 return;
1084 } else if (Offset < 0) {
1085 Offset = -Offset;
1086 isSub = true;
1087 MI.setDesc(TII.get(getOpcode(ARMII::SUBri)));
1088 }
1089
1090 // Common case: small offset, fits into instruction.
1091 if (ARM_AM::getSOImmVal(Offset) != -1) {
1092 // Replace the FrameIndex with sp / fp
1093 MI.getOperand(i).ChangeToRegister(FrameReg, false);
1094 MI.getOperand(i+1).ChangeToImmediate(Offset);
1095 return;
1096 }
1097
1098 // Otherwise, we fallback to common code below to form the imm offset with
1099 // a sequence of ADDri instructions. First though, pull as much of the imm
1100 // into this ADDri as possible.
1101 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
1102 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt);
1103
1104 // We will handle these bits from offset, clear them.
1105 Offset &= ~ThisImmVal;
1106
1107 // Get the properly encoded SOImmVal field.
1108 assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 &&
1109 "Bit extraction didn't work?");
1110 MI.getOperand(i+1).ChangeToImmediate(ThisImmVal);
1111 } else {
1112 unsigned ImmIdx = 0;
1113 int InstrOffs = 0;
1114 unsigned NumBits = 0;
1115 unsigned Scale = 1;
1116 bool encodedOffset = true;
1117 bool HandlesNeg = true;
1118 switch (AddrMode) {
1119 case ARMII::AddrMode2: {
1120 ImmIdx = i+2;
1121 InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm());
1122 if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1123 InstrOffs *= -1;
1124 NumBits = 12;
1125 break;
1126 }
1127 case ARMII::AddrMode3: {
1128 ImmIdx = i+2;
1129 InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm());
1130 if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1131 InstrOffs *= -1;
1132 NumBits = 8;
1133 break;
1134 }
1135 case ARMII::AddrMode5: {
1136 ImmIdx = i+1;
1137 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
1138 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1139 InstrOffs *= -1;
1140 NumBits = 8;
1141 Scale = 4;
1142 break;
1143 }
1144 case ARMII::AddrModeT2_i12: {
1145 ImmIdx = i+1;
1146 InstrOffs = MI.getOperand(ImmIdx).getImm();
1147 NumBits = 12;
1148 encodedOffset = false;
1149 HandlesNeg = false;
1150 break;
1151 }
1152 case ARMII::AddrModeT2_i8: {
1153 ImmIdx = i+1;
1154 InstrOffs = MI.getOperand(ImmIdx).getImm();
1155 NumBits = 8;
1156 encodedOffset = false;
1157 break;
1158 }
1159 case ARMII::AddrModeT2_so: {
1160 ImmIdx = i+2;
1161 InstrOffs = MI.getOperand(ImmIdx).getImm();
1162 encodedOffset = false;
1163 break;
1164 }
1165 default:
1166 llvm_unreachable("Unsupported addressing mode!");
1167 break;
1168 }
1169
1170 Offset += InstrOffs * Scale;
1171 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
1172 if (Offset < 0) {
1173 // For addrmodes that cannot handle negative offsets, convert to
1174 // an opcode that can, or set NumBits == 0 to avoid folding
1175 // address computation
1176 if (!HandlesNeg) {
1177 unsigned usop = unsignedOffsetOpcodeToSigned(Opcode, &NumBits);
1178 if (usop != 0) {
1179 MI.setDesc(TII.get(usop));
1180 HandlesNeg = true;
1181 Opcode = usop;
1182 }
1183 else {
1184 NumBits = 0;
1185 }
1186 }
1187
1188 Offset = -Offset;
1189 isSub = true;
1190 }
1191
1192 // Attempt to fold address comp. if opcode has offset bits
1193 if (NumBits > 0) {
1194 // Common case: small offset, fits into instruction.
1195 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
1196 int ImmedOffset = Offset / Scale;
1197 unsigned Mask = (1 << NumBits) - 1;
1198 if ((unsigned)Offset <= Mask * Scale) {
1199 // Replace the FrameIndex with sp
1200 MI.getOperand(i).ChangeToRegister(FrameReg, false);
1201 if (isSub) {
1202 if (encodedOffset)
1203 ImmedOffset |= 1 << NumBits;
1204 else
1205 ImmedOffset = -ImmedOffset;
1206 }
1207 ImmOp.ChangeToImmediate(ImmedOffset);
1208 return;
1209 }
1210
1211 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
1212 ImmedOffset = ImmedOffset & Mask;
1213 if (isSub) {
1214 if (encodedOffset)
1215 ImmedOffset |= 1 << NumBits;
1216 else
1217 ImmedOffset = -ImmedOffset;
1218 }
1219 ImmOp.ChangeToImmediate(ImmedOffset);
1220 Offset &= ~(Mask*Scale);
1221 }
1222 }
1179 // modify MI as necessary to handle as much of 'Offset' as possible
1180 Offset = rewriteFrameIndex(MI, i, FrameReg, Offset);
1181 if (Offset == 0)
1182 return;
12231183
12241184 // If we get here, the immediate doesn't fit into the instruction. We folded
12251185 // as much as possible above, handle the rest, providing a register that is
12391199 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
12401200 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
12411201 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
1242 isSub ? -Offset : Offset, Pred, PredReg, TII, dl);
1202 Offset, Pred, PredReg, TII, dl);
12431203 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
12441204 }
12451205
12481208 /// 3: fp area, 0: don't care).
12491209 static void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
12501210 MachineBasicBlock::iterator &MBBI,
1251 int Opc, unsigned Area,
1211 int Opc1, int Opc2, unsigned Area,
12521212 const ARMSubtarget &STI) {
12531213 while (MBBI != MBB.end() &&
1254 MBBI->getOpcode() == Opc && MBBI->getOperand(1).isFI()) {
1214 ((MBBI->getOpcode() == Opc1) || (MBBI->getOpcode() == Opc2)) &&
1215 MBBI->getOperand(1).isFI()) {
12551216 if (Area != 0) {
12561217 bool Done = false;
12571218 unsigned Category = 0;
13411302
13421303 // Build the new SUBri to adjust SP for integer callee-save spill area 1.
13431304 emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS1Size);
1344 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::STR), 1, STI);
1305 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::STRrr),
1306 getOpcode(ARMII::STRri), 1, STI);
13451307
13461308 // Darwin ABI requires FP to point to the stack slot that contains the
13471309 // previous FP.
13561318 emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS2Size);
13571319
13581320 // Build the new SUBri to adjust SP for FP callee-save spill area.
1359 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::STR), 2, STI);
1321 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::STRrr),
1322 getOpcode(ARMII::STRri), 2, STI);
13601323 emitSPUpdate(MBB, MBBI, TII, dl, -DPRCSSize);
13611324
13621325 // Determine starting offsets of spill areas.
13711334 NumBytes = DPRCSOffset;
13721335 if (NumBytes) {
13731336 // Insert it after all the callee-save spills.
1374 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::FSTD), 3, STI);
1337 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::FSTD), 0, 3, STI);
13751338 emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes);
13761339 }
13771340
13961359 const ARMBaseInstrInfo &TII,
13971360 const unsigned *CSRegs) {
13981361 return ((MI->getOpcode() == (int)TII.getOpcode(ARMII::FLDD) ||
1399 MI->getOpcode() == (int)TII.getOpcode(ARMII::LDR)) &&
1362 MI->getOpcode() == (int)TII.getOpcode(ARMII::LDRrr) ||
1363 MI->getOpcode() == (int)TII.getOpcode(ARMII::LDRri)) &&
14001364 MI->getOperand(1).isFI() &&
14011365 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
14021366 }
14571421 }
14581422
14591423 // Move SP to start of integer callee save spill area 2.
1460 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::FLDD), 3, STI);
1424 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::FLDD), 0, 3, STI);
14611425 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getDPRCalleeSavedAreaSize());
14621426
14631427 // Move SP to start of integer callee save spill area 1.
1464 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::LDR), 2, STI);
1428 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::LDRrr),
1429 getOpcode(ARMII::LDRri), 2, STI);
14651430 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea2Size());
14661431
14671432 // Move SP to SP upon entry to the function.
1468 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::LDR), 1, STI);
1433 movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::LDRrr),
1434 getOpcode(ARMII::LDRri), 1, STI);
14691435 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea1Size());
14701436 }
14711437
5757
5858 // Return the opcode that implements 'Op', or 0 if no opcode
5959 unsigned getOpcode(int Op) const;
60
61 // If 'opcode' is an instruction with an unsigned offset that also
62 // has a version with a signed offset, return the opcode for the
63 // version with the signed offset. In 'NumBits' return the number of
64 // bits for the signed offset.
65 unsigned unsignedOffsetOpcodeToSigned(unsigned opcode,
66 unsigned *NumBits) const;
6760
6861 public:
6962 /// getRegisterNumbering - Given the enum value for some register, e.g.
132125 MachineBasicBlock &MBB,
133126 MachineBasicBlock::iterator I) const;
134127
128 // rewrite MI to access 'Offset' bytes from the FP. Return the offset that
129 // could not be handled directly in MI.
130 virtual int rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
131 unsigned FrameReg, int Offset) const;
135132 virtual void eliminateFrameIndex(MachineBasicBlock::iterator II,
136133 int SPAdj, RegScavenger *RS = NULL) const;
137134
627627 if (N.getOpcode() == ISD::SUB)
628628 RHSC = -RHSC;
629629
630 if ((RHSC >= -255) && (RHSC <= 255)) { // sign + 8 bits.
630 if ((RHSC >= -255) && (RHSC <= 0)) { // 8 bits (always negative)
631631 Base = N.getOperand(0);
632632 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
633633 return true;
2626
2727 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
2828 : ARMBaseInstrInfo(STI), RI(*this, STI) {
29 }
30
31 unsigned ARMInstrInfo::
32 unsignedOffsetOpcodeToSigned(unsigned opcode, unsigned *NumBits) const {
33 return 0;
3429 }
3530
3631 unsigned ARMInstrInfo::
8479 case ARMII::FLDS: return ARM::FLDS;
8580 case ARMII::FSTD: return ARM::FSTD;
8681 case ARMII::FSTS: return ARM::FSTS;
87 case ARMII::LDR: return ARM::LDR;
82 case ARMII::LDRrr: return ARM::LDR;
83 case ARMII::LDRri: return 0;
8884 case ARMII::MOVr: return ARM::MOVr;
89 case ARMII::STR: return ARM::STR;
85 case ARMII::STRrr: return ARM::STR;
86 case ARMII::STRri: return 0;
9087 case ARMII::SUBri: return ARM::SUBri;
9188 case ARMII::SUBrs: return ARM::SUBrs;
9289 case ARMII::SUBrr: return ARM::SUBrr;
3434 // Return the opcode that implements 'Op', or 0 if no opcode
3535 unsigned getOpcode(ARMII::Op Op) const;
3636
37 // If 'opcode' is an instruction with an unsigned offset that also
38 // has a version with a signed offset, return the opcode for the
39 // version with the signed offset. In 'NumBits' return the number of
40 // bits for the signed offset.
41 unsigned unsignedOffsetOpcodeToSigned(unsigned opcode,
42 unsigned *NumBits) const;
43
4437 // Return true if the block does not fall through.
4538 bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
4639
108108 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
109109 }
110110
111 // t2addrmode_imm8 := reg +/- imm8
111 // t2addrmode_imm8 := reg - imm8
112112 def t2addrmode_imm8 : Operand,
113113 ComplexPattern {
114114 let PrintMethod = "printT2AddrModeImm8Operand";
2626 }
2727
2828 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
29 return 0;
30 }
31
32 unsigned
33 Thumb1InstrInfo::unsignedOffsetOpcodeToSigned(unsigned opcode,
34 unsigned *NumBits) const {
3529 return 0;
3630 }
3731
5246 case ARMII::FLDS: return 0;
5347 case ARMII::FSTD: return 0;
5448 case ARMII::FSTS: return 0;
55 case ARMII::LDR: return ARM::tLDR;
49 case ARMII::LDRrr: return ARM::tLDR;
50 case ARMII::LDRri: return 0;
5651 case ARMII::MOVr: return ARM::tMOVr;
57 case ARMII::STR: return ARM::tSTR;
52 case ARMII::STRrr: return ARM::tSTR;
53 case ARMII::STRri: return 0;
5854 case ARMII::SUBri: return ARM::tSUBi8;
5955 case ARMII::SUBrs: return 0;
6056 case ARMII::SUBrr: return ARM::tSUBrr;
3232
3333 // Return the opcode that implements 'Op', or 0 if no opcode
3434 unsigned getOpcode(ARMII::Op Op) const;
35
36 // If 'opcode' is an instruction with an unsigned offset that also
37 // has a version with a signed offset, return the opcode for the
38 // version with the signed offset. In 'NumBits' return the number of
39 // bits for the signed offset.
40 unsigned unsignedOffsetOpcodeToSigned(unsigned opcode,
41 unsigned *NumBits) const;
4235
4336 // Return true if the block does not fall through.
4437 bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
384384 unsigned Op = i;
385385 for (unsigned e = MI.getNumOperands(); i != e; ++i)
386386 MI.RemoveOperand(Op);
387 }
388
389 int Thumb1RegisterInfo::
390 rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
391 unsigned FrameReg, int Offset) const
392 {
393 // if/when eliminateFrameIndex() conforms with ARMBaseRegisterInfo
394 // version then can pull out Thumb1 specific parts here
395 return 0;
387396 }
388397
389398 void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
4747 MachineBasicBlock &MBB,
4848 MachineBasicBlock::iterator I) const;
4949
50 // rewrite MI to access 'Offset' bytes from the FP. Return the offset that
51 // could not be handled directly in MI.
52 int rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
53 unsigned FrameReg, int Offset) const;
5054 void eliminateFrameIndex(MachineBasicBlock::iterator II,
5155 int SPAdj, RegScavenger *RS = NULL) const;
5256
4747 case ARMII::FLDS: return ARM::FLDS;
4848 case ARMII::FSTD: return ARM::FSTD;
4949 case ARMII::FSTS: return ARM::FSTS;
50 case ARMII::LDR: return ARM::LDR; // FIXME
50 case ARMII::LDRrr: return ARM::t2LDRs;
51 case ARMII::LDRri: return ARM::t2LDRi12;
5152 case ARMII::MOVr: return ARM::t2MOVr;
52 case ARMII::STR: return ARM::STR; // FIXME
53 case ARMII::STRrr: return ARM::t2STRs;
54 case ARMII::STRri: return ARM::t2STRi12;
5355 case ARMII::SUBri: return ARM::t2SUBri;
5456 case ARMII::SUBrs: return ARM::t2SUBrs;
5557 case ARMII::SUBrr: return ARM::t2SUBrr;
8789 return false;
8890 }
8991
90 unsigned
91 Thumb2InstrInfo::unsignedOffsetOpcodeToSigned(unsigned opcode,
92 unsigned *NumBits) const
93 {
94 if (NumBits != NULL)
95 *NumBits = 8;
96
97 switch (opcode) {
98 case ARM::t2LDRi12: return ARM::t2LDRi8;
99 case ARM::t2LDRHi12: return ARM::t2LDRHi8;
100 case ARM::t2LDRBi12: return ARM::t2LDRBi8;
101 case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
102 case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
103 case ARM::t2STRi12: return ARM::t2STRi8;
104 case ARM::t2STRBi12: return ARM::t2STRBi8;
105 case ARM::t2STRHi12: return ARM::t2STRHi8;
106 default:
107 break;
108 }
109
110 return 0;
111 }
112
11392 bool
11493 Thumb2InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
11594 MachineBasicBlock::iterator I,
3333 // Return the opcode that implements 'Op', or 0 if no opcode
3434 unsigned getOpcode(ARMII::Op Op) const;
3535
36 // If 'opcode' is an instruction with an unsigned offset that also
37 // has a version with a signed offset, return the opcode for the
38 // version with the signed offset. In 'NumBits' return the number of
39 // bits for the signed offset.
40 unsigned unsignedOffsetOpcodeToSigned(unsigned opcode,
41 unsigned *NumBits) const;
42
4336 // Return true if the block does not fall through.
4437 bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
4538
6060 .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0);
6161 }
6262
63 static unsigned
64 negativeOffsetOpcode(unsigned opcode)
65 {
66 switch (opcode) {
67 case ARM::t2LDRi12: return ARM::t2LDRi8;
68 case ARM::t2LDRHi12: return ARM::t2LDRHi8;
69 case ARM::t2LDRBi12: return ARM::t2LDRBi8;
70 case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
71 case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
72 case ARM::t2STRi12: return ARM::t2STRi8;
73 case ARM::t2STRBi12: return ARM::t2STRBi8;
74 case ARM::t2STRHi12: return ARM::t2STRHi8;
75
76 case ARM::t2LDRi8:
77 case ARM::t2LDRHi8:
78 case ARM::t2LDRBi8:
79 case ARM::t2LDRSHi8:
80 case ARM::t2LDRSBi8:
81 case ARM::t2STRi8:
82 case ARM::t2STRBi8:
83 case ARM::t2STRHi8:
84 return opcode;
85
86 default:
87 break;
88 }
89
90 return 0;
91 }
92
93 static unsigned
94 positiveOffsetOpcode(unsigned opcode)
95 {
96 switch (opcode) {
97 case ARM::t2LDRi8: return ARM::t2LDRi12;
98 case ARM::t2LDRHi8: return ARM::t2LDRHi12;
99 case ARM::t2LDRBi8: return ARM::t2LDRBi12;
100 case ARM::t2LDRSHi8: return ARM::t2LDRSHi12;
101 case ARM::t2LDRSBi8: return ARM::t2LDRSBi12;
102 case ARM::t2STRi8: return ARM::t2STRi12;
103 case ARM::t2STRBi8: return ARM::t2STRBi12;
104 case ARM::t2STRHi8: return ARM::t2STRHi12;
105
106 case ARM::t2LDRi12:
107 case ARM::t2LDRHi12:
108 case ARM::t2LDRBi12:
109 case ARM::t2LDRSHi12:
110 case ARM::t2LDRSBi12:
111 case ARM::t2STRi12:
112 case ARM::t2STRBi12:
113 case ARM::t2STRHi12:
114 return opcode;
115
116 default:
117 break;
118 }
119
120 return 0;
121 }
122
123 static unsigned
124 immediateOffsetOpcode(unsigned opcode)
125 {
126 switch (opcode) {
127 case ARM::t2LDRs: return ARM::t2LDRi12;
128 case ARM::t2LDRHs: return ARM::t2LDRHi12;
129 case ARM::t2LDRBs: return ARM::t2LDRBi12;
130 case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
131 case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
132 case ARM::t2STRs: return ARM::t2STRi12;
133 case ARM::t2STRBs: return ARM::t2STRBi12;
134 case ARM::t2STRHs: return ARM::t2STRHi12;
135
136 case ARM::t2LDRi12:
137 case ARM::t2LDRHi12:
138 case ARM::t2LDRBi12:
139 case ARM::t2LDRSHi12:
140 case ARM::t2LDRSBi12:
141 case ARM::t2STRi12:
142 case ARM::t2STRBi12:
143 case ARM::t2STRHi12:
144 case ARM::t2LDRi8:
145 case ARM::t2LDRHi8:
146 case ARM::t2LDRBi8:
147 case ARM::t2LDRSHi8:
148 case ARM::t2LDRSBi8:
149 case ARM::t2STRi8:
150 case ARM::t2STRBi8:
151 case ARM::t2STRHi8:
152 return opcode;
153
154 default:
155 break;
156 }
157
158 return 0;
159 }
160
63161 bool Thumb2RegisterInfo::
64162 requiresRegisterScavenging(const MachineFunction &MF) const {
65163 // FIXME
66164 return false;
67165 }
166
167 int Thumb2RegisterInfo::
168 rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
169 unsigned FrameReg, int Offset) const
170 {
171 unsigned Opcode = MI.getOpcode();
172 const TargetInstrDesc &Desc = MI.getDesc();
173 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
174 bool isSub = false;
175
176 // Memory operands in inline assembly always use AddrModeT2_i12
177 if (Opcode == ARM::INLINEASM)
178 AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
179
180 if (Opcode == getOpcode(ARMII::ADDri)) {
181 Offset += MI.getOperand(FrameRegIdx+1).getImm();
182 if (Offset == 0) {
183 // Turn it into a move.
184 MI.setDesc(TII.get(getOpcode(ARMII::MOVr)));
185 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
186 MI.RemoveOperand(FrameRegIdx+1);
187 return 0;
188 } else if (Offset < 0) {
189 Offset = -Offset;
190 isSub = true;
191 MI.setDesc(TII.get(getOpcode(ARMII::SUBri)));
192 }
193
194 // Common case: small offset, fits into instruction.
195 if (ARM_AM::getT2SOImmVal(Offset) != -1) {
196 // Replace the FrameIndex with sp / fp
197 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
198 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
199 return 0;
200 }
201
202 // Otherwise, extract 8 adjacent bits from the immediate into this
203 // t2ADDri/t2SUBri.
204 unsigned RotAmt = CountLeadingZeros_32(Offset);
205 if (RotAmt > 24)
206 RotAmt = 24;
207 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
208
209 // We will handle these bits from offset, clear them.
210 Offset &= ~ThisImmVal;
211
212 assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
213 "Bit extraction didn't work?");
214 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
215 } else {
216 // AddrModeT2_so cannot handle any offset. If there is no offset
217 // register then we change to an immediate version.
218 if (AddrMode == ARMII::AddrModeT2_so) {
219 unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
220 if (OffsetReg != 0) {
221 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
222 return Offset;
223 }
224
225 MI.RemoveOperand(FrameRegIdx+1);
226 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
227 Opcode = immediateOffsetOpcode(Opcode);
228 AddrMode = ARMII::AddrModeT2_i12;
229 }
230
231 // Neon and FP address modes are handled by the base ARM version...
232 if ((AddrMode != ARMII::AddrModeT2_i8) &&
233 (AddrMode != ARMII::AddrModeT2_i12)) {
234 return ARMBaseRegisterInfo::rewriteFrameIndex(MI, FrameRegIdx,
235 FrameReg, Offset);
236 }
237
238 unsigned NumBits = 0;
239 Offset += MI.getOperand(FrameRegIdx+1).getImm();
240
241 // i8 supports only negative, and i12 supports only positive, so
242 // based on Offset sign convert Opcode to the appropriate
243 // instruction
244 if (Offset < 0) {
245 Opcode = negativeOffsetOpcode(Opcode);
246 NumBits = 8;
247 isSub = true;
248 Offset = -Offset;
249 }
250 else {
251 Opcode = positiveOffsetOpcode(Opcode);
252 NumBits = 12;
253 }
254
255 if (Opcode) {
256 MI.setDesc(TII.get(Opcode));
257 MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
258
259 // Attempt to fold address computation
260 // Common case: small offset, fits into instruction.
261 unsigned Mask = (1 << NumBits) - 1;
262 if ((unsigned)Offset <= Mask) {
263 // Replace the FrameIndex with fp/sp
264 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
265 ImmOp.ChangeToImmediate((isSub) ? -Offset : Offset);
266 return 0;
267 }
268
269 // Otherwise, offset doesn't fit. Pull in what we can to simplify
270 unsigned ImmedOffset = Offset & Mask;
271 ImmOp.ChangeToImmediate((isSub) ? -ImmedOffset : ImmedOffset);
272 Offset &= ~Mask;
273 }
274 }
275
276 return (isSub) ? -Offset : Offset;
277 }
2626 public:
2727 Thumb2RegisterInfo(const ARMBaseInstrInfo &tii, const ARMSubtarget &STI);
2828
29 // rewrite MI to access 'Offset' bytes from the FP. Return the offset that
30 // could not be handled directly in MI.
31 int rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
32 unsigned FrameReg, int Offset) const;
33
2934 /// emitLoadConstPool - Emits a load from constpool to materialize the
3035 /// specified immediate.
31 void emitLoadConstPool(MachineBasicBlock &MBB,
32 MachineBasicBlock::iterator &MBBI,
33 DebugLoc dl,
34 unsigned DestReg, unsigned SubIdx, int Val,
35 ARMCC::CondCodes Pred = ARMCC::AL,
36 unsigned PredReg = 0) const;
36 void emitLoadConstPool(MachineBasicBlock &MBB,
37 MachineBasicBlock::iterator &MBBI,
38 DebugLoc dl,
39 unsigned DestReg, unsigned SubIdx, int Val,
40 ARMCC::CondCodes Pred = ARMCC::AL,
41 unsigned PredReg = 0) const;
3742
3843 bool requiresRegisterScavenging(const MachineFunction &MF) const;
3944 };