234 lines
6.5 KiB
C
234 lines
6.5 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (C) Microsoft Corporation, 1995 - 1999
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
Align.h
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Defines a macro for aligning an integer value or pointer
|
||
|
to 0 mod 2^n for any n.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Mario Goertzel [MarioGo]
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
MarioGo 12-22-95 Bits 'n pieces
|
||
|
MarioGo 02-19-96 Made type safe for C++.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef _ALIGN_H
|
||
|
#define _ALIGN_H
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
//
|
||
|
// The C++ interface looks like
|
||
|
//
|
||
|
// val = Align(val, 8) // returns val aligned to 0 mod 8
|
||
|
// val = Align16(val); // returns val aligned to 0 mod 16
|
||
|
//
|
||
|
// Boths forms on the interface are equally efficient.
|
||
|
//
|
||
|
// Returns the argument aligned up to the nearest "0 mod factor" boundary. Has
|
||
|
// no affect on values which are already aligned to 0 mod factor. The argument
|
||
|
// maybe any integer or void pointer type.
|
||
|
//
|
||
|
//
|
||
|
|
||
|
#define DECL_ALIGN_N(type) inline type Align( type value, int poft) \
|
||
|
{ \
|
||
|
return (type)( ((unsigned long)(value) + ((poft)-1)) & ~(poft - 1) ); \
|
||
|
}
|
||
|
|
||
|
#define DECL_ALIGN(poft, type) inline type Align##poft ( type value ) \
|
||
|
{ \
|
||
|
return Align(value, poft); \
|
||
|
}
|
||
|
|
||
|
#define DECL_PAD_N(type) inline unsigned int Pad( type value, int poft ) \
|
||
|
{ \
|
||
|
return (-(long)value) & (poft - 1); \
|
||
|
}
|
||
|
|
||
|
#define DECL_PAD(poft, type) inline unsigned int Pad##poft (type value) \
|
||
|
{ \
|
||
|
return Pad(value, poft); \
|
||
|
}
|
||
|
|
||
|
// same padding, but on pointer type size of argument
|
||
|
#define DECL_ALIGN_PTR_N(type) inline type AlignPtr( type value, int poft) \
|
||
|
{ \
|
||
|
return (type)( ((ULONG_PTR)(value) + ((poft)-1)) & ~(poft - 1) ); \
|
||
|
}
|
||
|
|
||
|
#define DECL_ALIGN_PTR(poft, type) inline type AlignPtr##poft ( type value ) \
|
||
|
{ \
|
||
|
return AlignPtr(value, poft); \
|
||
|
}
|
||
|
|
||
|
#define DECL_PAD_PTR_N(type) inline unsigned int PadPtr( type value, int poft ) \
|
||
|
{ \
|
||
|
return (unsigned int)((-(LONG_PTR)value) & (poft - 1)); \
|
||
|
}
|
||
|
|
||
|
#define DECL_PAD_PTR(poft, type) inline unsigned int PadPtr##poft (type value) \
|
||
|
{ \
|
||
|
return PadPtr(value, poft); \
|
||
|
}
|
||
|
|
||
|
#define DECL_ALL_ALIGN(type) \
|
||
|
DECL_ALIGN_N(type) \
|
||
|
DECL_ALIGN(2, type) \
|
||
|
DECL_ALIGN(4, type) \
|
||
|
DECL_ALIGN(8, type) \
|
||
|
DECL_ALIGN(16, type) \
|
||
|
DECL_ALIGN(32, type)
|
||
|
|
||
|
#define DECL_ALL_PAD(type) \
|
||
|
DECL_PAD_N(type) \
|
||
|
DECL_PAD(2, type) \
|
||
|
DECL_PAD(4, type) \
|
||
|
DECL_PAD(8, type) \
|
||
|
DECL_PAD(16, type) \
|
||
|
DECL_PAD(32, type)
|
||
|
|
||
|
#define DECL_ALL_ALIGN_PTR(type) \
|
||
|
DECL_ALIGN_PTR_N(type) \
|
||
|
DECL_ALIGN_PTR(2, type) \
|
||
|
DECL_ALIGN_PTR(4, type) \
|
||
|
DECL_ALIGN_PTR(8, type) \
|
||
|
DECL_ALIGN_PTR(16, type) \
|
||
|
DECL_ALIGN_PTR(32, type)
|
||
|
|
||
|
#define DECL_ALL_PAD_PTR(type) \
|
||
|
DECL_PAD_PTR_N(type) \
|
||
|
DECL_PAD_PTR(2, type) \
|
||
|
DECL_PAD_PTR(4, type) \
|
||
|
DECL_PAD_PTR(8, type) \
|
||
|
DECL_PAD_PTR(16, type) \
|
||
|
DECL_PAD_PTR(32, type)
|
||
|
|
||
|
#define DECL_ALL_ALIGN_AND_PAD(type) \
|
||
|
DECL_ALL_PAD(type) \
|
||
|
DECL_ALL_ALIGN(type)
|
||
|
|
||
|
#define DECL_ALL_ALIGN_AND_PAD_PTR(type) \
|
||
|
DECL_ALL_PAD_PTR(type) \
|
||
|
DECL_ALL_ALIGN_PTR(type)
|
||
|
|
||
|
DECL_ALL_ALIGN_AND_PAD(short)
|
||
|
DECL_ALL_ALIGN_AND_PAD(unsigned short)
|
||
|
DECL_ALL_ALIGN_AND_PAD(long)
|
||
|
DECL_ALL_ALIGN_AND_PAD(unsigned long)
|
||
|
DECL_ALL_ALIGN_AND_PAD(int)
|
||
|
DECL_ALL_ALIGN_AND_PAD(unsigned int)
|
||
|
DECL_ALL_ALIGN_AND_PAD_PTR(void __RPC_FAR *)
|
||
|
|
||
|
#ifdef _WIN64
|
||
|
DECL_ALL_ALIGN_AND_PAD(unsigned __int64)
|
||
|
#endif
|
||
|
|
||
|
inline BOOL IsBufferAligned(PVOID p)
|
||
|
{
|
||
|
#if defined(_WIN64)
|
||
|
return (((ULONG_PTR)p % 16) == 0);
|
||
|
#else
|
||
|
return (((ULONG_PTR)p % 8) == 0);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
inline BOOL IsBufferSizeAligned(size_t s)
|
||
|
{
|
||
|
#if defined(_WIN64)
|
||
|
return ((s % 16) == 0);
|
||
|
#else
|
||
|
return ((s % 8) == 0);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
inline unsigned int PadToNaturalBoundary (unsigned int Value)
|
||
|
{
|
||
|
#if defined(_WIN64)
|
||
|
return Pad16(Value);
|
||
|
#else
|
||
|
return Pad8(Value);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
inline PVOID AlignOnNaturalBoundary (PVOID Value)
|
||
|
{
|
||
|
#if defined(_WIN64)
|
||
|
return AlignPtr16(Value);
|
||
|
#else
|
||
|
return AlignPtr8(Value);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
// required for global constant expressions
|
||
|
#define ConstPadN(p, poft) ( (-(long)p) & (poft - 1) )
|
||
|
|
||
|
#if defined(_WIN64)
|
||
|
#define RPCRT_DEFAULT_STRUCT_ALIGNMENT 8
|
||
|
#else
|
||
|
#define RPCRT_DEFAULT_STRUCT_ALIGNMENT 4
|
||
|
#endif
|
||
|
|
||
|
#define SIZE_OF_OBJECT_AND_PADDING(ObjectType) \
|
||
|
(sizeof(ObjectType) + ConstPadN(sizeof(ObjectType), RPCRT_DEFAULT_STRUCT_ALIGNMENT))
|
||
|
|
||
|
#else
|
||
|
|
||
|
// C interface.
|
||
|
|
||
|
#define AlignN(p, poft) ( ((unsigned long)(p) + ((poft)-1)) & ~(poft - 1) )
|
||
|
#define PadN(p, poft) ( (-(long)p) & (poft - 1) )
|
||
|
|
||
|
#ifdef DOS
|
||
|
#define AlignPtrN(value, poft) (void __far *)AlignN(value, poft)
|
||
|
#define AlignNearPtrN(value, poft) (void __near *)AlignN(value, poft)
|
||
|
#else
|
||
|
#define AlignPtrN(value, poft) (void *)AlignN(value, poft)
|
||
|
#define AlignNearPtrN(value, poft) (void *)AlignN(value, poft)
|
||
|
#endif
|
||
|
|
||
|
// For aligning integer values
|
||
|
|
||
|
#define Align2(p) AlignN((p), 2)
|
||
|
#define Align4(p) AlignN((p), 4)
|
||
|
#define Align8(p) AlignN((p), 8)
|
||
|
#define Align16(p) AlignN((p), 16)
|
||
|
#define Align32(p) AlignN((p), 32)
|
||
|
|
||
|
// For aligning pointers
|
||
|
|
||
|
#define AlignPtr2(p) AlignPtrN((p), 2)
|
||
|
#define AlignPtr4(p) AlignPtrN((p), 4)
|
||
|
#define AlignPtr8(p) AlignPtrN((p), 8)
|
||
|
#define AlignPtr16(p) AlignPtrN((p), 16)
|
||
|
#define AlignPtr32(p) AlignPtrN((p), 32)
|
||
|
|
||
|
// For near pointers
|
||
|
#define AlignNearPtr2(p) AlignNearPtrN((p), 2)
|
||
|
#define AlignNearPtr4(p) AlignNearPtrN((p), 4)
|
||
|
#define AlignNearPtr8(p) AlignNearPtrN((p), 8)
|
||
|
#define AlignNearPtr16(p) AlignNearPtrN((p), 16)
|
||
|
#define AlignNearPtr32(p) AlignNearPtrN((p), 32)
|
||
|
|
||
|
// For everything
|
||
|
#define Pad2(p) PadN((p), 2)
|
||
|
#define Pad4(p) PadN((p), 4)
|
||
|
#define Pad8(p) PadN((p), 8)
|
||
|
#define Pad16(p) PadN((p), 16)
|
||
|
#define Pad32(p) PadN((p), 32)
|
||
|
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
#endif // _ALIGN_H
|
||
|
|