// Minimal stdint.h for the W65816 runtime.  Standalone (does not
// include the host clang's stdint.h, which pulls in glibc headers
// and breaks the build).  Sizes per the W65816 backend's view:
//   char     = 8 bits
//   short    = 16 bits
//   int      = 16 bits
//   long     = 32 bits
//   long long = 64 bits

#ifndef _STDINT_H
#define _STDINT_H

typedef signed char        int8_t;
typedef unsigned char      uint8_t;
typedef short              int16_t;
typedef unsigned short     uint16_t;
typedef long               int32_t;
typedef unsigned long      uint32_t;
typedef long long          int64_t;
typedef unsigned long long uint64_t;

typedef int8_t   int_least8_t;
typedef uint8_t  uint_least8_t;
typedef int16_t  int_least16_t;
typedef uint16_t uint_least16_t;
typedef int32_t  int_least32_t;
typedef uint32_t uint_least32_t;
typedef int64_t  int_least64_t;
typedef uint64_t uint_least64_t;

typedef int16_t  int_fast8_t;
typedef uint16_t uint_fast8_t;
typedef int16_t  int_fast16_t;
typedef uint16_t uint_fast16_t;
typedef int32_t  int_fast32_t;
typedef uint32_t uint_fast32_t;
typedef int64_t  int_fast64_t;
typedef uint64_t uint_fast64_t;

// Under ptr32 (data layout `p:32:16`), pointers are 32 bits even though
// the IIgs's physical address bus is 24-bit; the high byte of the bank
// word is reserved.  `uintptr_t` is uint32_t so casts pointer↔integer
// round-trip without truncating the bank byte (libcxxabiSjlj's exception
// buffer pointers exercised this — uint16_t lost the bank).
typedef int32_t  intptr_t;
typedef uint32_t uintptr_t;

typedef int64_t  intmax_t;
typedef uint64_t uintmax_t;

#define INT8_MIN   (-0x7F - 1)
#define INT8_MAX   0x7F
#define UINT8_MAX  0xFFU
#define INT16_MIN  (-0x7FFF - 1)
#define INT16_MAX  0x7FFF
#define UINT16_MAX 0xFFFFU
#define INT32_MIN  (-0x7FFFFFFFL - 1)
#define INT32_MAX  0x7FFFFFFFL
#define UINT32_MAX 0xFFFFFFFFUL
#define INT64_MIN  (-0x7FFFFFFFFFFFFFFFLL - 1)
#define INT64_MAX  0x7FFFFFFFFFFFFFFFLL
#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL

#define INT_LEAST8_MIN   INT8_MIN
#define INT_LEAST8_MAX   INT8_MAX
#define UINT_LEAST8_MAX  UINT8_MAX
#define INT_LEAST16_MIN  INT16_MIN
#define INT_LEAST16_MAX  INT16_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define INT_LEAST32_MIN  INT32_MIN
#define INT_LEAST32_MAX  INT32_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define INT_LEAST64_MIN  INT64_MIN
#define INT_LEAST64_MAX  INT64_MAX
#define UINT_LEAST64_MAX UINT64_MAX

// int_fast{8,16}_t are i16; int_fast{32,64}_t are i32/i64.
#define INT_FAST8_MIN    INT16_MIN
#define INT_FAST8_MAX    INT16_MAX
#define UINT_FAST8_MAX   UINT16_MAX
#define INT_FAST16_MIN   INT16_MIN
#define INT_FAST16_MAX   INT16_MAX
#define UINT_FAST16_MAX  UINT16_MAX
#define INT_FAST32_MIN   INT32_MIN
#define INT_FAST32_MAX   INT32_MAX
#define UINT_FAST32_MAX  UINT32_MAX
#define INT_FAST64_MIN   INT64_MIN
#define INT_FAST64_MAX   INT64_MAX
#define UINT_FAST64_MAX  UINT64_MAX

// Under ptr32 uintptr_t is uint32_t (see typedef above) — these limit
// macros must match the type, not the historical INT16 mistake.
#define INTPTR_MIN   INT32_MIN
#define INTPTR_MAX   INT32_MAX
#define UINTPTR_MAX  UINT32_MAX

#define PTRDIFF_MIN  INT16_MIN
#define PTRDIFF_MAX  INT16_MAX

#define SIZE_MAX     UINT32_MAX

// wchar_t is int (i16) per stddef.h's typedef.
#define WCHAR_MIN    INT16_MIN
#define WCHAR_MAX    INT16_MAX

#define INTMAX_MIN   INT64_MIN
#define INTMAX_MAX   INT64_MAX
#define UINTMAX_MAX  UINT64_MAX

#define INT8_C(v)    v
#define UINT8_C(v)   v ## U
#define INT16_C(v)   v
#define UINT16_C(v)  v ## U
#define INT32_C(v)   v ## L
#define UINT32_C(v)  v ## UL
#define INT64_C(v)   v ## LL
#define UINT64_C(v)  v ## ULL
#define INTMAX_C(v)  v ## LL
#define UINTMAX_C(v) v ## ULL

#endif
