@@ -546,15 +546,39 @@ bool HWConformity::fixMathInst(INST_LIST_ITER it, G4_BB* bb)
546
546
newType = src->getType ();
547
547
if (isIntDivide)
548
548
{
549
- // cases:
550
- // math.quot r10:w r20:ub -r30:ub
551
- // Make sure newType is D, not UD. The correct code is:
552
- // mov r22:d r20:ub
553
- // mov r32:d -r30:ub
554
- // math.quot r10:w r22:d r32:d
555
- bool src0Unsigned = IS_UNSIGNED_INT (inst->getSrc (0 )->getType ()) && !hasModMinus (inst->getSrc (0 ));
556
- bool src1Unsigned = IS_UNSIGNED_INT (inst->getSrc (1 )->getType ()) && !hasModMinus (inst->getSrc (1 ));
557
- G4_Type divType = (src0Unsigned && src1Unsigned) ? Type_UD : Type_D;
549
+ // case 1: Perform a signed division if there's any minus src modifier.
550
+ // math.quot r10:w r20:ub -r30:ub
551
+ // Make sure newType is D, not UD. The correct code is:
552
+ // mov r22:d r20:ub
553
+ // mov r32:d -r30:ub
554
+ // math.quot r10:w r22:d r32:d
555
+ // case 2: Perform an appropriate type conversion based on the type ranks of both sources.
556
+ // math.quot r6:ud r3:b r4:ud
557
+ // Make sure it's still an unsigned division.
558
+ // mov r11:ud r3:b
559
+ // math.quot r6:ud r11:ud r4:ud
560
+ G4_Type src0Type = inst->getSrc (0 )->getType ();
561
+ G4_Type src1Type = inst->getSrc (1 )->getType ();
562
+ G4_Type divType = Type_UNDEF;
563
+ if (hasModMinus (inst->getSrc (0 )) || hasModMinus (inst->getSrc (1 )))
564
+ {
565
+ // If there's any minus source modifier, do a signed division.
566
+ divType = Type_D;
567
+ }
568
+ else if (TypeSize (src0Type) != TypeSize (src1Type))
569
+ {
570
+ // If src0 and src1 have different ranks, get the signedness of the
571
+ // division from the higher rank src.
572
+ G4_Type higherRankType = TypeSize (src0Type) > TypeSize (src1Type) ? src0Type : src1Type;
573
+ divType = IS_SIGNED_INT (higherRankType) ? Type_D : Type_UD;
574
+ }
575
+ else
576
+ {
577
+ // If both sources have the same rank, do a signed division only
578
+ // when both are signed. Otherwise, do an unsigned division.
579
+ divType = IS_SIGNED_INT (src0Type) && IS_SIGNED_INT (src1Type) ? Type_D : Type_UD;
580
+ }
581
+ assert (divType == Type_D || divType == Type_UD);
558
582
if (newType != divType)
559
583
{
560
584
newType = divType;
0 commit comments