aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-01-22 13:09:10 -0800
committerAlon Zakai <alonzakai@gmail.com>2014-01-22 13:09:10 -0800
commit30fb3ff89104c2a4112f54740722c43f42286f74 (patch)
treeb86707e574efc191682ed396b51f954490727187
parent4f5b909434e73adbceb1e96a95d0bda1b34666aa (diff)
handle fptosi|ui on both floats and doubles
-rw-r--r--lib/Target/JSBackend/CallHandlers.h31
-rw-r--r--lib/Transforms/NaCl/ExpandI64.cpp42
2 files changed, 42 insertions, 31 deletions
diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h
index b99577134c..48edd2b8b7 100644
--- a/lib/Target/JSBackend/CallHandlers.h
+++ b/lib/Target/JSBackend/CallHandlers.h
@@ -163,50 +163,43 @@ DEF_CALL_HANDLER(emscripten_get_longjmp_result, {
DEF_CALL_HANDLER(getHigh32, {
return getAssign(getJSName(CI), CI->getType()) + "tempRet0";
})
-
DEF_CALL_HANDLER(setHigh32, {
return "tempRet0 = " + getValueAsStr(CI->getOperand(0));
})
-
-DEF_CALL_HANDLER(FPtoILow, {
- return getAssign(getJSName(CI), CI->getType()) + "(~~" + getValueAsStr(CI->getOperand(0)) + ")>>>0";
-})
-
-DEF_CALL_HANDLER(FPtoIHigh, {
- std::string Input = getValueAsStr(CI->getOperand(0));
- return getAssign(getJSName(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";
+#define TO_I(low, high) \
+DEF_CALL_HANDLER(low, { \
+ return getAssign(getJSName(CI), CI->getType()) + "(~~" + getValueAsStr(CI->getOperand(0)) + ")>>>0"; \
+}) \
+DEF_CALL_HANDLER(high, { \
+ std::string Input = getValueAsStr(CI->getOperand(0)); \
+ return getAssign(getJSName(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"; \
})
-
+TO_I(FtoILow, FtoIHigh);
+TO_I(DtoILow, DtoIHigh);
DEF_CALL_HANDLER(BDtoILow, {
return "HEAPF64[tempDoublePtr>>3] = " + getValueAsStr(CI->getOperand(0)) + ";" + getAssign(getJSName(CI), CI->getType()) + "HEAP32[tempDoublePtr>>2]|0";
})
-
DEF_CALL_HANDLER(BDtoIHigh, {
return getAssign(getJSName(CI), CI->getType()) + "HEAP32[tempDoublePtr+4>>2]|0";
})
-
DEF_CALL_HANDLER(SItoF, {
// TODO: fround
return getAssign(getJSName(CI), CI->getType()) + "(+" + getValueAsCastParenStr(CI->getOperand(0), ASM_UNSIGNED) + ") + " +
"(+4294967296*(+" + getValueAsCastParenStr(CI->getOperand(1), ASM_SIGNED) + "))";
})
-
DEF_CALL_HANDLER(UItoF, {
// TODO: fround
return getAssign(getJSName(CI), CI->getType()) + "(+" + getValueAsCastParenStr(CI->getOperand(0), ASM_UNSIGNED) + ") + " +
"(+4294967296*(+" + getValueAsCastParenStr(CI->getOperand(1), ASM_UNSIGNED) + "))";
})
-
DEF_CALL_HANDLER(SItoD, {
return getAssign(getJSName(CI), CI->getType()) + "(+" + getValueAsCastParenStr(CI->getOperand(0), ASM_UNSIGNED) + ") + " +
"(+4294967296*(+" + getValueAsCastParenStr(CI->getOperand(1), ASM_SIGNED) + "))";
})
-
DEF_CALL_HANDLER(UItoD, {
return getAssign(getJSName(CI), CI->getType()) + "(+" + getValueAsCastParenStr(CI->getOperand(0), ASM_UNSIGNED) + ") + " +
"(+4294967296*(+" + getValueAsCastParenStr(CI->getOperand(1), ASM_UNSIGNED) + "))";
})
-
DEF_CALL_HANDLER(BItoD, {
return "HEAP32[tempDoublePtr>>2] = " + getValueAsStr(CI->getOperand(0)) + ";" +
"HEAP32[tempDoublePtr+4>>2] = " + getValueAsStr(CI->getOperand(1)) + ";" +
@@ -616,8 +609,10 @@ void setupCallHandlers() {
SETUP_CALL_HANDLER(emscripten_get_longjmp_result);
SETUP_CALL_HANDLER(getHigh32);
SETUP_CALL_HANDLER(setHigh32);
- SETUP_CALL_HANDLER(FPtoILow);
- SETUP_CALL_HANDLER(FPtoIHigh);
+ SETUP_CALL_HANDLER(FtoILow);
+ SETUP_CALL_HANDLER(FtoIHigh);
+ SETUP_CALL_HANDLER(DtoILow);
+ SETUP_CALL_HANDLER(DtoIHigh);
SETUP_CALL_HANDLER(BDtoILow);
SETUP_CALL_HANDLER(BDtoIHigh);
SETUP_CALL_HANDLER(SItoF);
diff --git a/lib/Transforms/NaCl/ExpandI64.cpp b/lib/Transforms/NaCl/ExpandI64.cpp
index 5af1ac197d..40ad6b6cbf 100644
--- a/lib/Transforms/NaCl/ExpandI64.cpp
+++ b/lib/Transforms/NaCl/ExpandI64.cpp
@@ -98,7 +98,7 @@ namespace {
void finalizeInst(Instruction *I);
- Function *Add, *Sub, *Mul, *SDiv, *UDiv, *SRem, *URem, *LShr, *AShr, *Shl, *GetHigh, *SetHigh, *FPtoILow, *FPtoIHigh, *SItoF, *UItoF, *SItoD, *UItoD, *BItoD, *BDtoILow, *BDtoIHigh;
+ Function *Add, *Sub, *Mul, *SDiv, *UDiv, *SRem, *URem, *LShr, *AShr, *Shl, *GetHigh, *SetHigh, *FtoILow, *FtoIHigh, *DtoILow, *DtoIHigh, *SItoF, *UItoF, *SItoD, *UItoD, *BItoD, *BDtoILow, *BDtoIHigh;
void ensureFuncs();
@@ -509,9 +509,16 @@ void ExpandI64::splitInst(Instruction *I, DataLayout& DL) {
case Instruction::FPToSI: {
ensureFuncs();
SmallVector<Value *, 1> Args;
- Args.push_back(I->getOperand(0));
- Instruction *L = CopyDebug(CallInst::Create(FPtoILow, Args, "", I), I);
- Instruction *H = CopyDebug(CallInst::Create(FPtoIHigh, Args, "", I), I);
+ Value *Input = I->getOperand(0);
+ Args.push_back(Input);
+ Instruction *L, *H;
+ if (Input->getType()->isFloatTy()) {
+ L = CopyDebug(CallInst::Create(FtoILow, Args, "", I), I);
+ H = CopyDebug(CallInst::Create(FtoIHigh, Args, "", I), I);
+ } else {
+ L = CopyDebug(CallInst::Create(DtoILow, Args, "", I), I);
+ H = CopyDebug(CallInst::Create(DtoIHigh, Args, "", I), I);
+ }
SplitInfo &Split = Splits[I];
Split.LowHigh.Low = L;
Split.LowHigh.High = H;
@@ -890,16 +897,25 @@ void ExpandI64::ensureFuncs() {
Type *Double = Type::getDoubleTy(TheModule->getContext());
Type *Float = Type::getFloatTy(TheModule->getContext());
- SmallVector<Type*, 1> FPtoITypes;
- 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);
- BDtoILow = Function::Create(FPtoIFunc, GlobalValue::ExternalLinkage,
+ SmallVector<Type*, 1> FtoITypes;
+ FtoITypes.push_back(Float);
+ FunctionType *FtoIFunc = FunctionType::get(i32, FtoITypes, false);
+
+ SmallVector<Type*, 1> DtoITypes;
+ DtoITypes.push_back(Double);
+ FunctionType *DtoIFunc = FunctionType::get(i32, DtoITypes, false);
+
+ FtoILow = Function::Create(FtoIFunc, GlobalValue::ExternalLinkage,
+ "FtoILow", TheModule);
+ FtoIHigh = Function::Create(FtoIFunc, GlobalValue::ExternalLinkage,
+ "FtoIHigh", TheModule);
+ DtoILow = Function::Create(DtoIFunc, GlobalValue::ExternalLinkage,
+ "DtoILow", TheModule);
+ DtoIHigh = Function::Create(DtoIFunc, GlobalValue::ExternalLinkage,
+ "DtoIHigh", TheModule);
+ BDtoILow = Function::Create(DtoIFunc, GlobalValue::ExternalLinkage,
"BDtoILow", TheModule);
- BDtoIHigh = Function::Create(FPtoIFunc, GlobalValue::ExternalLinkage,
+ BDtoIHigh = Function::Create(DtoIFunc, GlobalValue::ExternalLinkage,
"BDtoIHigh", TheModule);
SmallVector<Type*, 2> ItoTypes;