Skip to content

Commit af8e2f6

Browse files
committed
Merge pull request #397 from pguyot/w45/add-missing-opcodes
Add missing FP opcodes These opcodes are officially supported since R8. `fclearerror/0` and `fcheckerror/1` are noops as they are no longer implemented in OTP24 and the error is always checked by other OP_F* opcodes. Compiler support for `STDC FENV_ACCESS` pragma is checked and it is assumed that it means the compiler is conforming to C11 FENV support when the pragma is accepted. In this case, exception are checked using C11 floating point environment functions. If the pragma is unknown, `isfinite(3)` is used instead, assuming a non finite result is an error. This is what BEAM does on Unix. No `badarith` exception is raised on underflow divisions, to be compatible with BEAM (which cannot check that as it uses `isfinite(3)`). The only checked exceptions are overflow and division by zero. The tests were updated to actually generate the FP opcodes with OTP21-24 compilers. A new test was added for div. CI is updated to usually not use AVM_DISABLE_FP option. Only one configuration is maintained shall we decide to keep the option. Also assert types of operands at load time and ignore them at execution time. Also simplify macros by getting rid of the duplicate last parameter. These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents d9040e9 + 42a2e12 commit af8e2f6

File tree

17 files changed

+682
-51
lines changed

17 files changed

+682
-51
lines changed

.github/workflows/build-and-test.yaml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,19 +93,15 @@ jobs:
9393

9494
- otp: "21"
9595
elixir_version: "1.7"
96-
cmake_opts: ""
9796

9897
- otp: "22"
9998
elixir_version: "1.8"
100-
cmake_opts: "-DAVM_DISABLE_FP=on"
10199

102100
- otp: "23"
103-
elixir_version: "1.10.4"
104-
cmake_opts: "-DAVM_DISABLE_FP=on"
101+
elixir_version: "1.11"
105102

106103
- otp: "24"
107-
elixir_version: "1.11"
108-
cmake_opts: "-DAVM_DISABLE_FP=on"
104+
elixir_version: "1.14"
109105

110106
- os: "ubuntu-18.04"
111107
cc: "gcc-4.8"
@@ -123,13 +119,22 @@ jobs:
123119
cxx: "g++-10"
124120
cflags: "-m32 -O3"
125121
otp: "23"
126-
elixir_version: "1.10.4"
127-
cmake_opts: "-DOPENSSL_CRYPTO_LIBRARY=/usr/lib/i386-linux-gnu/libcrypto.so
128-
-DAVM_DISABLE_FP=on"
122+
elixir_version: "1.11"
123+
cmake_opts: "-DOPENSSL_CRYPTO_LIBRARY=/usr/lib/i386-linux-gnu/libcrypto.so"
129124
arch: "i386"
130125
compiler_pkgs: "gcc-10 g++-10 gcc-10-multilib g++-10-multilib libc6-dev-i386
131126
libc6-dbg:i386 zlib1g-dev:i386 libssl-dev:i386"
132127

128+
# keep one FP disabled configuration
129+
- os: "ubuntu-20.04"
130+
cc: "gcc-10"
131+
cxx: "g++-10"
132+
cflags: "-O3"
133+
otp: "24"
134+
elixir_version: "1.14"
135+
cmake_opts: "-DAVM_DISABLE_FP=on"
136+
compiler_pkgs: "gcc-10 g++-10"
137+
133138
env:
134139
CC: ${{ matrix.cc }}
135140
CXX: ${{ matrix.cxx }}

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3232
- Added support for the OTP `math` module
3333
- Added support for `erlang:integer_to_list/2` and `erlang:integer_to_binary/2`
3434
- Added functions `esp:sleep_enable_ext0_wakeup/2` and `esp:sleep_enable_ext1_wakeup/2.`
35+
- Added support for FP opcodes 94-102 thus removing the need for `AVM_DISABLE_FP=On` with OTP-22+
3536

3637
### Fixed
3738
- Fixed issue with formatting integers with io:format() on STM32 platform

src/libAtomVM/context.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
#include "context.h"
2222

23+
#include <fenv.h>
24+
#include <math.h>
25+
2326
#include "dictionary.h"
2427
#include "globalcontext.h"
2528
#include "list.h"
@@ -55,6 +58,10 @@ Context *context_new(GlobalContext *glb)
5558

5659
context_clean_registers(ctx, 0);
5760

61+
#ifndef AVM_NO_FP
62+
ctx->fr = NULL;
63+
#endif
64+
5865
ctx->min_heap_size = 0;
5966
ctx->max_heap_size = 0;
6067
ctx->has_min_heap_size = 0;
@@ -111,6 +118,9 @@ Context *context_new(GlobalContext *glb)
111118

112119
void context_destroy(Context *ctx)
113120
{
121+
#ifndef AVM_NO_FP
122+
free(ctx->fr);
123+
#endif
114124
list_remove(&ctx->processes_table_head);
115125

116126
memory_sweep_mso_list(ctx->mso_list);

src/libAtomVM/context.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ struct Context
7171

7272
term x[MAX_REG];
7373

74+
#ifndef AVM_NO_FP
75+
avm_float_t *fr;
76+
#endif
77+
7478
term *heap_start;
7579
term *stack_base;
7680
term *heap_ptr;
@@ -163,6 +167,23 @@ Context *context_new(GlobalContext *glb);
163167
*/
164168
void context_destroy(Context *c);
165169

170+
#ifndef AVM_NO_FP
171+
/**
172+
* @brief Ensure we have FP registers, allocating them if necessary.
173+
* @param c context fo allocate FP registers for
174+
*/
175+
static inline void context_ensure_fpregs(Context *c)
176+
{
177+
if (UNLIKELY(c->fr == NULL)) {
178+
c->fr = (avm_float_t *) malloc(sizeof(avm_float_t) * MAX_REG);
179+
if (UNLIKELY(c->fr == NULL)) {
180+
fprintf(stderr, "Could not allocate FP registers\n");
181+
AVM_ABORT();
182+
}
183+
}
184+
}
185+
#endif
186+
166187
/**
167188
* @brief Starts executing a function
168189
*

src/libAtomVM/opcodes.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@
8787
#define OP_BS_PUT_INTEGER 89
8888
#define OP_BS_PUT_BINARY 90
8989
#define OP_BS_PUT_STRING 92
90+
#define OP_FCLEARERROR 94
91+
#define OP_FCHECKERROR 95
92+
#define OP_FMOVE 96
93+
#define OP_FCONV 97
94+
#define OP_FADD 98
95+
#define OP_FSUB 99
96+
#define OP_FMUL 100
97+
#define OP_FDIV 101
98+
#define OP_FNEGATE 102
9099
#define OP_MAKE_FUN2 103
91100
#define OP_TRY 104
92101
#define OP_TRY_END 105

0 commit comments

Comments
 (0)