diff options
-rw-r--r-- | lib/Target/CppBackend/CallHandlers.h | 12 | ||||
-rw-r--r-- | lib/Transforms/NaCl/ExpandI64.cpp | 41 |
2 files changed, 51 insertions, 2 deletions
diff --git a/lib/Target/CppBackend/CallHandlers.h b/lib/Target/CppBackend/CallHandlers.h index e126b34bb9..14c418704b 100644 --- a/lib/Target/CppBackend/CallHandlers.h +++ b/lib/Target/CppBackend/CallHandlers.h @@ -51,6 +51,16 @@ DEF_CALL_HANDLER(FPtoIHigh, { return getAssign(getCppName(CI), CI->getType()) + "Math_abs(" + Input + ") >= +1 ? " + Input + " > +0 ? (Math_min(+Math_floor(" + Input + " / +4294967296), +4294967295) | 0) >>> 0 : ~~+Math_ceil((" + Input + " - +(~~" + Input + " >>> 0)) / +4294967296) >>> 0 : 0"; }) +DEF_CALL_HANDLER(SItoFP, { + return getAssign(getCppName(CI), CI->getType()) + "(+" + getValueAsCastParenStr(CI->getArgOperand(0), ASM_UNSIGNED) + ") + " + + "(+4294967296*(+" + getValueAsCastParenStr(CI->getArgOperand(1), ASM_SIGNED) + "))"; +}) + +DEF_CALL_HANDLER(UItoFP, { + return getAssign(getCppName(CI), CI->getType()) + "(+" + getValueAsCastParenStr(CI->getArgOperand(0), ASM_UNSIGNED) + ") + " + + "(+4294967296*(+" + getValueAsCastParenStr(CI->getArgOperand(1), ASM_UNSIGNED) + "))"; +}) + DEF_CALL_HANDLER(llvm_nacl_atomic_store_i32, { return "HEAP32[" + getValueAsStr(CI->getArgOperand(0)) + ">>2]=" + getValueAsStr(CI->getArgOperand(1)); }) @@ -369,6 +379,8 @@ void setupCallHandlers() { SETUP_CALL_HANDLER(setHigh32); SETUP_CALL_HANDLER(FPtoILow); SETUP_CALL_HANDLER(FPtoIHigh); + SETUP_CALL_HANDLER(SItoFP); + SETUP_CALL_HANDLER(UItoFP); SETUP_CALL_HANDLER(llvm_nacl_atomic_store_i32); SETUP_CALL_HANDLER(llvm_memcpy_p0i8_p0i8_i32); SETUP_CALL_HANDLER(llvm_memset_p0i8_i32); diff --git a/lib/Transforms/NaCl/ExpandI64.cpp b/lib/Transforms/NaCl/ExpandI64.cpp index f1f8e2dcfa..061f4fbc53 100644 --- a/lib/Transforms/NaCl/ExpandI64.cpp +++ b/lib/Transforms/NaCl/ExpandI64.cpp @@ -96,7 +96,7 @@ namespace { void finalizeInst(Instruction *I); - Function *Add, *Sub, *Mul, *SDiv, *UDiv, *SRem, *URem, *LShr, *AShr, *Shl, *GetHigh, *SetHigh, *FPtoILow, *FPtoIHigh; + Function *Add, *Sub, *Mul, *SDiv, *UDiv, *SRem, *URem, *LShr, *AShr, *Shl, *GetHigh, *SetHigh, *FPtoILow, *FPtoIHigh, *SItoFP, *UItoFP; void ensureFuncs(); @@ -461,6 +461,23 @@ void ExpandI64::splitInst(Instruction *I, DataLayout& DL) { Split.LowHigh.High = H; break; } + case Instruction::SIToFP: + case Instruction::UIToFP: { + ensureFuncs(); + SmallVector<Value *, 2> Args; + Args.push_back(Zero); + Args.push_back(Zero); + Function *F; + switch (I->getOpcode()) { + case Instruction::SIToFP: F = SItoFP; break; + case Instruction::UIToFP: F = UItoFP; break; + default: assert(0); + } + Instruction *D = CopyDebug(CallInst::Create(F, Args, "", I), I); + SplitInfo &Split = Splits[I]; + Split.ToFix.push_back(D); + break; + } default: { dumpIR(I); assert(0 && "some i64 thing we can't legalize yet"); @@ -515,6 +532,16 @@ void ExpandI64::finalizeInst(Instruction *I) { Split.ToFix[1]->setOperand(0, LowHigh.High); break; } + case Instruction::SIToFP: + case Instruction::UIToFP: { + // generic fix of an instruction with one 64-bit input, and a legal output + LowHighPair LowHigh = getLowHigh(I->getOperand(0)); + Instruction *D = Split.ToFix[0]; + D->setOperand(0, LowHigh.Low); + D->setOperand(1, LowHigh.High); + I->replaceAllUsesWith(D); + break; + } case Instruction::Add: case Instruction::Sub: case Instruction::Mul: @@ -656,13 +683,23 @@ void ExpandI64::ensureFuncs() { SetHigh = Function::Create(SetHighFunc, GlobalValue::ExternalLinkage, "setHigh32", TheModule); + Type *Double = Type::getDoubleTy(TheModule->getContext()); SmallVector<Type*, 1> FPtoITypes; - FPtoITypes.push_back(Type::getDoubleTy(TheModule->getContext())); + FPtoITypes.push_back(Double); FunctionType *FPtoIFunc = FunctionType::get(i32, FPtoITypes, false); FPtoILow = Function::Create(FPtoIFunc, GlobalValue::ExternalLinkage, "FPtoILow", TheModule); FPtoIHigh = Function::Create(FPtoIFunc, GlobalValue::ExternalLinkage, "FPtoIHigh", TheModule); + + SmallVector<Type*, 2> ItoFPTypes; + ItoFPTypes.push_back(i32); + ItoFPTypes.push_back(i32); + FunctionType *ItoFPFunc = FunctionType::get(Double, ItoFPTypes, false); + SItoFP = Function::Create(ItoFPFunc, GlobalValue::ExternalLinkage, + "SItoFP", TheModule); + UItoFP = Function::Create(ItoFPFunc, GlobalValue::ExternalLinkage, + "UItoFP", TheModule); } bool ExpandI64::runOnModule(Module &M) { |