source: tags/parabix-0.40/lib/lib_simd.h @ 4027

Last change on this file since 4027 was 43, checked in by cameron, 12 years ago

Generic simd library file.

File size: 2.9 KB
Line 
1/*  lib_simd_h:  SIMD Library including idealized SIMD operations
2    Copyright (C) 2008, Robert D. Cameron
3    Licensed to the public under the Open Software License 3.0.
4    Licensed to International Characters Inc.
5       under the Academic Free License version 3.0.
6
7    This file contains generic architecture-independent definitions,
8    importing architecture-specific implementations from appropriate
9    files.
10*/
11
12/*------------------------------------------------------------*/
13#ifndef LIB_SIMD_H
14#define LIB_SIMD_H
15
16
17#ifdef __i386
18#include "sse_simd.h"
19#endif
20#ifdef _ARCH_PPC
21#include "altivec_simd.h"
22#endif
23
24/* Shift forward and back operations, based on endianness */
25#if BYTE_ORDER == BIG_ENDIAN
26#define sisd_sfl(blk, n) sisd_srl(blk, n)
27#define sisd_sbl(blk, n) sisd_sll(blk, n)
28#define sisd_sfli(blk, n) sisd_srli(blk, n)
29#define sisd_sbli(blk, n) sisd_slli(blk, n)
30#define sb_op(x, n) ((x)<<(n))
31#define sf_op(x, n) ((x)>>(n))
32#define cfzl __builtin_clzl
33#endif
34#if BYTE_ORDER == LITTLE_ENDIAN
35#define sisd_sfl(blk, n) sisd_sll(blk, n)
36#define sisd_sbl(blk, n) sisd_srl(blk, n)
37#define sisd_sfli(blk, n) sisd_slli(blk, n)
38#define sisd_sbli(blk, n) sisd_srli(blk, n)
39#define sb_op(x, n) ((x)>>(n))
40#define sf_op(x, n) ((x)<<(n))
41#define cfzl __builtin_ctzl
42#endif
43
44/* Scans for a 1 as long as it takes.  Use a sentinel to fence.
45   Works for either endianness.  */
46static inline int bitstream_scan(SIMD_type * stream, int bit_posn) {
47  unsigned long * bitstream_ptr = (unsigned long *) (((intptr_t) stream) + bit_posn/8);
48  unsigned long bitstream_slice = sb_op(*bitstream_ptr, bit_posn % 8);
49  if (bitstream_slice != 0) return bit_posn + cfzl(bitstream_slice);
50  else {
51    do {
52      bitstream_ptr++;
53      bitstream_slice = *bitstream_ptr;
54    } while (bitstream_slice == 0);
55    int base_posn = 8*((intptr_t) bitstream_ptr - (intptr_t) stream);
56    return base_posn + cfzl(bitstream_slice);
57  }
58}
59
60static inline int bitstream_scan0(SIMD_type * stream) {
61  unsigned long * bitstream_ptr = (unsigned long *) stream;
62  unsigned long bitstream_slice = *bitstream_ptr;
63  int base_posn = 0;
64  while (bitstream_slice == 0) {
65    bitstream_ptr++;
66    bitstream_slice = *bitstream_ptr;
67  }
68  base_posn = 8*((intptr_t) bitstream_ptr - (intptr_t) stream);
69  return base_posn + cfzl(bitstream_slice);
70}
71
72
73/* Allocator for arrays of aligned SIMD data values.
74   Ideally the new operator could be used to allocate arrays
75   of vector data aligned on the required boundaries
76   (16-byte for SSE or Altivec).  But since this alignment
77   is not guaranteed except on Mac OS X, the following routine
78   is used. */
79
80static inline SIMD_type * simd_new(size_t SIMD_packs) {
81#ifdef __APPLE__
82        return new SIMD_type [SIMD_packs];
83#endif
84#ifndef __APPLE__
85        SIMD_type * v;
86        int rslt = posix_memalign((void **) &v,
87                                  sizeof(SIMD_type),
88                                  sizeof(SIMD_type) * SIMD_packs);
89        if (rslt == 0) return v;
90        else {
91                printf("Failed to allocated new array of %i SIMD packs.\n");
92                exit(-1);
93        }
94#endif
95}
96
97
98#endif
99
Note: See TracBrowser for help on using the repository browser.