picorv32/firmware/sieve.c

79 lines
1.3 KiB
C
Raw Normal View History

2015-06-06 20:01:37 +08:00
// A simple Sieve of Eratosthenes
2015-06-27 04:02:22 +08:00
#include "firmware.h"
2015-06-06 20:01:37 +08:00
#define BITMAP_SIZE 64
static uint32_t bitmap[BITMAP_SIZE/32];
2015-06-27 04:02:22 +08:00
static uint32_t hash;
static uint32_t mkhash(uint32_t a, uint32_t b)
{
// The XOR version of DJB2
return ((a << 5) + a) ^ b;
}
2015-06-06 20:01:37 +08:00
static void bitmap_set(int idx)
{
bitmap[idx/32] |= 1 << (idx % 32);
}
static bool bitmap_get(int idx)
{
return (bitmap[idx/32] & (1 << (idx % 32))) != 0;
}
static void print_prime(int idx, int val)
{
if (idx < 10)
print_str(" ");
print_dec(idx);
if (idx / 10 == 1)
goto force_th;
switch (idx % 10) {
case 1: print_str("st"); break;
case 2: print_str("nd"); break;
case 3: print_str("rd"); break;
force_th:
default: print_str("th"); break;
}
print_str(" prime is ");
print_dec(val);
print_str(".\n");
2015-06-27 04:02:22 +08:00
hash = mkhash(hash, idx);
hash = mkhash(hash, val);
2015-06-06 20:01:37 +08:00
}
void sieve()
{
int i, j, k;
int idx = 1;
2015-06-27 04:02:22 +08:00
hash = 5381;
2015-06-06 20:01:37 +08:00
print_prime(idx++, 2);
for (i = 0; i < BITMAP_SIZE; i++) {
if (bitmap_get(i))
continue;
print_prime(idx++, 3+2*i);
for (j = 2*(3+2*i);; j += 3+2*i) {
if (j%2 == 0)
continue;
k = (j-3)/2;
if (k >= BITMAP_SIZE)
break;
bitmap_set(k);
}
}
2015-06-27 04:02:22 +08:00
print_str("checksum: ");
print_hex(hash);
2015-06-25 20:08:39 +08:00
2015-06-27 04:02:22 +08:00
if (hash == 0x1772A48F) {
print_str(" OK\n");
} else {
print_str(" ERROR\n");
asm volatile ("sbreak");
2015-06-25 20:08:39 +08:00
}
}