Skip to content

Commit 8468686

Browse files
authored
[FPU] prevent GCC from emitting fused multiply-add instructions (#905)
2 parents 1981b40 + 316b6c6 commit 8468686

File tree

4 files changed

+43
-63
lines changed

4 files changed

+43
-63
lines changed

docs/datasheet/cpu.adoc

+7-3
Original file line numberDiff line numberDiff line change
@@ -680,10 +680,14 @@ register file-related load/store or move instructions. The `Zfinx` extension'S f
680680
via dedicated <<_floating_point_csrs>>.
681681
This ISA extension is implemented as multi-cycle ALU co-process (`rtl/core/neorv32_cpu_cp_fpu.vhd`).
682682

683-
.Fused Multiply-Add and Division Instructions
683+
.Fused / Multiply-Add Instructions
684684
[WARNING]
685-
Fused multiply-add instructions `f[n]m[add/sub].s` are not supported!
686-
Division `fdiv.s` and square root `fsqrt.s` instructions are not supported yet!
685+
Fused multiply-add instructions `f[n]m[add/sub].s` are not supported. A special GCC switch is used to prevent the
686+
compiler from emitting contracted/fused floating-point operations (see <<_default_compiler_flags>>).
687+
688+
.Division and Squarer Root Instructions
689+
[WARNING]
690+
Division `fdiv.s` and square root `fsqrt.s` instructions are not supported yet.
687691

688692
.Subnormal Number
689693
[WARNING]

docs/datasheet/software.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ The makefile's `CC_OPTS` is exported as **define** to be available within a C pr
286286
| `-g` | Include debugging information/symbols in ELF.
287287
| `-mstrict-align` | Unaligned memory accesses cannot be resolved by the hardware and require emulation.
288288
| `-mbranch-cost=10` | Branching costs a lot of cycles.
289+
| `-ffp-contract=off` | Do not allow contraction of floatind-point operations (no fused operations as they are not supported).
289290
|=======================
290291
291292
:sectnums:

sw/common/common.mk

+21-48
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
111111

112112
# Compiler & linker flags
113113
CC_OPTS = -march=$(MARCH) -mabi=$(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
114-
CC_OPTS += -mstrict-align -mbranch-cost=10 -g -Wl,--gc-sections
114+
CC_OPTS += -mstrict-align -mbranch-cost=10 -g -Wl,--gc-sections -ffp-contract=off
115115
CC_OPTS += $(USER_FLAGS)
116116
LD_LIBS = -lm -lc -lgcc
117117
LD_LIBS += $(USER_LIBS)
@@ -324,72 +324,45 @@ clean_all: clean
324324
# Show configuration
325325
# -----------------------------------------------------------------------------
326326
info:
327-
@echo "------------------------------------------------------"
328-
@echo "-- Project"
329-
@echo "------------------------------------------------------"
330-
@echo "Project folder: $(shell basename $(CURDIR))"
331-
@echo "Source files: $(APP_SRC)"
332-
@echo "Include folder(s): $(APP_INC)"
327+
@echo "******************************************************"
328+
@echo "Project / Makfile Configuration"
329+
@echo "******************************************************"
330+
@echo "Project folder: $(shell basename $(CURDIR))"
331+
@echo "Source files: $(APP_SRC)"
332+
@echo "Include folder(s): $(APP_INC)"
333333
@echo "ASM include folder(s): $(ASM_INC)"
334-
@echo "------------------------------------------------------"
335-
@echo "-- NEORV32"
336-
@echo "------------------------------------------------------"
337334
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
338335
@echo "IMAGE_GEN: $(IMAGE_GEN)"
339336
@echo "Core source files:"
340337
@echo "$(CORE_SRC)"
341338
@echo "Core include folder:"
342339
@echo "$(NEORV32_INC_PATH)"
343-
@echo "------------------------------------------------------"
344-
@echo "-- Objects"
345-
@echo "------------------------------------------------------"
346340
@echo "Project object files:"
347341
@echo "$(OBJ)"
348-
@echo "------------------------------------------------------"
349-
@echo "-- RISC-V CPU"
350-
@echo "------------------------------------------------------"
351-
@echo "MARCH: $(MARCH)"
352-
@echo "MABI: $(MABI)"
353-
@echo "------------------------------------------------------"
354-
@echo "-- Toolchain"
355-
@echo "------------------------------------------------------"
356-
@echo "CC: $(CC)"
357-
@echo "OBJDUMP: $(OBJDUMP)"
358-
@echo "OBJCOPY: $(OBJCOPY)"
359-
@echo "SIZE: $(SIZE)"
360-
@echo "DEBUGGER: $(GDB)"
361-
@echo "------------------------------------------------------"
362-
@echo "-- GDB Arguments"
363-
@echo "------------------------------------------------------"
364-
@echo "GDB_ARGS: $(GDB_ARGS)"
365-
@echo "------------------------------------------------------"
366-
@echo "-- GHDL Run Arguments"
367-
@echo "------------------------------------------------------"
368-
@echo "GHDL_RUN_FLAGS: $(GHDL_RUN_FLAGS)"
369-
@echo "------------------------------------------------------"
370-
@echo "-- Libraries"
371-
@echo "------------------------------------------------------"
372342
@echo "LIBGCC:"
373343
@$(CC) -print-libgcc-file-name
374344
@echo "SEARCH-DIRS:"
375345
@$(CC) -print-search-dirs
376-
@echo "------------------------------------------------------"
377-
@echo "-- Compiler Flags"
378-
@echo "------------------------------------------------------"
379-
@echo "USER_FLAGS: $(USER_FLAGS)"
380-
@echo "CC_OPTS: $(CC_OPTS)"
381-
@echo "------------------------------------------------------"
382-
@echo "-- Libraries"
383-
@echo "------------------------------------------------------"
384-
@echo "USER_LIBS: $(USER_LIBS)"
385-
@echo "LD_LIBS: $(LD_LIBS)"
346+
@echo "USER_LIBS: $(USER_LIBS)"
347+
@echo "LD_LIBS: $(LD_LIBS)"
348+
@echo "MARCH: $(MARCH)"
349+
@echo "MABI: $(MABI)"
350+
@echo "CC: $(CC)"
351+
@echo "OBJDUMP: $(OBJDUMP)"
352+
@echo "OBJCOPY: $(OBJCOPY)"
353+
@echo "SIZE: $(SIZE)"
354+
@echo "DEBUGGER: $(GDB)"
355+
@echo "GDB_ARGS: $(GDB_ARGS)"
356+
@echo "GHDL_RUN_FLAGS: $(GHDL_RUN_FLAGS)"
357+
@echo "USER_FLAGS: $(USER_FLAGS)"
358+
@echo "CC_OPTS: $(CC_OPTS)"
386359

387360

388361
# -----------------------------------------------------------------------------
389362
# Help
390363
# -----------------------------------------------------------------------------
391364
help:
392-
@echo "NEORV32 Software Application Makefile"
365+
@echo "NEORV32 Software Makefile"
393366
@echo "Find more information at https://github.com/stnolting/neorv32"
394367
@echo ""
395368
@echo "Targets:"

sw/lib/source/neorv32_uart.c

+14-12
Original file line numberDiff line numberDiff line change
@@ -284,21 +284,12 @@ void neorv32_uart_puts(neorv32_uart_t *UARTx, const char *s) {
284284
/**********************************************************************//**
285285
* Custom version of 'vprintf' printing to UART.
286286
*
287+
* @warning: This functions only provides a minimal subset of the 'vprintf' formating features!
287288
* @note This function is blocking.
288289
*
289290
* @param[in,out] UARTx Hardware handle to UART register struct, #neorv32_uart_t.
290291
* @param[in] format Pointer to format string.
291292
* @param[in] args A value identifying a variable arguments list.
292-
*
293-
* <TABLE>
294-
* <TR><TD>%s</TD><TD>String (array of chars, zero-terminated)</TD></TR>
295-
* <TR><TD>%c</TD><TD>Single char</TD></TR>
296-
* <TR><TD>%d/%i</TD><TD>32-bit signed number, printed as decimal</TD></TR>
297-
* <TR><TD>%u</TD><TD>32-bit unsigned number, printed as decimal</TD></TR>
298-
* <TR><TD>%x</TD><TD>32-bit number, printed as 8-char hexadecimal - lower-case</TD></TR>
299-
* <TR><TD>%X</TD><TD>32-bit number, printed as 8-char hexadecimal - upper-case</TD></TR>
300-
* <TR><TD>%p</TD><TD>32-bit pointer, printed as 8-char hexadecimal - lower-case</TD></TR>
301-
* </TABLE>
302293
**************************************************************************/
303294
void neorv32_uart_vprintf(neorv32_uart_t *UARTx, const char *format, va_list args) {
304295

@@ -344,11 +335,21 @@ void neorv32_uart_vprintf(neorv32_uart_t *UARTx, const char *format, va_list arg
344335
neorv32_uart_puts(UARTx, string_buf);
345336
break;
346337

338+
// case 'f': // floating point: print binary representation in hex
339+
// union { double fp64; uint32_t u32[2]; } fp2hex;
340+
// neorv32_uart_puts(UARTx, "FP64:0x");
341+
// fp2hex.fp64 = va_arg(args, double); // C promotes float to double!
342+
// __neorv32_uart_tohex(fp2hex.u32[0], string_buf);
343+
// neorv32_uart_puts(UARTx, string_buf);
344+
// __neorv32_uart_tohex(fp2hex.u32[1], string_buf);
345+
// neorv32_uart_puts(UARTx, string_buf);
346+
// break;
347+
347348
case '%': // escaped percent sign
348-
neorv32_uart_putc(UARTx, '%');
349+
neorv32_uart_putc(UARTx, c);
349350
break;
350351

351-
default: // unsupported format
352+
default: // unsupported formating character
352353
neorv32_uart_putc(UARTx, '%');
353354
neorv32_uart_putc(UARTx, c);
354355
break;
@@ -367,6 +368,7 @@ void neorv32_uart_vprintf(neorv32_uart_t *UARTx, const char *format, va_list arg
367368
/**********************************************************************//**
368369
* Custom version of 'printf' printing to UART.
369370
*
371+
* @warning: This functions only provides a minimal subset of the 'printf' formating features!
370372
* @note This function is blocking.
371373
*
372374
* @param[in,out] UARTx Hardware handle to UART register struct, #neorv32_uart_t.

0 commit comments

Comments
 (0)