aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/JSBackend/CallHandlers.h2
-rw-r--r--lib/Target/JSBackend/JSBackend.cpp26
2 files changed, 17 insertions, 11 deletions
diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h
index e8a3d9c1d4..b286b54339 100644
--- a/lib/Target/JSBackend/CallHandlers.h
+++ b/lib/Target/JSBackend/CallHandlers.h
@@ -98,7 +98,7 @@ DEF_CALL_HANDLER(__default__, {
getAssign(getJSName(CI), InstRT); // ensure the variable is defined, but do not emit it here
// it should have 0 uses, but just to be safe
} else if (!ActualRT->isVoidTy()) {
- text = getAssign(getJSName(CI), ActualRT) + getCast(text, ActualRT, ASM_NONSPECIFIC);
+ text = getAssign(getJSName(CI), ActualRT) + getCast(text, ActualRT, ASM_NONSPECIFIC | ASM_FFI);
}
return text;
})
diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp
index d77eff7aee..cb380b3d9b 100644
--- a/lib/Target/JSBackend/JSBackend.cpp
+++ b/lib/Target/JSBackend/JSBackend.cpp
@@ -72,11 +72,11 @@ extern "C" void LLVMInitializeJSBackendTarget() {
}
namespace {
- enum AsmCast {
- ASM_SIGNED = 0,
- ASM_UNSIGNED = 1,
- ASM_NONSPECIFIC = 2 // nonspecific means to not differentiate ints. |0 for all, regardless of size and sign
- };
+ #define ASM_SIGNED 0
+ #define ASM_UNSIGNED 1
+ #define ASM_NONSPECIFIC 2 // nonspecific means to not differentiate ints. |0 for all, regardless of size and sign
+ #define ASM_FFI 4 // FFI values are limited to things that work in ffis
+ typedef unsigned AsmCast;
const char *SIMDLane = "XYZW";
const char *simdLane = "xyzw";
@@ -469,17 +469,23 @@ std::string JSWriter::getCast(const StringRef &s, const Type *t, AsmCast sign) {
if (!t->isVectorTy()) assert(false && "Unsupported type");
}
case Type::FloatTyID: {
- if (PreciseF32) return ("Math_fround(" + s + ")").str();
+ if (PreciseF32) {
+ if (sign & ASM_FFI) {
+ return ("Math_fround(+(" + s + "))").str();
+ } else {
+ return ("Math_fround(" + s + ")").str();
+ }
+ }
// otherwise fall through to double
}
case Type::DoubleTyID: return ("+" + s).str();
case Type::IntegerTyID: {
// fall through to the end for nonspecific
switch (t->getIntegerBitWidth()) {
- case 1: if (sign != ASM_NONSPECIFIC) return (s + "&1").str();
- case 8: if (sign != ASM_NONSPECIFIC) return sign == ASM_UNSIGNED ? (s + "&255").str() : (s + "<<24>>24").str();
- case 16: if (sign != ASM_NONSPECIFIC) return sign == ASM_UNSIGNED ? (s + "&65535").str() : (s + "<<16>>16").str();
- case 32: return (sign == ASM_SIGNED || sign == ASM_NONSPECIFIC ? s + "|0" : s + ">>>0").str();
+ case 1: if (!(sign & ASM_NONSPECIFIC)) return (s + "&1").str();
+ case 8: if (!(sign & ASM_NONSPECIFIC)) return sign == ASM_UNSIGNED ? (s + "&255").str() : (s + "<<24>>24").str();
+ case 16: if (!(sign & ASM_NONSPECIFIC)) return sign == ASM_UNSIGNED ? (s + "&65535").str() : (s + "<<16>>16").str();
+ case 32: return (sign == ASM_SIGNED || (sign & ASM_NONSPECIFIC) ? s + "|0" : s + ">>>0").str();
default: assert(0);
}
}