Skip to content

Commit bf03b2e

Browse files
committed
Make major improvements to redbean and libraries
The most exciting improvement is dynamic pages will soon be able to use the executable itself as an object store. it required a heroic technique for overcoming ETXTBSY restrictions which lets us open the executable in read/write mode, which means (1) wa can restore the APE header, and (2) we can potentially containerize redbean extension code so that modules you download for your redbean online will only impact your redbean. Here's a list of breaking changes to redbean: - Remove /tool/net/ prefix from magic ZIP paths - GetHeader() now returns NIL if header is absent Here's a list of fixes and enhancements to redbean: - Support 64-bit ZIP archives - Record User-Agent header in logs - Add twelve error handlers to accept() - Display octal st_mode on listing page - Show ZIP file comments on listing page - Restore APE MZ header on redbean startup - Track request count on redbean index page - Report server uptime on redbean index page - Don't bind server socket using SO_REUSEPORT - Fix #151 where Lua LoadAsset() could free twice - Report rusage accounting when workers exit w/ -vv - Use ZIP iattr field as text/plain vs. binary hint - Add ParseUrl() API for parsing things like a.href - Add ParseParams() API for parsing HTTP POST bodies - Add IsAcceptablePath() API for checking dots, etc. - Add IsValidHttpToken() API for validating sane ASCII - Add IsAcceptableHostPort() for validating HOST[:PORT] - Send 400 response to HTTP/1.1 requests without a Host - Send 403 response if ZIP or file isn't other readable - Add virtual hosting that tries prepending Host to path - Route requests based on Host in Request-URI if present - Host routing will attempt to remove or add the www. prefix - Sign-extend UNIX timestamps and don't adjust FileTime zone Here's some of the improvements made to Cosmopolitan Libc: - Fix ape.S indentation - Improve consts.sh magnums - Write pretty good URL parser - Improve rusage accounting apis - Bring mremap() closer to working - Added ZIP APIs which will change - Check for overflow in reallocarray() - Remove overly fancy linkage in strerror() - Fix GDB attach on crash w/ OpenBSD msyscall() - Make sigqueue() portable to most UNIX distros - Make integer serialization macros more elegant - Bring back 34x tprecode8to16() performance boost - Make malloc() more resilient to absurdly large sizes
1 parent 69c5087 commit bf03b2e

File tree

307 files changed

+4557
-2581
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

307 files changed

+4557
-2581
lines changed

ape/ape.S

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -865,48 +865,48 @@ ape_macho:
865865
@see "The Portable Executable File Format from Top to Bottom",
866866
Randy Kath, Microsoft Developer Network Technology Group. */
867867

868-
// ┌14:Uniprocessor Machine ┌─────────────────────────┐
869-
// │┌13:DLL │ PE File Characteristics │
870-
// ││┌12:System ├─────────────────────────┤
871-
// │││┌11:If Net Run From Swap │ r │ reserved │
872-
// ││││┌10:If Removable Run From Swap │ d │ deprecated │
873-
// │││││┌9:Debug Stripped │ D │ deprecated with │
874-
// ││││││┌8:32bit Machine │ │ extreme prejudice │
875-
// │││││││ ┌5:Large Address Aware └───┴─────────────────────┘
876-
// │││││││ │ ┌1:Executable
877-
// │││││││ │ │┌0:Relocs Stripped
878-
// d│││││││dr│Ddd││
879-
PEEXE = 0b0000001000100011
880-
881-
// ┌15:TERMINAL_SERVER_AWARE ┌─────────────────────────┐
882-
// │┌14:GUARD_CF │ PE DLL Characteristics │
883-
// ││┌13:WDM_DRIVER ├─────────────────────────┤
884-
// │││┌12:APPCONTAINER │ r │ reserved │
885-
// ││││┌11:NO_BIND └───┴─────────────────────┘
886-
// │││││┌10:NO_SEH
887-
// ││││││┌9:NO_ISOLATION
888-
// │││││││┌8:NX_COMPAT
889-
// ││││││││┌7:FORCE_INTEGRITY
890-
// │││││││││┌6:DYNAMIC_BASE
891-
// ││││││││││┌5:HIGH_ENTROPY_VA
892-
// │││││││││││rrrrr
868+
// ┌14:Uniprocessor Machine ┌─────────────────────────┐
869+
// │┌13:DLL │ PE File Characteristics │
870+
// ││┌12:System ├─────────────────────────┤
871+
// │││┌11:If Net Run From Swap │ r │ reserved │
872+
// ││││┌10:If Removable Run From Swap │ d │ deprecated │
873+
// │││││┌9:Debug Stripped │ D │ deprecated with │
874+
// ││││││┌8:32bit Machine │ │ extreme prejudice │
875+
// │││││││ ┌5:Large Address Aware └───┴─────────────────────┘
876+
// │││││││ │ ┌1:Executable
877+
// │││││││ │ │┌0:Relocs Stripped
878+
// d│││││││dr│Ddd││
879+
PEEXE = 0b00000001000100011
880+
881+
// ┌15:TERMINAL_SERVER_AWARE ┌─────────────────────────┐
882+
// │┌14:GUARD_CF │ PE DLL Characteristics │
883+
// ││┌13:WDM_DRIVER ├─────────────────────────┤
884+
// │││┌12:APPCONTAINER │ r │ reserved │
885+
// ││││┌11:NO_BIND └───┴─────────────────────┘
886+
// │││││┌10:NO_SEH
887+
// ││││││┌9:NO_ISOLATION
888+
// │││││││┌8:NX_COMPAT
889+
// ││││││││┌7:FORCE_INTEGRITY
890+
// │││││││││┌6:DYNAMIC_BASE
891+
// ││││││││││┌5:HIGH_ENTROPY_VA
892+
// │││││││││││rrrrr
893893
DLLSTD = 0b0000000100100000
894894
DLLPIE = 0b0000000001100000
895895
DLLEXE = DLLSTD
896896

