summaryrefslogtreecommitdiffstats
path: root/libitm/config/alpha
diff options
context:
space:
mode:
authoraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-08 11:13:41 +0000
committeraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-08 11:13:41 +0000
commit4c0315d05fa0f707875686abc4f91f7a979a7c7b (patch)
treee07de8d0b6265f8d72388d335bd471022e753d57 /libitm/config/alpha
parentbf09288ee7b5f264f28081a84fde4c6aa1ac5c82 (diff)
downloadppe42-gcc-4c0315d05fa0f707875686abc4f91f7a979a7c7b.tar.gz
ppe42-gcc-4c0315d05fa0f707875686abc4f91f7a979a7c7b.zip
Merge from transactional-memory branch.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181154 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libitm/config/alpha')
-rw-r--r--libitm/config/alpha/cacheline.h122
-rw-r--r--libitm/config/alpha/sjlj.S108
-rw-r--r--libitm/config/alpha/target.h60
-rw-r--r--libitm/config/alpha/unaligned.h118
4 files changed, 408 insertions, 0 deletions
diff --git a/libitm/config/alpha/cacheline.h b/libitm/config/alpha/cacheline.h
new file mode 100644
index 00000000000..5e38486b713
--- /dev/null
+++ b/libitm/config/alpha/cacheline.h
@@ -0,0 +1,122 @@
+/* Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+ This file is part of the GNU Transactional Memory Library (libitm).
+
+ Libitm is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ Libitm 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef LIBITM_ALPHA_CACHELINE_H
+#define LIBITM_ALPHA_CACHELINE_H 1
+
+// A cacheline is the smallest unit with which locks are associated.
+// The current implementation of the _ITM_[RW] barriers assumes that
+// all data types can fit (aligned) within a cachline, which means
+// in practice sizeof(complex long double) is the smallest cacheline size.
+// It ought to be small enough for efficient manipulation of the
+// modification mask, below.
+#define CACHELINE_SIZE 64
+
+#ifdef __alpha_bwx__
+# include "config/generic/cacheline.h"
+#else
+// If we don't have byte-word stores, then we'll never be able to
+// adjust *all* of the byte loads/stores to be truely atomic. So
+// only guarantee 4-byte aligned values atomicly stored, exactly
+// like the native system. Use byte zap instructions to accelerate
+// sub-word masked stores.
+
+namespace GTM HIDDEN {
+
+// A gtm_cacheline_mask stores a modified bit for every modified byte
+// in the cacheline with which it is associated.
+typedef sized_integral<CACHELINE_SIZE / 8>::type gtm_cacheline_mask;
+
+union gtm_cacheline
+{
+ // Byte access to the cacheline.
+ unsigned char b[CACHELINE_SIZE] __attribute__((aligned(CACHELINE_SIZE)));
+
+ // Larger sized access to the cacheline.
+ uint16_t u16[CACHELINE_SIZE / sizeof(uint16_t)];
+ uint32_t u32[CACHELINE_SIZE / sizeof(uint32_t)];
+ uint64_t u64[CACHELINE_SIZE / sizeof(uint64_t)];
+ gtm_word w[CACHELINE_SIZE / sizeof(gtm_word)];
+
+ // Store S into D, but only the bytes specified by M.
+ static void store_mask(uint32_t *d, uint32_t s, uint8_t m);
+ static void store_mask(uint64_t *d, uint64_t s, uint8_t m);
+
+ // Copy S to D, but only the bytes specified by M.
+ static void copy_mask (gtm_cacheline * __restrict d,
+ const gtm_cacheline * __restrict s,
+ gtm_cacheline_mask m);
+
+ // A write barrier to emit after (a series of) copy_mask.
+ static void copy_mask_wb () { atomic_write_barrier(); }
+};
+
+inline void ALWAYS_INLINE
+gtm_cacheline::store_mask (uint32_t *d, uint32_t s, uint8_t m)
+{
+ const uint8_t tm = (1 << sizeof(uint32_t)) - 1;
+
+ m &= tm;
+ if (__builtin_expect (m, tm))
+ {
+ if (__builtin_expect (m == tm, 1))
+ *d = s;
+ else
+ *d = __builtin_alpha_zap (*d, m) | __builtin_alpha_zapnot (s, m);
+ }
+}
+
+inline void ALWAYS_INLINE
+gtm_cacheline::store_mask (uint64_t *d, uint64_t s, uint8_t m)
+{
+ if (__builtin_expect (m, 0xff))
+ {
+ if (__builtin_expect (m == 0xff, 1))
+ *d = s;
+ else
+ {
+ typedef uint32_t *p32 __attribute__((may_alias));
+ p32 d32 = reinterpret_cast<p32>(d);
+
+ if ((m & 0x0f) == 0x0f)
+ {
+ d32[0] = s;
+ m &= 0xf0;
+ }
+ else if ((m & 0xf0) == 0xf0)
+ {
+ d32[1] = s >> 32;
+ m &= 0x0f;
+ }
+
+ if (m)
+ *d = __builtin_alpha_zap (*d, m) | __builtin_alpha_zapnot (s, m);
+ }
+ }
+}
+
+} // namespace GTM
+
+#endif // __alpha_bwx__
+#endif // LIBITM_ALPHA_CACHELINE_H
diff --git a/libitm/config/alpha/sjlj.S b/libitm/config/alpha/sjlj.S
new file mode 100644
index 00000000000..d60a82df62b
--- /dev/null
+++ b/libitm/config/alpha/sjlj.S
@@ -0,0 +1,108 @@
+/* Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+ This file is part of the GNU Transactional Memory Library (libitm).
+
+ Libitm is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ Libitm 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+ .text
+ .align 4
+ .globl _ITM_beginTransaction
+ .ent _ITM_beginTransaction
+
+#define FRAME 144
+
+_ITM_beginTransaction:
+ ldgp $29, 0($27)
+ subq $30, FRAME, $30
+ .frame $30, FRAME, $26, 0
+ .mask 0x04000000, 0
+ stq $26, 0($30)
+ .prologue 1
+
+ stq $9, 8($30)
+ stq $10, 16($30)
+ addq $30, FRAME, $0
+ stq $11, 24($30)
+
+ stq $12, 32($30)
+ stq $13, 40($30)
+ stq $14, 48($30)
+ stq $15, 56($30)
+
+ stq $0, 64($30)
+ stt $f2, 72($30)
+ stt $f3, 80($30)
+ stt $f4, 88($30)
+
+ stt $f5, 96($30)
+ stt $f6, 104($30)
+ stt $f7, 112($30)
+ stt $f8, 120($30)
+
+ stt $f9, 128($30)
+ mov $30, $17
+#ifdef __PIC__
+ unop
+ bsr $26, GTM_begin_transaction !samegp
+#else
+ jsr $26, GTM_begin_transaction
+ ldgp $29, 0($26)
+#endif
+
+ ldq $26, 0($30)
+ addq $30, FRAME, $30
+ ret
+.end _ITM_beginTransaction
+
+ .align 4
+ .globl GTM_longjmp
+ .hidden GTM_longjmp
+ .ent GTM_longjmp
+
+GTM_longjmp:
+ .prologue 0
+ ldq $26, 0($16)
+ ldq $9, 8($16)
+ ldq $10, 16($16)
+ ldq $11, 24($16)
+
+ ldq $12, 32($16)
+ ldq $13, 40($16)
+ ldq $14, 48($16)
+ ldq $15, 56($16)
+
+ ldq $1, 64($16)
+ ldt $f2, 72($16)
+ ldt $f3, 80($16)
+ ldt $f4, 88($16)
+
+ ldt $f5, 96($16)
+ ldt $f6, 104($16)
+ ldt $f7, 112($16)
+ ldt $f8, 120($16)
+
+ ldt $f9, 128($16)
+ mov $17, $0
+ mov $1, $30
+ ret
+.end GTM_longjmp
+
+.section .note.GNU-stack, "", @progbits
diff --git a/libitm/config/alpha/target.h b/libitm/config/alpha/target.h
new file mode 100644
index 00000000000..121546f5f52
--- /dev/null
+++ b/libitm/config/alpha/target.h
@@ -0,0 +1,60 @@
+/* Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+ This file is part of the GNU Transactional Memory Library (libitm).
+
+ Libitm is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ Libitm 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+namespace GTM HIDDEN {
+
+typedef struct gtm_jmpbuf
+{
+ unsigned long pc;
+ unsigned long s[7];
+ void *cfa;
+ unsigned long f[8];
+} gtm_jmpbuf;
+
+/* Alpha generally uses a fixed page size of 8K. */
+#define PAGE_SIZE 8192
+#define FIXED_PAGE_SIZE 1
+
+/* The size of one line in hardware caches (in bytes). */
+#define HW_CACHELINE_SIZE 64
+
+static inline void
+cpu_relax (void)
+{
+ __asm volatile ("" : : : "memory");
+}
+
+static inline void
+atomic_read_barrier (void)
+{
+ __sync_synchronize ();
+}
+
+static inline void
+atomic_write_barrier (void)
+{
+ __asm volatile ("wmb" : : : "memory");
+}
+
+} // namespace GTM
diff --git a/libitm/config/alpha/unaligned.h b/libitm/config/alpha/unaligned.h
new file mode 100644
index 00000000000..3d091aee228
--- /dev/null
+++ b/libitm/config/alpha/unaligned.h
@@ -0,0 +1,118 @@
+/* Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+ This file is part of the GNU Transactional Memory Library (libitm).
+
+ Libitm is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ Libitm 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef LIBITM_ALPHA_UNALIGNED_H
+#define LIBITM_ALPHA_UNALIGNED_H 1
+
+#define HAVE_ARCH_UNALIGNED_LOAD2_U2 1
+#define HAVE_ARCH_UNALIGNED_LOAD2_U4 1
+#define HAVE_ARCH_UNALIGNED_LOAD2_U8 1
+
+#ifndef __alpha_bwx__
+#define HAVE_ARCH_UNALIGNED_STORE2_U2 1
+#endif
+#define HAVE_ARCH_UNALIGNED_STORE2_U4 1
+#define HAVE_ARCH_UNALIGNED_STORE2_U8 1
+
+#include "config/generic/unaligned.h"
+
+namespace GTM HIDDEN {
+
+template<>
+inline uint16_t ALWAYS_INLINE
+unaligned_load2<uint16_t>(const gtm_cacheline *c1,
+ const gtm_cacheline *c2, size_t ofs)
+{
+ uint64_t v1 = c1->u64[CACHELINE_SIZE / sizeof(uint64_t) - 1];
+ uint64_t v2 = c2->u64[0];
+
+ return __builtin_alpha_extwl (v1, ofs) | __builtin_alpha_extwh (v2, ofs);
+}
+
+template<>
+inline uint32_t ALWAYS_INLINE
+unaligned_load2<uint32_t>(const gtm_cacheline *c1,
+ const gtm_cacheline *c2, size_t ofs)
+{
+ uint64_t v1 = c1->u64[CACHELINE_SIZE / sizeof(uint64_t) - 1];
+ uint64_t v2 = c2->u64[0];
+
+ return __builtin_alpha_extll (v1, ofs) + __builtin_alpha_extlh (v2, ofs);
+}
+
+template<>
+inline uint64_t ALWAYS_INLINE
+unaligned_load2<uint64_t>(const gtm_cacheline *c1,
+ const gtm_cacheline *c2, size_t ofs)
+{
+ uint64_t v1 = c1->u64[CACHELINE_SIZE / sizeof(uint64_t) - 1];
+ uint64_t v2 = c2->u64[0];
+
+ return __builtin_alpha_extql (v1, ofs) | __builtin_alpha_extqh (v2, ofs);
+}
+
+#ifndef __alpha_bwx__
+template<>
+inline void
+unaligned_store2<uint16_t>(gtm_cacheline *c1, gtm_cacheline *c2,
+ size_t ofs, uint16_t val)
+{
+ uint32_t vl = (uint32_t)val << 24, vh = val >> 8;
+
+ gtm_cacheline::store_mask (&c1->u32[CACHELINE_SIZE / 4 - 1], vl, 4);
+ gtm_cacheline::store_mask (&c2->u32[0], vh, 1);
+}
+#endif
+
+template<>
+inline void
+unaligned_store2<uint32_t>(gtm_cacheline *c1, gtm_cacheline *c2,
+ size_t ofs, uint32_t val)
+{
+ uint64_t vl = __builtin_alpha_insll (val, ofs);
+ uint64_t ml = __builtin_alpha_insll (~0u, ofs);
+ uint64_t vh = __builtin_alpha_inslh (val, ofs);
+ uint64_t mh = __builtin_alpha_inslh (~0u, ofs);
+
+ gtm_cacheline::store_mask (&c1->u64[CACHELINE_SIZE / 8 - 1], vl, ml);
+ gtm_cacheline::store_mask (&c2->u64[0], vh, mh);
+}
+
+template<>
+inline void
+unaligned_store2<uint64_t>(gtm_cacheline *c1, gtm_cacheline *c2,
+ size_t ofs, uint64_t val)
+{
+ uint64_t vl = __builtin_alpha_insql (val, ofs);
+ uint64_t ml = __builtin_alpha_insql (~0u, ofs);
+ uint64_t vh = __builtin_alpha_insqh (val, ofs);
+ uint64_t mh = __builtin_alpha_insqh (~0u, ofs);
+
+ gtm_cacheline::store_mask (&c1->u64[CACHELINE_SIZE / 8 - 1], vl, ml);
+ gtm_cacheline::store_mask (&c2->u64[0], vh, mh);
+}
+
+} // namespace GTM
+
+#endif // LIBITM_ALPHA_UNALIGNED_H
OpenPOWER on IntegriCloud