@@ -245,6 +245,41 @@ INST_LIST_ITER InstSplitPass::splitInstruction(INST_LIST_ITER it,
245
245
}
246
246
}
247
247
248
+ // Special handling for vISA ADDC (SUBB) instruction,
249
+ // which is translated to addc (subb)/mov acc pair
250
+ // and should be splitted together.
251
+ G4_INST *carryMovInst = nullptr ;
252
+ G4_Predicate* newCarryMovPred = NULL ;
253
+ G4_CondMod* newCarryMovCondMod = NULL ;
254
+ INST_LIST_ITER nextIter = std::next (it);
255
+ if (inst->opcode () == G4_addc || inst->opcode () == G4_subb) {
256
+ G4_INST *nextInst = *nextIter;
257
+ if (nextInst->opcode () == G4_mov && nextInst->isAccSrcInst () &&
258
+ nextInst->getExecSize () == inst->getExecSize ()) {
259
+ carryMovInst = nextInst;
260
+
261
+ if (carryMovInst->getPredicate ()) {
262
+ newCarryMovPred = carryMovInst->getPredicate ();
263
+ newCarryMovPred->splitPred ();
264
+ }
265
+
266
+ if (carryMovInst->getCondMod ()) {
267
+ newCarryMovCondMod = carryMovInst->getCondMod ();
268
+ newCarryMovCondMod->splitCondMod ();
269
+ }
270
+ }
271
+ }
272
+
273
+ G4_SrcRegRegion* accSrcRegion = NULL ;
274
+ if (inst->getImplAccSrc ()) {
275
+ accSrcRegion = inst->getImplAccSrc ()->asSrcRegRegion ();
276
+ }
277
+
278
+ G4_DstRegRegion* accDstRegion = NULL ;
279
+ if (inst->getImplAccDst ()) {
280
+ accDstRegion = inst->getImplAccDst ();
281
+ }
282
+
248
283
// Create new predicate
249
284
G4_Predicate *newPred = NULL ;
250
285
if (inst->getPredicate ()) {
@@ -319,12 +354,47 @@ INST_LIST_ITER InstSplitPass::splitInstruction(INST_LIST_ITER it,
319
354
newInst->setMaskOption (newMask);
320
355
}
321
356
322
- // Call recursive splitting function
323
- newInstIterator = splitInstruction (newInstIterator, instList);
357
+ if (accDstRegion)
358
+ newInst->setImplAccDst (m_builder->duplicateOperand (accDstRegion));
359
+
360
+ if (accSrcRegion)
361
+ newInst->setImplAccSrc (m_builder->duplicateOperand (accSrcRegion));
362
+
363
+ if (carryMovInst) {
364
+ G4_INST* newCarryMovInst = m_builder->makeSplittingInst (carryMovInst, newExecSize);
365
+
366
+ G4_DstRegRegion* carryMovDst = carryMovInst->getDst ();
367
+ G4_DstRegRegion* newCarryMovDst;
368
+ if (carryMovDst && !carryMovInst->hasNULLDst ()) {
369
+ newCarryMovDst = m_builder->createSubDstOperand (carryMovDst, (uint16_t )i, newExecSize);
370
+ }
371
+ else {
372
+ newCarryMovDst = newCarryMovDst;
373
+ }
374
+
375
+ newCarryMovInst->setDest (newCarryMovDst);
376
+ newCarryMovInst->setPredicate (m_builder->duplicateOperand (newCarryMovPred));
377
+ newCarryMovInst->setCondMod (m_builder->duplicateOperand (newCarryMovCondMod));
378
+ newCarryMovInst->setSrc (m_builder->duplicateOperand (carryMovInst->getSrc (0 )), 0 );
379
+ auto prevInstIterator = newInstIterator;
380
+ newInstIterator = instList.insert (it, newCarryMovInst);
381
+
382
+ // Call recursive splitting function
383
+ newInstIterator = splitInstruction (prevInstIterator, instList);
384
+ }
385
+ else {
386
+ // Call recursive splitting function
387
+ newInstIterator = splitInstruction (newInstIterator, instList);
388
+ }
324
389
}
325
390
326
391
// remove original instruction
327
392
instList.erase (it);
393
+
394
+ if (carryMovInst) {
395
+ instList.erase (nextIter);
396
+ }
397
+
328
398
return newInstIterator;
329
399
}
330
400
0 commit comments