897-
// ┌31:Writeable ┌─────────────────────────┐
898-
// │┌30:Readable │ PE Section Flags │
899-
// ││┌29:Executable ├─────────────────────────┤
900-
// │││┌28:Shareable │ o │ for object files │
901-
// ││││┌27:Unpageable │ r │ reserved │
902-
// │││││┌26:Uncacheable └───┴─────────────────────┘
903-
// ││││││┌25:Discardable
904-
// │││││││┌24:Contains Extended Relocations
905-
// ││││││││ ┌15:Contains Global Pointer (GP) Relative Data
906-
// ││││││││ │ ┌7:Contains Uninitialized Data
907-
// ││││││││ │ │┌6:Contains Initialized Data
908-
// ││││││││ o │ ││┌5:Contains Code
909-
// ││││││││┌┴─┐rrrr│ ooror│││rorrr
897+
// ┌31:Writeable ┌─────────────────────────┐
898+
// │┌30:Readable │ PE Section Flags │
899+
// ││┌29:Executable ├─────────────────────────┤
900+
// │││┌28:Shareable │ o │ for object files │
901+
// ││││┌27:Unpageable │ r │ reserved │
902+
// │││││┌26:Uncacheable └───┴─────────────────────┘
903+
// ││││││┌25:Discardable
904+
// │││││││┌24:Contains Extended Relocations
905+
// ││││││││ ┌15:Contains Global Pointer (GP) Relative Data
906+
// ││││││││ │ ┌7:Contains Uninitialized Data
907+
// ││││││││ │ │┌6:Contains Initialized Data
908+
// ││││││││ o │ ││┌5:Contains Code
909+
// ││││││││┌┴─┐rrrr│ ooror│││rorrr
910910
PETEXT = 0b01110000000000000000000001100000
911911
PEDATA = 0b11000000000000000000000011000000
912912
PEIMPS = 0b11000000000000000000000001000000
@@ -1437,7 +1437,7 @@ long: push $GDT_LONG_DATA
14371437
.endfn long
14381438

