Skip to content

Commit

Permalink
[FPU] prevent GCC from emitting fused multiply-add instructions (#905)
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting committed May 18, 2024
2 parents 1981b40 + 316b6c6 commit 8468686
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 63 deletions.
10 changes: 7 additions & 3 deletions docs/datasheet/cpu.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -680,10 +680,14 @@ register file-related load/store or move instructions. The `Zfinx` extension'S f
via dedicated <<_floating_point_csrs>>.
This ISA extension is implemented as multi-cycle ALU co-process (`rtl/core/neorv32_cpu_cp_fpu.vhd`).

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

.Division and Squarer Root Instructions
[WARNING]
Division `fdiv.s` and square root `fsqrt.s` instructions are not supported yet.

.Subnormal Number
[WARNING]
Expand Down
1 change: 1 addition & 0 deletions docs/datasheet/software.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ The makefile's `CC_OPTS` is exported as **define** to be available within a C pr
| `-g` | Include debugging information/symbols in ELF.
| `-mstrict-align` | Unaligned memory accesses cannot be resolved by the hardware and require emulation.
| `-mbranch-cost=10` | Branching costs a lot of cycles.
| `-ffp-contract=off` | Do not allow contraction of floatind-point operations (no fused operations as they are not supported).
|=======================
:sectnums:
Expand Down
69 changes: 21 additions & 48 deletions sw/common/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen

# Compiler & linker flags
CC_OPTS = -march=$(MARCH) -mabi=$(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -mstrict-align -mbranch-cost=10 -g -Wl,--gc-sections
CC_OPTS += -mstrict-align -mbranch-cost=10 -g -Wl,--gc-sections -ffp-contract=off
CC_OPTS += $(USER_FLAGS)
LD_LIBS = -lm -lc -lgcc
LD_LIBS += $(USER_LIBS)
Expand Down Expand Up @@ -324,72 +324,45 @@ clean_all: clean
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "------------------------------------------------------"
@echo "-- Project"
@echo "------------------------------------------------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "******************************************************"
@echo "Project / Makfile Configuration"
@echo "******************************************************"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "------------------------------------------------------"
@echo "-- NEORV32"
@echo "------------------------------------------------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "------------------------------------------------------"
@echo "-- Objects"
@echo "------------------------------------------------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "------------------------------------------------------"
@echo "-- RISC-V CPU"
@echo "------------------------------------------------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "------------------------------------------------------"
@echo "-- Toolchain"
@echo "------------------------------------------------------"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "DEBUGGER: $(GDB)"
@echo "------------------------------------------------------"
@echo "-- GDB Arguments"
@echo "------------------------------------------------------"
@echo "GDB_ARGS: $(GDB_ARGS)"
@echo "------------------------------------------------------"
@echo "-- GHDL Run Arguments"
@echo "------------------------------------------------------"
@echo "GHDL_RUN_FLAGS: $(GHDL_RUN_FLAGS)"
@echo "------------------------------------------------------"
@echo "-- Libraries"
@echo "------------------------------------------------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "------------------------------------------------------"
@echo "-- Compiler Flags"
@echo "------------------------------------------------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "------------------------------------------------------"
@echo "-- Libraries"
@echo "------------------------------------------------------"
@echo "USER_LIBS: $(USER_LIBS)"
@echo "LD_LIBS: $(LD_LIBS)"
@echo "USER_LIBS: $(USER_LIBS)"
@echo "LD_LIBS: $(LD_LIBS)"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "DEBUGGER: $(GDB)"
@echo "GDB_ARGS: $(GDB_ARGS)"
@echo "GHDL_RUN_FLAGS: $(GHDL_RUN_FLAGS)"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"


# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "NEORV32 Software Application Makefile"
@echo "NEORV32 Software Makefile"
@echo "Find more information at https://github.com/stnolting/neorv32"
@echo ""
@echo "Targets:"
Expand Down
26 changes: 14 additions & 12 deletions sw/lib/source/neorv32_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,21 +284,12 @@ void neorv32_uart_puts(neorv32_uart_t *UARTx, const char *s) {
/**********************************************************************//**
* Custom version of 'vprintf' printing to UART.
*
* @warning: This functions only provides a minimal subset of the 'vprintf' formating features!
* @note This function is blocking.
*
* @param[in,out] UARTx Hardware handle to UART register struct, #neorv32_uart_t.
* @param[in] format Pointer to format string.
* @param[in] args A value identifying a variable arguments list.
*
* <TABLE>
* <TR><TD>%s</TD><TD>String (array of chars, zero-terminated)</TD></TR>
* <TR><TD>%c</TD><TD>Single char</TD></TR>
* <TR><TD>%d/%i</TD><TD>32-bit signed number, printed as decimal</TD></TR>
* <TR><TD>%u</TD><TD>32-bit unsigned number, printed as decimal</TD></TR>
* <TR><TD>%x</TD><TD>32-bit number, printed as 8-char hexadecimal - lower-case</TD></TR>
* <TR><TD>%X</TD><TD>32-bit number, printed as 8-char hexadecimal - upper-case</TD></TR>
* <TR><TD>%p</TD><TD>32-bit pointer, printed as 8-char hexadecimal - lower-case</TD></TR>
* </TABLE>
**************************************************************************/
void neorv32_uart_vprintf(neorv32_uart_t *UARTx, const char *format, va_list args) {

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

// case 'f': // floating point: print binary representation in hex
// union { double fp64; uint32_t u32[2]; } fp2hex;
// neorv32_uart_puts(UARTx, "FP64:0x");
// fp2hex.fp64 = va_arg(args, double); // C promotes float to double!
// __neorv32_uart_tohex(fp2hex.u32[0], string_buf);
// neorv32_uart_puts(UARTx, string_buf);
// __neorv32_uart_tohex(fp2hex.u32[1], string_buf);
// neorv32_uart_puts(UARTx, string_buf);
// break;

case '%': // escaped percent sign
neorv32_uart_putc(UARTx, '%');
neorv32_uart_putc(UARTx, c);
break;

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

0 comments on commit 8468686

Please sign in to comment.