-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Hello! 👋
First, thank you to the TinyGo team for the excellent work on ESP32C3 support! While studying the code, I noticed something about the compilation flags that I'm not sure if this is intentional design or something that could be improved, and I'd like to ask the team about it.
🔍 What I Observed
When compiling for ESP32C3, I found:
- User code and CGo: Uses
-march=rv32imc(without atomic extensiona) ✅ - C libraries (compiler-rt/picolibc): Uses
-march=rv32imac(with atomic extensiona) ❓
Since ESP32C3 doesn't support the RISC-V atomic extension, I'm not sure if this difference is intentional.
📝 Full Reproduction Steps
1. Create Test Program
cat > test.go << 'EOF'
package main
func main() {
println("Hello ESP32C3")
}
EOF2. Clear Cache (to see full compilation process)
# macOS
rm -rf ~/Library/Caches/tinygo/*riscv32*
# Linux
rm -rf ~/.cache/tinygo/*riscv32*3. Build with -x flag and view compilation commands
# Using xiao-esp32c3 target
tinygo build -target=xiao-esp32c3 -x -o test.elf test.go 2>&1 | tee build.log
# View -march parameters
grep "march=" build.log | head -104. My Actual Output
In my environment (TinyGo dev branch, commit 13bb59c3), I saw this output:
# Compiler-RT compilation command (example)
clang -Werror -Wall -std=c11 -nostdlibinc \
-c -Oz -gdwarf-4 \
-ffunction-sections -fdata-sections \
-Wno-macro-redefined \
--target=riscv32-unknown-none \
-fdebug-prefix-map=... \
-resource-dir=.../lib/clang/19 \
-mcpu=generic-rv32 \
-mabi=ilp32 \
-march=rv32imac \ ← Contains 'a' (atomic)
-fforce-enable-int128 \
-o .../absvdi2.c.o \
.../compiler-rt/lib/builtins/absvdi2.cIn the full log, 493 files all used -march=rv32imac.
🤔 My Questions
Background
What I understand:
- ESP32C3 does not support the RISC-V atomic extension (features configured as
-a) targets/esp32c3.jsoncorrectly configurescflags: ["-march=rv32imc"]- PR ESP32-C3: implement atomics #2146 implemented excellent software atomic operations (via interrupt disabling)
My Questions
-
Is this the intended design?
- Is there a special reason for C libraries to use
rv32imac? - Is it related to caching or other architectural considerations?
- Is there a special reason for C libraries to use
-
Does this cause actual problems?
- Do Compiler-RT/Picolibc generate atomic instructions on ESP32C3?
- Or do software atomic operations already fully cover this scenario?
-
Why this difference?
- I traced it to hardcoded values in
builder/library.go:169-170:case "riscv32": args = append(args, "-march=rv32imac", "-fforce-enable-int128")
- While user code uses
config.CFlags()which reads from target JSON
- I traced it to hardcoded values in
📊 Detailed Analysis (for reference)
Code Location
Hardcoded location (builder/library.go:169-170):
switch compileopts.CanonicalArchName(target) {
case "riscv32":
args = append(args, "-march=rv32imac", "-fforce-enable-int128")
// This hardcode applies to all riscv32 targets
}Target JSON Configuration (targets/esp32c3.json):
{
"inherits": ["riscv32"],
"features": "+32bit,+c,+m,+zmmul,-a,...", // Explicitly disables atomic
"cflags": ["-march=rv32imc"] // Correct parameter
}Historical Context (my speculation)
I looked at the git history:
- This hardcode comes from commit
ad022ef2on 2019-11-30 - At that time, there was only HiFive1 (SiFive FE310), which supports the atomic extension
- So hardcoding
rv32imacwas correct for all targets at that time
But after ESP32C3 was added in 2021 (without atomic support), this hardcode may no longer be appropriate.
Why It Might Still Work (my understanding)
- TinyGo implements complete software atomic operations
- Compiler-RT/Picolibc probably don't trigger code paths that need hardware atomic instructions
- ESP32C3 typically runs single-core, so atomic operation needs are minimal
❓ Questions for the Team
Core Question
Is this difference in compilation parameters intentional design, or something that could be improved?
Specifically, I'd Like to Understand
-
Design Intent
- What's the consideration for using hardcoded
-marchfor library compilation? - Is it related to the caching mechanism (
LibraryPath)?
- What's the consideration for using hardcoded
-
Actual Impact
- Do Compiler-RT/Picolibc generate hardware atomic instructions in the current implementation?
- Could this parameter mismatch cause problems in practice?
-
Does It Need Fixing
- If this is indeed an issue, I can try to submit a PR
- I've thought of a few possible approaches:
- Option A: Check
featuresto decide whether to includea - Option B: Let library compilation also read target JSON's cflags
- Option C: Add special case handling for ESP32C3
- Option A: Check
-
Other Targets
- Will there be more RISC-V chips without atomic support in the future?
- Does this pattern apply to them as well?
🧪 My Test Environment
TinyGo version: dev (commit 13bb59c3)
Target: xiao-esp32c3
LLVM: 19
OS: macOSRecommended Reproduction Commands
# 1. Create test file
cat > test.go << 'EOF'
package main
func main() {
println("Hello ESP32C3")
}
EOF
# 2. Clear cache
rm -rf ~/Library/Caches/tinygo/*riscv32* # macOS
# or
rm -rf ~/.cache/tinygo/*riscv32* # Linux
# 3. Build and save log
tinygo build -target=xiao-esp32c3 -x -o test.elf test.go 2>&1 | tee build.log
# 4. View compiler-rt's -march parameters
grep "compiler-rt.*march=" build.log | head -5
# 5. Count usage of rv32imac
grep -c "march=rv32imac" build.log📎 Related References
- PR ESP32-C3: implement atomics #2146: "ESP32-C3: implement atomics"
- Commit
ad022ef2: Where-march=rv32imacwas originally introduced - Commit
cb147b94: Added ESP32C3 support builder/library.go:169-170: Current hardcoded location
💭 My Thoughts
I'm not sure if this is really a problem because:
- ✅ ESP32C3 currently works fine
- ✅ Software atomic operations are already implemented
- ❓ But from an architectural consistency perspective, libraries and user code using different instruction sets feels a bit odd
So I'd like to hear the team's perspective first! If this does need improvement, I'd be happy to try contributing code. If this is intentional design, I'd also like to understand the reasoning so I can learn more 😊
Thank you for reading! Looking forward to the team's guidance! 🙏
If you need more information or testing, please let me know!