From 35705e595dfcae368143add13e24f1a089a744f3 Mon Sep 17 00:00:00 2001 From: Larry Frieson Date: Fri, 23 Feb 2024 09:04:35 -0800 Subject: [PATCH] Add new endian-based float packing to cnex --- exec/cnex/global.c | 12 +++-- exec/cnex/lib/struct.c | 112 +++++++++++++++++++++++++++++++++++++---- exec/cnex/lib/struct.h | 15 ++++-- lib/nd.proj/Menu.txt | 4 +- 4 files changed, 122 insertions(+), 21 deletions(-) diff --git a/exec/cnex/global.c b/exec/cnex/global.c index 35434dd48e..4545aea6b0 100644 --- a/exec/cnex/global.c +++ b/exec/cnex/global.c @@ -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), diff --git a/exec/cnex/lib/struct.c b/exec/cnex/lib/struct.c index 580213a0ad..87ba671a20 100644 --- a/exec/cnex/lib/struct.c +++ b/exec/cnex/lib/struct.c @@ -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))); diff --git a/exec/cnex/lib/struct.h b/exec/cnex/lib/struct.h index c9fab553ea..55ea2cb6f0 100644 --- a/exec/cnex/lib/struct.h +++ b/exec/cnex/lib/struct.h @@ -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 diff --git a/lib/nd.proj/Menu.txt b/lib/nd.proj/Menu.txt index 28e8c00db0..f038e14205 100644 --- a/lib/nd.proj/Menu.txt +++ b/lib/nd.proj/Menu.txt @@ -41,7 +41,6 @@ Timestamp: Generated on day month, year File: global (global.neon) -File: bigint (bigint.neon) File: binary (binary.neon) File: cformat (cformat.neon) File: complex (complex.neon) @@ -50,7 +49,6 @@ File: datetime (datetime.neon) File: debugger (debugger.neon) File: encoding (encoding.neon) File: file (file.neon) -File: http (http.neon) File: io (io.neon) File: json (json.neon) File: math (math.neon) @@ -60,8 +58,8 @@ File: net (net.neon) File: os (os.neon) File: posix (posix.neon) File: random (random.neon) -File: regex (regex.neon) File: runtime (runtime.neon) +File: simplehttp (simplehttp.neon) File: sqlite (sqlite.neon) File: string (string.neon) File: struct (struct.neon)