Skip to content

Releases: llvm-mos/llvm-mos-sdk

SDK v0.9.2

24 Sep 17:55
Compare
Choose a tag to compare

Bug fixes

  • The linker will now emit errors for relative branches that are out of range. Previously, this would result in a miscompile. Note that the compiler should never generate these; they should only be possible via hand-written assembly.

New features

  • The compiler now supports the .hword, .word, .dword, and .xword directives, for 1, 2, 4, and 8 byte values, respectively.
  • The NES target now includes a port of the Famitone2 library. The SDK also includes a llvm-mos port of the included assembly generation utilities. The library has been modified to be placeable anywhere in memory by the linker, and no hand-edits are required to use it.
  • The NES target has a new .dpcm section, which places DPCM data with the alignment (64 bytes) and address (>=$c000) necessary for the APU. It also generates a __dpcm_offset symbol to the start of the section in the format the APU expects (addr >> 6). The famitone2 port picks up samples from this section using usual linker relocation mechanisms; no hand edits are necessary.

SDK v0.9.1

11 Sep 18:18
Compare
Choose a tag to compare

New libraries

  • The nesdoug library has been added to the NES target and is accessible via -lnesdoug. It is likely buggy and should be considered alpha quality.

Bug fixes

  • Added C++ extern C declarations to the neslib library.
  • The neslib crt0 additions now clear memory before copying .data, not after. This had the effect of zeroing all data segments.
  • Misc small cleanups and bug fixes to the neslib port.
  • BSS and Data section zero and copy routines no longer run if a section coincidentally begins with the prefix. Instead, the prefix must end with a dot, followed by another name. For example, a .data_ptr section will no longer trigger data copying, while .data.ptr and .data both still would.

Optimizations

  • The register allocator will no longer place a value into a register such that the only uses of that register are copies out of it to physical registers. It will instead prefer to split the live range into something that can be assigned to the destination physical register. This has the particular effect of rematerializing constant loads used as function arguments to right before the call, rather than stashing them in the zero page.
  • Multi-byte comparisons against zero no longer consider bytes that are statically known to be zero.
  • Sums where one addend is either -1 or 1, depending on control flow, are split into separate increment and decrement operations.
  • An expensive copy optimization pass was added right before copy elimination. This helps to remove some of the worse excesses of the register allocator, and this brings our CoreMark score up to 0.089 from 0.088. (A rare occurrence!)

SDK v0.9.0

03 Sep 15:46
Compare
Choose a tag to compare

New Features

  • Added nesdoug's port of Shiru's neslib to the SDK. This isn't included by default, but can be used with -lneslib. The library needed to be ported by hand, and it isn't very well tested, so it should be considered alpha quality at best, and wholly broken at worst. As work continues porting the nesdoug tutorial series to llvm-mos, the library will get more reliable, and this will be reported in future release notes.
  • Zero page allocation now takes into account symbols given explicit sections in the zero page. The sizes of those symbols are deducted from the amount given to the compiler for zero page use. This allows assembly libraries to ship their zero page symbols as bitcode, which allows users to safely use the library without needing to manually specify -mreserve-zp.
  • Added llvm-mlb utility to generate Mesen label files (.mlb) from ELF binaries. The Clang driver now automatically runs this after the link step for NES targets in the SDK.
  • Added the -fpost-link-tool= compiler option used to implement the above.
  • The compiler now correctly sets the SHT_NOBITS section type for symbols placed in zero-page BSS, zero-page noinit, and generalized noinit sections (i.e., any section ending in .noinit or containing .noinit.).

SDK v0.8

25 Aug 02:41
Compare
Choose a tag to compare

Breaking Changes

  • The compiler driver now only provides the default linker script (-Tlink.ld) if no -T flag is explicitly given on the command line. This allows completely overriding the default linker script.
  • The NES targets have been completely reworked. They now support a fairly broad subset of their respective mappers (NROM and MMC1). As far as possible, the linker scripts are configured by defining symbol values. Some configuration requires forming a custom linker script by INCLUDE-ing snippets to form the configuration. The linker scripts support PRG-ROM/(NV)RAM and CHR-ROM/(NV)RAM banking of various sizes, with the option to place the C sections into either NES RAM or PRG-RAM.

New Features

  • The linker now supports an OVERLAY output section flag to cause the VMAs of that section not to be checked for overlap, just like with the OVERLAY syntax. The OVERLAY syntax is unfortunately too restrictive for typical 6502 targets with banked ROMs, as it requires that the LMAs of banks with the same VMA be contiguous.

Misc

  • The _exit function defined in the exit-loop library is now a weak symbol. Exiting by infinite loop is a fallback used when there's no better option. Accordingly, it should be left open for users to supply a better one.
  • The SDK now runs NES tests in continuous integration using the Mesen emulator's test-runner mode. As a result, the NES linker scripts are fairly well tested now, better even than most of the rest of the SDK, which relies only on manual testing and the simulator target.

SDK v0.7.1

11 Aug 15:59
672cc4d
Compare
Choose a tag to compare

New Targets

  • #51 cx16Commander X16. Partial support was previously available through the c64 target, but this target adds native support.

Bug Fixes

  • llvm-mos/llvm-mos#213-mcpu= now produces an error when an incorrect CPU type is given.

  • The NES status registers are now unsigned. The cc65 definitions were signed due to an obscure cc65-specific codegen issue.

  • #69 — The PEEK and POKE macros imported from cc65 now use volatile. Previously, the compiler may have optimized them away.

  • #73 — The MEGA65 target now uses the mos65ce02 CPU type. Previously, this was the default mos6502, which restricted functionality to that avaiable on a vanilla NMOS 6502.

