// Compiler Intrinsic
__builtin__ module LatencyOffset #(T, int OFFSET) {
    interface LatencyOffset : T in'0 -> T out'OFFSET
}

// Compiler Intrinsic
__builtin__ module CrossDomain #(T) {
    domain in_clk
    interface in_domain : T in'0
    domain out_clk
    interface out_domain : -> T out'0
}

__builtin__ module IntToBits {
    interface IntToBits : int value'0 -> bool[32] bits'0
}

__builtin__ module BitsToInt {
    interface IntToBits : bool[32] bits'0 -> int value'0
}

// For now these builtin declarations must be in this order, because they're constants in the code. 
// We'll get a better system for this at some point

// The decider of truth and falsity
__builtin__ struct bool {}
// An integer of variable size. Right now it's not implemented yet, so this is just a 32-bit int. 
__builtin__ struct int {}

// Single precision IEEE 32-bit float. Operators are definted externally, but it's defined here for convenience. 
__builtin__ struct float {}

// For intentionally triggering an ICE for debugging. It is a constant that crashes the compiler when it is evaluated
__builtin__ const bool __crash_compiler {}

// True, as in '1'
__builtin__ const bool true {}
// False, as in '0'
__builtin__ const bool false {}

// Fails to execute if C == false
__builtin__ const bool assert #(bool C) {}

// Returns the size of the given type, in bits. 
//
// `sizeof #(T: type bool) = 1`
// `sizeof #(T: type bool[50]) = 50`
// `sizeof #(T: type int[10][10]) = 3200`
__builtin__ const int sizeof #(T) {}


// Computes the Log2 of a value, rounded up. 
// 
// Typically used to find the size in bits that the address would need to be to address into a memory of size V. 
//
// Requires V > 0
//
// `clog2 #(V: 15) = 4`
// `clog2 #(V: 16) = 4`
// `clog2 #(V: 17) = 5`
__builtin__ const int clog2 #(int V) {}