# Changeset View

Changeset View

# Standalone View

Standalone View

# llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Show First 20 Lines • Show All 5409 Lines • ▼ Show 20 Line(s) | 5403 | } else { | |||
---|---|---|---|---|---|

5410 | SDValue SumNeg = DAG.getSetCC(dl, BoolVT, SumDiff, Zero, ISD::SETLT); | 5410 | SDValue SumNeg = DAG.getSetCC(dl, BoolVT, SumDiff, Zero, ISD::SETLT); | ||

5411 | Result = DAG.getSelect(dl, ResultType, SumNeg, SatMax, SatMin); | 5411 | Result = DAG.getSelect(dl, ResultType, SumNeg, SatMax, SatMin); | ||

5412 | return DAG.getSelect(dl, ResultType, Overflow, Result, SumDiff); | 5412 | return DAG.getSelect(dl, ResultType, Overflow, Result, SumDiff); | ||

5413 | } | 5413 | } | ||

5414 | } | 5414 | } | ||

5415 | 5415 | | |||

5416 | SDValue | 5416 | SDValue | ||

5417 | TargetLowering::expandFixedPointMul(SDNode *Node, SelectionDAG &DAG) const { | 5417 | TargetLowering::expandFixedPointMul(SDNode *Node, SelectionDAG &DAG) const { | ||

5418 | assert(Node->getOpcode() == ISD::SMULFIX && "Expected opcode to be SMULFIX."); | 5418 | assert((Node->getOpcode() == ISD::SMULFIX || | ||

5419 | Node->getOpcode() == ISD::UMULFIX) && | ||||

5420 | "Expected opcode to be SMULFIX or UMULFIX."); | ||||

5419 | 5421 | | |||

5420 | SDLoc dl(Node); | 5422 | SDLoc dl(Node); | ||

5421 | SDValue LHS = Node->getOperand(0); | 5423 | SDValue LHS = Node->getOperand(0); | ||

5422 | SDValue RHS = Node->getOperand(1); | 5424 | SDValue RHS = Node->getOperand(1); | ||

5423 | EVT VT = LHS.getValueType(); | 5425 | EVT VT = LHS.getValueType(); | ||

5424 | unsigned Scale = Node->getConstantOperandVal(2); | 5426 | unsigned Scale = Node->getConstantOperandVal(2); | ||

5425 | 5427 | | |||

5426 | // [us]mul.fix(a, b, 0) -> mul(a, b) | 5428 | // [us]mul.fix(a, b, 0) -> mul(a, b) | ||

5427 | if (!Scale) { | 5429 | if (!Scale) { | ||

5428 | if (VT.isVector() && !isOperationLegalOrCustom(ISD::MUL, VT)) | 5430 | if (VT.isVector() && !isOperationLegalOrCustom(ISD::MUL, VT)) | ||

5429 | return SDValue(); | 5431 | return SDValue(); | ||

5430 | return DAG.getNode(ISD::MUL, dl, VT, LHS, RHS); | 5432 | return DAG.getNode(ISD::MUL, dl, VT, LHS, RHS); | ||

5431 | } | 5433 | } | ||

5432 | 5434 | | |||

5435 | unsigned VTSize = VT.getScalarSizeInBits(); | ||||

5436 | bool Signed = Node->getOpcode() == ISD::SMULFIX; | ||||

5437 | | ||||

5438 | assert(((Signed && Scale < VTSize) || (!Signed && Scale <= VTSize)) && | ||||

5439 | "Expected scale to be less than the number of bits if signed or at " | ||||

5440 | "most the number of bits if unsigned."); | ||||

5433 | assert(LHS.getValueType() == RHS.getValueType() && | 5441 | assert(LHS.getValueType() == RHS.getValueType() && | ||

5434 | "Expected both operands to be the same type"); | 5442 | "Expected both operands to be the same type"); | ||

5435 | assert(Scale < VT.getScalarSizeInBits() && | | |||

5436 | "Expected scale to be less than the number of bits."); | | |||

5437 | 5443 | | |||

5438 | // Get the upper and lower bits of the result. | 5444 | // Get the upper and lower bits of the result. | ||

5439 | SDValue Lo, Hi; | 5445 | SDValue Lo, Hi; | ||

5440 | if (isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) { | 5446 | unsigned LoHiOp = Signed ? ISD::SMUL_LOHI : ISD::UMUL_LOHI; | ||

5441 | SDValue Result = | 5447 | unsigned HiOp = Signed ? ISD::MULHS : ISD::MULHU; | ||

5442 | DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(VT, VT), LHS, RHS); | 5448 | if (isOperationLegalOrCustom(LoHiOp, VT)) { | ||

5449 | SDValue Result = DAG.getNode(LoHiOp, dl, DAG.getVTList(VT, VT), LHS, RHS); | ||||

5443 | Lo = Result.getValue(0); | 5450 | Lo = Result.getValue(0); | ||

5444 | Hi = Result.getValue(1); | 5451 | Hi = Result.getValue(1); | ||

5445 | } else if (isOperationLegalOrCustom(ISD::MULHS, VT)) { | 5452 | } else if (isOperationLegalOrCustom(HiOp, VT)) { | ||

5446 | Lo = DAG.getNode(ISD::MUL, dl, VT, LHS, RHS); | 5453 | Lo = DAG.getNode(ISD::MUL, dl, VT, LHS, RHS); | ||

5447 | Hi = DAG.getNode(ISD::MULHS, dl, VT, LHS, RHS); | 5454 | Hi = DAG.getNode(HiOp, dl, VT, LHS, RHS); | ||

5448 | } else if (VT.isVector()) { | 5455 | } else if (VT.isVector()) { | ||

5449 | return SDValue(); | 5456 | return SDValue(); | ||

5450 | } else { | 5457 | } else { | ||

5451 | report_fatal_error("Unable to expand signed fixed point multiplication."); | 5458 | report_fatal_error("Unable to expand fixed point multiplication."); | ||

5452 | } | 5459 | } | ||

5453 | 5460 | | |||

5461 | if (Scale == VTSize) | ||||

5462 | // Result is just the top half since we'd be shifting by the width of the | ||||

5463 | // operand. | ||||

5464 | return Hi; | ||||

5465 | | ||||

5454 | // The result will need to be shifted right by the scale since both operands | 5466 | // The result will need to be shifted right by the scale since both operands | ||

5455 | // are scaled. The result is given to us in 2 halves, so we only want part of | 5467 | // are scaled. The result is given to us in 2 halves, so we only want part of | ||

5456 | // both in the result. | 5468 | // both in the result. | ||

5457 | EVT ShiftTy = getShiftAmountTy(VT, DAG.getDataLayout()); | 5469 | EVT ShiftTy = getShiftAmountTy(VT, DAG.getDataLayout()); | ||

5458 | Lo = DAG.getNode(ISD::SRL, dl, VT, Lo, DAG.getConstant(Scale, dl, ShiftTy)); | 5470 | Lo = DAG.getNode(ISD::SRL, dl, VT, Lo, DAG.getConstant(Scale, dl, ShiftTy)); | ||

5459 | Hi = DAG.getNode( | 5471 | Hi = DAG.getNode( | ||

5460 | ISD::SHL, dl, VT, Hi, | 5472 | ISD::SHL, dl, VT, Hi, | ||

5461 | DAG.getConstant(VT.getScalarSizeInBits() - Scale, dl, ShiftTy)); | 5473 | DAG.getConstant(VT.getScalarSizeInBits() - Scale, dl, ShiftTy)); | ||

5462 | return DAG.getNode(ISD::OR, dl, VT, Lo, Hi); | 5474 | return DAG.getNode(ISD::OR, dl, VT, Lo, Hi); | ||

5463 | } | 5475 | } |