diff --git a/ChangeLog b/ChangeLog
index 3150310d9bbcfb532381c4ee1176c06b83cb0e39..79540d5b570548bb016dc9f5ae835c922f5c3b57 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2015-01-17  Niels Möller  <nisse@lysator.liu.se>
+
+	* fat-x86_64.c: Set up for sse2 vs non-sse2 memxor. Patch by Nikos
+	Mavrogiannopoulos.
+	* configure.ac (asm_nettle_optional_list): Added memxor-2.asm.
+	* x86_64/fat/memxor-2.asm: New file.
+	* x86_64/fat/memxor.asm: New file.
+
+	* x86_64/memxor.asm: Use ifdef, not ifelse, for testing USE_SSE2.
+
 2015-01-16  Niels Möller  <nisse@lysator.liu.se>
 
 	* configure.ac (OPT_NETTLE_SOURCES): New substituted variable.
diff --git a/configure.ac b/configure.ac
index 7b8dc775f46960af6cb34c9f14958b6e12041e56..2ebdb0b0aa44711dcfe82b571bd08db012512fc2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -299,7 +299,7 @@ asm_replace_list="aes-encrypt-internal.asm aes-decrypt-internal.asm \
 
 # Assembler files which generate additional object files if they are used.
 asm_nettle_optional_list="gcm-hash8.asm cpuid.asm \
-  aes-encrypt-internal-2.asm aes-decrypt-internal-2.asm"
+  aes-encrypt-internal-2.asm aes-decrypt-internal-2.asm memxor-2.asm"
 asm_hogweed_optional_list=""
 if test "x$enable_public_key" = "xyes" ; then
   asm_hogweed_optional_list="ecc-192-modp.asm ecc-224-modp.asm \
diff --git a/fat-x86_64.c b/fat-x86_64.c
index 30d1c249bc56a2d77b638334eabfc53c5606648e..b6c1f44278dba4d6e4956e0f86c6dd92ae8d10c3 100644
--- a/fat-x86_64.c
+++ b/fat-x86_64.c
@@ -36,6 +36,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "nettle-types.h"
 
@@ -102,6 +103,13 @@ aes_crypt_internal_func _aes_decrypt IFUNC ("_aes_decrypt_resolve");
 aes_crypt_internal_func _nettle_aes_decrypt_x86_64;
 aes_crypt_internal_func _nettle_aes_decrypt_aesni;
 
+typedef void *(memxor_func)(void *dst_in, const void *src_in, size_t n);
+
+/* FIXME: Fix fat name-mangling to get _nettle prefix. */
+memxor_func nettle_memxor IFUNC ("_memxor_resolve");
+memxor_func nettle_memxor_x86_64;
+memxor_func nettle_memxor_sse2;
+
 #if HAVE_LINK_IFUNC
 #define _aes_encrypt_init NULL
 #define _aes_decrypt_init NULL
@@ -112,6 +120,7 @@ static aes_crypt_internal_func _aes_decrypt_init;
 
 static aes_crypt_internal_func *_aes_encrypt_vec = _aes_encrypt_init;
 static aes_crypt_internal_func *_aes_decrypt_vec = _aes_decrypt_init;
+static memxor_func *_memxor_vec = nettle_memxor_x86_64;
 
 /* This function should usually be called only once, at startup. But
    it is idempotent, and on x86, pointer updates are atomic, so
@@ -151,6 +160,22 @@ fat_init (void)
       _aes_decrypt_vec = _nettle_aes_decrypt_x86_64;
     }
 
+  _nettle_cpuid (0, cpuid_data);
+  if (memcmp(&cpuid_data[1], "Genu", 4) == 0 &&
+      memcmp(&cpuid_data[3], "ineI", 4) == 0 &&
+      memcmp(&cpuid_data[2], "ntel", 4) == 0)
+    {
+      if (verbose)
+	fprintf (stderr, "libnettle: intel SSE2 will be used for XOR.\n");
+      _memxor_vec = nettle_memxor_sse2;
+    }
+  else
+    {
+      if (verbose)
+	fprintf (stderr, "libnettle: intel SSE2 will not be used for XOR.\n");
+      _memxor_vec = nettle_memxor_x86_64;
+    }
+
   /* The x86_64 architecture should always make stores visible in the
      right order to other processors (except for non-temporal stores
      and the like). So we don't need any memory barrier. */
@@ -177,6 +202,15 @@ _aes_decrypt_resolve (void)
   return (void_func *) _aes_decrypt_vec;
 }
 
+static void_func *
+_memxor_resolve (void)
+{
+  if (getenv ("NETTLE_FAT_VERBOSE"))
+    fprintf (stderr, "libnettle: _memxor_resolve\n");
+  fat_init ();
+  return (void_func *) _memxor_vec;
+}
+
 #else /* !HAVE_LINK_IFUNC */
 
 /* We need wrapper functions jumping via the function pointer. */
@@ -224,4 +258,11 @@ _aes_decrypt_init (unsigned rounds, const uint32_t *keys,
   _aes_decrypt (rounds, keys, T, length, dst, src);
 }
 
+/* FIXME: Missing _memxor_init. */
+void *
+memxor(void *dst_in, const void *src_in, size_t n)
+{
+  return _memxor_vec (dst_in, src_in, n);
+}
+
 #endif /* !HAVE_LINK_IFUNC */
diff --git a/x86_64/fat/memxor-2.asm b/x86_64/fat/memxor-2.asm
new file mode 100644
index 0000000000000000000000000000000000000000..ffc844401cb4b3cb1bd9ff93ba4e21d83696f873
--- /dev/null
+++ b/x86_64/fat/memxor-2.asm
@@ -0,0 +1,36 @@
+C x86_64/fat/memxor-2.asm
+
+
+ifelse(<
+   Copyright (C) 2015 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+>)
+
+define(<fat_suffix>, <_sse2>)
+define(<USE_SSE2>, <yes>)	
+include_src(<x86_64/memxor.asm>)
diff --git a/x86_64/fat/memxor.asm b/x86_64/fat/memxor.asm
new file mode 100644
index 0000000000000000000000000000000000000000..a040bb3958275b035de630e34bd1c767bf9f8d9e
--- /dev/null
+++ b/x86_64/fat/memxor.asm
@@ -0,0 +1,35 @@
+C x86_64/fat/memxor.asm
+
+
+ifelse(<
+   Copyright (C) 2015 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+>)
+
+define(<fat_suffix>, <_x86_64>)
+include_src(<x86_64/memxor.asm>)
diff --git a/x86_64/memxor.asm b/x86_64/memxor.asm
index 69d6cfe382a12e8a0d2ace1d1019a9db44d23f24..f07f00177c4ebef18cc75ef457cd5ba96ad83db3 100644
--- a/x86_64/memxor.asm
+++ b/x86_64/memxor.asm
@@ -79,7 +79,7 @@ PROLOGUE(nettle_memxor)
 	jnz	.Lalign_loop
 
 .Laligned:
-ifelse(USE_SSE2, yes, <
+ifdef(<USE_SSE2>, <
 	cmp	$16, N
 	jnc	.Lsse2_case
 >)
@@ -135,7 +135,7 @@ ifelse(USE_SSE2, yes, <
 	W64_EXIT(3, 0)
 	ret
 
-ifelse(USE_SSE2, yes, <
+ifdef(<USE_SSE2>, <
 
 .Lsse2_case:
 	lea	(DST, N), TMP