Parse quoted LIBRARY names as a single token and add the default .dll
extension when needed. Allocate the stored name dynamically.
Add a Windows regression test using a quoted name with spaces.
tcc 0.9.27 does have a usable ldexp - but not ldexpl. however,
on windows these functions are identical, so map ldexpl to ldexp
and remove the MUSL-implementation which was copied from tcc_libm.h.
Commit cb39bc4 ("Calculate hex floating point with 128 bits instead of
64 bits.", 2025-05-27) started using ldexpl in tccpp.c, however, older
tcc like 0.9.27 (2017) don't have it on windows - ldexpl was added to
win32/include/math.h (in tcc_libm.h) in commit b11144d (2020).
So copy the current ldexpl definition from current tcc_libm.h into
tccpp.c - but under a different name.
Commit 03d58b0 ("arm64-win32 support : runtime", 2026-04-04) added
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE to winnt.h, and it was later
used in tccpe.c, but older tcc like 0.9.27 don't have it.
So define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE is missing.
Commit 44977b0 ("tcctest: restore & combine", 2026-05-06) effectively
changed the run-if macro to "true" - i.e. don't run the command and
don't report that it's skippped. As a result, all the doc targets
were skippped quietly and unconditionally.
Presumably it was a temporary in-development change - the commit
message doesn't mention docs changes, and the doc targets still exist
at Makefile, but this change was not reverted before the commit.
Revert this specific change, which restores the automatic doc targets
(build them only if the command to generate them exists).
Preserve symbolic offsets when materializing i386 TLS addresses, generate ARM64 TLS addresses from the thread pointer, and carry RISC-V addends on both halves of the TPREL relocation pair.
Keep undefined ELF TLS symbols typed as STT_TLS so objects produced by TCC can be linked by the system linker. Extend the TLS regression coverage for narrow signed and unsigned accesses, address-taking, runtime indexing, thread isolation, large RISC-V offsets, unsupported runtimes, and external TLS definitions.
tccgen.c:
remove VT_TLS in gen_cast
libtcc.c:
remove warning for gcc 16
i386-gen.c:
fix gen_modrm for VT_LDOUBLE
riscv64-gen.c:
add fc to TLS address
x86_64-gen.c:
add TLS prefix in gen_opf
tests2/144_tls.c/tests2/144_tls.expect:
updated test case
tests/tests2/Makefile
skip TLS test for BSD
tccrun.c:
- simplify usage of VirtualAlloc on win32/64
from 6728a64f1b
tccpe.c:
- revert changes to pe_create_pdb()
(doesn't work and/or too much complication)
from 37b7247796
- reduce #ifdef amount
tccgen.c:
- fix fix for cast to void
from fad812360b
tccelf.c:
- put create_riscv_attribute_section() into right place
from c77339ab41
tcc.h/libtcc.c:
- simplify link-option parser for pe dll_characteristics
from 1a54e47dda
i386-gen.c:
- fix tls
from 8502540b4a
workflow/build.yml:
- add i386-linux
- disable riscv64-linux-native (seems not supported currently)
Use the existing array-aware qualifier helper when propagating qualifiers from a const or volatile aggregate to a selected field. This keeps address-of array members from spuriously warning while preserving warnings for discarded qualifiers and read-only writes.
Add regression coverage for pointer-to-array returns, array decay, and writes through const array members.
Replace hardcoded VsDevCmd.bat Enterprise path with vswhere.exe +
vcvarsall.bat for dynamic VS discovery across editions and runner
image versions. Architecture args: amd64, x86, amd64_arm64.
Split x86_64/i386 win32 jobs into separate build and test steps.
For arm64: keep build+test in one step (needs vcvarsall for lib.exe).
Prepend standalone LLVM bin to PATH so clang targets ARM64 natively
instead of VS's clang-cl inheriting the x64-hosted cross-compile env.
Wire gen_clear_cache to __riscv64_clear_cache builtin, emitting
fence.i for instruction cache synchronization.
Add lib/riscvflush.c to provide __clear_cache for JIT bootstrap.
Extend tccrun.c I-cache flush guard to include RISC-V targets.
Add gen_clear_cache declaration to tcc.h riscv64 section.
Move the TinyCC/Windows ARM64 Interlocked workaround from the semlock call site into the bundled WinAPI header. This keeps tcc.h using the normal Interlocked API while avoiding unresolved Interlocked imports when tcc -run self-compiles on Windows ARM64.
Update lib/bt-exe.c as well so its ARM64 runtime object does not define a second InterlockedExchange fallback now provided by winnt.h.
Windows/arm64 exposes Interlocked* operations as compiler intrinsics rather than kernel32 exports. When tcc -run self-compiles tcc.c, calls to InterlockedCompareExchange or InterlockedExchange can therefore remain as unresolved imports in the in-memory linker.
Route the TinyCC arm64 path through the existing __atomic helpers while keeping Interlocked* for other Windows compilers. The compile-lock initialization state machine remains unchanged.
Report VirtualProtect failures with a Windows-specific -run diagnostic.
On Win64, also treat RtlAddFunctionTable failure as an error so unwind
registration problems are visible.
Add PE linker switches to set and clear DYNAMIC_BASE, NX_COMPAT,
HIGH_ENTROPY_VA and TERMINAL_SERVER_AWARE without changing x86/x64
defaults. HIGH_ENTROPY_VA is limited to 64-bit PE targets and implies
DYNAMIC_BASE; clearing DYNAMIC_BASE also clears HIGH_ENTROPY_VA.
When DYNAMIC_BASE is requested for an executable, emit base relocations
and clear RELOCS_STRIPPED so Windows ASLR can relocate the image. Keep
the existing ARM64 default hardening flags.
Invoke cv2pdb with _spawnvp on Windows so output paths are passed
as argv entries instead of through cmd.exe.
For non-Windows PE cross builds, keep the system() fallback but
shell-quote the executable name and size the PDB path dynamically.
Use interlocked state transitions around the lazily initialized Windows
CRITICAL_SECTION so concurrent first-time callers cannot race into a
double initialization.
- tccmacho.c: add STT_TLS to convert_symbol() for Mach-O output
- tests/tests2/Makefile: skip 144_tls on Win32 (no pthread.h) and
remove arm from TLS arch list (QEMU user-mode cannot emulate
MRC p15 TLS register access)
Emit fence + fence.i (Zifencei extension) for I/D cache
synchronization, needed for tcc -run mode on RISC-V.
Zifencei is required by the RISC-V Linux ABI and present
on all Linux-capable cores, though technically not part
of the RV64G base ISA.
Replace raw-register AMO asm with proper inline-asm constraints
for all three operands (rd, rs2, rs1). Use long long for .d-word
AMO variants with pre-set values (xd=0xCAFEBABECAFEBABE,
val=0xDEADBEEFDEADBEEF) to avoid uninitialized-data issues.
Restore csr_pseudo_main printf output and re-enable amo_main()
in the test (was commented out as 'crash on qemu').
Use GEN = $(GEN-TCC) since GCC and TCC produce different fcsr
initial values on riscv64.
Revert 199369bb17
- generating test.ref with tcc makes little sense.
- combine riscv_asm & conversion tests into only two files.
(too many files are bad ...)
tccgen.c:
- init_putv(): improve long double cross constants
now in separate function including some basic conversions
arm-gen.c:
- switch to using TCC_USING_DOUBLE_FOR_LDOUBLE
now it actually never will see VT_LDOUBLE
lib/lib-arm64.c:
- simplify by using unions
tccpp.c:
- reduce amounts of #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
originally, this was meant to avoid 'void' values leak
to the gen-xxx.c generators which would otherwise try
to load void from/to registers. Also catch invalid types
such as 'unsigned bool' eariler.
tccgen.c:
- expr_cond()/gexpr(): ignore VT_VOID
- gen_cast(): set float reg with static initializers to make
backends happier with invalid input
- init_putv():
improve static compound literal initializers
Also:
- ignore "missing prototype" and "might return no value"
for old style K&R functions
tcc.c, libtcc.c:
- tcc_set_output_type(): return errors from loading crt1.o
tcc.h/tccpp.c:
- fix horrible longstanding mistake with sizeof SValue.tab.
Must have place for sizeof (long double) rather than the
target's LDOUBLE_SIZE.
tccdefs.h:
- add a fake __[u]int128_t for all platforms
arm-gen.c:
- gen_cvt_ftof() must load to reg always
arm64-gen.c:
- simplify arm64_pcs() a bit
i386/x86_64-gen.c:
- do not assume char is signed (for cross compilation arm->x86)
tccelf/macho linker message:
- instead of
"undefined symbol 'X'"
now say
"unresolved reference to 'X'"
which makes it more clear that it is a _linker_error_.
tccasm.c:
- .align/p2align: use 'nop's in exec sections
Add handlers for csrr, csrw, csrwi, csrsi, csrci as pseudo-instructions:
csrr rd, csr -> csrrs rd, csr, x0
csrw csr, rs -> csrrw x0, csr, rs
csrwi csr, uimm -> csrrwi x0, csr, uimm
csrsi csr, uimm -> csrrsi x0, csr, uimm
csrci csr, uimm -> csrrci x0, csr, uimm
Tokens were already defined in riscv64-tok.h. Tested on
Spacemit X100 using fcsr (0x003) which is accessible in user mode.
cycle/instret CSRs are privileged and not accessible from Linux
user mode on this hardware.
The promote char/short funcret test in tcctest.c invokes
undefined behavior (narrow return without extension). GCC
produces one set of values, TCC with PROMOTE_RET produces
correct ABI-compliant values. Generate the reference with
TCC so self-tests are consistent.
Adds the 8 most essential floating-point arithmetic instructions:
fadd.s/d, fsub.s/d, fmul.s/d, fdiv.s/d, for both single and double
precision. These complement the existing fsgnj/fmax/fmin/fsqrt set.
Comparison (feq/flt/fle) and conversion (fcvt) instructions remain
as future work.
sext.w: addiw rd, rs, 0 (sign-extend 32-bit word)
fmv.s/fmv.d: fsgnj.s/d rd, rs, rs (float register move)
fneg.s/fneg.d: fsgnjn.s/d rd, rs, rs (float register negate)
These were defined in riscv64-tok.h but had no handler code.
CSR pseudo-instructions (csrr, csrw, csrci, csrsi, csrwi) skipped
for now — they require CSR operand parsing in binary mode.
Previously, .reloc unconditionally errored on RISCV64 — only ARM64
had permission to use R_AARCH64_CALL26. Now supports common RISCV64
relocations: R_RISCV_CALL, CALL_PLT, BRANCH, JAL, PCREL_HI20,
PCREL_LO12_I/S, 32_PCREL, 32, 64.
Restructured to use string-to-reloc-type mapping, shared across all
targets.
arm64-link.c has R_AARCH64_RELATIVE handling. Without this case,
incoming R_RISCV_RELATIVE relocations from object files fall through
to the 'FIXME: handle reloc type' default path.
P1.7 (NEED_BUILD_GOT guards) is not needed: NEED_RELOC_TYPE and
NEED_BUILD_GOT are always defined in the build context (tcc.h:1608).