aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/CppBackend/CallHandlers.h12
-rw-r--r--lib/Transforms/NaCl/ExpandI64.cpp41
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) {