コード例 #1
0
ファイル: AVRISelLowering.cpp プロジェクト: saaadhu/AVR
SDValue AVRTargetLowering::LowerShifts(SDValue Op,
                                          SelectionDAG &DAG) const {
  unsigned Opc = Op.getOpcode();
  SDNode* N = Op.getNode();
  EVT VT = Op.getValueType();
  DebugLoc dl = N->getDebugLoc();

  // Expand non-constant shifts to loops:
  if (!isa<ConstantSDNode>(N->getOperand(1)))
    switch (Opc) {
    default:
      assert(0 && "Invalid shift opcode!");
    case ISD::SHL:
      return DAG.getNode(AVRISD::SHL, dl,
                         VT, N->getOperand(0), N->getOperand(1));
    case ISD::SRA:
      return DAG.getNode(AVRISD::SRA, dl,
                         VT, N->getOperand(0), N->getOperand(1));
    case ISD::SRL:
      return DAG.getNode(AVRISD::SRL, dl,
                         VT, N->getOperand(0), N->getOperand(1));
    }

  uint64_t ShiftAmount = N->getConstantOperandVal(1);

  // Expand the stuff into sequence of shifts.
  // FIXME: for some shift amounts this might be done better!
  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
  SDValue Victim = N->getOperand(0);

  unsigned int TargetOpcode = 0;
  switch(Opc) {
    case ISD::SHL: TargetOpcode = AVRISD::SHLC; break;
    case ISD::SRA: TargetOpcode = AVRISD::SRAC; break;
    case ISD::SRL: TargetOpcode = AVRISD::SRLC; break;
  }

  while (ShiftAmount--)
    Victim = DAG.getNode(TargetOpcode, dl, VT, Victim);

  return Victim;
}