void IREmitter::emitSpecialNode()

in ARM/DAG/IREmitter.cpp [651:1286]


void IREmitter::emitSpecialNode(SDNode *Node) {
  unsigned Opc = Node->getOpcode();
  Module &M = *MR->getModule();

  BasicBlock *BB = getBlock();
  BasicBlock *CurBB = getCurBlock();
  switch (Opc) {
  default:
    // assert(false && "Unknown SDNode Type!");
    break;
  case EXT_ARMISD::BX_RET: {
    Value *Ret = getIRValue(Node->getOperand(0));
    if (!ConstantSDNode::classof(Node->getOperand(0).getNode()))
      IRB.CreateRet(Ret);
    else
      IRB.CreateRetVoid();
  } break;
  // TODO:
  // Specical instruction we do here. e.g Br Invoke IndirectBr ..
  case ISD::BRCOND: {
    unsigned Cond = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
    // br i1 %cmp, label %if.then, label %if.else
    MachineBasicBlock *MBB = FuncInfo->MBBMap[CurBB];
    MachineBasicBlock::succ_iterator SuI = MBB->succ_begin();
    BasicBlock *Iftrue = FuncInfo->getOrCreateBasicBlock(*SuI);
    MachineBasicBlock *NextMBB = &*std::next(MBB->getIterator());
    BasicBlock *NextBB = FuncInfo->getOrCreateBasicBlock(NextMBB);

    emitCondCode(Cond, BB, Iftrue, NextBB);
  } break;
  case ISD::BR: {
    // br label %xxx
    MachineBasicBlock *LMBB = FuncInfo->MBBMap[CurBB];
    MachineBasicBlock::succ_iterator SuI = LMBB->succ_begin();
    if (SuI != LMBB->succ_end()) {
      BasicBlock *BrDest = FuncInfo->getOrCreateBasicBlock(*SuI);
      IRB.CreateBr(BrDest);
      break;
    }
    LLVM_FALLTHROUGH;
  }
  case EXT_ARMISD::BRD: {
    // Get the function call Index.
    uint64_t Index = Node->getConstantOperandVal(0);
    // Get function from ModuleRaiser.
    Function *CallFunc = MR->getRaisedFunctionAt(Index);
    unsigned IFFuncArgNum = 0; // The argument number which gets from analyzing
                               // variadic function prototype.
    bool IsSyscall = false;
    if (CallFunc == nullptr) {
      // According MI to get BL instruction address.
      // uint64_t callAddr = DAGInfo->NPMap[Node]->InstAddr;
      uint64_t CallAddr = MR->getTextSectionAddress() +
                          getMCInstIndex(*(DAGInfo->NPMap[Node]->MI));
      Function *IndefiniteFunc = MR->getCallFunc(CallAddr);
      CallFunc = MR->getSyscallFunc(Index);
      if (CallFunc != nullptr && IndefiniteFunc != nullptr) {
        IFFuncArgNum = MR->getFunctionArgNum(CallAddr);
        IsSyscall = true;
      }
    }
    assert(CallFunc && "Failed to get called function!");
    // Get argument number from callee.
    unsigned ArgNum = CallFunc->arg_size();
    if (IFFuncArgNum > ArgNum)
      ArgNum = IFFuncArgNum;
    Argument *CalledFuncArgs = CallFunc->arg_begin();
    std::vector<Value *> CallInstFuncArgs;
    CallInst *Inst = nullptr;
    if (ArgNum > 0) {
      Value *ArgVal = nullptr;
      const MachineFrameInfo &MFI = FuncInfo->MF->getFrameInfo();
      unsigned StackArg = 0; // Initialize argument size on stack to 0.
      if (ArgNum > 4) {
        StackArg = ArgNum - 4;

        unsigned StackNum = MFI.getNumObjects() - 2;
        if (StackNum > StackArg)
          StackArg = StackNum;
      }
      for (unsigned i = 0; i < ArgNum; i++) {
        if (i < 4)
          ArgVal = FuncInfo->ArgValMap[ARM::R0 + i];
        else {
          const Value *StackAlloc =
              MFI.getObjectAllocation(StackArg - i - 4 + 1);
          ArgVal = CallCreateAlignedLoad(
              const_cast<Value *>(StackAlloc),
              MaybeAlign(Log2(DLT->getPointerPrefAlignment())));
        }
        if (IsSyscall && i < CallFunc->arg_size() &&
            ArgVal->getType() != CalledFuncArgs[i].getType()) {
          CastInst *CInst = CastInst::Create(
              CastInst::getCastOpcode(ArgVal, false,
                                      CalledFuncArgs[i].getType(), false),
              ArgVal, CalledFuncArgs[i].getType());
          IRB.GetInsertBlock()->getInstList().push_back(CInst);
          ArgVal = CInst;
        }
        CallInstFuncArgs.push_back(ArgVal);
      }
      Inst = IRB.CreateCall(CallFunc, ArrayRef<Value *>(CallInstFuncArgs));
    } else
      Inst = IRB.CreateCall(CallFunc);

    DAGInfo->setRealValue(Node, Inst);
  } break;
  case ISD::BRIND: {
    Value *Func = getIRValue(Node->getOperand(0));
    unsigned NumDests = Node->getNumOperands();
    IRB.CreateIndirectBr(Func, NumDests);
  } break;
  case ISD::BR_JT: {
    // Emit the switch instruction.
    if (jtList.size() > 0) {
      MachineBasicBlock *mbb = FuncInfo->MBBMap[CurBB];
      MachineFunction *MF = mbb->getParent();

      std::vector<JumpTableBlock> JTCases;
      const MachineJumpTableInfo *MJT = MF->getJumpTableInfo();
      unsigned jtIndex = Node->getConstantOperandVal(0);
      std::vector<MachineJumpTableEntry> JumpTables = MJT->getJumpTables();
      for (unsigned j = 0, f = JumpTables[jtIndex].MBBs.size(); j != f; ++j) {
        llvm::Type *i32_type = llvm::IntegerType::getInt32Ty(*CTX);
        llvm::ConstantInt *i32_val =
            cast<ConstantInt>(llvm::ConstantInt::get(i32_type, j, true));
        MachineBasicBlock *Succ = JumpTables[jtIndex].MBBs[j];
        ConstantInt *CaseVal = i32_val;
        JTCases.push_back(std::make_pair(CaseVal, Succ));
      }
      // main->getEntryBlock().setName("entry");

      unsigned int numCases = JTCases.size();
      BasicBlock *def_bb =
          FuncInfo->getOrCreateBasicBlock(jtList[jtIndex].df_MBB);

      BasicBlock *cd_bb =
          FuncInfo->getOrCreateBasicBlock(jtList[jtIndex].conditionMBB);

      // conditon instruction
      Instruction *cdi = nullptr;
      for (BasicBlock::iterator DI = cd_bb->begin(); DI != cd_bb->end(); DI++) {
        Instruction *ins = dyn_cast<Instruction>(DI);
        if (isa<LoadInst>(DI) && !cdi) {
          cdi = ins;
        }

        if (cdi && (ins->getOpcode() == Instruction::Sub)) {
          if (isa<ConstantInt>(ins->getOperand(1))) {
            ConstantInt *opr = dyn_cast<ConstantInt>(ins->getOperand(1));
            if (opr->uge(0)) {
              cdi = ins;
            }
          }
        }
      }

      SwitchInst *Inst = IRB.CreateSwitch(cdi, def_bb, numCases);
      for (unsigned i = 0, e = numCases; i != e; ++i) {
        BasicBlock *case_bb =
            FuncInfo->getOrCreateBasicBlock(JTCases[i].second);
        Inst->addCase(JTCases[i].first, case_bb);
      }
    }
  } break;
  case ISD::ROTR: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Value *S1 = getIRValue(Node->getOperand(1));
    Type *Ty = getDefaultType();
    Value *Val = ConstantInt::get(Ty, 32, true);

    if (DAGInfo->NPMap[Node]->HasCPSR) {
      unsigned CondValue = DAGInfo->NPMap[Node]->Cond;

      if (DAGInfo->NPMap[Node]->UpdateCPSR) {
        Value *InstSub = IRB.CreateSub(Val, S1);
        Value *InstLShr = IRB.CreateLShr(S0, S1);
        Value *InstShl = IRB.CreateShl(S0, InstSub);
        Value *Inst = IRB.CreateOr(InstLShr, InstShl);
        DAGInfo->setRealValue(Node, Inst);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;

        emitSpecialCPSR(Inst, BB, 0);
      } else {
        // Create new BB for EQ instructin exectute.
        BasicBlock *IfBB = BasicBlock::Create(*CTX, "", BB->getParent());
        // Create new BB to update the DAG BB.
        BasicBlock *ElseBB = BasicBlock::Create(*CTX, "", BB->getParent());

        // Emit the condition code.
        emitCondCode(CondValue, BB, IfBB, ElseBB);
        IRB.SetInsertPoint(IfBB);
        Value *InstSub = IRB.CreateSub(Val, S1);
        Value *InstLShr = IRB.CreateLShr(S0, S1);
        Value *InstShl = IRB.CreateShl(S0, InstSub);
        Value *Inst = IRB.CreateOr(InstLShr, InstShl);
        PHINode *Phi = createAndEmitPHINode(Node, BB, IfBB, ElseBB,
                                            dyn_cast<Instruction>(Inst));
        DAGInfo->setRealValue(Node, Phi);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Phi;
        IRB.CreateBr(ElseBB);
        IRB.SetInsertPoint(ElseBB);
      }
    } else {
      Value *InstSub = IRB.CreateSub(Val, S1);
      Value *InstLShr = IRB.CreateLShr(S0, S1);
      Value *InstShl = IRB.CreateShl(S0, InstSub);
      Value *Inst = IRB.CreateOr(InstLShr, InstShl);
      DAGInfo->setRealValue(Node, Inst);
      FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;
    }
  } break;
  case ARMISD::RRX: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Type *Ty = getDefaultType();
    Value *Val1 = ConstantInt::get(Ty, 1, true);
    Value *Val2 = ConstantInt::get(Ty, 31, true);
    if (DAGInfo->NPMap[Node]->HasCPSR) {
      unsigned CondValue = DAGInfo->NPMap[Node]->Cond;

      if (DAGInfo->NPMap[Node]->UpdateCPSR) {
        Value *InstLShr = IRB.CreateLShr(S0, Val1);
        Value *C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
        C_Flag = IRB.CreateZExt(C_Flag, Ty);
        Value *Bit31 = IRB.CreateShl(C_Flag, Val2);
        Value *Inst = IRB.CreateAdd(InstLShr, Bit31);
        DAGInfo->setRealValue(Node, Inst);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;

        /**************************************/
        emitSpecialCPSR(Inst, BB, 0);
        // Update C flag.
        // c flag = s0[0]
        C_Flag = IRB.CreateAnd(S0, Val1);
        IRB.CreateStore(C_Flag, FuncInfo->AllocaMap[2]);
      } else {
        // Create new BB for EQ instructin exectute.
        BasicBlock *IfBB = BasicBlock::Create(*CTX, "", BB->getParent());
        // Create new BB to update the DAG BB.
        BasicBlock *ElseBB = BasicBlock::Create(*CTX, "", BB->getParent());

        // Emit the condition code.
        emitCondCode(CondValue, BB, IfBB, ElseBB);
        IRB.SetInsertPoint(IfBB);
        Value *InstLShr = IRB.CreateLShr(S0, Val1);
        Value *C_Flag = nullptr;

        C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
        C_Flag = IRB.CreateZExt(C_Flag, Ty);
        Value *Bit31 = IRB.CreateShl(C_Flag, Val2);
        Value *Inst = IRB.CreateAdd(InstLShr, Bit31);
        PHINode *Phi = createAndEmitPHINode(Node, BB, IfBB, ElseBB,
                                            dyn_cast<Instruction>(Inst));
        DAGInfo->setRealValue(Node, Phi);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Phi;
        IRB.CreateBr(ElseBB);
        IRB.SetInsertPoint(ElseBB);
      }
    } else {
      Value *InstLShr = IRB.CreateLShr(S0, Val1);
      Value *C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
      C_Flag = IRB.CreateZExt(C_Flag, Ty);
      Value *Bit31 = IRB.CreateShl(C_Flag, Val2);
      Value *Inst = IRB.CreateAdd(InstLShr, Bit31);
      DAGInfo->setRealValue(Node, Inst);
      FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;
    }
  } break;
  case EXT_ARMISD::BIC: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Value *S1 = getIRValue(Node->getOperand(1));
    Type *tp = getDefaultType();
    Value *val = ConstantInt::get(tp, -1, true);

    if (DAGInfo->NPMap[Node]->HasCPSR) {
      unsigned CondValue = DAGInfo->NPMap[Node]->Cond;

      if (DAGInfo->NPMap[Node]->UpdateCPSR) {
        Value *InstXor = IRB.CreateXor(val, S1);
        Value *Inst = IRB.CreateAnd(S0, InstXor);

        DAGInfo->setRealValue(Node, Inst);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;

        emitSpecialCPSR(Inst, BB, 0);
        // Update C flag.
        // C flag not change.

        // Update V flag.
        // unchanged.
      } else {
        // Create new BB for EQ instructin exectute.
        BasicBlock *IfBB = BasicBlock::Create(*CTX, "", BB->getParent());
        // Create new BB to update the DAG BB.
        BasicBlock *ElseBB = BasicBlock::Create(*CTX, "", BB->getParent());
        // Emit the condition code.
        emitCondCode(CondValue, BB, IfBB, ElseBB);
        IRB.SetInsertPoint(IfBB);
        Value *InstXor = IRB.CreateXor(val, S1);
        Value *Inst = IRB.CreateAnd(S0, InstXor);
        PHINode *Phi = createAndEmitPHINode(Node, BB, IfBB, ElseBB,
                                            dyn_cast<Instruction>(Inst));
        DAGInfo->setRealValue(Node, Phi);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Phi;

        IRB.CreateBr(ElseBB);
        IRB.SetInsertPoint(ElseBB);
      }
    } else {
      Value *InstXor, *Inst;
      InstXor = IRB.CreateXor(val, S1);
      Inst = IRB.CreateAnd(S0, InstXor);
      DAGInfo->setRealValue(Node, Inst);
      FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;
    }
  } break;
  case ARMISD::CMN: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Value *S1 = getIRValue(Node->getOperand(1));
    Value *Inst;
    if (DAGInfo->NPMap[Node]->HasCPSR) {
      unsigned CondValue = DAGInfo->NPMap[Node]->Cond;
      HANDLE_EMIT_CONDCODE_COMMON(Add)
      emitCPSR(S0, S1, IfBB, 0);
      IRB.CreateBr(ElseBB);
      IRB.SetInsertPoint(ElseBB);
    } else {
      Inst = IRB.CreateAdd(S0, S1);
      DAGInfo->setRealValue(Node, Inst);
      FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;
      emitCPSR(S0, S1, BB, 0);
    }
  } break;
  case ISD::CTLZ: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Function *CTLZ = Intrinsic::getDeclaration(BB->getParent()->getParent(),
                                               Intrinsic::ctlz, S0->getType());
    Type *i1_type = llvm::IntegerType::getInt1Ty(*CTX);
    Value *is_zero_undef = ConstantInt::get(i1_type, true, true);

    std::vector<Value *> Vec;
    Vec.push_back(S0);
    Vec.push_back(is_zero_undef);
    ArrayRef<Value *> Args(Vec);

    Value *Inst = IRB.CreateCall(CTLZ, Args);
    DAGInfo->setRealValue(Node, Inst);
    FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;
  } break;
  case EXT_ARMISD::MLA: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Value *S1 = getIRValue(Node->getOperand(1));
    Value *S2 = getIRValue(Node->getOperand(2));

    Value *InstMul = IRB.CreateMul(S0, S1);
    Value *Inst = IRB.CreateAdd(InstMul, S2);

    DAGInfo->setRealValue(Node, Inst);
    FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;
  } break;
  case EXT_ARMISD::TST: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Value *S1 = getIRValue(Node->getOperand(1));

    if (DAGInfo->NPMap[Node]->HasCPSR) {
      unsigned CondValue = DAGInfo->NPMap[Node]->Cond;
      // Create new BB for EQ instructin exectute.
      BasicBlock *IfBB = BasicBlock::Create(*CTX, "", BB->getParent());
      // Create new BB to update the DAG BB.
      BasicBlock *ElseBB = BasicBlock::Create(*CTX, "", BB->getParent());

      // TODO:
      // Not change def. Consider how to use PHI.
      // PHINode *Phi = createAndEmitPHINode(Node, BB, ElseBB);

      emitCondCode(CondValue, BB, IfBB, ElseBB);
      IRB.SetInsertPoint(IfBB);
      Value *Inst = IRB.CreateAnd(S0, S1);
      emitSpecialCPSR(Inst, IfBB, 0);
      IRB.CreateBr(ElseBB);
      IRB.SetInsertPoint(ElseBB);
    } else {
      Value *Inst = IRB.CreateAnd(S0, S1);
      emitSpecialCPSR(Inst, BB, 0);
    }
  } break;
  case EXT_ARMISD::SBC: {
    Value *S1 = getIRValue(Node->getOperand(0));
    Value *S2 = getIRValue(Node->getOperand(1));
    Type *Ty = getDefaultType();

    if (DAGInfo->NPMap[Node]->HasCPSR) {
      unsigned CondValue = DAGInfo->NPMap[Node]->Cond;

      if (DAGInfo->NPMap[Node]->UpdateCPSR) {
        Value *InstSub = IRB.CreateSub(S1, S2);
        Value *C_Flag = nullptr;
        C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
        Value *CZext = IRB.CreateZExt(C_Flag, Ty);
        Value *InstSBC = IRB.CreateAdd(InstSub, CZext);
        DAGInfo->setRealValue(Node, InstSBC);
        Value *InstNot = IRB.CreateNot(S2);
        if (1)
          emitCPSR(S1, InstNot, BB, 0);
        else
          emitCPSR(S1, InstNot, BB, 1);
      } else {
        BasicBlock *IfBB = BasicBlock::Create(*CTX, "", BB->getParent());
        BasicBlock *ElseBB = BasicBlock::Create(*CTX, "", BB->getParent());

        emitCondCode(CondValue, BB, IfBB, ElseBB);

        IRB.SetInsertPoint(IfBB);
        Value *InstSub = IRB.CreateSub(S1, S2);
        Value *C_Flag = nullptr;
        C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
        Value *CZext = IRB.CreateZExt(C_Flag, Ty);
        Value *Inst = IRB.CreateAdd(InstSub, CZext);
        PHINode *Phi = createAndEmitPHINode(Node, BB, IfBB, ElseBB,
                                            dyn_cast<Instruction>(Inst));
        DAGInfo->setRealValue(Node, Phi);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Phi;

        IRB.CreateBr(ElseBB);
        IRB.SetInsertPoint(ElseBB);
      }
    } else {
      Value *InstSub = IRB.CreateSub(S1, S2);
      Value *C_Flag = nullptr;
      C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
      Value *CZext = IRB.CreateZExt(C_Flag, Ty);
      Value *InstSBC = IRB.CreateAdd(InstSub, CZext);
      DAGInfo->setRealValue(Node, InstSBC);
    }
  } break;
  case EXT_ARMISD::TEQ: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Value *S1 = getIRValue(Node->getOperand(1));

    if (DAGInfo->NPMap[Node]->HasCPSR) {
      unsigned CondValue = DAGInfo->NPMap[Node]->Cond;
      // Create new BB for EQ instructin exectute.
      BasicBlock *IfBB = BasicBlock::Create(*CTX, "", BB->getParent());
      // Create new BB to update the DAG BB.
      BasicBlock *ElseBB = BasicBlock::Create(*CTX, "", BB->getParent());

      // TODO:
      // This instruction not change def, consider phi later.

      emitCondCode(CondValue, BB, IfBB, ElseBB);
      IRB.SetInsertPoint(IfBB);
      Value *Inst = IRB.CreateXor(S0, S1);
      emitSpecialCPSR(Inst, IfBB, 0);
      IRB.CreateBr(ElseBB);
      IRB.SetInsertPoint(ElseBB);
    } else {
      Value *Inst = IRB.CreateXor(S0, S1);
      emitSpecialCPSR(Inst, BB, 0);
    }
  } break;
  case EXT_ARMISD::MSR: {
    Value *Cond = getIRValue(Node->getOperand(0));
    // 1 1 1 1
    // N set 1 0 0 0   8
    // Z set 0 1 0 0   4
    // C set 0 0 1 0   2
    // Z set 0 0 0 1   1
    IRB.CreateStore(Cond, dyn_cast<Value>(M.getGlobalVariable("Reserved")));
    // Pattern msr CPSR_f, Rn
    if (1) {
      Value *Shift_Num = IRB.getInt32(28);
      Value *Shift = IRB.CreateLShr(Cond, Shift_Num);
      // Update N Flag.
      Value *N_Cmp = IRB.getInt32(8);
      Value *N_Flag = IRB.CreateICmpEQ(Shift, N_Cmp);
      IRB.CreateStore(N_Flag, FuncInfo->AllocaMap[0]);
      // Update Z Flag.
      Value *Z_Cmp = IRB.getInt32(4);
      Value *Z_Flag = IRB.CreateICmpEQ(Shift, Z_Cmp);
      IRB.CreateStore(Z_Flag, FuncInfo->AllocaMap[1]);
      // Update C Flag.
      Value *C_Cmp = IRB.getInt32(2);
      Value *C_Flag = IRB.CreateICmpEQ(Shift, C_Cmp);
      IRB.CreateStore(C_Flag, FuncInfo->AllocaMap[2]);
      // Update V Flag.
      Value *V_Cmp = IRB.getInt32(1);
      Value *V_Flag = IRB.CreateICmpEQ(Shift, V_Cmp);
      IRB.CreateStore(V_Flag, FuncInfo->AllocaMap[3]);
    } else {
      // Pattern msr CSR_f, #const.
    }
  } break;
  case EXT_ARMISD::MRS: {
    Value *Rn = getIRValue(Node->getOperand(0));
    // Reserved || N_Flag << 31 || Z_Flag << 30 || C_Flag << 29 || V_Flag << 28
    PointerType *PtrTy = PointerType::getInt32PtrTy(*CTX);
    Type *Ty = Type::getInt32Ty(*CTX);

    Value *BitNShift = IRB.getInt32(31);
    Value *BitZShift = IRB.getInt32(30);
    Value *BitCShift = IRB.getInt32(29);
    Value *BitVShift = IRB.getInt32(28);

    Value *N_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[0]);
    Value *Z_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[1]);
    Value *C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
    Value *V_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[3]);

    N_Flag = IRB.CreateZExt(N_Flag, Ty);
    Z_Flag = IRB.CreateZExt(Z_Flag, Ty);
    C_Flag = IRB.CreateZExt(C_Flag, Ty);
    V_Flag = IRB.CreateZExt(V_Flag, Ty);

    Value *N_Shift = IRB.CreateShl(N_Flag, BitNShift);
    Value *Z_Shift = IRB.CreateShl(Z_Flag, BitZShift);
    Value *C_Shift = IRB.CreateShl(C_Flag, BitCShift);
    Value *V_Shift = IRB.CreateShl(V_Flag, BitVShift);
    Value *NZ_Val = IRB.CreateAdd(N_Shift, Z_Shift);
    Value *CV_Val = IRB.CreateAdd(C_Shift, V_Shift);
    Value *NZCV_Val = IRB.CreateAdd(NZ_Val, CV_Val);
    Value *Reserved =
        CallCreateAlignedLoad(dyn_cast<Value>(M.getGlobalVariable("Reserved")));

    Value *CPSR_Val = IRB.CreateAdd(NZCV_Val, Reserved);
    Value *Rn_Ptr = IRB.CreateIntToPtr(Rn, PtrTy);
    Value *RnStore = IRB.CreateStore(CPSR_Val, Rn_Ptr);

    DAGInfo->setRealValue(Node, RnStore);
    FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = RnStore;
  } break;
  case ISD::ADDC: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Value *S1 = getIRValue(Node->getOperand(1));
    Type *OperandTy = getDefaultType();

    if (DAGInfo->NPMap[Node]->HasCPSR) {
      unsigned CondValue = DAGInfo->NPMap[Node]->Cond;

      if (DAGInfo->NPMap[Node]->UpdateCPSR) {
        // Create add emit.
        Value *C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
        Value *Result = IRB.CreateAdd(S0, S1);
        Value *CZext = IRB.CreateZExt(C_Flag, OperandTy);
        Value *InstADC = IRB.CreateAdd(Result, CZext);
        DAGInfo->setRealValue(Node, InstADC);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] =
            dyn_cast<Instruction>(InstADC);

        // Update CPSR.
        // TODO:
        // Should consider how to do this.
        if (1)
          emitCPSR(S0, S1, BB, 1);
        else
          emitCPSR(S0, S1, BB, 0);
      } else {
        // Create new BB for EQ instructin exectute.
        BasicBlock *IfBB = BasicBlock::Create(*CTX, "", BB->getParent());
        // Create new BB to update the DAG BB.
        BasicBlock *ElseBB = BasicBlock::Create(*CTX, "", BB->getParent());

        // Emit the condition code.
        emitCondCode(CondValue, BB, IfBB, ElseBB);

        Value *C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
        IRB.SetInsertPoint(IfBB);
        Value *InstAdd = IRB.CreateAdd(S0, S1);
        Value *CZext = IRB.CreateZExtOrTrunc(C_Flag, OperandTy);
        Value *Inst = IRB.CreateAdd(InstAdd, CZext);
        PHINode *Phi = createAndEmitPHINode(Node, BB, IfBB, ElseBB,
                                            dyn_cast<Instruction>(Inst));
        DAGInfo->setRealValue(Node, Phi);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Phi;

        IRB.CreateBr(ElseBB);
        IRB.SetInsertPoint(ElseBB);
      }
    } else {
      Value *C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
      Value *Inst = IRB.CreateAdd(S0, S1);
      Value *CTrunc = IRB.CreateZExtOrTrunc(C_Flag, getDefaultType());
      Value *InstADC = IRB.CreateAdd(Inst, CTrunc);

      DAGInfo->setRealValue(Node, InstADC);
      FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = InstADC;
    }
  } break;
  case EXT_ARMISD::RSC: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Value *S1 = getIRValue(Node->getOperand(1));

    Value *C_Flag = CallCreateAlignedLoad(FuncInfo->AllocaMap[2]);
    Value *CZext = IRB.CreateZExt(C_Flag, getDefaultType());

    Value *Inst = IRB.CreateAdd(S0, CZext);
    Inst = IRB.CreateSub(S1, Inst);
    DAGInfo->setRealValue(Node, Inst);
    FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;
  } break;
  case EXT_ARMISD::UXTB: {
    Value *S1 = getIRValue(Node->getOperand(1));
    Value *Rotation = getIRValue(Node->getOperand(2));
    Value *ror_val = ConstantInt::get(getDefaultType(), 8, true);
    Value *add_val = ConstantInt::get(getDefaultType(), 0, true);
    Value *and_val = ConstantInt::get(getDefaultType(), 0xff, true);
    Value *Inst_mul = IRB.CreateMul(Rotation, ror_val);
    Value *Inst_lshr = IRB.CreateLShr(S1, Inst_mul);
    Value *Inst_add = IRB.CreateAdd(Inst_lshr, add_val);
    Value *Inst_and = IRB.CreateAnd(Inst_add, and_val);
    DAGInfo->setRealValue(Node, Inst_and);
  } break;
  case EXT_ARMISD::RSB: {
    Value *S0 = getIRValue(Node->getOperand(0));
    Value *S1 = getIRValue(Node->getOperand(1));

    if (DAGInfo->NPMap[Node]->HasCPSR) {
      unsigned CondValue = DAGInfo->NPMap[Node]->Cond;
      if (DAGInfo->NPMap[Node]->UpdateCPSR) {
        // Create add emit.
        Value *Inst = IRB.CreateSub(S0, S1);
        DAGInfo->setRealValue(Node, Inst);
        FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;

        Value *InstNot = IRB.CreateNot(S1);
        emitCPSR(InstNot, S0, BB, 1);
      } else {
        HANDLE_EMIT_CONDCODE(Sub)
      }
    } else {
      Value *Inst = IRB.CreateSub(S0, S1);
      DAGInfo->setRealValue(Node, Inst);
      FuncInfo->ArgValMap[FuncInfo->NodeRegMap[Node]] = Inst;
    }
  } break;
  }
}