@@ -5219,6 +5219,141 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
5219
5219
// We limit the max depth to track incoming values of PHIs or binary ops
5220
5220
// (e.g. AND) to avoid excessive cost.
5221
5221
const unsigned MAX_BINOP_DEPTH = 1 ;
5222
+
5223
+ void PPCInstrInfo::replaceInstrAfterElimExt32To64 (const Register &Reg,
5224
+ MachineRegisterInfo *MRI,
5225
+ unsigned BinOpDepth,
5226
+ LiveVariables *LV) const {
5227
+ if (MRI->getRegClass (Reg) == &PPC::G8RCRegClass)
5228
+ return ;
5229
+
5230
+ MachineInstr *MI = MRI->getVRegDef (Reg);
5231
+ if (!MI)
5232
+ return ;
5233
+
5234
+ unsigned Opcode = MI->getOpcode ();
5235
+ bool IsRelplaceIntr = false ;
5236
+ switch (Opcode) {
5237
+ case PPC::OR:
5238
+ case PPC::OR8:
5239
+ case PPC::PHI:
5240
+ case PPC::ISEL:
5241
+ if (BinOpDepth < MAX_BINOP_DEPTH) {
5242
+ if (Opcode == PPC::OR)
5243
+ IsRelplaceIntr = true ;
5244
+ unsigned OperandEnd = 3 , OperandStride = 1 ;
5245
+ if (MI->getOpcode () == PPC::PHI) {
5246
+ OperandEnd = MI->getNumOperands ();
5247
+ OperandStride = 2 ;
5248
+ }
5249
+
5250
+ for (unsigned I = 1 ; I != OperandEnd; I += OperandStride) {
5251
+ assert (MI->getOperand (I).isReg () && " Operand must be register" );
5252
+ Register SrcReg = MI->getOperand (I).getReg ();
5253
+ replaceInstrAfterElimExt32To64 (SrcReg, MRI, BinOpDepth + 1 , LV);
5254
+ }
5255
+ }
5256
+ break ;
5257
+ // case PPC::COPY:
5258
+ case PPC::ORI:
5259
+ case PPC::XORI:
5260
+ case PPC::ORI8:
5261
+ case PPC::XORI8:
5262
+ case PPC::ORIS:
5263
+ case PPC::XORIS:
5264
+ case PPC::ORIS8:
5265
+ case PPC::XORIS8: {
5266
+ if (Opcode == PPC::ORI || Opcode == PPC::XORI || Opcode == PPC::ORIS ||
5267
+ Opcode == PPC::ORIS || Opcode == PPC::XORIS)
5268
+ IsRelplaceIntr = true ;
5269
+ Register SrcReg = MI->getOperand (1 ).getReg ();
5270
+ replaceInstrAfterElimExt32To64 (SrcReg, MRI, BinOpDepth, LV);
5271
+ break ;
5272
+ }
5273
+ case PPC::AND:
5274
+ case PPC::AND8: {
5275
+ if (BinOpDepth < MAX_BINOP_DEPTH) {
5276
+ if (Opcode == PPC::AND)
5277
+ IsRelplaceIntr = true ;
5278
+ Register SrcReg1 = MI->getOperand (1 ).getReg ();
5279
+ replaceInstrAfterElimExt32To64 (SrcReg1, MRI, BinOpDepth, LV);
5280
+ Register SrcReg2 = MI->getOperand (2 ).getReg ();
5281
+ replaceInstrAfterElimExt32To64 (SrcReg2, MRI, BinOpDepth, LV);
5282
+ }
5283
+ break ;
5284
+ }
5285
+ default :
5286
+ break ;
5287
+ }
5288
+
5289
+ const PPCInstrInfo *TII =
5290
+ MI->getMF ()->getSubtarget <PPCSubtarget>().getInstrInfo ();
5291
+ if ((TII->isSExt32To64 (Opcode) && !TII->isZExt32To64 (Opcode)) ||
5292
+ IsRelplaceIntr) {
5293
+ DebugLoc DL = MI->getDebugLoc ();
5294
+ auto MBB = MI->getParent ();
5295
+
5296
+ // If the oprand of the instruction is Register which isPPC::GRCRegClass, we
5297
+ // need to promot the Oprande to PPC::G8RCRegClass.
5298
+ DenseMap<unsigned , Register> PromoteRegs;
5299
+ for (unsigned i = 1 ; i < MI->getNumOperands (); i++) {
5300
+ MachineOperand &Oprand = MI->getOperand (i);
5301
+ if (Oprand.isReg ()) {
5302
+ Register OprandReg = Oprand.getReg ();
5303
+ if (!OprandReg.isVirtual ())
5304
+ continue ;
5305
+ if (MRI->getRegClass (OprandReg) == &PPC::GPRCRegClass) {
5306
+ Register TmpReg = MRI->createVirtualRegister (&PPC::G8RCRegClass);
5307
+ Register DstTmpReg = MRI->createVirtualRegister (&PPC::G8RCRegClass);
5308
+
5309
+ BuildMI (*MBB, MI, DL, TII->get (PPC::IMPLICIT_DEF), TmpReg);
5310
+ BuildMI (*MBB, MI, DL, TII->get (PPC::INSERT_SUBREG), DstTmpReg)
5311
+ .addReg (TmpReg)
5312
+ .addReg (OprandReg)
5313
+ .addImm (PPC::sub_32);
5314
+ PromoteRegs[i] = DstTmpReg;
5315
+ } else {
5316
+ PromoteRegs[i] = OprandReg;
5317
+ }
5318
+ }
5319
+ }
5320
+
5321
+ Register NewReg = MRI->createVirtualRegister (&PPC::G8RCRegClass);
5322
+ Register SrcReg = MI->getOperand (0 ).getReg ();
5323
+
5324
+ // Most of the opcode of 64-bit instruction equal to the opcode of 32-bit
5325
+ // version of same instruction plus one. But there are some exception:
5326
+ // PPC::ANDC_rec, PPC::ANDI_rec, PPC::ANDIS_rec.
5327
+ unsigned NewOpcode = Opcode + 1 ;
5328
+
5329
+ if (Opcode == PPC::ANDC_rec)
5330
+ NewOpcode = PPC::ANDC8_rec;
5331
+ if (Opcode == PPC::ANDI_rec)
5332
+ NewOpcode = PPC::ANDI8_rec;
5333
+ if (Opcode == PPC::ANDIS_rec)
5334
+ NewOpcode = PPC::ANDIS8_rec;
5335
+
5336
+ BuildMI (*MBB, MI, DL, TII->get (NewOpcode), NewReg);
5337
+ MachineBasicBlock::instr_iterator Iter (MI);
5338
+ --Iter;
5339
+ for (unsigned i = 1 ; i < MI->getNumOperands (); i++)
5340
+ if (PromoteRegs.find (i) != PromoteRegs.end ())
5341
+ MachineInstrBuilder (*Iter->getMF (), Iter)
5342
+ .addReg (PromoteRegs[i], RegState::Kill);
5343
+ else
5344
+ Iter->addOperand (MI->getOperand (i));
5345
+
5346
+ for (auto Iter = PromoteRegs.begin (); Iter != PromoteRegs.end (); Iter++)
5347
+ LV->recomputeForSingleDefVirtReg (Iter->second );
5348
+ MI->eraseFromParent ();
5349
+ BuildMI (*MBB, ++Iter, DL, TII->get (PPC::COPY), SrcReg)
5350
+ .addReg (NewReg, RegState::Kill, PPC::sub_32);
5351
+ LV->recomputeForSingleDefVirtReg (NewReg);
5352
+ return ;
5353
+ }
5354
+ return ;
5355
+ }
5356
+
5222
5357
// The isSignOrZeroExtended function is recursive. The parameter BinOpDepth
5223
5358
// does not count all of the recursions. The parameter BinOpDepth is incremented
5224
5359
// only when isSignOrZeroExtended calls itself more than once. This is done to
0 commit comments