Miscellaneous

  • The SDK was relicensed to use the Apache License v2.0 with LLVM Exceptions. Previously, it did not include the LLVM exceptions, which technically required that distributions of binaries compiled against the SDK include a copy of the Apache License.

  • Upstream LLVM was merged at 65923012b3.

SDK v0.7.0

07 Aug 04:57
Compare
Choose a tag to compare

Breaking Changes

  • llvm-mos/llvm-mos#209: LLVM-MOS specific optimization passes are now generally disabled at -O0, just like regular optimization passes. These passes ignored optimization level for simplicity sake, but now they don't. This means that functions compiled at -O0 will use soft stacks and won't allocate zero page (other than the regular use of imaginary registers).
  • The hardware register definitions from cc65 were ported for all supported platforms. Conflicting functionality in the SDK was replaced with its cc65 equivalent.

New Features

  • cc65's peekpoke.h was ported to the SDK.

Bug fixes

  • llvm-mos/llvm-mos#208: The CLD instruction at the beginning of a C interrupt handler was placed after the stack was adjusted. Since adjusting the stack requires an addition, the result of the addition may have been incorrect.
  • llvm-mos/llvm-mos#206: There were two cases where the compiler would produce incorrect assembly. This only affected assembly output, since clang goes directly from C to machine code. If assembled later, the first case would fail, and the second would assemble to a different opcode than was emitted.
  • DODO API functions no longer prevent the allocation of ZP. Linker script support was also fixed.

Optimizations

  • llvm-mos/llvm-mos#210: Zero page locations can now be allocated to functions that appear to recurse in the call graph, but are known for other reasons not to ever recurse. For example, for main in C++ to recurse is undefined behavior, so it can now always allocate ZP.

SDK v0.6.0

27 Jul 15:52
Compare
Choose a tag to compare

Breaking changes

  • (Missed in previous release) The default c.ld linker script now requires that a zp memory region be available. It can be of size zero.

New Features

Whole-program automatic zero page allocation

The C compiler now automatically allocates global variables/constants, function local variables, and callee-saved registers to function-specific zero page locations whenever possible. Each SDK target uses the new -mlto-zp=<xxx> flag to set the number of bytes of contiguous zero page available for use by the compiler. The compiler then estimates the benefit of assigning each possible candidate to that zero page region, then greedily assigns them until the available zero page is consumed. The new -mreserve-zp=<xxx> flag can reduce the number of bytes of zero page reserved for compiler use, allowing programmer use of the zero page outside of C's automatic assignment. Such zero page regions sections still be recorded and placed by the linker (that is, not by directly manipulating pointers <256), otherwise, they risk conflicting with compiler-allocated zero page.

As with static stack frames, the zero page regions used by different functions can overlap if the compiler can prove that the functions can never simultaneously be active. Given the relatively large amount of zero page available in our current targets, we've observed that a considerable portion of most program's working set can now fit entirely within the zero page.

Bug fixes

  • Fixed an issue where function pointer usage could cause static stack frames of functions to inappropriately overlap.
  • The presence of the .zp.rodata section will now also cause data to be copied to the zero page at program startup, just like .zp.data.

SDK v0.5.1

19 Jul 15:06
Compare
Choose a tag to compare

New Features

Zero Page Sections

The SDK now supports placing sections in the available zero page for all supported targets. To be placed by the target linker scripts, zero page sections must begin with the prefix .zp. By default, sections placed here will be uninitialized at program load time, the semantics are equivalent to the .noinit section in main memory. If a zero page section is prefixed by .zp.bss, the program will initialize it with zeroes at startup, like with .bss. If it is instead prefixed by .zp.data, then the contents of the section will be copied into the zero page at startup, like with .data on ROM targets. Note that the copy routines aren't particularly well optimized yet; they just use the 16-bit memcpy, pending further work on the C side for supporting zero page addressing.

Bug Fixes

  • Fixed internal compiler error where multi-byte increment pseudoinstruction might escape lowering.
  • Fixed inline assembly constraint R in clang; added operand size checking for c and v.

SDK v0.5.0

10 Jul 03:55
664baf5
Compare
Choose a tag to compare

Breaking changes

  • The mosw65ce02 CPU type was renamed to mos65ce02.

New targets

  • mos-dodo: The Dodo 6502 portable game system. Thanks @atn34 !

New features

  • The assembler and disassembler now support 65CE02 opcodes. This includes the remaining 65C02 opcodes as well. Thanks @mlund !

Bug fixes

  • Fixed issue with tail duplication in -O3 where increment and decrement operations could lose their tied operands, leading to incorrect code generation.
  • llvm-mos/llvm-mos#200: Fixed error that occured whenever an integer constant >32767 was used with the i inline assembly predicate.

SDK v0.4.0

05 Jul 23:35
Compare
Choose a tag to compare

Breaking changes

  • Responsibility for setting --gc-sections has been moved from the SDK to the compiler driver. Compiling against the mos target using the clang family of commands now defaults to --gc-sections. This can still be disabled manually on the command line and in the SDK via --no-gc-sections.

New Features

  • c and v are now suppored as inline assembly constraints to specify that a boolean value should be placed in the C or V flag, respectively.

Bug fixes

  • Libcalls in the SDK that are compiled outside of LTO and that can be called an interrupt handler no longer use static stack.

Optimizations

  • Redundant immediate load instructions are now opportunistically re-written to the T__ family of transfer instructions. This saves one byte of space.
  • The register coalescer can choose to rematerialize constant loads instead of copying them to a new register. Previously, these rematerialized loads would use a tighter register class than is required, which can lead to additional copies as the register allocator attempts to satisfy it. The register class constraint has now been loosened, which can help the register allocator to keep these values alive, in particular, for the entirety of loops.