14391439
/* ▄▄▒▀▀▀▀▒▒▄
1440-
█████▓▓▄░░░░ ▒▒▄
1440+
█████▓▓▄░░░░ ▒▒▄
14411441
▐█▓▓█▓▄█████▓░ ▀▒▄
14421442
▓█▓▓▓▓▓▓▓▓▓█▓ ░▀▒░
14431443
▀▀▓█▓▓▓▓▓▓█▓ ░▀▒▄▄▒▄▄▄▒▒▒▀▀▀▀▀▀▀▀▀▀▀▀▀▀▒▒▄▒

build/bootstrap/package.com

308 KB
Binary file not shown.

build/bootstrap/zipobj.com

4 KB
Binary file not shown.

libc/alg/bisect.internal.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,23 @@ COSMOPOLITAN_C_START_
66
forceinline void *bisect(const void *k, const void *data, size_t n, size_t size,
77
int cmp(const void *a, const void *b, void *arg),
88
void *arg) {
9-
int dir;
10-
const char *p, *pos;
11-
p = data;
12-
while (n > 0) {
13-
pos = p + size * (n / 2);
14-
dir = cmp(k, pos, arg);
15-
if (dir < 0) {
16-
n /= 2;
17-
} else if (dir > 0) {
18-
p = pos + size;
19-
n -= n / 2 + 1;
20-
} else {
21-
return (void *)pos;
9+
int c;
10+
const char *p;
11+
ssize_t m, l, r;
12+
if (n) {
13+
l = 0;
14+
r = n - 1;
15+
p = data;
16+
while (l <= r) {
17+
m = (l + r) >> 1;
18+
c = cmp(k, p + m * size, arg);
19+
if (c > 0) {
20+
l = m + 1;
21+
} else if (c < 0) {
22+
r = m - 1;
23+
} else {
24+
return p + m * size;
25+
}
2226
}
2327
}
2428
return NULL;

libc/bits/bitreverse16.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
/**
2222
* Reverses bits in 16-bit word.
2323
*/
24-
uint16_t(bitreverse16)(uint16_t x) {
25-
return kReverseBits[x & 0x00FF] << 8 | kReverseBits[(x & 0xFF00) >> 8];
24+
int bitreverse16(int x) {
25+
return BITREVERSE16(x);
2626
}

libc/bits/bitreverse32.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
/**
2323
* Reverses bits in 32-bit word.
2424
*/
25-
uint32_t(bitreverse32)(uint32_t x) {
25+
uint32_t bitreverse32(uint32_t x) {
2626
x = bswap_32(x);
27-
x = ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1);
28-
x = ((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2);
29-
x = ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4);
27+
x = (x & 0xaaaaaaaa) >> 1 | (x & 0x55555555) << 1;
28+
x = (x & 0xcccccccc) >> 2 | (x & 0x33333333) << 2;
29+
x = (x & 0xf0f0f0f0) >> 4 | (x & 0x0f0f0f0f) << 4;
3030
return x;
3131
}

libc/bits/bitreverse64.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
*/
2525
uint64_t bitreverse64(uint64_t x) {
2626
x = bswap_64(x);
27-
x = ((x & 0xaaaaaaaaaaaaaaaa) >> 1) | ((x & 0x5555555555555555) << 1);
28-
x = ((x & 0xcccccccccccccccc) >> 2) | ((x & 0x3333333333333333) << 2);
29-
x = ((x & 0xf0f0f0f0f0f0f0f0) >> 4) | ((x & 0x0f0f0f0f0f0f0f0f) << 4);
27+
x = (x & 0xaaaaaaaaaaaaaaaa) >> 1 | (x & 0x5555555555555555) << 1;
28+
x = (x & 0xcccccccccccccccc) >> 2 | (x & 0x3333333333333333) << 2;
29+
x = (x & 0xf0f0f0f0f0f0f0f0) >> 4 | (x & 0x0f0f0f0f0f0f0f0f) << 4;
3030
return x;
3131
}

libc/bits/bitreverse8.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
/**
2222
* Reverses bits in 8-bit word.
2323
*/
24-
uint8_t(bitreverse8)(uint8_t x) {
25-
return kReverseBits[x];
24+
int bitreverse8(int x) {
25+
return BITREVERSE8(x);
2626
}

libc/bits/bits.h

Lines changed: 98 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ extern const uint8_t kReverseBits[256];
1313

1414
uint32_t gray(uint32_t) pureconst;
1515
uint32_t ungray(uint32_t) pureconst;
16-
uint8_t bitreverse8(uint8_t) libcesque pureconst;
17-
uint16_t bitreverse16(uint16_t) libcesque pureconst;
16+
int bitreverse8(int) libcesque pureconst;
17+
int bitreverse16(int) libcesque pureconst;
1818
uint32_t bitreverse32(uint32_t) libcesque pureconst;
1919
uint64_t bitreverse64(uint64_t) libcesque pureconst;
2020
unsigned long roundup2pow(unsigned long) libcesque pureconst;
@@ -31,106 +31,104 @@ intptr_t atomic_store(void *, intptr_t, size_t);
3131
│ cosmopolitan § bits » no assembly required ─╬─│┼
3232
╚────────────────────────────────────────────────────────────────────────────│*/
3333

34-
#define bitreverse8(X) (kReverseBits[(uint8_t)(X)])
35-
#define bitreverse16(X) \
36-
((uint16_t)kReverseBits[(uint8_t)(X)] << 010 | \
37-
kReverseBits[((uint16_t)(X) >> 010) & 0xff])
34+
#define BITREVERSE8(X) (kReverseBits[255 & (X)])
35+
#define BITREVERSE16(X) \
36+
(kReverseBits[0x00FF & (X)] << 8 | kReverseBits[(0xFF00 & (X)) >> 8])
3837

39-
#define READ16LE(S) \
40-
((uint16_t)((unsigned char *)(S))[1] << 010 | \
41-
(uint16_t)((unsigned char *)(S))[0] << 000)
42-
#define READ32LE(S) \
43-
((uint32_t)((unsigned char *)(S))[3] << 030 | \
44-
(uint32_t)((unsigned char *)(S))[2] << 020 | \
45-
(uint32_t)((unsigned char *)(S))[1] << 010 | \
46-
(uint32_t)((unsigned char *)(S))[0] << 000)
47-
#define READ64LE(S) \
48-
((uint64_t)((unsigned char *)(S))[7] << 070 | \
49-
(uint64_t)((unsigned char *)(S))[6] << 060 | \
50-
(uint64_t)((unsigned char *)(S))[5] << 050 | \
51-
(uint64_t)((unsigned char *)(S))[4] << 040 | \
52-
(uint64_t)((unsigned char *)(S))[3] << 030 | \
53-
(uint64_t)((unsigned char *)(S))[2] << 020 | \
54-
(uint64_t)((unsigned char *)(S))[1] << 010 | \
55-
(uint64_t)((unsigned char *)(S))[0] << 000)
56-
57-
#define READ16BE(S) \
58-
((uint16_t)((unsigned char *)(S))[0] << 010 | \
59-
(uint16_t)((unsigned char *)(S))[1] << 000)
60-
#define READ32BE(S) \
61-
((uint32_t)((unsigned char *)(S))[0] << 030 | \
62-
(uint32_t)((unsigned char *)(S))[1] << 020 | \
63-
(uint32_t)((unsigned char *)(S))[2] << 010 | \
64-
(uint32_t)((unsigned char *)(S))[3] << 000)
65-
#define READ64BE(S) \
66-
((uint64_t)((unsigned char *)(S))[0] << 070 | \
67-
(uint64_t)((unsigned char *)(S))[1] << 060 | \
68-
(uint64_t)((unsigned char *)(S))[2] << 050 | \
69-
(uint64_t)((unsigned char *)(S))[3] << 040 | \
70-
(uint64_t)((unsigned char *)(S))[4] << 030 | \
71-
(uint64_t)((unsigned char *)(S))[5] << 020 | \
72-
(uint64_t)((unsigned char *)(S))[6] << 010 | \
73-
(uint64_t)((unsigned char *)(S))[7] << 000)
74-
75-
#define WRITE16LE(P, V) \
76-
do { \
77-
uint8_t *Ple = (uint8_t *)(P); \
78-
uint16_t Vle = (V); \
79-
Ple[0] = (uint8_t)(Vle >> 000); \
80-
Ple[1] = (uint8_t)(Vle >> 010); \
81-
} while (0)
82-
#define WRITE32LE(P, V) \
83-
do { \
84-
uint8_t *Ple = (uint8_t *)(P); \
85-
uint32_t Vle = (V); \
86-
Ple[0] = (uint8_t)(Vle >> 000); \
87-
Ple[1] = (uint8_t)(Vle >> 010); \
88-
Ple[2] = (uint8_t)(Vle >> 020); \
89-
Ple[3] = (uint8_t)(Vle >> 030); \
90-
} while (0)
91-
#define WRITE64LE(P, V) \
92-
do { \
93-
uint8_t *Ple = (uint8_t *)(P); \
94-
uint64_t Vle = (V); \
95-
Ple[0] = (uint8_t)(Vle >> 000); \
96-
Ple[1] = (uint8_t)(Vle >> 010); \
97-
Ple[2] = (uint8_t)(Vle >> 020); \
98-
Ple[3] = (uint8_t)(Vle >> 030); \
99-
Ple[4] = (uint8_t)(Vle >> 040); \
100-
Ple[5] = (uint8_t)(Vle >> 050); \
101-
Ple[6] = (uint8_t)(Vle >> 060); \
102-
Ple[7] = (uint8_t)(Vle >> 070); \
103-
} while (0)
38+
#ifdef __STRICT_ANSI__
39+
#define READ16LE(S) ((255 & (S)[1]) << 8 | (255 & (S)[0]))
40+
#define READ16BE(S) ((255 & (S)[0]) << 8 | (255 & (S)[1]))
41+
#define READ32LE(S) \
42+
((uint32_t)(255 & (S)[3]) << 030 | (uint32_t)(255 & (S)[2]) << 020 | \
43+
(uint32_t)(255 & (S)[1]) << 010 | (uint32_t)(255 & (S)[0]) << 000)
44+
#define READ32BE(S) \
45+
((uint32_t)(255 & (S)[0]) << 030 | (uint32_t)(255 & (S)[1]) << 020 | \
46+
(uint32_t)(255 & (S)[2]) << 010 | (uint32_t)(255 & (S)[3]) << 000)
47+
#define READ64LE(S) \
48+
((uint64_t)(255 & (S)[7]) << 070 | (uint64_t)(255 & (S)[6]) << 060 | \
49+
(uint64_t)(255 & (S)[5]) << 050 | (uint64_t)(255 & (S)[4]) << 040 | \
50+
(uint64_t)(255 & (S)[3]) << 030 | (uint64_t)(255 & (S)[2]) << 020 | \
51+
(uint64_t)(255 & (S)[1]) << 010 | (uint64_t)(255 & (S)[0]) << 000)
52+
#define READ64BE(S) \
53+
((uint64_t)(255 & (S)[0]) << 070 | (uint64_t)(255 & (S)[1]) << 060 | \
54+
(uint64_t)(255 & (S)[2]) << 050 | (uint64_t)(255 & (S)[3]) << 040 | \
55+
(uint64_t)(255 & (S)[4]) << 030 | (uint64_t)(255 & (S)[5]) << 020 | \
56+
(uint64_t)(255 & (S)[6]) << 010 | (uint64_t)(255 & (S)[7]) << 000)
57+
#else /* gcc needs help knowing above are mov if s isn't a variable */
58+
#define READ16LE(S) \
59+
({ \
60+
const uint8_t *Ptr = (const uint8_t *)(S); \
61+
Ptr[1] << 8 | Ptr[0]; \
62+
})
63+
#define READ16BE(S) \
64+
({ \
65+
const uint8_t *Ptr = (const uint8_t *)(S); \
66+
Ptr[0] << 8 | Ptr[1]; \
67+
})
68+
#define READ32LE(S) \
69+
({ \
70+
const uint8_t *Ptr = (const uint8_t *)(S); \
71+
((uint32_t)Ptr[3] << 030 | (uint32_t)Ptr[2] << 020 | \
72+
(uint32_t)Ptr[1] << 010 | (uint32_t)Ptr[0] << 000); \
73+
})
74+
#define READ32BE(S) \
75+
({ \
76+
const uint8_t *Ptr = (const uint8_t *)(S); \
77+
((uint32_t)Ptr[0] << 030 | (uint32_t)Ptr[1] << 020 | \
78+
(uint32_t)Ptr[2] << 010 | (uint32_t)Ptr[3] << 000); \
79+
})
80+
#define READ64LE(S) \
81+
({ \
82+
const uint8_t *Ptr = (const uint8_t *)(S); \
83+
((uint64_t)Ptr[7] << 070 | (uint64_t)Ptr[6] << 060 | \
84+
(uint64_t)Ptr[5] << 050 | (uint64_t)Ptr[4] << 040 | \
85+
(uint64_t)Ptr[3] << 030 | (uint64_t)Ptr[2] << 020 | \
86+
(uint64_t)Ptr[1] << 010 | (uint64_t)Ptr[0] << 000); \
87+
})
88+
#define READ64BE(S) \
89+
({ \
90+
const uint8_t *Ptr = (const uint8_t *)(S); \
91+
((uint64_t)Ptr[0] << 070 | (uint64_t)Ptr[1] << 060 | \
92+
(uint64_t)Ptr[2] << 050 | (uint64_t)Ptr[3] << 040 | \
93+
(uint64_t)Ptr[4] << 030 | (uint64_t)Ptr[5] << 020 | \
94+
(uint64_t)Ptr[6] << 010 | (uint64_t)Ptr[7] << 000); \
95+
})
96+
#endif
10497

105-
#define WRITE16BE(P, V) \
106-
do { \
107-
uint8_t *Ple = (uint8_t *)(P); \
108-
uint16_t Vle = (V); \
109-
Ple[1] = (uint8_t)(Vle >> 000); \
110-
Ple[0] = (uint8_t)(Vle >> 010); \
111-
} while (0)
112-
#define WRITE32BE(P, V) \
113-
do { \
114-
uint8_t *Ple = (uint8_t *)(P); \
115-
uint32_t Vle = (V); \
116-
Ple[3] = (uint8_t)(Vle >> 000); \
117-
Ple[2] = (uint8_t)(Vle >> 010); \
118-
Ple[1] = (uint8_t)(Vle >> 020); \
119-
Ple[0] = (uint8_t)(Vle >> 030); \
120-
} while (0)
121-
#define WRITE64BE(P, V) \
122-
do { \
123-
uint8_t *Ple = (uint8_t *)(P); \
124-
uint64_t Vle = (V); \
125-
Ple[7] = (uint8_t)(Vle >> 000); \
126-
Ple[6] = (uint8_t)(Vle >> 010); \
127-
Ple[5] = (uint8_t)(Vle >> 020); \
128-
Ple[4] = (uint8_t)(Vle >> 030); \
129-
Ple[3] = (uint8_t)(Vle >> 040); \
130-
Ple[2] = (uint8_t)(Vle >> 050); \
131-
Ple[1] = (uint8_t)(Vle >> 060); \
132-
Ple[0] = (uint8_t)(Vle >> 070); \
133-
} while (0)
98+
#define WRITE16LE(P, V) \
99+
((P)[0] = (0x00000000000000FF & (V)) >> 000, \
100+
(P)[1] = (0x000000000000FF00 & (V)) >> 010, (P) + 2)
101+
#define WRITE16BE(P, V) \
102+
((P)[0] = (0x000000000000FF00 & (V)) >> 010, \
103+
(P)[1] = (0x00000000000000FF & (V)) >> 000, (P) + 2)
104+
#define WRITE32LE(P, V) \
105+
((P)[0] = (0x00000000000000FF & (V)) >> 000, \
106+
(P)[1] = (0x000000000000FF00 & (V)) >> 010, \
107+
(P)[2] = (0x0000000000FF0000 & (V)) >> 020, \
108+
(P)[3] = (0x00000000FF000000 & (V)) >> 030, (P) + 4)
109+
#define WRITE32BE(P, V) \
110+
((P)[0] = (0x00000000FF000000 & (V)) >> 030, \
111+
(P)[1] = (0x0000000000FF0000 & (V)) >> 020, \
112+
(P)[2] = (0x000000000000FF00 & (V)) >> 010, \
113+
(P)[3] = (0x00000000000000FF & (V)) >> 000, (P) + 4)
114+
#define WRITE64LE(P, V) \
115+
((P)[0] = (0x00000000000000FF & (V)) >> 000, \
116+
(P)[1] = (0x000000000000FF00 & (V)) >> 010, \
117+
(P)[2] = (0x0000000000FF0000 & (V)) >> 020, \
118+
(P)[3] = (0x00000000FF000000 & (V)) >> 030, \
119+
(P)[4] = (0x000000FF00000000 & (V)) >> 040, \
120+
(P)[5] = (0x0000FF0000000000 & (V)) >> 050, \
121+
(P)[6] = (0x00FF000000000000 & (V)) >> 060, \
122+
(P)[7] = (0xFF00000000000000 & (V)) >> 070, (P) + 8)
123+
#define WRITE64BE(P, V) \
124+
((P)[0] = (0xFF00000000000000 & (V)) >> 070, \
125+
(P)[1] = (0x00FF000000000000 & (V)) >> 060, \
126+
(P)[2] = (0x0000FF0000000000 & (V)) >> 050, \
127+
(P)[3] = (0x000000FF00000000 & (V)) >> 040, \
128+
(P)[4] = (0x00000000FF000000 & (V)) >> 030, \
129+
(P)[5] = (0x0000000000FF0000 & (V)) >> 020, \
130+
(P)[6] = (0x000000000000FF00 & (V)) >> 010, \
131+
(P)[7] = (0x00000000000000FF & (V)) >> 000, (P) + 8)
134132

135133
/*───────────────────────────────────────────────────────────────────────────│─╗
136134
│ cosmopolitan § bits » some assembly required ─╬─│┼

0 commit comments

Comments
 (0)