#pragma once

/// Tracking allocations with TRACK_ALLOCATIONS keeps a count of
/// exactly how many bytes are CONSed by Clasp
/// Compiling min-boehm-recompile with it defined 4:54 min and off 4.56 min
/// so it has no significant impact at this stage
#define TRACK_ALLOCATIONS // this may slow down allocation

#define TAG_BITS 3

// Match tags using (ptr&MATCH_TAG_MASK)==MATCH_TAG_EQ
// These values are used in point
//
// When you add/remove tags you will need to change write_ugly_object so that it can print that
// tagged object and you will need to change _rep_ in foundation.cc

#define FIXNUM_MASK 0x03
#define FIXNUM0_TAG 0x00
#define FIXNUM1_TAG 0x04 // fixnum means lower two bits are zero so two tags
#define FIXNUM_SHIFT 2
#define GENERAL_TAG 0b001
#define CHARACTER_TAG 0b010
#define CHARACTER_SHIFT TAG_BITS
#define CONS_TAG 0x03
#define VASLIST0_TAG 0x05
#define UNBOUND_TAG 0x07
#ifdef CLASP_SHORT_FLOAT
#define SHORT_FLOAT_TAG 0b1100
#define SINGLE_FLOAT_TAG 0b1101
#define SHORT_FLOAT_SHIFT (TAG_BITS + 1)
#define SINGLE_FLOAT_SHIFT (TAG_BITS + 1)
#else
#define SINGLE_FLOAT_TAG 0b110
#define SINGLE_FLOAT_SHIFT TAG_BITS
#endif
#if TAG_BITS == 3
#define CLASP_ALIGNMENT 8
#define ZERO_TAG_MASK 0x07
#define GC_TAG 0x07
#define IMMEDIATE_MASK 0x07
#define VASLIST_ALIGNMENT 8
// The following are different unbound-like values that can be tested for by
// comparing the least significant byte of a pointer to the following bytes.
#define UNBOUND_MASK ((uintptr_t)0xFF)
#define UNBOUND_BYTE ((uint8_t)(0x0 | UNBOUND_TAG))
#define NO_THREAD_LOCAL_BINDING_UNBOUND_BYTE ((uint8_t)(0x40 | UNBOUND_TAG))
#define NO_KEY_UNBOUND_BYTE ((uint8_t)(0x10 | UNBOUND_TAG))
#define DELETED_UNBOUND_BYTE ((uint8_t)(0x18 | UNBOUND_TAG))
#define SAME_AS_KEY_UNBOUND_BYTE ((uint8_t)(0x20 | UNBOUND_TAG))
#else // TAG_BITS==4
#define CLASP_ALIGNMENT 16
#define ZERO_TAG_MASK 0x0F
#define GC_TAG 0x0F
#define IMMEDIATE_MASK 0x0F
#define FIXNUM2_TAG 0x08 // fixnum means lower two bits are zero so four tags (if TAG_BITS==4)
#define FIXNUM3_TAG 0x0C // fixnum means lower two bits are zero so four tags (if TAG_BITS==4)
#define VASLIST_ALIGNMENT 16
#endif

/*! A test for pointers that MPS needs to fix/manage has the form (potential_ptr&POINTER_TAG_MASK)==POINTER_TAG_EQ)
    MPS needs to manage tagged pointers with POINTER_GENERAL_TAG or POINTER_CONS_TAG and nothing else.
    POINTER_GENERAL_TAG and POINTER_CONS_TAG objects are the only objects that are moved/fixed/updated by MPS.
    This will recognize 0x03 (CONS_TAG) and 0x01 (GENERAL_TAG) and not anything else ie: 0x05 (VALIST_S)*/
#define POINTER_TAG_MASK ((~(GENERAL_TAG ^ CONS_TAG)) & ZERO_TAG_MASK)
#define POINTER_TAG_EQ (GENERAL_TAG & CONS_TAG)

/// The size of the sigaltstack that Clasp requires to do at least some Common Lisp calls
/// 1 MB is large - if we have a lot of threads we will want to knock this down
#define SIGNAL_STACK_SIZE (1024 * 1024)

#define CLASP_DESIRED_STACK_CUR 16 * 1024 * 1024
