Skip to content

Commit 66173d2

Browse files
authored
32-bit support: fix _umul call; address warnings (#5)
* 32-bit support: fix _umul call; address warnings And fix test harness to always preserve the sign bit of NaN even when strtod does not * Remove arch flags from makefile since we'll just have 2 jobs * any old ubuntu will do * Try the clanker's cross arch script * Skip amalgamate in crossarch containers * install clang * No need for the dirty check in cross containers
1 parent eb6c899 commit 66173d2

File tree

10 files changed

+81
-19
lines changed

10 files changed

+81
-19
lines changed

.github/workflows/c.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ name: Simple Test
22

33
on:
44
push:
5-
branches: [ "main" ]
65
pull_request:
7-
branches: [ "main" ]
86

97
jobs:
108
build:
119
runs-on: ubuntu-latest
1210

1311
steps:
1412
- uses: actions/checkout@v4
15-
- name: Install 32bit headers
16-
run: sudo apt-get update && sudo apt-get install -y gcc-multilib
13+
- name: Install dependencies
14+
run: sudo apt-get update && sudo apt-get install -y clang gcc make python3
1715
- name: make test
1816
run: make test
17+
- name: make example
18+
run: make example
19+
- name: Check dirty single-header
20+
run: git diff --exit-code ffc.h
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Cross-Arch CI
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
8+
jobs:
9+
native:
10+
name: Linux amd64 (native)
11+
runs-on: ubuntu-22.04
12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Install dependencies
15+
run: sudo apt-get update && sudo apt-get install -y build-essential
16+
- name: make test
17+
run: make test
18+
- name: make example
19+
run: make example
20+
- name: Check dirty single-header
21+
run: git diff --exit-code ffc.h
22+
23+
cross:
24+
name: Linux ${{ matrix.arch }}
25+
runs-on: ubuntu-22.04
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
include:
30+
- arch: i386
31+
distro: debian:bookworm
32+
install: apt-get update && apt-get install -y build-essential clang
33+
- arch: aarch64
34+
distro: ubuntu:22.04
35+
install: apt-get update && apt-get install -y build-essential clang
36+
steps:
37+
- uses: actions/checkout@v4
38+
- uses: docker/setup-qemu-action@v3
39+
- name: Build and test (${{ matrix.arch }})
40+
run: |
41+
docker run --rm \
42+
--platform linux/${{ matrix.arch == 'i386' && '386' || matrix.arch }} \
43+
-v "${{ github.workspace }}:/work" \
44+
-w /work \
45+
${{ matrix.distro }} \
46+
bash -c "
47+
${{ matrix.install }} &&
48+
touch ffc.h &&
49+
make test &&
50+
make example
51+
"

Makefile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@ endif
99
CLANG_FLAGS := -xc -Wall -Wextra -Wpedantic -O3 -g -std=c99 $(EXTRA_CFLAGS)
1010

1111
out/test_runner: ffc.h test_src/test.c | out
12-
gcc -xc -m64 -Wall -Wextra -Wpedantic ffc.h -fsyntax-only
13-
gcc -xc -m32 -Wall -Wextra -Wpedantic ffc.h -fsyntax-only
14-
clang $(CLANG_FLAGS) -I. -Itest_src -DFFC_IMPL test_src/test.c -o out/test_runner -lm
12+
gcc -xc -Wall -Wextra -Wpedantic ffc.h -fsyntax-only
13+
clang $(CLANG_FLAGS) -I. -Itest_src test_src/test.c -o out/test_runner -lm
1514

1615
test: out/test_runner out/test_int_runner
1716
./out/test_runner
1817
./out/test_int_runner
1918

2019
out/test_int_runner: ffc.h test_src/test_int.c | out
21-
clang $(CLANG_FLAGS) -I. -Itest_src -DFFC_IMPL test_src/test_int.c -o out/test_int_runner -lm
20+
clang $(CLANG_FLAGS) -I. -Itest_src test_src/test_int.c -o out/test_int_runner -lm
2221

2322
ffc.h: src/ffc.h src/common.h src/parse.h src/digit_comparison.h src/api.h src/bigint.h amalgamate.py
2423
python3 amalgamate.py > ffc.h

ffc.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ ffc_u128 ffc_full_multiplication(uint64_t a, uint64_t b) {
550550
// But MinGW on ARM64 doesn't have native support for 64-bit multiplications
551551
answer.high = __umulh(a, b);
552552
answer.low = a * b;
553-
#elif defined(FFC_32BIT) || (defined(_WIN64) && !defined(__clang__) && \
553+
#elif (defined(_WIN64) && !defined(__clang__) && \
554554
!defined(_M_ARM64) && !defined(__GNUC__))
555555
answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
556556
#elif defined(FFC_64BIT) && defined(__SIZEOF_INT128__)
@@ -851,7 +851,7 @@ static const float FFC_FLOAT_POWERS_OF_TEN[] = {
851851

852852
// Largest integer value v so that (5**index * v) <= 1<<53.
853853
// 0x20000000000000 == 1 << 53
854-
#define FFC_55555 (5L * 5L * 5L * 5L * 5L)
854+
#define FFC_55555 (5LL * 5LL * 5LL * 5LL * 5LL)
855855
static const uint64_t FFC_DOUBLE_MAX_MANTISSA[] = {
856856
(uint64_t)0x20000000000000L,
857857
(uint64_t)0x20000000000000L / 5,
@@ -2417,7 +2417,7 @@ bool ffc_char_eq_zero(char const *p, size_t char_width) {
24172417
ffc_internal ffc_inline
24182418
void ffc_skip_zeros(char **first, char *last, size_t char_width) {
24192419
size_t cmp_len;
2420-
size_t cmp_mask;
2420+
uint64_t cmp_mask;
24212421
switch (char_width) {
24222422
case 1:
24232423
cmp_len = FFC_INT_CMP_LEN_1;
@@ -2457,7 +2457,7 @@ void ffc_skip_zeros(char **first, char *last, size_t char_width) {
24572457
ffc_internal ffc_inline
24582458
bool ffc_is_truncated(char const *first, char const *last, size_t char_width) {
24592459
size_t cmp_len;
2460-
size_t cmp_mask;
2460+
uint64_t cmp_mask;
24612461
switch (char_width) {
24622462
case 1:
24632463
cmp_len = FFC_INT_CMP_LEN_1;

src/common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ ffc_u128 ffc_full_multiplication(uint64_t a, uint64_t b) {
308308
// But MinGW on ARM64 doesn't have native support for 64-bit multiplications
309309
answer.high = __umulh(a, b);
310310
answer.low = a * b;
311-
#elif defined(FFC_32BIT) || (defined(_WIN64) && !defined(__clang__) && \
311+
#elif (defined(_WIN64) && !defined(__clang__) && \
312312
!defined(_M_ARM64) && !defined(__GNUC__))
313313
answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
314314
#elif defined(FFC_64BIT) && defined(__SIZEOF_INT128__)
@@ -609,7 +609,7 @@ static const float FFC_FLOAT_POWERS_OF_TEN[] = {
609609

610610
// Largest integer value v so that (5**index * v) <= 1<<53.
611611
// 0x20000000000000 == 1 << 53
612-
#define FFC_55555 (5L * 5L * 5L * 5L * 5L)
612+
#define FFC_55555 (5LL * 5LL * 5LL * 5LL * 5LL)
613613
static const uint64_t FFC_DOUBLE_MAX_MANTISSA[] = {
614614
(uint64_t)0x20000000000000L,
615615
(uint64_t)0x20000000000000L / 5,

src/digit_comparison.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ bool ffc_char_eq_zero(char const *p, size_t char_width) {
235235
ffc_internal ffc_inline
236236
void ffc_skip_zeros(char **first, char *last, size_t char_width) {
237237
size_t cmp_len;
238-
size_t cmp_mask;
238+
uint64_t cmp_mask;
239239
switch (char_width) {
240240
case 1:
241241
cmp_len = FFC_INT_CMP_LEN_1;
@@ -275,7 +275,7 @@ void ffc_skip_zeros(char **first, char *last, size_t char_width) {
275275
ffc_internal ffc_inline
276276
bool ffc_is_truncated(char const *first, char const *last, size_t char_width) {
277277
size_t cmp_len;
278-
size_t cmp_mask;
278+
uint64_t cmp_mask;
279279
switch (char_width) {
280280
case 1:
281281
cmp_len = FFC_INT_CMP_LEN_1;

test_src/double_cases_infnan.csv

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@ inf,inf,ok,,
1212
1.8e308,inf,out_of_range,
1313
1.832312213213213232132132143451234453123412321321312e308,inf,out_of_range,
1414
2e30000000000000000, inf,out_of_range,
15-
2e3000, inf,out_of_range,
15+
2e3000,inf,out_of_range,
1616
1.9e308,inf,out_of_range,
1717
1.79769313486231581e308,inf,out_of_range,DBL_MAX + 0.00000000000000001e308
1818
1.7976931348623159e308,inf,out_of_range,DBL_MAX + 0.0000000000000001e308
1919
179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497792,inf,out_of_range,( (2 - 0.5*2^(−52)) * 2^1023 ) smallest number that overflows to infinity
2020
infinity,inf,ok,,
21-
-NaN,-nan,ok,,
21+
-NaN,-nan,ok,be sure to write '-nan' as its intercepted by the test harness,
2222
-inf,-inf,ok,,
2323
nan,nan,ok,,
2424
Inf,inf,ok,,
2525
-infinity,-inf,ok,,
2626
inf,inf,ok,,
27-
-nan,-nan,ok,,
27+
-nan,-nan,ok,be sure to write '-nan' as its intercepted by the test harness,
2828
NaN,nan,ok,,
2929
-Inf,-inf,ok,,
3030
-+inf,0.0,invalid,

test_src/test.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "sonicsv.h"
33

44
#define FFC_DEBUG 0
5+
#define FFC_IMPL
56
#include "ffc.h"
67
#include <stdlib.h>
78
#include <stdio.h>
@@ -311,6 +312,7 @@ void cb_test(const csv_row_t *row, void *ctx) {
311312
bool is_neg_max = strncmp(expected_field->data, "-MAX", 4) == 0;
312313
bool is_min = strncmp(expected_field->data, "MIN", 3) == 0;
313314
bool is_neg_min = strncmp(expected_field->data, "-MIN", 4) == 0;
315+
bool is_neg_nan = strncmp(expected_field->data, "-nan", 4) == 0;
314316
switch (vk) {
315317
case FFC_VALUE_KIND_DOUBLE:
316318
if (is_max) {
@@ -321,6 +323,8 @@ void cb_test(const csv_row_t *row, void *ctx) {
321323
expected_value.d = DBL_MIN;
322324
} else if (is_neg_min) {
323325
expected_value.d = -DBL_MIN;
326+
} else if (is_neg_nan) {
327+
expected_value.d = -NAN;
324328
} else {
325329
expected_value.d = strtod(my_strndup(expected_field->size, expected_field->data), NULL);
326330
};
@@ -334,6 +338,8 @@ void cb_test(const csv_row_t *row, void *ctx) {
334338
expected_value.f = FLT_MIN;
335339
} else if (is_neg_min) {
336340
expected_value.f = -FLT_MIN;
341+
} else if (is_neg_nan) {
342+
expected_value.f = -NAN;
337343
} else {
338344
expected_value.f = strtof(my_strndup(expected_field->size, expected_field->data), NULL);
339345
};
@@ -616,6 +622,7 @@ int main(void) {
616622

617623
float_special();
618624

625+
#define FFC_TEST_EXHAUSTIVE 0
619626
#if FFC_TEST_EXHAUSTIVE
620627
exhaustive_32_run();
621628
#endif

test_src/test_int.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <assert.h>
88

99
#define FFC_DEBUG 0
10+
#define FFC_IMPL
1011
#include "ffc.h"
1112

1213
static int FAILS = 0;

tools/ubuntu_32_devel/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
apt update
2+
apt install make gcc clang

0 commit comments

Comments
 (0)