about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--lib/Core/Executor.cpp4
-rw-r--r--lib/Core/ExternalDispatcher.cpp5
2 files changed, 9 insertions, 0 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index c50e4520..85413a42 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -3881,6 +3881,10 @@ void Executor::callExternalFunction(ExecutionState &state,
     } else {
       ref<Expr> arg = toUnique(state, *ai);
       if (ConstantExpr *ce = dyn_cast<ConstantExpr>(arg)) {
+        // fp80 must be aligned to 16 according to the System V AMD 64 ABI
+        if (ce->getWidth() == Expr::Fl80 && wordIndex & 0x01)
+          wordIndex++;
+
         // XXX kick toMemory functions from here
         ce->toMemory(&args[wordIndex]);
         wordIndex += (ce->getWidth()+63)/64;
diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp
index e43a8a83..aadb340d 100644
--- a/lib/Core/ExternalDispatcher.cpp
+++ b/lib/Core/ExternalDispatcher.cpp
@@ -302,6 +302,11 @@ Function *ExternalDispatcherImpl::createDispatcher(Function *target,
     // functions.
     auto argTy =
         (i < FTy->getNumParams() ? FTy->getParamType(i) : (*ai)->getType());
+
+    // fp80 must be aligned to 16 according to the System V AMD 64 ABI
+    if (argTy->isX86_FP80Ty() && idx & 0x01)
+      idx++;
+
     auto argI64p =
         Builder.CreateGEP(argI64s->getType()->getPointerElementType(), argI64s,
                           ConstantInt::get(Type::getInt32Ty(ctx), idx));