Projects/tigris
Projects
/
tigris
Archived
5
0
Fork 0
This repository has been archived on 2024-07-04. You can view files and clone it, but cannot push or open issues or pull requests.
tigris/TIKI-100_emul-src/messaudio/tokenize.h

246 lines
8.6 KiB
C

/***************************************************************************
tokenize.h
Common definitions and macros for tokenizing definitions.
Copyright Nicola Salmoria and the MAME Team.
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/
#pragma once
#ifndef __TOKENIZE_H__
#define __TOKENIZE_H__
/***************************************************************************
CONSTANTS
***************************************************************************/
/* tokens per item */
#define TOKENS_PER_PTR (1)
#define TOKENS_PER_UINT32 (1)
#define TOKENS_PER_UINT64 (8 / sizeof(FPTR))
#define TOKENS_PER_ATTOTIME (TOKENS_PER_UINT32 + TOKENS_PER_UINT64)
/***************************************************************************
MACROS
***************************************************************************/
/* include this at the top of your union to get the standard fields */
#define TOKEN_COMMON_FIELDS \
FPTR i; \
const char * stringptr; \
const void * voidptr; \
const UINT8 * ui8ptr; \
const INT8 * i8ptr; \
const UINT16 * ui16ptr; \
const INT16 * i16ptr; \
const UINT32 * ui32ptr; \
const INT32 * i32ptr; \
const UINT64 * ui64ptr; \
const INT64 * i64ptr; \
/* ----- compile-time token generation macros ----- */
/* GCC and C99 compilers can use designated initializers for type safety */
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(_STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
#define TOKEN_VALUE(field,a) { .field = (a) }
#else
#define TOKEN_VALUE(field,a) { (FPTR)(a) }
#endif
/* token output primitives */
/* note that regardless of the endianness, UINT64s are packed LSW first */
#define TOKEN_PTR(field,p) TOKEN_VALUE(field, p)
#define TOKEN_STRING(p) TOKEN_VALUE(stringptr, p)
#define TOKEN_UINT32(a) TOKEN_VALUE(i, a)
#ifdef PTR64
#define TOKEN_UINT64(a) TOKEN_VALUE(i, a)
#else
#define TOKEN_UINT64(a) TOKEN_VALUE(i, (UINT32)(a)), TOKEN_VALUE(i, (UINT32)((a) >> 32))
#endif
/* mask a value to a fixed number of bits and then shift it */
#define SHIFT_AND_MASK32(val, bits, shift) (((UINT32)(val) & ((1 << (bits)) - 1)) << (shift))
#define SHIFT_AND_MASK64(val, bits, shift) (((UINT64)(val) & (((UINT64)1 << (bits)) - 1)) << (shift))
/* 32-bit integer packing */
#define TOKEN_UINT32_PACK1(val1, bits1) \
TOKEN_UINT32(SHIFT_AND_MASK32((val1), (bits1), 0))
#define TOKEN_UINT32_PACK2(val1, bits1, val2, bits2) \
TOKEN_UINT32(SHIFT_AND_MASK32((val1), (bits1), 0) | \
SHIFT_AND_MASK32((val2), (bits2), (bits1)))
#define TOKEN_UINT32_PACK3(val1, bits1, val2, bits2, val3, bits3) \
TOKEN_UINT32(SHIFT_AND_MASK32((val1), (bits1), 0) | \
SHIFT_AND_MASK32((val2), (bits2), (bits1)) | \
SHIFT_AND_MASK32((val3), (bits3), (bits1)+(bits2)))
#define TOKEN_UINT32_PACK4(val1, bits1, val2, bits2, val3, bits3, val4, bits4) \
TOKEN_UINT32(SHIFT_AND_MASK32((val1), (bits1), 0) | \
SHIFT_AND_MASK32((val2), (bits2), (bits1)) | \
SHIFT_AND_MASK32((val3), (bits3), (bits1)+(bits2)) | \
SHIFT_AND_MASK32((val4), (bits4), (bits1)+(bits2)+(bits3)))
/* 64-bit integer packing */
#define TOKEN_UINT64_PACK1(val1, bits1) \
TOKEN_UINT64(SHIFT_AND_MASK64((val1), (bits1), 0))
#define TOKEN_UINT64_PACK2(val1, bits1, val2, bits2) \
TOKEN_UINT64(SHIFT_AND_MASK64((val1), (bits1), 0) | \
SHIFT_AND_MASK64((val2), (bits2), (bits1)))
#define TOKEN_UINT64_PACK3(val1, bits1, val2, bits2, val3, bits3) \
TOKEN_UINT64(SHIFT_AND_MASK64((val1), (bits1), 0) | \
SHIFT_AND_MASK64((val2), (bits2), (bits1)) | \
SHIFT_AND_MASK64((val3), (bits3), (bits1)+(bits2)))
#define TOKEN_UINT64_PACK4(val1, bits1, val2, bits2, val3, bits3, val4, bits4) \
TOKEN_UINT64(SHIFT_AND_MASK64((val1), (bits1), 0) | \
SHIFT_AND_MASK64((val2), (bits2), (bits1)) | \
SHIFT_AND_MASK64((val3), (bits3), (bits1)+(bits2)) | \
SHIFT_AND_MASK64((val4), (bits4), (bits1)+(bits2)+(bits3)))
/* ----- run-time token extraction macros ----- */
/* token fetch and advance primitives */
#define TOKEN_GET_PTR(tp,field) (((tp)++)->field)
#define TOKEN_GET_STRING(tp) (((tp)++)->stringptr)
#define TOKEN_GET_UINT32(tp) (((tp)++)->i)
#ifdef PTR64
#define TOKEN_EXTRACT_UINT64(tp,a) do { (a) = (tp)->i; (tp)++; } while (0)
#else
#define TOKEN_EXTRACT_UINT64(tp,a) do { (a) = (tp)[0].i | ((UINT64)(tp)[1].i << 32); (tp) += 2; } while (0)
#endif
/* token unfetch primitives */
#define TOKEN_UNGET_PTR(tp) ((tp)--)
#define TOKEN_UNGET_STRING(tp) ((tp)--)
#define TOKEN_UNGET_UINT32(tp) ((tp)--)
#define TOKEN_UNGET_UINT64(tp) ((tp) -= 8 / sizeof(FPTR))
/* token skip primitives */
#define TOKEN_SKIP_PTR(tp) ((tp)++)
#define TOKEN_SKIP_STRING(tp) ((tp)++)
#define TOKEN_SKIP_UINT32(tp) ((tp)++)
#define TOKEN_SKIP_UINT64(tp) ((tp) += 8 / sizeof(FPTR))
/* extract a value from a fixed number of bits; if bits is negative, treat it as a signed value */
#define UNSHIFT_AND_MASK32(src, val, bits, shift) do { \
if ((bits) < 0) \
(val) = token_sign_extend32((src) >> (shift), -(bits)); \
else \
(val) = token_zero_extend32((src) >> (shift), (bits)); \
} while (0)
#define UNSHIFT_AND_MASK64(src, val, bits, shift) do { \
if ((bits) < 0) \
(val) = token_sign_extend64((src) >> (shift), -(bits)); \
else \
(val) = token_zero_extend64((src) >> (shift), (bits)); \
} while (0)
/* cheesy inline absolute value */
#define TOKENABS(v) (((v) < 0) ? -(v) : (v))
/* 32-bit integer unpacking */
#define TOKEN_GET_UINT32_UNPACK1(tp, val1, bits1) do { \
UINT32 token32 = TOKEN_GET_UINT32(tp); \
UNSHIFT_AND_MASK32(token32, val1, (bits1), 0); \
} while (0)
#define TOKEN_GET_UINT32_UNPACK2(tp, val1, bits1, val2, bits2) do { \
UINT32 token32 = TOKEN_GET_UINT32(tp); \
UINT8 shift = 0; \
UNSHIFT_AND_MASK32(token32, val1, (bits1), shift); shift += TOKENABS(bits1); \
UNSHIFT_AND_MASK32(token32, val2, (bits2), shift); \
} while (0)
#define TOKEN_GET_UINT32_UNPACK3(tp, val1, bits1, val2, bits2, val3, bits3) do { \
UINT32 token32 = TOKEN_GET_UINT32(tp); \
UINT8 shift = 0; \
UNSHIFT_AND_MASK32(token32, val1, (bits1), shift); shift += TOKENABS(bits1); \
UNSHIFT_AND_MASK32(token32, val2, (bits2), shift); shift += TOKENABS(bits2); \
UNSHIFT_AND_MASK32(token32, val3, (bits3), shift); \
} while (0)
#define TOKEN_GET_UINT32_UNPACK4(tp, val1, bits1, val2, bits2, val3, bits3, val4, bits4) do { \
UINT32 token32 = TOKEN_GET_UINT32(tp); \
UINT8 shift = 0; \
UNSHIFT_AND_MASK32(token32, val1, (bits1), shift); shift += TOKENABS(bits1); \
UNSHIFT_AND_MASK32(token32, val2, (bits2), shift); shift += TOKENABS(bits2); \
UNSHIFT_AND_MASK32(token32, val3, (bits3), shift); shift += TOKENABS(bits3); \
UNSHIFT_AND_MASK32(token32, val4, (bits4), shift); \
} while (0)
/* 64-bit integer unpacking */
#define TOKEN_GET_UINT64_UNPACK1(tp, val1, bits1) do { \
UINT64 token64; \
TOKEN_EXTRACT_UINT64(tp, token64); \
UNSHIFT_AND_MASK64(token64, val1, (bits1), 0); \
} while (0)
#define TOKEN_GET_UINT64_UNPACK2(tp, val1, bits1, val2, bits2) do { \
UINT64 token64; \
UINT8 shift = 0; \
TOKEN_EXTRACT_UINT64(tp, token64); \
UNSHIFT_AND_MASK64(token64, val1, (bits1), shift); shift += TOKENABS(bits1); \
UNSHIFT_AND_MASK64(token64, val2, (bits2), shift); \
} while (0)
#define TOKEN_GET_UINT64_UNPACK3(tp, val1, bits1, val2, bits2, val3, bits3) do { \
UINT64 token64; \
UINT8 shift = 0; \
TOKEN_EXTRACT_UINT64(tp, token64); \
UNSHIFT_AND_MASK64(token64, val1, (bits1), shift); shift += TOKENABS(bits1); \
UNSHIFT_AND_MASK64(token64, val2, (bits2), shift); shift += TOKENABS(bits2); \
UNSHIFT_AND_MASK64(token64, val3, (bits3), shift); \
} while (0)
#define TOKEN_GET_UINT64_UNPACK4(tp, val1, bits1, val2, bits2, val3, bits3, val4, bits4) do { \
UINT64 token64; \
UINT8 shift = 0; \
TOKEN_EXTRACT_UINT64(tp, token64); \
UNSHIFT_AND_MASK64(token64, val1, (bits1), shift); shift += TOKENABS(bits1); \
UNSHIFT_AND_MASK64(token64, val2, (bits2), shift); shift += TOKENABS(bits2); \
UNSHIFT_AND_MASK64(token64, val3, (bits3), shift); shift += TOKENABS(bits3); \
UNSHIFT_AND_MASK64(token64, val4, (bits4), shift); \
} while (0)
/***************************************************************************
INLINE FUNCTIONS
***************************************************************************/
INLINE UINT32 token_zero_extend32(UINT32 val, UINT8 bits)
{
return val & (((UINT32)1 << bits) - 1);
}
INLINE INT32 token_sign_extend32(UINT32 val, UINT8 bits)
{
return (INT32)(val << (32 - bits)) >> (32 - bits);
}
INLINE UINT64 token_zero_extend64(UINT64 val, UINT8 bits)
{
return val & (((UINT64)1 << bits) - 1);
}
INLINE INT64 token_sign_extend64(UINT64 val, UINT8 bits)
{
return (INT64)(val << (64 - bits)) >> (64 - bits);
}
#endif