#ifndef GLOBALS
#define GLOBALS 1

#ifndef NFACTOR
#define NFACTOR 10
#endif

#if NFACTOR == 1
#  define __NF__ 2u
#elif NFACTOR == 2
# define __NF__ 4u
#elif NFACTOR == 3
#  define __NF__ 8u
#elif NFACTOR == 4
#  define __NF__ 16u
#elif NFACTOR == 5
#  define __NF__ 32u
#elif NFACTOR == 6
#  define __NF__ 64u
#elif NFACTOR == 7
#  define __NF__ 128u
#elif NFACTOR == 8
#  define __NF__ 256u
#elif NFACTOR == 9
#  define __NF__ 512u
#elif NFACTOR == 10
#  define __NF__ 1024u
#elif NFACTOR == 11
#  define __NF__ 2048u
#elif NFACTOR == 12
#  define __NF__ 4096u
#elif NFACTOR == 13
#  define __NF__ 8192u
#elif NFACTOR == 14
#  define __NF__ 16384u
#elif NFACTOR == 15
#  define __NF__ 32768u
#elif NFACTOR == 16
#  define __NF__ 65536u
#elif NFACTOR == 17
#  define __NF__ 131072u
#elif NFACTOR == 18
#  define __NF__ 262144u
#elif NFACTOR == 19
#  define __NF__ 524288u
#elif NFACTOR == 20
#  define __NF__ 1048576u
#else
# define __NF__ 1024u
#endif

#define E0 0x00FF00FFU
#define E1 0xFF00FF00U

#define SK00 0x80000000U
#define SK01 0x00000280U
#define SK02 0x5C5C5C5CU
#define SK03 0x36363636U
#define SK04 0x000004a0U
#define SK05 0x00000300U

#define ZERO   0x0U
#define ONE    0x1U
#define TWO    0x2U
#define THREE  0x3U

__constant uint16 Kc[4] = {
(uint16)(0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU, 0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U, 0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U, 0xc19bf174U),
(uint16)(0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU, 0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U, 0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U, 0x06ca6351U, 0x14292967U),
(uint16)(0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU, 0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U, 0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U, 0xd6990624U, 0xf40e3585U, 0x106aa070U),
(uint16)(0x19a4c116U, 0x1e376c08U, 0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU, 0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U, 0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U)
};

typedef struct INPUT_t{
	uint8 a;
	uint8 b;
	uint c;
	uint d;
	uint e;
	uint f;
}input_t;

#define rotl(x,y) rotate(x,y)
#define Ch(x,y,z) bitselect(z,y,x)
#define Maj(x,y,z) Ch((x^z),y,z)

#define EndianSwapa(n) (Ch(E0, rotl(n, 8U), rotl(n, 24U)))
#define EndianSwapb(n) (rotl(n & E0, 24U)|rotl(n & E1, 8U))

#define Tr2(x)		(rotl(x, 30U) ^ rotl(x, 19U) ^ rotl(x, 10U))
#define Tr1(x)		(rotl(x, 26U) ^ rotl(x, 21U) ^ rotl(x, 7U))

#define Wr2(x)		(rotl(x, 25U) ^ rotl(x, 14U) ^ (x>>3U))
#define Wr1(x)		(rotl(x, 15U) ^ rotl(x, 13U) ^ (x>>10U))

#define RND(a, b, c, d, e, f, g, h, k)  \
	h += Tr1(e);            \
	h += Ch(e, f, g);  \
	h += k;             \
	d += h;				\
	h += Tr2(a);       \
	h += Maj(a, b, c);

//# define CO_0 ((y*CONCURRENT_THREADS+x)<<1)
//# define CO_1 ((y*CONCURRENT_THREADS+x)<<1)+1
# define CO_0 (idx=(y*CONCURRENT_THREADS+x)<<1)
# define CO_1 idx+1
# define CO_W0 (idx=(y+x)<<1)
# define CO_W1 idx+1

#define FOUND (0xFF)
#define SETFOUND(Xnonce) output[output[FOUND]++] = Xnonce

#endif