1 #ifndef SRL_COMMON_H_
2 #define SRL_COMMON_H_
3 
4 #include "srl_inline.h"
5 
6 /* inspired by JSON::XS code */
7 #if __GNUC__ >= 3
8 # define expect(expr,value) __builtin_expect((expr), (value))
9 #else
10 # define expect(expr,value) (expr)
11 #endif
12 
13 #define expect_false(expr) expect((expr) != 0, 0)
14 #define expect_true(expr)  expect((expr) != 0, 1)
15 
16 /* these defines are somewhat borrowed from miniz.c */
17 
18 #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) || defined(__x86_64)
19 /* SRL_X86_OR_X64_CPU is only used to help set the below macros. */
20 #define SRL_X86_OR_X64_CPU
21 #ifndef SRL_EXTENDED_PRECISION_LONG_DOUBLE
22 #define SRL_EXTENDED_PRECISION_LONG_DOUBLE 1
23 #endif
24 #endif
25 
26 #ifndef SRL_EXTENDED_PRECISION_LONG_DOUBLE
27 #define SRL_EXTENDED_PRECISION_LONG_DOUBLE 0
28 #endif
29 
30 #ifndef SRL_USE_ALIGNED_LOADS_AND_STORES
31 
32 #ifdef __hpux
33 /* HP-UX runs on Itanium but has strict alignment so we check it first. */
34 #define SRL_USE_ALIGNED_LOADS_AND_STORES 1
35 #elif defined(SRL_X86_OR_X64_CPU)
36 /* Set SRL_USE_ALIGNED_LOADS_AND_STORES to 0 on CPU's that permit efficient integer loads and stores from unaligned addresses. */
37 #define SRL_USE_ALIGNED_LOADS_AND_STORES 0
38 #else
39 /* When in doubt use aligned loads and stores */
40 #define SRL_USE_ALIGNED_LOADS_AND_STORES 1
41 #endif
42 
43 #endif
44 
45 
46 /* In x86 one can try to enforce strict alignment in runtime.
47  *
48  * Setting the CPU flag bit 18 (called "AC", aligment check) in
49  * the "EFLAGS" (user-settable) causes unaligned access traps but
50  * only iff the system register CR0 (only system-settable, usually done
51  * (or not) during kernel boot) has the same bit set (there called "AM",
52  * alignment mask).  If both flags are not set, the strict alignment
53  * traps (silently) do not happen.
54  *
55  * The Linux kernel and the Solarix x86 set the "AM".  The Windows and
56  * OS X do not.  The *BSD behavior is unknown, though suspecting they do.
57  *
58  * http://en.wikipedia.org/wiki/Control_register
59  * http://en.wikipedia.org/wiki/FLAGS_register_(computing)
60  */
61 #ifdef SRL_X86_OR_X64_CPU
62 #  if defined(__x86_64__) || defined(__x86_64)
63 #    define SRL_TRY_ENABLE_STRICT_ALIGN() asm("pushf\norl $0x40000, (%rsp)\npopf")
64 #  elif defined(__i386__) || defined(__i386)
65 #    define SRL_TRY_ENABLE_STRICT_ALIGN() asm("pushf\norl $0x40000, (%esp)\npopf")
66 #  endif
67 #else
68 #  define SRL_TRY_ENABLE_STRICT_ALIGN() (void)0
69 #endif
70 
71 /* define constant for other code to use in preallocations or buffer space
72  * assertions */
73 #define SRL_MAX_VARINT_LENGTH 11
74 
75 
76 /* perl 5.25 op_sibling renaming related compat macros. Should probably
77  * live in ppport or so. */
78 
79 #ifndef OpSIBLING
80 # define OpSIBLING(op) ((op)->op_sibling)
81 #endif
82 
83 #ifndef OpHAS_SIBLING
84 # define OpHAS_SIBLING(op) ((op)->op_sibling != NULL)
85 #endif
86 
87 /* This is completely opting out, sigh */
88 #ifndef op_parent
89 # undef OpLASTSIB_set
90 # undef OpMORESIB_set
91 # define op_parent(op) NULL
92 # define OpMORESIB_set(op, sib) ((op)->op_sibling = (sib))
93 # define OpLASTSIB_set(op, parent) ((op)->op_sibling = NULL)
94 #endif
95 
96 #endif
97