6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Apr 19, 2024 10:23 pm

All times are UTC




Post new topic Reply to topic  [ 155 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 11  Next
Author Message
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Tue May 18, 2021 5:00 pm 
Offline

Joined: Sun Jan 10, 2021 11:25 pm
Posts: 64
Minor update:

Now that printf kinda-sorta-barely-just works, I've managed to hook up LLVM's end-to-end test suite, using a 6502 simulator derived from https://github.com/mist64/perfect6502, which is itself based off the visual6502 netlists.

Of the SingleSource test targets (MultiSource and Benchmarks has stuff like 7zip, lol, yeah right):

Passed : 420
Failed : 55
Executable Missing: 1321

Executable missing is mostly compile failures. I'll be heads down in the coming months getting passed as high as possible, before beginning major optimization work. Probably won't be much news until then, "the number passed got bigger" isn't very interesting. :)

EDIT: Interestingly, quite a few of these cases are in C++! We'll probably get some degree of C++ support "for free", since the backend doesn't really care whether or not, say, the function pointers it receives are from C++ virtual functions. I have extreme doubts that a C++ standard library could be made to fit in 64K, but that still leaves a relatively large subset of C++ potentially usable. Way after the initial release, I may try to get this working, if just for the bragging rights.


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Wed May 26, 2021 10:27 pm 
Offline

Joined: Wed May 26, 2021 9:27 pm
Posts: 3
mysterymath wrote:
We'll probably get some degree of C++ support "for free"

Even more: thanks to your amazing work I was able to compile first ever Rust program for 6502 and test it on Atari!

To reproduce you need working rustc, llvm-mos and llvm-mos-sdk. Create following files:

factorial.rs
Code:
#![no_std]

#[no_mangle]
pub extern "C" fn factorial(n: u16) -> u16 {
  match n {
    0 => 1,
    _ => n * factorial(n-1),
  }
}

#[no_mangle]
pub extern "C" fn factorial2(n: u16) -> u16 {
  (1..n+1).fold(1u16, |acc, v| acc * v)
}


main.c
Code:
#include <stdint.h>
#include <stdio.h>

extern uint16_t factorial(uint16_t n);
extern uint16_t factorial2(uint16_t n);

int main() {
  uint16_t n = 6;
  uint16_t result = factorial(n);
  uint16_t result2 = factorial2(n);
  printf("hello from rust, %u! is %u (%u)", n, result, result2);
  return 0;
}


and build it with following Makefile:
Code:
CLANG=llvm-mos/build/bin/clang --config llvm-mos-sdk/build/atari/800xl.cfg -O0

all: factorial.xex factorial.s

factorial.xex: factorial.ll main.c
   ${CLANG} main.c factorial.ll -o factorial.xex

factorial.s: factorial.ll main.c
   ${CLANG} main.c factorial.ll -o factorial.s -Wl,--lto-emit-asm

factorial.ll: factorial.rs
   rustc factorial.rs --emit=llvm-ir --crate-type=rlib -C debuginfo=0 -C opt-level=1


Of course in current state after some modifications I'm able to easily crash clang with unable to legalize instruction or simply generate not working code - so I'm patiently waiting even for "the number passed got bigger" updates ;)


Last edited by mrk on Thu May 27, 2021 11:32 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Thu May 27, 2021 4:18 am 
Offline

Joined: Sun Jan 10, 2021 11:25 pm
Posts: 64
That's incredible! I'm sure the Rust community would love to hear about this, especially once the LLVM backend is closer to feature-complete.

EDIT: Ah, I see it's on r/rust already! :)


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Thu May 27, 2021 8:56 am 
Offline

Joined: Thu May 27, 2021 8:50 am
Posts: 1
Super cool work on this! I did the 6502 GCC port (well, out of the two I know about, the more-recent one). Hi!


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Thu May 27, 2021 10:07 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10789
Location: England
(welcome, mrk and itszor!)


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Wed Jun 02, 2021 7:49 am 
Offline

Joined: Mon May 01, 2017 7:13 am
Posts: 82
itszor wrote:
Super cool work on this! I did the 6502 GCC port (well, out of the two I know about, the more-recent one). Hi!


Good to meet you, itszor. I remember reviewing your work, and it influenced my thinking on how the llvm-mos project should be architected.

