Skip to content

Commit

Permalink
Add endian-based float packing to cnex
Browse files Browse the repository at this point in the history
  • Loading branch information
gitlarryf committed Feb 23, 2024
1 parent 11c9640 commit 0d8e5d1
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 19 deletions.
1 change: 0 additions & 1 deletion exec/cnex/exclude.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ gc2.neon # Object Count
gc3.neon # Object Count
gc-two-pointers.neon # garbage collection
math-test.neon # math.powmod()
struct-test.neon # iEEE big endian packing

extsample-test.neon # cell_set_pointer
http-test.neon # string$split
Expand Down
12 changes: 8 additions & 4 deletions exec/cnex/global.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,14 @@ TDispatch gfuncDispatch[] = {
PDFUNC("string$upper", string_upper),

// struct - C struct serialization functions
PDFUNC("struct$packIEEE32", struct_packIEEE32),
PDFUNC("struct$packIEEE64", struct_packIEEE64),
PDFUNC("struct$unpackIEEE32", struct_unpackIEEE32),
PDFUNC("struct$unpackIEEE64", struct_unpackIEEE64),
PDFUNC("struct$packIEEE32BE", struct_packIEEE32BE),
PDFUNC("struct$packIEEE32LE", struct_packIEEE32LE),
PDFUNC("struct$packIEEE64BE", struct_packIEEE64BE),
PDFUNC("struct$packIEEE64LE", struct_packIEEE64LE),
PDFUNC("struct$unpackIEEE32BE", struct_unpackIEEE32BE),
PDFUNC("struct$unpackIEEE32LE", struct_unpackIEEE32LE),
PDFUNC("struct$unpackIEEE64BE", struct_unpackIEEE64BE),
PDFUNC("struct$unpackIEEE64LE", struct_unpackIEEE64LE),

// sys - System level calls
PDFUNC("sys$exit", sys_exit),
Expand Down
112 changes: 102 additions & 10 deletions exec/cnex/lib/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,139 @@



void struct_packIEEE32(struct tagTExecutor *exec)
void struct_packIEEE32BE(struct tagTExecutor *exec)
{
Number n = top(exec->stack)->number; pop(exec->stack);

float x = number_to_float(n);
Cell *r = cell_createStringCell(sizeof(x));
memcpy(r->string->data, &x, sizeof(x));
uint32_t i = *(uint32_t *)&x;
r->string->data[0] = (i >> 24) & 0xff;
r->string->data[1] = (i >> 16) & 0xff;
r->string->data[2] = (i >> 8) & 0xff;
r->string->data[3] = (i ) & 0xff;
r->type = cBytes;

push(exec->stack, r);
}

void struct_packIEEE64(struct tagTExecutor *exec)
void struct_packIEEE32LE(struct tagTExecutor *exec)
{
Number n = top(exec->stack)->number; pop(exec->stack);

float x = number_to_float(n);
Cell *r = cell_createStringCell(sizeof(x));
uint32_t i = *(uint32_t *)&x;
r->string->data[3] = (i >> 24) & 0xff;
r->string->data[2] = (i >> 16) & 0xff;
r->string->data[1] = (i >> 8) & 0xff;
r->string->data[0] = (i ) & 0xff;
r->type = cBytes;

push(exec->stack, r);
}

void struct_packIEEE64BE(struct tagTExecutor *exec)
{
Number n = top(exec->stack)->number; pop(exec->stack);

double x = number_to_double(n);
Cell *r = cell_createStringCell(sizeof(x));
uint64_t i = *(uint64_t *)&x;
r->string->data[0] = (i >> 56) & 0xff;
r->string->data[1] = (i >> 48) & 0xff;
r->string->data[2] = (i >> 40) & 0xff;
r->string->data[3] = (i >> 32) & 0xff;
r->string->data[4] = (i >> 24) & 0xff;
r->string->data[5] = (i >> 16) & 0xff;
r->string->data[6] = (i >> 8) & 0xff;
r->string->data[7] = (i ) & 0xff;
r->type = cBytes;

push(exec->stack, r);
}

void struct_packIEEE64LE(struct tagTExecutor *exec)
{
Number n = top(exec->stack)->number; pop(exec->stack);

double x = number_to_double(n);
Cell *r = cell_createStringCell(sizeof(x));
memcpy(r->string->data, &x, sizeof(x));
uint64_t i = *(uint64_t *)&x;
r->string->data[7] = (i >> 56) & 0xff;
r->string->data[6] = (i >> 48) & 0xff;
r->string->data[5] = (i >> 40) & 0xff;
r->string->data[4] = (i >> 32) & 0xff;
r->string->data[3] = (i >> 24) & 0xff;
r->string->data[2] = (i >> 16) & 0xff;
r->string->data[1] = (i >> 8) & 0xff;
r->string->data[0] = (i ) & 0xff;
r->type = cBytes;

push(exec->stack, r);
}

void struct_unpackIEEE32(struct tagTExecutor *exec)
void struct_unpackIEEE32BE(struct tagTExecutor *exec)
{
TString *b = top(exec->stack)->string;

uint32_t i = (b->data[0] << 24) |
(b->data[1] << 16) |
(b->data[2] << 8) |
(b->data[3] );
float x = *(float *)&i;

pop(exec->stack);
push(exec->stack, cell_fromNumber(number_from_float(x)));
}

void struct_unpackIEEE32LE(struct tagTExecutor *exec)
{
TString *b = top(exec->stack)->string;

float x;
memcpy(&x, b->data, sizeof(x));
uint32_t i = (b->data[3] << 24) |
(b->data[2] << 16) |
(b->data[1] << 8) |
(b->data[0] );
float x = *(float *)&i;

pop(exec->stack);
push(exec->stack, cell_fromNumber(number_from_float(x)));
}

void struct_unpackIEEE64(struct tagTExecutor *exec)
void struct_unpackIEEE64BE(struct tagTExecutor *exec)
{
TString *b = top(exec->stack)->string;

double x;
memcpy(&x, b->data, sizeof(x));
uint64_t i = ((uint64_t)b->data[0] << 56) |
((uint64_t)b->data[1] << 48) |
((uint64_t)b->data[2] << 40) |
((uint64_t)b->data[3] << 32) |
((uint64_t)b->data[4] << 24) |
((uint64_t)b->data[5] << 16) |
((uint64_t)b->data[6] << 8) |
((uint64_t)b->data[7] );

double x = *(double *)&i;

pop(exec->stack);
push(exec->stack, cell_fromNumber(number_from_double(x)));
}

void struct_unpackIEEE64LE(struct tagTExecutor *exec)
{
TString *b = top(exec->stack)->string;

uint64_t i = ((uint64_t)b->data[7] << 56) |
((uint64_t)b->data[6] << 48) |
((uint64_t)b->data[5] << 40) |
((uint64_t)b->data[4] << 32) |
((uint64_t)b->data[3] << 24) |
((uint64_t)b->data[2] << 16) |
((uint64_t)b->data[1] << 8) |
((uint64_t)b->data[0] );

double x = *(double *)&i;

pop(exec->stack);
push(exec->stack, cell_fromNumber(number_from_double(x)));
Expand Down
15 changes: 11 additions & 4 deletions exec/cnex/lib/struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@

struct tagTExecutor;

void struct_packIEEE32(struct tagTExecutor *exec);
void struct_packIEEE64(struct tagTExecutor *exec);
void struct_unpackIEEE32(struct tagTExecutor *exec);
void struct_unpackIEEE64(struct tagTExecutor *exec);
void struct_packIEEE32BE(struct tagTExecutor *exec);
void struct_packIEEE32LE(struct tagTExecutor *exec);

void struct_packIEEE64BE(struct tagTExecutor *exec);
void struct_packIEEE64LE(struct tagTExecutor *exec);

void struct_unpackIEEE32BE(struct tagTExecutor *exec);
void struct_unpackIEEE32LE(struct tagTExecutor *exec);

void struct_unpackIEEE64BE(struct tagTExecutor *exec);
void struct_unpackIEEE64LE(struct tagTExecutor *exec);

#endif

0 comments on commit 0d8e5d1

Please sign in to comment.