/************************************************************************
 *
 * This file contains the platform-dependent definitions for the x86_64
 * in 64-bit mode running Linux 2.4.x or later.
 *
 *	Copyright (C) 1999-2008 Cincom Systems, Inc.
 *
 ************************************************************************/

#define RIGHT_BIT_FIELD_ORDER 1 /* Compiler ordering of bit fields in structs */

#define HaveCleanSignals TRUE
#ifdef PLATFORM_SIGNAL_HANDLER
#   define CanSmashRegisters TRUE
#else
#   define CanSmashRegisters FALSE
#endif
#define HaveLimitRegister FALSE

#if !defined(UseEdenAllocRegister)
# define UseEdenAllocRegister FALSE
#endif
#if UseEdenAllocRegister && !defined(assembly)
register void *edenAllocAndLimitRegister asm("%r15");
#endif

/*
 * Use a 32-bit send cache even though this is a 64-bit platform.
 */
#define ThinSendCache 1

/* Ideally this would be defined in the processor include file, but differences
 * in platform assembler syntax makes this a better place.
 */
#define GlueProc "gluex86_64.h"
/* This is potentially OS-specific and so does belong here.
 */
#define platcallc_h "x86_64CallC.h"

#define pdFPUType() 1

/* The following instruction resets the floating-point unit to the desired
 * initial state which is necessary for correct detection of exceptions in
 * floating-point primitives.  The FPU won't generate a NaN for an illegal
 * operation such as a divide-by-zero if the exception bit corresponding to
 * that exception is already set in the FPU status word.  So to ensure NaNs
 * are produced it is necessary to clear the exception bits before any
 * floating-point operation.  This is because e.g. external code might leave
 * exception bits set in the status word.  We do this on re-entry to the system
 * after callouts or callbacks.
 * Implementing it as a single instruction is the fastest approach.
 */
#define setSaneFPUState() asm("fnclex")

/* The AMD x86-64 ABI requires 16-byte alignment.
 */
#define C_STACK_POINTER_BYTE_ALIGNMENT 16
#if defined(__GNUC__)
# define getsp() ({ register void *sp;				\
	asm volatile ("movq %%rsp,%0" : "=r"(sp) : );	\
	sp; })
#elif !defined(assembly)
extern void *getsp(void);
#endif

/* define the context path to the PC register */
#define SC_PC uc_mcontext.gregs[REG_RIP]
#if !defined(OE_PROFILE)
# define OE_PROFILE 1
#endif

/* I/O defines */
#define PLAT_OSNAME "unix sysV x86_64 linux"

/* Use sbrk for initial alloc to ensure permSpace is below any new old segs. */
#define MORE_MEMORY_USES_SBRK 1
#define USV 1
#define USVR4 1
/* To interoperate with Linux Threads the stack zone needs to be allocated
 * on the stack.
 */
#define ALLOCATE_STACKZONE_ON_C_STACK TRUE

#define HaveWriteSigiosOnDisplayConnection TRUE

/* This is to ensure callee-saved registers are saved/restored on callback. */
#define USE_JMPBUF 1