When I was at Sega, I worked with Toshi Morita, who I believe did another 6502 gcc port some decades ago.


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Wed Jun 09, 2021 12:58 pm 
Offline
User avatar

Joined: Tue Sep 11, 2007 8:48 am
Posts: 27
Location: Pruszków/Poland
johnwbyrd wrote:
When I was at Sega, I worked with Toshi Morita, who I believe did another 6502 gcc port some decades ago.


And who was active here:
memberlist.php?mode=viewprofile&u=17

_________________
Practice safe HEX !


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Wed Jun 09, 2021 5:36 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8423
Location: Southern California
Konrad_B wrote:
And who was active here:
memberlist.php?mode=viewprofile&u=17

Wow, I didn't realize he hadn't logged in in so long! I've seen him recently (maybe even in the last week) on other 6502 forums though, so I know he's still interested.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Fri Jun 11, 2021 5:34 am 
Offline

Joined: Sun Jan 10, 2021 11:25 pm
Posts: 64
Code:
Testing Time: 1332.06s
  Passed            : 676
  Failed            : 538


After 50-ish fixes to the compiler and additions to the SDK, all LLVM single-source tests that cover only C99 freestanding functionality (except float/double) now compile!

Only half of them actually pass, of course.

I also had to disable maybe 300 of them that didn't apply. The two biggest causes were by far floating point and assuming 32-bit integers.

It's likely that many, or even most, of the remaining runtime test failures are also due to assuming 32-bit integers.

The next step is to go through all 538 failing test cases, by hand, and either fix the corresponding issue or disable the test. Hopefully there's only a few big issues responsible for most of the failures.

Afterwards, I'll need to see about repairing the 32-bit int tests and adding a soft float library. There's too much functionality covered by tests that include a float somewhere "for alignment" or somesuch.

The good news is that the each compiler failure is getting harder and harder to debug and fix. This really is good news: they're starting to look like genuine Compiler Bugs! Which means, of course, this is starting to look like a genuine compiler.

A surprisingly broad set of things now (ostensibly) compile. Off the top of my head:
  • C++ templates. (I'm even using them to generate some of the libcalls.)
  • C++ pointer-to-member-functions, apparently.
  • In that vein, pretty much all C++ syntax that doesn't have any special runtime or code emission requirements. (Although I'm not enough of a C++ language lawyer to know exactly what that subset is...)
  • C99's va_copy works.
  • A ton of weird syntax and semantics edge cases in the GCC torture suite.
  • All the shifts, multiplies, divides, and so on that I hadn't gotten around to previously.
  • Quite a bit of string.h and a few other parts of libc, since they're needed by the tests.


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Fri Jun 11, 2021 7:21 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10789
Location: England
Good news indeed - thanks for the update!


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Wed Jun 16, 2021 10:10 pm 
Offline

Joined: Wed May 26, 2021 9:27 pm
Posts: 3
Good news also on rust frontend work :)

