Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FPU] prevent GCC from emitting fused multiply-add instructions #905

Merged
merged 3 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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