Qore Programming Language  0.8.9
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
macros-ia64.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  macros-itanium.h
4 
5  assembly macros for the Itanium (IA-64) architecture
6 
7  Qore Programming Language
8 
9  Copyright 2003 - 2013 David Nichols
10 
11  This library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU Lesser General Public
13  License as published by the Free Software Foundation; either
14  version 2.1 of the License, or (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public
22  License along with this library; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #ifndef _QORE_MACHINE_MACROS_H
27 #define _QORE_MACHINE_MACROS_H
28 
29 #define STACK_DIRECTION_DOWN 1
30 
31 #ifdef __GNUC__
32 #ifdef __LP64__
33 
34 #define HAVE_ATOMIC_MACROS
35 #define HAVE_CHECK_STACK_POS
36 
37 // 64-bit IA-64 atomic operations borrowed from linux
38 #define ia64_cmpxchg4_acq(ptr, new, old) ({ \
39  unsigned long ia64_intri_res; \
40  asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
41  asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv": \
42  "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
43  (int)ia64_intri_res; \
44 })
45 
46 static __inline__ int ia64_atomic_add (int i, volatile int *v) {
47  int old, vnew;
48 
49  do {
50  old = *v;
51  vnew = old + i;
52  } while (ia64_cmpxchg4_acq(v, vnew, old) != old);
53  return vnew;
54 }
55 
56 static __inline__ int ia64_atomic_sub (int i, volatile int *v) {
57  int old, vnew;
58 
59  do {
60  old = *v;
61  vnew = old - i;
62  } while (ia64_cmpxchg4_acq(v, vnew, old) != old);
63  return vnew;
64 }
65 
66 static inline void atomic_inc(volatile int *a) {
67  ia64_atomic_add(1, a);
68 }
69 
70 // returns 1 when counter reaches zero, 0 if not
71 static inline int atomic_dec(volatile int *a) {
72  return !ia64_atomic_sub(1, a);
73 }
74 
75 static inline size_t get_stack_pos() {
76  size_t addr;
77  asm volatile ("mov %0=sp" : "=r" (addr));
78  return addr;
79 }
80 
81 static inline size_t get_rse_bsp() {
82  size_t addr;
83  asm volatile ("mov %0=ar.bsp" : "=r" (addr));
84  return addr;
85 }
86 
87 #endif // #ifdef __LP64__
88 #endif // #ifdef __GNUC__
89 
90 #ifdef __HP_aCC
91 #ifdef __LP64__
92 
93 #define HAVE_ATOMIC_MACROS
94 #define HAVE_CHECK_STACK_POS
95 
96 // these routines are implemented in assembler
97 extern "C" void atomic_inc(int *v);
98 extern "C" int atomic_dec(int *v);
99 extern "C" size_t get_stack_pos();
100 extern "C" size_t get_rse_bsp(); // get ia64 Register Stack Engine backing store pointer
101 
102 #endif // #ifdef __LP64__
103 #endif // #ifdef __HP_aCC
104 
105 #endif // #ifndef _QORE_MACHINE_MACROS_H
106