summaryrefslogtreecommitdiffstats
path: root/src/a3.c
blob: cd5d879f3428a6677aaa926f2e45c17103a96a19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "def.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

void                a3_init(uint64_t n);
void                a3_loop(uint64_t x0,uint64_t x1);

algo_t a3 = {
  .name = "a3 codename \"substantial diameter increase\" aka SDI0 aka waste of tyme",
  .nmax = 1ULL<<32,
  .init = a3_init,
  .loop = a3_loop,
};

#define M24_SIZE              3
#define M24_RANGE             (1<<(M24_SIZE*8))

#define M32_SIZE              4

#define CROSSOVER             (1<<15)
#define CROSSOVER_MASK        (~(CROSSOVER-1))

//static uint8_t     *m24;
//static uint8_t     *m32;
static uint8_t     *m;
static uint8_t     *m_32ik; //TMP
static size_t       m24_n;
static size_t       m32_n;
static uint32_t     m32_off;

static void         inner     (uint32_t x);
static void         inner_bias(uint32_t x);

void a3_init(uint64_t n){
  size_t size;
  t       = 0;
  m24_n   = n > CROSSOVER ? CROSSOVER : n;
  m32_n   = n-m24_n;
  size    = sizeof(uint8_t)*M24_SIZE*m24_n;
  m32_off = size;
  size   += sizeof(uint8_t)*M32_SIZE*m32_n;
  m       = calloc(size,1);
  m_32ik  = m+m32_off;
  if(!m) fuk("memory\n");
}

void a3_loop(uint64_t x0,uint64_t x1){
  uint32_t x;
  uint32_t x1_32;
  uint32_t x1_first;

  x1_32     = x1;
  x1_first  = x0+M24_RANGE;
  if(x1_first > x1_32) x1_first = x1_32;

  for(x = x0;x < x1_first;x++){
    inner(x);
  }
  for(;x < x1_32;x++){
    inner_bias(x);
  }
}

static void inner(uint32_t x){
  uint32_t r;

  //if(t >= CROSSOVER){
  if(t & CROSSOVER_MASK){
    /*
    uint64_t i = t-m24_n;
    r       = m32[i];
    m32[i]  = x;
    */

    uint8_t *p;

    r = 0;
    p = m_32ik+(t*M32_SIZE);
    memcpy(&r,p,M32_SIZE);
    memcpy(p,&x,M32_SIZE);
  }else{
    uint8_t *p;

    r = 0;
    p = m+(t*M24_SIZE);
    memcpy(&r,p,M24_SIZE);
    memcpy(p,&x,M24_SIZE);
  }
  t = r == 0 ? 0 : x-r;
}

static void inner_bias(uint32_t x){
  /*
  uint32_t r;

  //if(t >= CROSSOVER){
  if(t & CROSSOVER_MASK){
    uint8_t *p;

    r = 0;
    p = m_32ik+(t*M32_SIZE);
    memcpy(&r,p,M32_SIZE);
    memcpy(p,&x,M32_SIZE);
    t = r == 0 ? 0 : x-r;
  }else{
    uint8_t *p;

    r = 0;
    p = m+(t*M24_SIZE);
    memcpy(&r,p,M24_SIZE);
    memcpy(p,&x,M24_SIZE);
    t = (x-r) & 0x00FFFFFF;
  }
  */

  uint32_t  r;
  uint8_t  *p;
  uint32_t  m_sel;
  uint32_t  m_size;
  uint32_t  m_off;
  uint32_t  tmask;
  uint32_t  rnzero;
  uint32_t  rxdiff;

  m_sel   = ((int32_t)t-CROSSOVER)>>31; //FFFFetc.. if t < CROSSOVER
  m_size  = (m_sel & M24_SIZE) | (~m_sel & M32_SIZE);
  m_off   = ~m_sel & m32_off;
  m_off  += m_size*t;
  p       = m+m_off;
  r       = 0;

  //TODO: get rid of memcpy
  memcpy(&r,p,m_size);
  memcpy(p,&x,m_size);
  
  tmask   = 0x00FFFFFF | ~m_sel;
  rnzero  = (-(int32_t)r)>>31; //FFFFetc.. if r != 0
  rxdiff  = x-r;
  rxdiff &= tmask;
  rxdiff &= m_sel | rnzero; //clear rxdiff if t >= CROSSOVER and r == 0
  t       = rxdiff;


  

  
}