Upon re-implementing "vTaskSwitchContext" from FreeRTOS in RISC-V 
(implementation attached), the "clz a5, a5" instruction is incorrectly 
assembled as 0x60079793, when the RISC-V Zbb extension specification 
(https://five-embeddev.com/riscv-bitmanip/1.0.0/bitmanip.html#insns-clz) 
specifies that it should be 0x600a9a93.

Version:

GNU assembler (xPack GNU RISC-V Embedded GCC x86_64) 2.43.1
Copyright (C) 2024 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `riscv-none-elf'.

I didn't compile these tools, I downloaded them here: 
https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack

I've also attached the two makefiles used to compile this project.

Attachment: vTaskSwitchContext.S
Description: vTaskSwitchContext.S

# ================================================================================ #
# NEORV32 Application Software Makefile                                            #
# -------------------------------------------------------------------------------- #
# Do not edit this file! Use the re-defines in the project-local makefile instead. #
# -------------------------------------------------------------------------------- #
# The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32              #
# Copyright (c) NEORV32 contributors.                                              #
# Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved.                  #
# Licensed under the BSD-3-Clause license, see LICENSE for details.                #
# SPDX-License-Identifier: BSD-3-Clause                                            #
# ================================================================================ #

# -----------------------------------------------------------------------------
# Default configuration (DO NOT EDIT THIS FILE! REDEFINE / OVERRIDE THE DEFAULT
# CONFIGURATION WHEN INCLUDING THIS MAKEFILE IN THE PROJECT-SPECIFIC MAKEFILE)
# -----------------------------------------------------------------------------

# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)

# User's application object files (*.o, *.cpp, *.s, *.S); add additional files here
APP_OBJ ?=

# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .

# Build folder for output
BUILD_DIR ?= build

# Optimization
EFFORT ?= -Os

# Compiler toolchain prefix
RISCV_PREFIX ?= riscv-none-elf-

# CPU architecture and ABI
MARCH ?= rv32i_zicsr_zifencei
MABI  ?= ilp32

# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=

# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..

# GDB arguments
GDB_ARGS ?= -ex "target extended-remote localhost:3333"

# GHDL simulation run arguments
GHDL_RUN_FLAGS ?=

# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------

# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl
# Path to NEORV32 sim folder
NEORV32_SIM_PATH = $(NEORV32_HOME)/sim

# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
# Linker script
LD_SCRIPT ?= $(NEORV32_COM_PATH)/neorv32.ld

# Main output files
APP_EXE  = neorv32_exe.bin
APP_ELF  = main.elf
APP_HEX  = neorv32_raw_exe.hex
APP_BIN  = neorv32_raw_exe.bin
APP_COE  = neorv32_raw_exe.coe
APP_MEM  = neorv32_raw_exe.mem
APP_MIF  = neorv32_raw_exe.mif
APP_ASM  = main.asm
APP_VHD  = neorv32_application_image.vhd
BOOT_VHD = neorv32_bootloader_image.vhd

# Binary main file
BIN_MAIN = $(BUILD_DIR)/main.bin

# Define all sources
SRC  = $(APP_SRC)
SRC += $(CORE_SRC)

# Define search path for prerequisites
VPATH = $(sort $(dir $(SRC)))

# Define all object files
OBJ := $(patsubst %,$(BUILD_DIR)/%.o,$(notdir $(SRC)))
OBJ += $(APP_OBJ)

# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------

# Compiler tools
CC      = $(RISCV_PREFIX)gcc
OBJDUMP = $(RISCV_PREFIX)objdump
OBJCOPY = $(RISCV_PREFIX)objcopy
READELF = $(RISCV_PREFIX)readelf
SIZE    = $(RISCV_PREFIX)size
GDB     = $(RISCV_PREFIX)gdb

# Host's native compiler
CC_HOST = gcc -Wall -O -g

# System tools
ECHO  = @echo
SET   = set
CP    = cp
RM    = rm
MKDIR = mkdir
SH    = sh
WC    = wc

# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
ifeq ($(OS),Windows_NT)
IMAGE_GEN := $(IMAGE_GEN).exe
endif

# Compiler & linker flags
CC_FLAGS  = -march=$(MARCH) -mabi=$(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_FLAGS += -mstrict-align -mbranch-cost=10 -Wl,--gc-sections -ffp-contract=off -g
CC_FLAGS += $(USER_FLAGS)
LD_LIBS   = -lm -lc -lgcc
LD_LIBS  += $(USER_LIBS)

# Allow users to use tool-specific flags
# Uses naming from https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
NEO_CFLAGS   = $(CC_FLAGS) $(CFLAGS)
NEO_CXXFLAGS = $(CC_FLAGS) $(CXXFLAGS)
NEO_LDFLAGS  = $(CC_FLAGS) $(LDFLAGS)
NEO_ASFLAGS  = $(CC_FLAGS) $(ASFLAGS)

# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------

.PHONY: check info help elf_info clean clean_all
.DEFAULT_GOAL := help

elf:     $(APP_ELF)
asm:     $(APP_ASM)
exe:     $(APP_EXE)
hex:     $(APP_HEX)
bin:     $(APP_BIN)
coe:     $(APP_COE)
mem:     $(APP_MEM)
mif:     $(APP_MIF)
image:   $(APP_VHD)
install: image install-$(APP_VHD)
all:     $(APP_ELF) $(APP_ASM) $(APP_EXE) $(APP_HEX) $(APP_BIN) $(APP_COE) $(APP_MEM) $(APP_MIF) $(APP_VHD) install hex bin

# -----------------------------------------------------------------------------
# Verbosity
# -----------------------------------------------------------------------------

ifeq ("$(origin V)", "command line")
BUILD_VERBOSE=$(V)
endif
ifndef BUILD_VERBOSE
BUILD_VERBOSE = 0
endif
ifeq ($(BUILD_VERBOSE),0)
Q = @
else
Q =
endif

# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------

# Compile image generator
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.c
	$(ECHO) Compiling image generator...
	$(Q)$(CC_HOST) $< -o $(IMAGE_GEN)

# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------

# Create the build directories if they don't exist
$(BUILD_DIR):
	$(Q)$(MKDIR) -p $(BUILD_DIR)

# Compile app *.s sources (assembly)
$(BUILD_DIR)/%.s.o: %.s | $(BUILD_DIR)
	$(Q)$(CC) -c $(NEO_ASFLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.s.d -MT $(BUILD_DIR)/$*.s.o -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@

# Compile app *.S sources (assembly + C pre-processor)
$(BUILD_DIR)/%.S.o: %.S | $(BUILD_DIR)
	$(Q)$(CC) -c $(NEO_ASFLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.S.d -MT $(BUILD_DIR)/$*.S.o -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@

# Compile app *.c sources
$(BUILD_DIR)/%.c.o: %.c | $(BUILD_DIR)
	$(Q)$(CC) -c $(NEO_CFLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.c.d -MT $(BUILD_DIR)/$*.c.o -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@

# Compile app *.cpp sources
$(BUILD_DIR)/%.cpp.o: %.cpp | $(BUILD_DIR)
	$(Q)$(CC) -c $(NEO_CXXFLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.cpp.d -MT $(BUILD_DIR)/$*.cpp.o -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@

# Link object files and show memory utilization
-include $(OBJ:.o=.d)
$(APP_ELF): $(OBJ)
	$(Q)$(CC) $(NEO_LDFLAGS) -T $(LD_SCRIPT) $^ $(LD_LIBS) -o $@
	$(ECHO) "Memory utilization:"
	$(Q)$(SIZE) $(APP_ELF)

# Assembly listing file (for debugging)
$(APP_ASM): $(APP_ELF)
	$(Q)$(OBJDUMP) -d -S -z $< > $@

# Generate final executable from .text + .rodata + .data (in THIS order!)
$(BIN_MAIN): $(APP_ELF) | $(BUILD_DIR)
	$(Q)$(OBJCOPY) -I elf32-little $< -j .text -j .rodata -j .data -O binary $@

# -----------------------------------------------------------------------------
# Application targets: Generate executable formats
# -----------------------------------------------------------------------------

# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): $(BIN_MAIN) $(IMAGE_GEN)
	$(Q)$(SET) -e
	$(ECHO) "Generating $(APP_EXE)"
	$(Q)$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
	$(ECHO) "Executable size in bytes:"
	$(Q)$(WC) -c < $(APP_EXE)

# Generate NEORV32 executable VHDL boot image
$(APP_VHD): $(BIN_MAIN) $(IMAGE_GEN)
	$(Q)$(SET) -e
	$(ECHO) "Generating $(APP_VHD)"
	$(Q)$(IMAGE_GEN) -app_vhd $< $@ $(shell basename $(CURDIR))

# Generate NEORV32 RAW executable image in plain hex format
$(APP_HEX): $(BIN_MAIN) $(IMAGE_GEN)
	$(Q)$(SET) -e
	$(ECHO) "Generating $(APP_HEX)"
	$(Q)$(IMAGE_GEN) -raw_hex $< $@ $(shell basename $(CURDIR))

# Generate NEORV32 RAW executable image in binary format
$(APP_BIN): $(BIN_MAIN) $(IMAGE_GEN)
	$(Q)$(SET) -e
	$(ECHO) "Generating $(APP_BIN)"
	$(Q)$(IMAGE_GEN) -raw_bin $< $@ $(shell basename $(CURDIR))

# Generate NEORV32 RAW executable image in COE format
$(APP_COE): $(BIN_MAIN) $(IMAGE_GEN)
	$(Q)$(SET) -e
	$(ECHO) "Generating $(APP_COE)"
	$(Q)$(IMAGE_GEN) -raw_coe $< $@ $(shell basename $(CURDIR))

# Generate NEORV32 RAW executable image in MIF format
$(APP_MIF): $(BIN_MAIN) $(IMAGE_GEN)
	$(Q)$(SET) -e
	$(ECHO) "Generating $(APP_MIF)"
	$(Q)$(IMAGE_GEN) -raw_mif $< $@ $(shell basename $(CURDIR))

# Generate NEORV32 RAW executable image in MEM format
$(APP_MEM): $(BIN_MAIN) $(IMAGE_GEN)
	$(Q)$(SET) -e
	$(ECHO) "Generating $(APP_MEM)"
	$(Q)$(IMAGE_GEN) -raw_mem $< $@ $(shell basename $(CURDIR))

# -----------------------------------------------------------------------------
# BOOTROM / bootloader image targets
# -----------------------------------------------------------------------------

# Create local VHDL BOOTROM image
bl_image: $(BIN_MAIN) $(IMAGE_GEN)
	$(Q)$(SET) -e
	$(ECHO) "Generating $(BOOT_VHD)"
	$(Q)$(IMAGE_GEN) -bld_vhd $< $(BOOT_VHD) $(shell basename $(CURDIR))

# Install BOOTROM image to VHDL source directory
bootloader: bl_image
	$(Q)$(SET) -e
	$(ECHO) "Installing bootloader image to $(NEORV32_RTL_PATH)/core/$(BOOT_VHD)"
	$(Q)$(CP) $(BOOT_VHD) $(NEORV32_RTL_PATH)/core/.

# -----------------------------------------------------------------------------
# In-console simulation using default testbench and GHDL
# -----------------------------------------------------------------------------

sim: $(APP_VHD)
	$(ECHO) "Simulating processor using default testbench..."
	$(Q)$(SH) $(NEORV32_SIM_PATH)/ghdl.sh $(GHDL_RUN_FLAGS)

# Install VHDL memory initialization file
install-$(APP_VHD): $(APP_VHD)
	$(Q)$(SET) -e
	$(ECHO) "Installing application image to $(NEORV32_RTL_PATH)/core/$(APP_VHD)"
	$(Q)$(CP) $(APP_VHD) $(NEORV32_RTL_PATH)/core/.

# -----------------------------------------------------------------------------
# Regenerate HDL file list file(s)
# -----------------------------------------------------------------------------

hdl_lists:
	$(Q)$(SH) $(NEORV32_RTL_PATH)/generate_file_lists.sh

# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------

elf_info: $(APP_ELF)
	$(Q)$(OBJDUMP) -x $(APP_ELF)

elf_sections: $(APP_ELF)
	$(Q)$(READELF) -S $(APP_ELF)

# -----------------------------------------------------------------------------
# Run GDB
# -----------------------------------------------------------------------------

gdb: $(APP_ELF)
	$(Q)$(GDB) $(APP_ELF) $(GDB_ARGS)

# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------

# remove all build artifacts
clean:
	$(Q)$(RM) -rf $(BUILD_DIR)
	$(Q)$(RM) -f $(APP_EXE) $(APP_ELF) $(APP_HEX) $(APP_BIN) $(APP_COE) $(APP_MEM) $(APP_MIF) $(APP_ASM) $(APP_VHD) $(BOOT_VHD)
	$(Q)$(RM) -f .gdb_history

# also remove image generator
clean_all: clean
	$(Q)$(RM) -f $(IMAGE_GEN)
	$(Q)$(RM) -rf $(NEORV32_SIM_PATH)/build

# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------

check: $(IMAGE_GEN)
	$(ECHO) "---------------- $(CC) ----------------"
	$(Q)$(CC) -v
	$(ECHO) "---------------- $(OBJDUMP) ----------------"
	$(Q)$(OBJDUMP) -V
	$(ECHO) "---------------- $(OBJCOPY) ----------------"
	$(Q)$(OBJCOPY) -V
	$(ECHO) "---------------- $(READELF) ----------------"
	$(Q)$(READELF) -v
	$(ECHO) "---------------- $(SIZE) ----------------"
	$(Q)$(SIZE) -V
	$(ECHO) "---------------- NEORV32 image_gen ----------------"
	$(Q)$(IMAGE_GEN) -help
	$(ECHO) "---------------- Native GCC ----------------"
	$(Q)$(CC_HOST) -v
	$(ECHO) ""
	$(ECHO) "Toolchain check OK"

# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------

info:
	$(ECHO) "******************************************************"
	$(ECHO) "Project / Makefile 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) "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) "Search path (VPATH)"
	$(ECHO) "$(VPATH)"
	$(ECHO) "Project object files:"
	$(ECHO) "$(OBJ)"
	$(ECHO) "LIBGCC:"
	$(Q)$(CC) -print-libgcc-file-name
	$(ECHO) "SEARCH-DIRS:"
	$(Q)$(CC) -print-search-dirs
	$(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_FLAGS: $(CC_FLAGS)"

# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------

help:
	$(ECHO) "NEORV32 Software Makefile"
	$(ECHO) "Find more information at https://github.com/stnolting/neorv32";
	$(ECHO) "Use make V=1 or set BUILD_VERBOSE to increase build verbosity"
	$(ECHO) ""
	$(ECHO) "Targets:"
	$(ECHO) ""
	$(ECHO) "  help          show this text"
	$(ECHO) "  check         check toolchain"
	$(ECHO) "  info          show makefile/toolchain configuration"
	$(ECHO) "  gdb           start GNU debugging session"
	$(ECHO) "  asm           compile and generate <$(APP_ASM)> assembly listing file for manual debugging"
	$(ECHO) "  elf           compile and generate <$(APP_ELF)> ELF file"
	$(ECHO) "  exe           compile and generate <$(APP_EXE)> executable image file for bootloader upload (includes a HEADER!)"
	$(ECHO) "  bin           compile and generate <$(APP_BIN)> executable memory image"
	$(ECHO) "  hex           compile and generate <$(APP_HEX)> executable memory image"
	$(ECHO) "  coe           compile and generate <$(APP_COE)> executable memory image"
	$(ECHO) "  mem           compile and generate <$(APP_MEM)> executable memory image"
	$(ECHO) "  mif           compile and generate <$(APP_MIF)> executable memory image"
	$(ECHO) "  image         compile and generate VHDL IMEM application boot image <$(APP_VHD)> in local folder"
	$(ECHO) "  install       compile, generate and install VHDL IMEM application boot image <$(APP_VHD)>"
	$(ECHO) "  sim           in-console simulation using default testbench (sim folder) and GHDL"
	$(ECHO) "  hdl_lists     regenerate HDL file-lists (*.f) in NEORV32_HOME/rtl"
	$(ECHO) "  all           exe + install + hex + bin + asm"
	$(ECHO) "  elf_info      show ELF layout info"
	$(ECHO) "  elf_sections  show ELF sections"
	$(ECHO) "  clean         clean up project home folder"
	$(ECHO) "  clean_all     clean up project home folder and image generator"
	$(ECHO) "  bl_image      compile and generate VHDL BOOTROM bootloader boot image <$(BOOT_VHD)> in local folder"
	$(ECHO) "  bootloader    compile, generate and install VHDL BOOTROM bootloader boot image <$(BOOT_VHD)>"
	$(ECHO) ""
	$(ECHO) "Variables:"
	$(ECHO) ""
	$(ECHO) "  BUILD_VERBOSE   Set to increase build verbosity: \"$(BUILD_VERBOSE)\""
	$(ECHO) "  USER_FLAGS      Custom toolchain flags [append only]: \"$(USER_FLAGS)\""
	$(ECHO) "  USER_LIBS       Custom libraries [append only]: \"$(USER_LIBS)\""
	$(ECHO) "  EFFORT          Optimization level: \"$(EFFORT)\""
	$(ECHO) "  MARCH           Machine architecture: \"$(MARCH)\""
	$(ECHO) "  MABI            Machine binary interface: \"$(MABI)\""
	$(ECHO) "  APP_INC         C include folder(s) [append only]: \"$(APP_INC)\""
	$(ECHO) "  APP_SRC         C source folder(s) [append only]: \"$(APP_SRC)\""
	$(ECHO) "  APP_OBJ         Object file(s) [append only]: \"$(APP_OBJ)\""
	$(ECHO) "  ASM_INC         ASM include folder(s) [append only]: \"$(ASM_INC)\""
	$(ECHO) "  RISCV_PREFIX    Toolchain prefix: \"$(RISCV_PREFIX)\""
	$(ECHO) "  NEORV32_HOME    NEORV32 home folder: \"$(NEORV32_HOME)\""
	$(ECHO) "  GDB_ARGS        GDB (connection) arguments: \"$(GDB_ARGS)\""
	$(ECHO) "  GHDL_RUN_FLAGS  GHDL simulation run arguments: \"$(GHDL_RUN_FLAGS)\""
	$(ECHO) ""

Reply via email to