/* tGFSR32x4.c
   créé par Yann GUIDON (whygee@f-cpu.org) le 2 juin 2007
   Ce petit programme mesure la période du tGSFR de 4 mots
   de 32 bits dont la caractéristique est donnée dans MMUL par
 gcc -DMMUL=$i -Os -fomit-frame-pointer -o test tGFSR32x4.c
*/


#include <stdio.h>

typedef unsigned int U32; /* DOIT être sur 32 bits */
typedef   signed int S32; /* DOIT être sur 32 bits */

#ifndef MMUL
  #define MMUL (128|16)
#endif
#ifndef MACRO_tGFSR32x4
 #define MACRO_tGFSR32x4 MACRO_tGFSR32x4_CMUL
#endif
#define DUMMY 0
#define INIT  67 /* la période ne doit pas varier en fonction
 de la donnée ou de l'état initial, mais ce dernier ne
 doit pas être nul ! */

#define MACRO_tGFSR32x4_CMUL(current, last, ptr) \
  current ^= last;        \
  current ^= ptr;         \
  t = current;            \
  current >>= 1;          \
  t &= 0x01010101;        \
  current &= 0x7F7F7F7F;  \
  t *= MMUL;              \
  current ^= t;

/* version optimisée avec MMUL=144 */
#define MACRO_tGFSR32x4_SHFT(current, last, ptr) \
  current ^= last;        \
  current ^= ptr;         \
  t = current;            \
  current >>= 1;          \
  t &= 0x01010101;        \
  current &= 0x7F7F7F7F;  \
  t <<= 4;                \
  current ^= t;           \
  t <<= 3;                \
  current ^= t;

volatile int dummy=DUMMY;

int main() {
  U32 r0=INIT, r1=0, r2=0, r3=0, t, i=0;

  do {
#ifdef TEST_3_REGS
    MACRO_tGFSR32x4(r0, r2, dummy)
    MACRO_tGFSR32x4(r1, r0, dummy)
    MACRO_tGFSR32x4(r2, r1, dummy)
#else
    MACRO_tGFSR32x4(r0, r3, dummy)
    MACRO_tGFSR32x4(r1, r0, dummy)
    MACRO_tGFSR32x4(r2, r1, dummy)
    MACRO_tGFSR32x4(r3, r2, dummy)
#endif
    i++;
    if (i==0) {
      printf("rebouclage du compteur\n");
      return -1;
    }
  } while ( !( (r0==INIT) && ((r1|r2|r3)==0) ));

  printf("%d\n",i);
  return 0;
}
