Add wasm tacle-bench targets
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,164 @@
|
||||
/*
|
||||
Include section
|
||||
*/
|
||||
|
||||
#include "ammunition_stdio.h"
|
||||
#include "ammunition_stdlib.h"
|
||||
#include "ammunition_string.h"
|
||||
|
||||
/*
|
||||
Standard library functions
|
||||
*/
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
char
|
||||
ammunition_isdigit(unsigned char c) {
|
||||
if ((c >= '0') & (c <= '9'))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ammunition_isspace(int c) {
|
||||
return (c == ' ') | (c == '\t') | (c == '\n') | (c == '\r');
|
||||
}
|
||||
|
||||
void *
|
||||
ammunition_memcpy(void *dest, const void *src, size_t size) {
|
||||
size_t i;
|
||||
__pragma_loopbound(2, 6);
|
||||
for (i = 0; i < size; i++)
|
||||
((unsigned char *) dest)[i] = ((unsigned char *) src)[i];
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *
|
||||
ammunition_memset(void *s, int c, size_t n) {
|
||||
size_t i;
|
||||
__pragma_loopbound(0, 4);
|
||||
for (i = 0; i < n; i++)
|
||||
((unsigned char *) s)[i] = (unsigned char) c;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
ammunition_memcmp(const void *mem1, const void *mem2, size_t size) {
|
||||
const unsigned char *p1 = (const unsigned char *) mem1,
|
||||
*p2 = (const unsigned char *) mem2;
|
||||
__pragma_loopbound(0, 4);
|
||||
while (size--)
|
||||
if (*p1 != *p2)
|
||||
return (*p1 - *p2);
|
||||
else
|
||||
p1++, p2++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The following function is an analog of standard C function
|
||||
`memmove'. The function returns the first operand. */
|
||||
|
||||
void *
|
||||
ammunition_memmove(void *s1, const void *s2, size_t n) {
|
||||
int i;
|
||||
|
||||
if (((char *) s1 < (char *) s2 && (char *) s1 + n <= (char *) s2) ||
|
||||
((char *) s2 < (char *) s1 && (char *) s2 + n <= (char *) s1))
|
||||
return (void *) ammunition_memcpy(s1, s2, n);
|
||||
if ((char *) s1 < (char *) s2 && (char *) s1 + n > (char *) s2) {
|
||||
__pragma_loopbound(0, 4);
|
||||
for (i = 0; (size_t) i < n; i++)
|
||||
((char *) s1)[i] = ((char *) s2)[i];
|
||||
} else {
|
||||
__pragma_loopbound(0, 4);
|
||||
for (i = n - 1; i >= 0; i--)
|
||||
((char *) s1)[i] = ((char *) s2)[i];
|
||||
}
|
||||
return s1;
|
||||
}
|
||||
|
||||
int
|
||||
ammunition_strcmp(const char *str1, const char *str2) {
|
||||
__pragma_loopbound(1, 11);
|
||||
while (*str1 && (*str1 == *str2))
|
||||
str1++, str2++;
|
||||
return *(const unsigned char *) str1 - *(const unsigned char *) str2;
|
||||
}
|
||||
|
||||
int
|
||||
ammunition_atoi(const char *str) {
|
||||
int result = 0;
|
||||
int sign = (str[0] == '-' ? -1 : 1);
|
||||
|
||||
int readingPos = 0;
|
||||
if (str[0] == '-' || str[0] == '+')
|
||||
readingPos++;
|
||||
__pragma_loopbound(1, 7);
|
||||
do {
|
||||
result *= 10;
|
||||
result += str[readingPos++] - 48;
|
||||
} while (str[readingPos] != 0);
|
||||
|
||||
return sign * result;
|
||||
}
|
||||
|
||||
int
|
||||
ammunition_sprintf_d(char *s, int number) {
|
||||
/* How many decimal digits do we need? */
|
||||
char digits = 0;
|
||||
unsigned char writePos = 0;
|
||||
long long copyOfNumber = number;
|
||||
__pragma_loopbound(1, 10);
|
||||
do {
|
||||
digits++;
|
||||
copyOfNumber /= 10;
|
||||
} while (copyOfNumber != 0);
|
||||
|
||||
writePos = digits;
|
||||
if (number < 0) {
|
||||
writePos++;
|
||||
s[0] = '-';
|
||||
}
|
||||
s[writePos] = 0;
|
||||
|
||||
copyOfNumber = number;
|
||||
__pragma_loopbound(1, 10);
|
||||
do {
|
||||
s[--writePos] =
|
||||
48 + ((copyOfNumber >= 0 ? copyOfNumber : -copyOfNumber) % 10);
|
||||
copyOfNumber /= 10;
|
||||
} while (copyOfNumber != 0);
|
||||
|
||||
return digits + (number < 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
ammunition_sprintf_u(char *s, unsigned int number) {
|
||||
/* How many decimal digits do we need? */
|
||||
char digits = 0;
|
||||
unsigned char writePos = 0;
|
||||
unsigned long long copyOfNumber = number;
|
||||
__pragma_loopbound(1, 10);
|
||||
do {
|
||||
digits++;
|
||||
copyOfNumber /= 10;
|
||||
} while (copyOfNumber != 0);
|
||||
|
||||
writePos = digits;
|
||||
s[writePos] = 0;
|
||||
|
||||
copyOfNumber = number;
|
||||
__pragma_loopbound(1, 10);
|
||||
do {
|
||||
s[--writePos] = 48 + (copyOfNumber % 10);
|
||||
copyOfNumber /= 10;
|
||||
} while (copyOfNumber != 0);
|
||||
|
||||
return digits;
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
|
||||
#ifndef AMMUNITION_LIMITS_H
|
||||
#define AMMUNITION_LIMITS_H
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
#define CHAR_BIT 8
|
||||
#endif
|
||||
#ifndef UCHAR_MAX
|
||||
#define UCHAR_MAX 255
|
||||
#endif
|
||||
#ifndef SCHAR_MAX
|
||||
#define SCHAR_MAX 127
|
||||
#endif
|
||||
#ifndef SCHAR_MIN
|
||||
#define SCHAR_MIN (-128)
|
||||
#endif
|
||||
#ifndef USHRT_MAX
|
||||
#define USHRT_MAX 65535
|
||||
#endif
|
||||
#ifndef SHRT_MAX
|
||||
#define SHRT_MAX 32767
|
||||
#endif
|
||||
#ifndef SHRT_MIN
|
||||
#define SHRT_MIN (-32768)
|
||||
#endif
|
||||
#ifndef UINT_MAX
|
||||
#define UINT_MAX (INT_MAX * 2U + 1)
|
||||
#endif
|
||||
#ifndef INT_MAX
|
||||
#define INT_MAX 2147483647
|
||||
#endif
|
||||
#ifndef INT_MIN
|
||||
#define INT_MIN (-INT_MAX - 1)
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef AMMUNITION_LIMITS_H */
|
||||
@ -0,0 +1,9 @@
|
||||
|
||||
#ifndef AMMUNITION_STDIO_H
|
||||
#define AMMUNITION_STDIO_H
|
||||
|
||||
int ammunition_sprintf_d(char *s, int number);
|
||||
|
||||
int ammunition_sprintf_u(char *s, unsigned int number);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef AMMUNITION_STDLIB_H
|
||||
#define AMMUNITION_STDLIB_H
|
||||
|
||||
int ammunition_atoi(const char *str);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,17 @@
|
||||
|
||||
#ifndef AMMUNITION_STRING_H
|
||||
#define AMMUNITION_STRING_H
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
|
||||
void *ammunition_memcpy(void *, const void *, size_t);
|
||||
void *ammunition_memset(void *, int, size_t);
|
||||
int ammunition_memcmp(const void *mem1, const void *mem2, size_t size);
|
||||
void *ammunition_memmove(void *s1, const void *s2, size_t n);
|
||||
int ammunition_strcmp(const char *str1, const char *str2);
|
||||
|
||||
#endif /* AMMUNITION_STRING_H */
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,105 @@
|
||||
/*
|
||||
FILE NAME: arithm.h
|
||||
|
||||
TITLE: Include file of package for arbitrary precision integer
|
||||
arithmetic
|
||||
|
||||
DESCRIPTION: This header file contains ANSI C prototype definitions of
|
||||
the package functions and definitions of external
|
||||
variable of the package and C++ classes for arbitrary
|
||||
precision integer arithmetic.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __ARITHMETIC__
|
||||
#define __ARITHMETIC__
|
||||
|
||||
#include "ammunition_limits.h"
|
||||
|
||||
/* This page contains definitions of variables and macros common for
|
||||
all package functions. */
|
||||
|
||||
/* The value of macro is suggested to be maximum length of integer operands
|
||||
The length of use integers should be not greater than this value. */
|
||||
|
||||
#define MAX_INTEGER_OPERAND_SIZE 128
|
||||
|
||||
/* The following macro value is sign of integer number (0 or 1) given
|
||||
as macro parameter. */
|
||||
|
||||
#define INTEGER_SIGN(operand) (*(unsigned char *) (operand) >> (CHAR_BIT - 1))
|
||||
|
||||
extern int ammunition_overflow_bit;
|
||||
|
||||
void ammunition_add_unsigned_integer(int size, const void *op1, const void *op2,
|
||||
void *result);
|
||||
void ammunition_add_integer(int size, const void *op1, const void *op2,
|
||||
void *result);
|
||||
void ammunition_subtract_unsigned_integer(int size, const void *op1,
|
||||
const void *op2, void *result);
|
||||
void ammunition_subtract_integer(int size, const void *op1, const void *op2,
|
||||
void *result);
|
||||
void ammunition_multiply_unsigned_integer(int size, const void *op1,
|
||||
const void *op2, void *result);
|
||||
void ammunition_multiply_integer(int size, const void *op1, const void *op2,
|
||||
void *result);
|
||||
void ammunition_divide_unsigned_integer(int size, const void *op1,
|
||||
const void *op2, void *result);
|
||||
void ammunition_divide_integer(int size, const void *op1, const void *op2,
|
||||
void *result);
|
||||
void ammunition_unsigned_integer_remainder(int size, const void *op1,
|
||||
const void *op2, void *result);
|
||||
|
||||
void ammunition_unsigned_integer_shift_right(int size, const void *operand,
|
||||
int bits, void *result);
|
||||
void ammunition_integer_shift_right(int size, const void *operand, int bits,
|
||||
void *result);
|
||||
void ammunition_integer_shift_left(int size, const void *operand, int bits,
|
||||
void *result);
|
||||
void ammunition_unsigned_integer_shift_left(int size, const void *operand,
|
||||
int bits, void *result);
|
||||
|
||||
void ammunition_integer_or(int size, const void *op1, const void *op2,
|
||||
void *result);
|
||||
void ammunition_unsigned_integer_or(int size, const void *op1, const void *op2,
|
||||
void *result);
|
||||
void ammunition_integer_and(int size, const void *op1, const void *op2,
|
||||
void *result);
|
||||
void ammunition_unsigned_integer_and(int size, const void *op1, const void *op2,
|
||||
void *result);
|
||||
void ammunition_integer_not(int size, const void *operand, void *result);
|
||||
void ammunition_unsigned_integer_not(int size, const void *operand,
|
||||
void *result);
|
||||
|
||||
int ammunition_eq_unsigned_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_eq_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_ne_unsigned_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_ne_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_gt_unsigned_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_gt_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_lt_unsigned_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_lt_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_ge_unsigned_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_ge_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_le_unsigned_integer(int size, const void *op1, const void *op2);
|
||||
int ammunition_le_integer(int size, const void *op1, const void *op2);
|
||||
|
||||
void ammunition_change_unsigned_integer_size(int operand_size,
|
||||
const void *operand,
|
||||
int result_size, void *result);
|
||||
void ammunition_change_integer_size(int operand_size, const void *operand,
|
||||
int result_size, void *result);
|
||||
|
||||
char *ammunition_unsigned_integer_to_string(int size, const void *operand,
|
||||
char *result);
|
||||
char *ammunition_integer_to_string(int size, const void *operand, char *result);
|
||||
|
||||
char *ammunition_unsigned_integer_from_string(int size, const char *operand,
|
||||
void *result);
|
||||
char *ammunition_integer_from_string(int size, const char *operand,
|
||||
void *result);
|
||||
|
||||
char ammunition_isdigit(unsigned char c);
|
||||
int ammunition_isspace(int c);
|
||||
|
||||
#endif /* #ifndef __ARITHMETIC__ */
|
||||
@ -0,0 +1,305 @@
|
||||
/*
|
||||
|
||||
FILE NAME: bits.c
|
||||
|
||||
TITLE: Package for work with bits
|
||||
|
||||
DESCRIPTION: This file implements functions of the package for work
|
||||
with bit strings. A bit is given by address (start address) of
|
||||
byte from which counting bits starts and its displacement which
|
||||
is any non negative number of bit from the start address. The
|
||||
most significant bit of the start address byte has number 0.
|
||||
The bit string is given by its first bit and its length in
|
||||
bits.
|
||||
|
||||
*/
|
||||
|
||||
#include "bits.h"
|
||||
|
||||
/* This function determines that given bit string contains only zero
|
||||
bits. The function retruns TRUE if all bits of given bit string
|
||||
are zero or `bit_length' <= 0. Value of `bit_displacement' must be
|
||||
non-negative and can be greater than CHAR_BIT. */
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
int
|
||||
ammunition_is_zero_bit_string(const void *start_byte, int bit_displacement,
|
||||
int bit_length) {
|
||||
const unsigned char *current_byte = (unsigned const char *) start_byte;
|
||||
|
||||
if (bit_length <= 0)
|
||||
return 1 /* TRUE */;
|
||||
current_byte += bit_displacement / CHAR_BIT;
|
||||
bit_displacement %= CHAR_BIT;
|
||||
if (bit_length < CHAR_BIT - bit_displacement)
|
||||
return (((*current_byte << bit_displacement) &
|
||||
(UCHAR_MAX << (CHAR_BIT - bit_length))) &
|
||||
UCHAR_MAX) == 0;
|
||||
else if (bit_displacement != 0) {
|
||||
if (((*current_byte << bit_displacement) & UCHAR_MAX) != 0)
|
||||
return 0 /* FALSE */;
|
||||
current_byte += 1;
|
||||
bit_length -= CHAR_BIT - bit_displacement;
|
||||
}
|
||||
__pragma_loopbound(0, 7);
|
||||
while (bit_length >= CHAR_BIT) {
|
||||
if (*current_byte != 0)
|
||||
return 0 /* FALSE */;
|
||||
current_byte++;
|
||||
bit_length -= CHAR_BIT;
|
||||
}
|
||||
if (bit_length > 0 && (*current_byte >> (CHAR_BIT - bit_length)) != 0)
|
||||
return 0 /* FALSE */;
|
||||
return 1 /* TRUE */;
|
||||
}
|
||||
|
||||
/* This function sets up new value of all bits of given bit string.
|
||||
This function is analog of standard C function `memset'. Value of
|
||||
`bit_displacement' must be non-negative and can be greater than
|
||||
CHAR_BIT. */
|
||||
|
||||
void
|
||||
ammunition_bit_string_set(void *start_byte, int bit_displacement, int bit,
|
||||
int bit_length) {
|
||||
unsigned char *current_byte = (unsigned char *) start_byte;
|
||||
unsigned char filling_byte;
|
||||
int mask;
|
||||
|
||||
if (bit_length <= 0)
|
||||
return;
|
||||
bit = bit != 0; /* 1 or 0 */
|
||||
filling_byte = (bit ? UCHAR_MAX : 0);
|
||||
current_byte += bit_displacement / CHAR_BIT;
|
||||
bit_displacement %= CHAR_BIT;
|
||||
if (bit_displacement != 0) {
|
||||
mask = UCHAR_MAX << (CHAR_BIT - bit_displacement);
|
||||
if (bit_length < CHAR_BIT - bit_displacement)
|
||||
mask |= UCHAR_MAX >> (bit_displacement + bit_length);
|
||||
*current_byte = (*current_byte & mask) | (filling_byte & ~mask);
|
||||
current_byte += 1;
|
||||
bit_length -= CHAR_BIT - bit_displacement;
|
||||
}
|
||||
__pragma_loopbound(0, 8);
|
||||
while (bit_length >= CHAR_BIT) {
|
||||
*current_byte = filling_byte;
|
||||
current_byte++;
|
||||
bit_length -= CHAR_BIT;
|
||||
}
|
||||
if (bit_length > 0)
|
||||
*current_byte =
|
||||
(*current_byte & ~(UCHAR_MAX << (CHAR_BIT - bit_length))) |
|
||||
(filling_byte & (UCHAR_MAX << (CHAR_BIT - bit_length)));
|
||||
}
|
||||
|
||||
/* This function copys a bit string to another bit string. This
|
||||
function is analog of standard C function `memcpy'. Values of
|
||||
`to_bit_displacement' and `from_bit_displacement' must be
|
||||
non-negative and can be greater than CHAR_BIT. The bit string must
|
||||
be non-overlapped. */
|
||||
|
||||
void
|
||||
ammunition_bit_string_copy(void *to, int to_bit_displacement, const void *from,
|
||||
int from_bit_displacement, int bit_length) {
|
||||
unsigned char *current_to_byte = (unsigned char *) to;
|
||||
const unsigned char *current_from_byte = (unsigned const char *) from;
|
||||
int byte;
|
||||
int mask;
|
||||
|
||||
if (bit_length <= 0)
|
||||
return;
|
||||
current_to_byte += to_bit_displacement / CHAR_BIT;
|
||||
to_bit_displacement %= CHAR_BIT;
|
||||
current_from_byte += from_bit_displacement / CHAR_BIT;
|
||||
from_bit_displacement %= CHAR_BIT;
|
||||
__pragma_loopbound(0, 7);
|
||||
while (1) {
|
||||
byte =
|
||||
(((*current_from_byte << from_bit_displacement) & UCHAR_MAX) |
|
||||
(from_bit_displacement != 0 &&
|
||||
bit_length > (CHAR_BIT - from_bit_displacement)
|
||||
? current_from_byte[1] >> (CHAR_BIT - from_bit_displacement)
|
||||
: 0));
|
||||
if (bit_length <= CHAR_BIT)
|
||||
break;
|
||||
/* Shift is correct when to_bit_displacement == 0 because its
|
||||
value is less than word bit size. */
|
||||
*current_to_byte = (*current_to_byte &
|
||||
(UCHAR_MAX << (CHAR_BIT - to_bit_displacement))) |
|
||||
(byte >> to_bit_displacement);
|
||||
if (to_bit_displacement != 0)
|
||||
current_to_byte[1] =
|
||||
(current_to_byte[1] & (UCHAR_MAX >> to_bit_displacement)) |
|
||||
(byte << (CHAR_BIT - to_bit_displacement));
|
||||
bit_length -= CHAR_BIT;
|
||||
current_from_byte++;
|
||||
current_to_byte++;
|
||||
}
|
||||
/* Shift is correct when to_bit_displacement == 0 because its
|
||||
value is less than word bit size. */
|
||||
mask = ((UCHAR_MAX << (CHAR_BIT - to_bit_displacement)) |
|
||||
(UCHAR_MAX >> (to_bit_displacement + bit_length)));
|
||||
*current_to_byte =
|
||||
(*current_to_byte & mask) | ((byte >> to_bit_displacement) & ~mask);
|
||||
bit_length -= CHAR_BIT - to_bit_displacement;
|
||||
if (bit_length > 0)
|
||||
current_to_byte[1] = (current_to_byte[1] & (UCHAR_MAX >> bit_length)) |
|
||||
((byte << (CHAR_BIT - to_bit_displacement)) &
|
||||
(UCHAR_MAX << (CHAR_BIT - bit_length)));
|
||||
}
|
||||
|
||||
/* This function copys a bit string to another bit string. Copying
|
||||
starts with the last bits of the bit strings. This function is
|
||||
used by function `bit_string_move'. Values of
|
||||
`to_bit_displacement' and `from_bit_displacement' must be
|
||||
non-negative and can be greater than CHAR_BIT. The bit string must
|
||||
be non-overlapped. */
|
||||
|
||||
void
|
||||
ammunition_reverse_bit_string_copy(void *to, int to_bit_displacement,
|
||||
const void *from, int from_bit_displacement,
|
||||
int bit_length) {
|
||||
unsigned char *current_to_byte = (unsigned char *) to;
|
||||
const unsigned char *current_from_byte = (unsigned const char *) from;
|
||||
int byte;
|
||||
int mask;
|
||||
|
||||
if (bit_length <= 0)
|
||||
return;
|
||||
to_bit_displacement += bit_length - 1;
|
||||
current_to_byte += to_bit_displacement / CHAR_BIT; /* last byte */
|
||||
to_bit_displacement %= CHAR_BIT; /* last bit */
|
||||
from_bit_displacement += bit_length - 1;
|
||||
current_from_byte += from_bit_displacement / CHAR_BIT; /* last byte */
|
||||
from_bit_displacement %= CHAR_BIT; /* last bit */
|
||||
__pragma_loopbound(0, 7);
|
||||
while (1) {
|
||||
/* Shift is correct when to_bit_displacement == 0 because its
|
||||
value is less than word bit size. */
|
||||
byte = ((*current_from_byte >> (CHAR_BIT - 1 - from_bit_displacement)) |
|
||||
((from_bit_displacement != CHAR_BIT - 1 &&
|
||||
bit_length > from_bit_displacement + 1
|
||||
? current_from_byte[-1] << (from_bit_displacement + 1)
|
||||
: 0) &
|
||||
UCHAR_MAX));
|
||||
if (bit_length <= CHAR_BIT)
|
||||
break;
|
||||
/* Shift is correct when to_bit_displacement == 0 because its
|
||||
value is less than word bit size. */
|
||||
*current_to_byte =
|
||||
(*current_to_byte & (UCHAR_MAX >> (to_bit_displacement + 1))) |
|
||||
(byte << (CHAR_BIT - 1 - to_bit_displacement));
|
||||
if (to_bit_displacement != CHAR_BIT - 1)
|
||||
current_to_byte[-1] =
|
||||
(current_to_byte[-1] &
|
||||
(UCHAR_MAX << (CHAR_BIT - 1 - to_bit_displacement))) |
|
||||
(byte >> (to_bit_displacement + 1));
|
||||
bit_length -= CHAR_BIT;
|
||||
current_from_byte--;
|
||||
current_to_byte--;
|
||||
}
|
||||
/* Shift is correct when to_bit_displacement == 0 because its
|
||||
value is less than word bit size. */
|
||||
mask = ((UCHAR_MAX >> (to_bit_displacement + 1)) |
|
||||
(UCHAR_MAX << (CHAR_BIT - 1 - to_bit_displacement + bit_length)));
|
||||
*current_to_byte = (*current_to_byte & mask) |
|
||||
((byte << (CHAR_BIT - 1 - to_bit_displacement)) & ~mask);
|
||||
bit_length -= to_bit_displacement + 1;
|
||||
if (bit_length > 0)
|
||||
current_to_byte[-1] =
|
||||
(current_to_byte[-1] & (UCHAR_MAX << bit_length)) |
|
||||
(byte >> (to_bit_displacement + 1) &
|
||||
(UCHAR_MAX >> (CHAR_BIT - bit_length)));
|
||||
}
|
||||
|
||||
/* This function copys a bit string to another bit string with the aid
|
||||
of functions `bit_string_copy' and `reverse_bit_string_copy'. This
|
||||
function is analog of standard C function `memmove'. Values of
|
||||
`to_bit_displacement' and `from_bit_displacement' must be
|
||||
non-negative and can be greater than CHAR_BIT. The bit string can
|
||||
be overlapped. */
|
||||
|
||||
void
|
||||
ammunition_bit_string_move(void *to, int to_bit_displacement, const void *from,
|
||||
int from_bit_displacement, int bit_length) {
|
||||
unsigned char *current_to_byte = (unsigned char *) to;
|
||||
const unsigned char *current_from_byte = (unsigned const char *) from;
|
||||
|
||||
if (bit_length <= 0)
|
||||
return;
|
||||
current_to_byte += to_bit_displacement / CHAR_BIT;
|
||||
to_bit_displacement %= CHAR_BIT;
|
||||
current_from_byte += from_bit_displacement / CHAR_BIT;
|
||||
from_bit_displacement %= CHAR_BIT;
|
||||
if (current_from_byte > current_to_byte ||
|
||||
(current_from_byte == current_to_byte &&
|
||||
from_bit_displacement > to_bit_displacement))
|
||||
ammunition_bit_string_copy(current_to_byte, to_bit_displacement,
|
||||
current_from_byte, from_bit_displacement,
|
||||
bit_length);
|
||||
else
|
||||
ammunition_reverse_bit_string_copy(current_to_byte, to_bit_displacement,
|
||||
current_from_byte,
|
||||
from_bit_displacement, bit_length);
|
||||
}
|
||||
|
||||
/* This function compares bit strings. This function is analog of
|
||||
standard C function `memcmp'. The function returns 0 if the bit
|
||||
strings are equal, 1 if the first bit string is greater than the
|
||||
second, -1 if the first bit string is less than the first. Values
|
||||
of `bit_displacement1' and `bit_displacement2' must be non-negative
|
||||
and can be greater than CHAR_BIT. */
|
||||
|
||||
int
|
||||
ammunition_bit_string_comparison(const void *str1, int bit_displacement1,
|
||||
const void *str2, int bit_displacement2,
|
||||
int bit_length) {
|
||||
const unsigned char *current_byte1 = (unsigned const char *) str1;
|
||||
const unsigned char *current_byte2 = (unsigned const char *) str2;
|
||||
int byte1;
|
||||
int byte2;
|
||||
int mask;
|
||||
|
||||
if (bit_length <= 0)
|
||||
return 0;
|
||||
current_byte1 += bit_displacement1 / CHAR_BIT;
|
||||
bit_displacement1 %= CHAR_BIT;
|
||||
current_byte2 += bit_displacement2 / CHAR_BIT;
|
||||
bit_displacement2 %= CHAR_BIT;
|
||||
__pragma_loopbound(0, 7);
|
||||
while (1) {
|
||||
byte1 = (((*current_byte1 << bit_displacement1) & UCHAR_MAX) |
|
||||
(bit_displacement1 != 0
|
||||
/* Shift is correct when to_bit_displacement == 0
|
||||
because its value is less than word bit size. */
|
||||
&& bit_length > CHAR_BIT - bit_displacement1
|
||||
? current_byte1[1] >> (CHAR_BIT - bit_displacement1)
|
||||
: 0));
|
||||
byte2 = (((*current_byte2 << bit_displacement2) & UCHAR_MAX) |
|
||||
(bit_displacement2 != 0 &&
|
||||
bit_length > CHAR_BIT - bit_displacement2
|
||||
? current_byte2[1] >> (CHAR_BIT - bit_displacement2)
|
||||
: 0));
|
||||
if (bit_length <= CHAR_BIT)
|
||||
break;
|
||||
if (byte1 > byte2)
|
||||
return 1;
|
||||
else if (byte1 < byte2)
|
||||
return -1;
|
||||
bit_length -= CHAR_BIT;
|
||||
current_byte2++;
|
||||
current_byte1++;
|
||||
}
|
||||
/* Shift is correct when to_bit_displacement == 0 because its value
|
||||
is less than word bit size. */
|
||||
mask = UCHAR_MAX << (CHAR_BIT - bit_length);
|
||||
if ((byte1 & mask) > (byte2 & mask))
|
||||
return 1;
|
||||
else if ((byte1 & mask) < (byte2 & mask))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
FILE NAME: bits.h
|
||||
|
||||
TITLE: Include file of package for work with bits
|
||||
|
||||
DESCRIPTION:
|
||||
This is header file contains macros and the ANSI C prototype
|
||||
definitions for the package for work with bits and bit strings
|
||||
and C++ class for work with bits and bit strings. A bit is
|
||||
given by address (start address) of byte from which counting
|
||||
bits starts and its displacement which is any non negative
|
||||
number of bit from the start address. The most significant bit
|
||||
of the start address byte has number 0. The bit string is
|
||||
given by its first bit and its length in bits.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __BITS__
|
||||
#define __BITS__
|
||||
|
||||
#include "ammunition_limits.h"
|
||||
|
||||
/* This macro value returns bit vlaue (0 or 1) with given bit
|
||||
displacement (0, 1, ...). The macro has side effects! Value of
|
||||
`bit_displacement' must be nonegative and can be greater than
|
||||
CHAR_BIT. */
|
||||
|
||||
#define BIT(start_byte, bit_displacement) \
|
||||
((((const char *) (start_byte))[(bit_displacement) / CHAR_BIT] >> \
|
||||
(CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT)) & \
|
||||
1)
|
||||
|
||||
/* This macro value sets up new value (must be `0' or `1') of a given
|
||||
bit (bit displacement starts with 0). The macro has side effects!
|
||||
Value of `bit_displacement' must be nonegative and can be greater
|
||||
than CHAR_BIT. */
|
||||
|
||||
#define SET_BIT(start_byte, bit_displacement, bit) \
|
||||
(((char *) (start_byte))[(bit_displacement) / CHAR_BIT] = \
|
||||
(((char *) (start_byte))[(bit_displacement) / CHAR_BIT] & \
|
||||
~(1 << (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT))) | \
|
||||
((bit) << (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT)))
|
||||
|
||||
int ammunition_is_zero_bit_string(const void *start_byte, int bit_displacement,
|
||||
int bit_length);
|
||||
void ammunition_bit_string_set(void *start_byte, int bit_displacement, int bit,
|
||||
int bit_length);
|
||||
void ammunition_bit_string_copy(void *to, int to_bit_displacement,
|
||||
const void *from, int from_bit_displacement,
|
||||
int bit_length);
|
||||
void ammunition_bit_string_move(void *to, int to_bit_displacement,
|
||||
const void *from, int from_bit_displacement,
|
||||
int bit_length);
|
||||
int ammunition_bit_string_comparison(const void *str1, int bit_displacement1,
|
||||
const void *str2, int bit_displacement2,
|
||||
int bit_length);
|
||||
|
||||
#endif /* #ifndef __BITS__ */
|
||||
Reference in New Issue
Block a user