summaryrefslogtreecommitdiff
path: root/libguile/vm-i-system.c
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2012-01-24 23:39:43 +0100
committerLudovic Courtès <ludo@gnu.org>2012-01-24 23:39:43 +0100
commit2b264d7e4fb649955ade1814527b6eb6f34f4e18 (patch)
treec11ad7254effcd7e814595645f56f73e29cf588d /libguile/vm-i-system.c
parent228e9ec137be1e7a2bc05641f975b52d1ad84416 (diff)
downloadguile-2b264d7e4fb649955ade1814527b6eb6f34f4e18.tar.gz
Work around instruction reordering on SPARC and HPPA in the VM.
Fixes part of <http://bugs.gnu.org/10520>. Reported by Bruno Haible <bruno@clisp.org>. * libguile/vm-i-system.c (COMPILER_BARRIER): New macro. (halt, return, return_values): Insert compiler barrier after each assignment to `fp'.
Diffstat (limited to 'libguile/vm-i-system.c')
-rw-r--r--libguile/vm-i-system.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c
index 474fe7883..7a7bccc1b 100644
--- a/libguile/vm-i-system.c
+++ b/libguile/vm-i-system.c
@@ -1,5 +1,6 @@
-/* Copyright (C) 2001,2008,2009,2010,2011 Free Software Foundation, Inc.
- *
+/* Copyright (C) 2001, 2008, 2009, 2010, 2011,
+ * 2012 Free Software Foundation, Inc.
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3 of
@@ -19,6 +20,17 @@
/* This file is included in vm_engine.c */
+/* Compiler barrier, to prevent instruction reordering, apparently due
+ to a bug in GCC 4.3.2 on sparc-linux-gnu and on hppa2.0-linux-gnu.
+ See <http://bugs.gnu.org/10520>, for details. */
+
+#ifdef __GNUC__
+# define COMPILER_BARRIER __asm__ __volatile__ ("")
+#else
+# define COMPILER_BARRIER do { } while (0)
+#endif
+
+
/*
* Basic operations
@@ -55,6 +67,7 @@ VM_DEFINE_INSTRUCTION (1, halt, "halt", 0, 0, 0)
stack */
ip = SCM_FRAME_RETURN_ADDRESS (fp);
fp = SCM_FRAME_DYNAMIC_LINK (fp);
+ COMPILER_BARRIER;
NULLSTACK (old_sp - sp);
}
@@ -1267,6 +1280,7 @@ VM_DEFINE_INSTRUCTION (67, return, "return", 0, 1, 1)
sp = SCM_FRAME_LOWER_ADDRESS (fp);
ip = SCM_FRAME_RETURN_ADDRESS (fp);
fp = SCM_FRAME_DYNAMIC_LINK (fp);
+ COMPILER_BARRIER;
#ifdef VM_ENABLE_STACK_NULLING
NULLSTACK (old_sp - sp);
@@ -1302,7 +1316,8 @@ VM_DEFINE_INSTRUCTION (68, return_values, "return/values", 1, -1, -1)
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
ip = SCM_FRAME_MV_RETURN_ADDRESS (fp);
fp = SCM_FRAME_DYNAMIC_LINK (fp);
-
+ COMPILER_BARRIER;
+
/* Push return values, and the number of values */
for (i = 0; i < nvalues; i++)
*++sp = vals[i+1];
@@ -1322,7 +1337,8 @@ VM_DEFINE_INSTRUCTION (68, return_values, "return/values", 1, -1, -1)
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
ip = SCM_FRAME_RETURN_ADDRESS (fp);
fp = SCM_FRAME_DYNAMIC_LINK (fp);
-
+ COMPILER_BARRIER;
+
/* Push first value */
*++sp = vals[1];
@@ -1713,6 +1729,7 @@ VM_DEFINE_INSTRUCTION (93, assert_nargs_ee_locals, "assert-nargs-ee/locals", 1,
NEXT;
}
+#undef COMPILER_BARRIER
/*
(defun renumber-ops ()