@@ -185,3 +185,298 @@ void XtensaInstrInfo::loadImmediate(MachineBasicBlock &MBB,
185
185
report_fatal_error (" Unsupported load immediate value" );
186
186
}
187
187
}
188
+
189
+ bool XtensaInstrInfo::reverseBranchCondition (
190
+ SmallVectorImpl<MachineOperand> &Cond) const {
191
+ assert (Cond.size () <= 4 && " Invalid branch condition!" );
192
+
193
+ switch (Cond[0 ].getImm ()) {
194
+ case Xtensa::BEQ:
195
+ Cond[0 ].setImm (Xtensa::BNE);
196
+ return false ;
197
+ case Xtensa::BNE:
198
+ Cond[0 ].setImm (Xtensa::BEQ);
199
+ return false ;
200
+ case Xtensa::BLT:
201
+ Cond[0 ].setImm (Xtensa::BGE);
202
+ return false ;
203
+ case Xtensa::BGE:
204
+ Cond[0 ].setImm (Xtensa::BLT);
205
+ return false ;
206
+ case Xtensa::BLTU:
207
+ Cond[0 ].setImm (Xtensa::BGEU);
208
+ return false ;
209
+ case Xtensa::BGEU:
210
+ Cond[0 ].setImm (Xtensa::BLTU);
211
+ return false ;
212
+ case Xtensa::BEQI:
213
+ Cond[0 ].setImm (Xtensa::BNEI);
214
+ return false ;
215
+ case Xtensa::BNEI:
216
+ Cond[0 ].setImm (Xtensa::BEQI);
217
+ return false ;
218
+ case Xtensa::BGEI:
219
+ Cond[0 ].setImm (Xtensa::BLTI);
220
+ return false ;
221
+ case Xtensa::BLTI:
222
+ Cond[0 ].setImm (Xtensa::BGEI);
223
+ return false ;
224
+ case Xtensa::BGEUI:
225
+ Cond[0 ].setImm (Xtensa::BLTUI);
226
+ return false ;
227
+ case Xtensa::BLTUI:
228
+ Cond[0 ].setImm (Xtensa::BGEUI);
229
+ return false ;
230
+ case Xtensa::BEQZ:
231
+ Cond[0 ].setImm (Xtensa::BNEZ);
232
+ return false ;
233
+ case Xtensa::BNEZ:
234
+ Cond[0 ].setImm (Xtensa::BEQZ);
235
+ return false ;
236
+ case Xtensa::BLTZ:
237
+ Cond[0 ].setImm (Xtensa::BGEZ);
238
+ return false ;
239
+ case Xtensa::BGEZ:
240
+ Cond[0 ].setImm (Xtensa::BLTZ);
241
+ return false ;
242
+ default :
243
+ report_fatal_error (" Invalid branch condition!" );
244
+ }
245
+ }
246
+
247
+ bool XtensaInstrInfo::analyzeBranch (MachineBasicBlock &MBB,
248
+ MachineBasicBlock *&TBB,
249
+ MachineBasicBlock *&FBB,
250
+ SmallVectorImpl<MachineOperand> &Cond,
251
+ bool AllowModify = false ) const {
252
+ // Most of the code and comments here are boilerplate.
253
+
254
+ // Start from the bottom of the block and work up, examining the
255
+ // terminator instructions.
256
+ MachineBasicBlock::iterator I = MBB.end ();
257
+ while (I != MBB.begin ()) {
258
+ --I;
259
+ if (I->isDebugValue ())
260
+ continue ;
261
+
262
+ // Working from the bottom, when we see a non-terminator instruction, we're
263
+ // done.
264
+ if (!isUnpredicatedTerminator (*I))
265
+ break ;
266
+
267
+ // A terminator that isn't a branch can't easily be handled by this
268
+ // analysis.
269
+ SmallVector<MachineOperand, 4 > ThisCond;
270
+ ThisCond.push_back (MachineOperand::CreateImm (0 ));
271
+ const MachineOperand *ThisTarget;
272
+ if (!isBranch (I, ThisCond, ThisTarget))
273
+ return true ;
274
+
275
+ // Can't handle indirect branches.
276
+ if (!ThisTarget->isMBB ())
277
+ return true ;
278
+
279
+ if (ThisCond[0 ].getImm () == Xtensa::J) {
280
+ // Handle unconditional branches.
281
+ if (!AllowModify) {
282
+ TBB = ThisTarget->getMBB ();
283
+ continue ;
284
+ }
285
+
286
+ // If the block has any instructions after a JMP, delete them.
287
+ while (std::next (I) != MBB.end ())
288
+ std::next (I)->eraseFromParent ();
289
+
290
+ Cond.clear ();
291
+ FBB = 0 ;
292
+
293
+ // TBB is used to indicate the unconditinal destination.
294
+ TBB = ThisTarget->getMBB ();
295
+ continue ;
296
+ }
297
+
298
+ // Working from the bottom, handle the first conditional branch.
299
+ if (Cond.empty ()) {
300
+ // FIXME: add X86-style branch swap
301
+ FBB = TBB;
302
+ TBB = ThisTarget->getMBB ();
303
+ Cond.push_back (MachineOperand::CreateImm (ThisCond[0 ].getImm ()));
304
+
305
+ // push remaining operands
306
+ for (unsigned int i = 0 ; i < (I->getNumExplicitOperands () - 1 ); i++)
307
+ Cond.push_back (I->getOperand (i));
308
+
309
+ continue ;
310
+ }
311
+
312
+ // Handle subsequent conditional branches.
313
+ assert (Cond.size () <= 4 );
314
+ assert (TBB);
315
+
316
+ // Only handle the case where all conditional branches branch to the same
317
+ // destination.
318
+ if (TBB != ThisTarget->getMBB ())
319
+ return true ;
320
+
321
+ // If the conditions are the same, we can leave them alone.
322
+ unsigned OldCond = Cond[0 ].getImm ();
323
+ if (OldCond == ThisCond[0 ].getImm ())
324
+ continue ;
325
+ }
326
+
327
+ return false ;
328
+ }
329
+
330
+ unsigned XtensaInstrInfo::removeBranch (MachineBasicBlock &MBB,
331
+ int *BytesRemoved) const {
332
+ // Most of the code and comments here are boilerplate.
333
+ MachineBasicBlock::iterator I = MBB.end ();
334
+ unsigned Count = 0 ;
335
+ if (BytesRemoved)
336
+ *BytesRemoved = 0 ;
337
+
338
+ while (I != MBB.begin ()) {
339
+ --I;
340
+ SmallVector<MachineOperand, 4 > Cond;
341
+ Cond.push_back (MachineOperand::CreateImm (0 ));
342
+ const MachineOperand *Target;
343
+ if (!isBranch (I, Cond, Target))
344
+ break ;
345
+ if (!Target->isMBB ())
346
+ break ;
347
+ // Remove the branch.
348
+ if (BytesRemoved)
349
+ *BytesRemoved += getInstSizeInBytes (*I);
350
+ I->eraseFromParent ();
351
+ I = MBB.end ();
352
+ ++Count;
353
+ }
354
+ return Count;
355
+ }
356
+
357
+ unsigned XtensaInstrInfo::insertBranch (
358
+ MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
359
+ ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
360
+ unsigned Count = 0 ;
361
+ if (BytesAdded)
362
+ *BytesAdded = 0 ;
363
+ if (FBB) {
364
+ // Need to build two branches then
365
+ // one to branch to TBB on Cond
366
+ // and a second one immediately after to unconditionally jump to FBB
367
+ Count = insertBranchAtInst (MBB, MBB.end (), TBB, Cond, DL, BytesAdded);
368
+ auto &MI = *BuildMI (&MBB, DL, get (Xtensa::J)).addMBB (FBB);
369
+ Count++;
370
+ if (BytesAdded)
371
+ *BytesAdded += getInstSizeInBytes (MI);
372
+ return Count;
373
+ }
374
+ // This function inserts the branch at the end of the MBB
375
+ Count += insertBranchAtInst (MBB, MBB.end (), TBB, Cond, DL, BytesAdded);
376
+ return Count;
377
+ }
378
+
379
+ unsigned XtensaInstrInfo::insertBranchAtInst (MachineBasicBlock &MBB,
380
+ MachineBasicBlock::iterator I,
381
+ MachineBasicBlock *TBB,
382
+ ArrayRef<MachineOperand> Cond,
383
+ const DebugLoc &DL,
384
+ int *BytesAdded) const {
385
+ // Shouldn't be a fall through.
386
+ assert (TBB && " InsertBranch must not be told to insert a fallthrough" );
387
+ assert (Cond.size () <= 4 &&
388
+ " Xtensa branch conditions have less than four components!" );
389
+
390
+ if (Cond.empty () || (Cond[0 ].getImm () == Xtensa::J)) {
391
+ // Unconditional branch
392
+ MachineInstr *MI = BuildMI (MBB, I, DL, get (Xtensa::J)).addMBB (TBB);
393
+ if (BytesAdded && MI)
394
+ *BytesAdded += getInstSizeInBytes (*MI);
395
+ return 1 ;
396
+ }
397
+
398
+ unsigned Count = 0 ;
399
+ unsigned BR_C = Cond[0 ].getImm ();
400
+ MachineInstr *MI = nullptr ;
401
+ switch (BR_C) {
402
+ case Xtensa::BEQ:
403
+ case Xtensa::BNE:
404
+ case Xtensa::BLT:
405
+ case Xtensa::BLTU:
406
+ case Xtensa::BGE:
407
+ case Xtensa::BGEU:
408
+ MI = BuildMI (MBB, I, DL, get (BR_C))
409
+ .addReg (Cond[1 ].getReg ())
410
+ .addReg (Cond[2 ].getReg ())
411
+ .addMBB (TBB);
412
+ break ;
413
+ case Xtensa::BEQI:
414
+ case Xtensa::BNEI:
415
+ case Xtensa::BLTI:
416
+ case Xtensa::BLTUI:
417
+ case Xtensa::BGEI:
418
+ case Xtensa::BGEUI:
419
+ MI = BuildMI (MBB, I, DL, get (BR_C))
420
+ .addReg (Cond[1 ].getReg ())
421
+ .addImm (Cond[2 ].getImm ())
422
+ .addMBB (TBB);
423
+ break ;
424
+ case Xtensa::BEQZ:
425
+ case Xtensa::BNEZ:
426
+ case Xtensa::BLTZ:
427
+ case Xtensa::BGEZ:
428
+ MI = BuildMI (MBB, I, DL, get (BR_C)).addReg (Cond[1 ].getReg ()).addMBB (TBB);
429
+ break ;
430
+ default :
431
+ report_fatal_error (" Invalid branch type!" );
432
+ }
433
+ if (BytesAdded && MI)
434
+ *BytesAdded += getInstSizeInBytes (*MI);
435
+ ++Count;
436
+ return Count;
437
+ }
438
+
439
+ bool XtensaInstrInfo::isBranch (const MachineBasicBlock::iterator &MI,
440
+ SmallVectorImpl<MachineOperand> &Cond,
441
+ const MachineOperand *&Target) const {
442
+ unsigned OpCode = MI->getOpcode ();
443
+ switch (OpCode) {
444
+ case Xtensa::J:
445
+ case Xtensa::JX:
446
+ case Xtensa::BR_JT:
447
+ Cond[0 ].setImm (OpCode);
448
+ Target = &MI->getOperand (0 );
449
+ return true ;
450
+ case Xtensa::BEQ:
451
+ case Xtensa::BNE:
452
+ case Xtensa::BLT:
453
+ case Xtensa::BLTU:
454
+ case Xtensa::BGE:
455
+ case Xtensa::BGEU:
456
+ Cond[0 ].setImm (OpCode);
457
+ Target = &MI->getOperand (2 );
458
+ return true ;
459
+
460
+ case Xtensa::BEQI:
461
+ case Xtensa::BNEI:
462
+ case Xtensa::BLTI:
463
+ case Xtensa::BLTUI:
464
+ case Xtensa::BGEI:
465
+ case Xtensa::BGEUI:
466
+ Cond[0 ].setImm (OpCode);
467
+ Target = &MI->getOperand (2 );
468
+ return true ;
469
+
470
+ case Xtensa::BEQZ:
471
+ case Xtensa::BNEZ:
472
+ case Xtensa::BLTZ:
473
+ case Xtensa::BGEZ:
474
+ Cond[0 ].setImm (OpCode);
475
+ Target = &MI->getOperand (1 );
476
+ return true ;
477
+
478
+ default :
479
+ assert (!MI->getDesc ().isBranch () && " Unknown branch opcode" );
480
+ return false ;
481
+ }
482
+ }
0 commit comments