After my first experiment with rust + llvm-mos I decided to go a step further and try to add real mos target triple to rust. This should allow to use standard rust tools (like cargo) to build some no_std programs. Creating mos-unknown-none triplet was quite easy task (code is here: https://github.com/mrk-its/rust/tree/mos_target), the real problem was compiling rust's core library. I commented out most problematic parts of compiler_builtins library (like float and 128-bit integer intrinsics) and everyday after batch of new @mysterymath's commits I was trying to build this simple thing: https://github.com/mrk-its/a800-rust-test. It was failing mostly with 'unable to legalize' errors.

And a few days ago it finally clicked! I built working a800 executable without any bits of C code, using standard rust's cargo, yay! Only opt-level=2 worked (opt-level='s' produced non-working binary, opt-level=1 was throwing 'unable to legalize') and some 64-bit ops was not working properly, but core::fmt (the rust equivalent of printf) worked perfectly! With today's llvm-mos it works even better: opt-level='s' started working and I'm able to compute 20! on u64 :) (opt-level=1 throws some assert error, I can fill an issue on llvm-mos). It seems compiling llvm test suite (https://github.com/llvm-mos/llvm-mos/issues/45) with different optimization levels is quite important thing as it may easily reveal number of other problems.

Great job, keep going!


Attachments:
Screenshot from 2021-06-17 00-12-27.png
Screenshot from 2021-06-17 00-12-27.png [ 1.33 KiB | Viewed 5792 times ]
Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Thu Jun 17, 2021 12:11 am 
Offline

Joined: Mon May 01, 2017 7:13 am
Posts: 82
We have now a fairly active Wiki, at https://www.llvm-mos.org. This might be a good point for newcomers to familiarize themselves with llvm-mos.


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Thu Jun 17, 2021 7:44 pm 
Offline

Joined: Sun Jan 10, 2021 11:25 pm
Posts: 64
mrk wrote:
Creating mos-unknown-none triplet was quite easy task (code is here: https://github.com/mrk-its/rust/tree/mos_target)


That's fantastic, I'd have guessed it was a huge job to tell cargo/rustc about a new target (although I'm not 100% sure why I thought that). I'm curious what rust features require runtime support; there's some VTable and exception handling stuff we may have to do for C++, but I've got no idea how much is handled by rust's frontend. Trait objects stand out as a possibility, since they do runtime dynamic dispatch. Same with panics if they lower to llvm exceptions.

It shouldn't be anything we can't handle if we want to; LLVM has a setjmp/longjmp based lowering for exceptions, and I am planning to support setjmp/longjmp at some point after the initial release.


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Thu Jun 17, 2021 8:03 pm 
Offline

Joined: Wed May 26, 2021 9:27 pm
Posts: 3
Quote:
I'm curious what rust features require runtime support; there's some VTable and exception handling stuff we may have to do for C++, but I've got no idea how much is handled by rust's frontend.


I still need to figure out what already works and what doesn't - I'm planning to spent some time on that. It seems panics already work (at least with 'abort' panic strategy, I've just tested panic generated by assert! macro - panic handler was called, so it seems to work).


Top
 Profile  
Reply with quote  
 Post subject: Re: LLVM 6502 Codegen
PostPosted: Sun Jun 20, 2021 1:58 am 
Offline

Joined: Sun Jan 10, 2021 11:25 pm
Posts: 64
Code:
Testing Time: 13.99s
  Passed: 1224


All 1224 relevant LLVM SingleSource test cases now compile at -Os and execute with the correct output under the SDK's 6502 simulator.
This includes quite a few of the tests with a 32-bit integer dependence; I repaired as many as I could to work in a 16-bit integer context.

What this means is that a good amount of highly varied code now can compile in one specific configuration of the compiler: -Os optimization mode, allowing compiler use of the entire zero page, and a specific set of linker scripts. In particular, this doesn't mean that any other configuration (including -O0) works very well, that the compiler is C99 compliant, that the compiler has no bugs, fewer bugs than cc65, or any other such thing. We'll also reserve the right to break the ABI at any time until we declare a formal v1.0 (using Semantic Versioning, that's quite a ways off).

The reason I'm saying all this is because the compiler is considerably more reliable than it was, probably reliable enough to try out, if you really wanted to. Some folks (mrk and company) are hacking on a rust port for instance, and the recent weeks-worth of bugfixes have unblocked a lot of their work. You'll need to be comfortable compiling the SDK yourself if you want to generate target binaries, as we don't have any release automation set up around it yet. I don't know of any other major issues on the C99 path though, so long as you keep usage within the scope of what we've tested.

If you do try it out, please do report any issues you find, and please do refrain from making extensive performance comparisons between this and cc65/vbcc. We literally haven't even started looking at the optimization story yet beyond the early "is it possible" work; all our focus is still on getting the compiler well-tested and functionally complete. The generated code is absolute crap compared to what I'd consider acceptable for a first release. For example, it compares integers by XORing all the bytes together, not because that's a sane thing for a 6502 compiler to do, but because that was the fewest lines of LLVM legalizer code required to get a working version of integer comparison.

From here, we'll be working to automate releases on the SDK and tests in the test suite, expand coverage to other optimization modes, and audit the compiler's passes to make sure we didn't miss anything. From there, we do still need to hammer down the semantics of inline assembly, since that's the only "special" (i.e. we have to do something for it to work) GCC extension we're planning on supporting for the first release.

Once all that's done, we'll need to get a few key automated benchmarks working, so we can have an objective measure of executable performance. From there, initial performance optimization will begin in earnest, in preparation for our first release.

It's been a long road from there to here, and there's still a long way to go before our first official release. Stay tuned!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 155 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 11  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: