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;
}
}