#include <stdio.h>

#define OBTER_ULTIMOS_BITS(x, k) ((x) & ((1 << (k)) - 1))
#define DESCARTAR_ULTIMOS_BITS(x, k) ((x) >> (k))

typedef struct CACHE {
    unsigned int lineSize;
    unsigned int associativity;
    unsigned int numLines;
} CACHE;

/*unsigned int log2(unsigned int x) {
    unsigned long long int resultado = 0;
    while (x >>= 1) resultado++;
    return resultado;
}*/

int main(void) {
    unsigned long long int address = 0x123456789ABCDEFLL;
    CACHE cacheconfig;
    cacheconfig.lineSize = 20;
    cacheconfig.numLines = 200;
    cacheconfig.associativity = 4;

    unsigned int a = log2(cacheconfig.numLines / cacheconfig.associativity);
    unsigned int b = log2(cacheconfig.lineSize);
    long unsigned int Tag = DESCARTAR_ULTIMOS_BITS(OBTER_ULTIMOS_BITS(address, cacheconfig.lineSize), b);
    long unsigned int Index = DESCARTAR_ULTIMOS_BITS(OBTER_ULTIMOS_BITS(address, b + a), b);
    long unsigned int Dado = OBTER_ULTIMOS_BITS(address, b);

	printf("%lu,%lu,%lu", Tag, Index, Dado);
	return 0;
}
