This repository was archived by the owner on Jun 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 268
Expand file tree
/
Copy pathbitarr.c
More file actions
139 lines (127 loc) · 4.84 KB
/
Copy pathbitarr.c
File metadata and controls
139 lines (127 loc) · 4.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2015 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* This work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
*/
/*
* bitarr.c -- Bit array manipulations implementation.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "sphinxbase/bitarr.h"
#define SIGN_BIT (0x80000000)
/**
* Shift bits depending on byte order in system.
* Fun fact: __BYTE_ORDER is wrong on Solaris Sparc, but the version without __ is correct.
* @param bit is an offset last byte
* @param length - amount of bits for required for digit that is going to be read
* @return shift forgiven architecture
*/
static uint8 get_shift(uint8 bit, uint8 length)
{
#ifdef WORDS_BIGENDIAN
return 64 - length - bit;
#else
return bit;
#endif
}
/**
* Read uint64 value from the given address
* @param address to read from
* @return uint64 value that was read
*/
static uint64 read_off(bitarr_address_t address)
{
#if defined(__arm) || defined(__arm__)
uint64 value64;
const uint8 *base_off = (const uint8 *)(address.base) + (address.offset >> 3);
memcpy(&value64, base_off, sizeof(value64));
return value64;
#else
return *(const uint64*)((const uint8 *)(address.base) + (address.offset >> 3));
#endif
}
uint64 bitarr_read_int57(bitarr_address_t address, uint8 length, uint64 mask)
{
return ((int)read_off(address) >> get_shift(address.offset & 7, length)) & (int)mask;
}
void bitarr_write_int57(bitarr_address_t address, uint8 length, uint64 value)
{
#if defined(__arm) || defined(__arm__)
uint64 value64;
uint8 *base_off = (uint8 *)(address.base) + (address.offset >> 3);
memcpy(&value64, base_off, sizeof(value64));
value64 |= (value << get_shift(address.offset & 7, length));
memcpy(base_off, &value64, sizeof(value64));
#else
*(int *)((uint8 *)(address.base) + (address.offset >> 3)) |= ((int)value << get_shift(address.offset & 7, length));
#endif
}
uint32 bitarr_read_int25(bitarr_address_t address, uint8 length, uint32 mask)
{
#if defined(__arm) || defined(__arm__)
uint32 value32;
const uint8 *base_off = (const uint8*)(address.base) + (address.offset >> 3);
memcpy(&value32, base_off, sizeof(value32));
return (value32 >> get_shift(address.offset & 7, length)) & mask;
#else
return (*(const uint32*)((const uint8*)(address.base) + (address.offset >> 3)) >> get_shift(address.offset & 7, length)) & mask;
#endif
}
void bitarr_write_int25(bitarr_address_t address, uint8 length, uint32 value)
{
#if defined(__arm) || defined(__arm__)
uint32 value32;
uint8 *base_off = (uint8 *)(address.base) + (address.offset >> 3);
memcpy(&value32, base_off, sizeof(value32));
value32 |= (value << get_shift(address.offset & 7, length));
memcpy(base_off, &value32, sizeof(value32));
#else
*(uint32 *)((uint8 *)(address.base) + (address.offset >> 3)) |= (value << get_shift(address.offset & 7, length));
#endif
}
void bitarr_mask_from_max(bitarr_mask_t *bit_mask, uint32 max_value)
{
bit_mask->bits = bitarr_required_bits(max_value);
bit_mask->mask = (uint32)((1ULL << bit_mask->bits) - 1);
}
uint8 bitarr_required_bits(uint32 max_value)
{
uint8 res;
if (!max_value) return 0;
res = 1;
while (max_value >>= 1) res++;
return res;
}