English Amiga Board


Go Back   English Amiga Board > Main > Amiga scene

 
 
Thread Tools
Old 08 July 2015, 18:33   #1
SainT
Registered User
 
Join Date: Jul 2015
Location: UK
Posts: 10
LLVM / Clang Progress

Thought I'd start a new thread on progress with getting LLVM working with a m68k backend. I've got a fair bit of the plumbing in now for calls (I think), working from one of the other backends as a source (as the whole m68k backend was by the looks of it).

I've got as far as getting this --

Code:
# Machine code for function main: Post SSA
Frame Objects:
  fi#0: size=4, align=4, at location [SP]
Function Live Outs: %D0L

BB#0: derived from LLVM BB %entry
        ADJCALLSTACKDOWN 6, %A7<imp-def>, %A7<imp-use>
        %vreg2<def> = COPY %A7; DR32:%vreg2
        %vreg1<def> = COPY %vreg2; AR:%vreg1 DR32:%vreg2
        MOVElim %vreg1<kill>, 0, 10; mem:ST4[<unknown>](align=2) AR:%vreg1
        %vreg2<def,tied1> = ADDlqd %vreg2<tied0>, 4, %CCR<imp-def,dead>; DR32:%vreg2
        %vreg3<def> = COPY %vreg2; AR:%vreg3 DR32:%vreg2
        MOVEbim %vreg3<kill>, 0, 12; mem:ST1[<unknown>] AR:%vreg3
        CALL <ga:@foo>, %A7<imp-use>, ...
        ADJCALLSTACKUP 6, 0, %A7<imp-def>, %A7<imp-use>
        %vreg4<def> = COPY %D0L; DR32:%vreg4
        MOVEldm <fi#0>, 0, %vreg4<kill>; mem:ST4[%b] DR32:%vreg4
        %vreg5<def> = MOVEQ 0; DR32:%vreg5
        %D0L<def> = COPY %vreg5<kill>; DR32:%vreg5
        RTS %D0L<imp-use,kill>

# End machine code for function main.

*** Bad machine code: Using an undefined physical register ***
- function:    main
- basic block: BB#0 entry (0xa19eac)
- instruction: %vreg4<def> = COPY %D0L; DR32:%vreg4
- operand 1:   %D0L
LLVM ERROR: Found 1 machine code errors.
Stack dump:
0.      Program arguments: D:\RetroMods\Jaguar\Compiler\llvm-build\bin\Debug\llc
.exe -mtriple m68k-apple-mac test.ll
1.      Running pass 'Function Pass Manager' on module 'test.ll'.
2.      Running pass 'Greedy Register Allocator' on function '@main'
Press any key to continue . . .
from this:

Code:
typedef unsigned int uint32_t;
typedef char int8_t;

uint32_t foo(uint32_t x, int8_t y)
{
    return (x | (1 << 17)) + y;
}

int main()
{
	uint32_t b = foo(10,12);
}
Which looks to me like the D0 output from the call isn't being registered as existing at that point or something. I'm completely new to LLVM development, so if anyone knows anything about this stuff please chime in. I'm trying the LLVM dev lists for info too...
SainT is offline  
Old 08 July 2015, 19:57   #2
nogginthenog
Amigan
 
Join Date: Feb 2012
Location: London
Posts: 1,309
Nice

For those who don't realise how exciting this could be:

Quote:
LLVM has since spawned a wide variety of front ends: languages with compilers that use LLVM include Common Lisp, ActionScript, Ada, D, Fortran, OpenGL Shading Language, Go, Haskell, Java bytecode, Julia, Objective-C, Swift, Python, Ruby, Rust, Scala, and Lua.
Is the source available SainT? I can't promise anything, but I can take a look. Lots of C/68k experience here, but no LLVM I'm afraid.
nogginthenog is offline  
Old 08 July 2015, 22:39   #3
SainT
Registered User
 
Join Date: Jul 2015
Location: UK
Posts: 10
Some progress --

Code:
uint32_t foo(uint32_t x, int8_t y)
{
    return (x | (1 << 17)) + y;
}

; GLOBAL foo
foo	PROC                            ; @foo
; BB#0:                                 ; %entry
	move.l	8(a6), 4(a6)
	move.b	12(a6), d0
	move.b	d0, 3(a6)
	move.b	d0, d1
	ext.w	d1
	ext.l	d1
	move.l	#131072, d0
	or.l	4(a6), d0
	add.l	d1, d0
	rts

int main()
{
	uint32_t b = foo(10,12);
}

; GLOBAL main
main	PROC                            ; @main
; BB#0:                                 ; %entry
	move.l	a7, 4(a6)
	subi.l	#6, a7
	move.l	a7, d0
	movea.l	d0, a0
	move.l	#10, (a0)
	addq.l	#4, d0
	movea.l	d0, a0
	move.b	#12, (a0)
	call	#foo
	subi.l	#-6, a7
	move.l	d0, (a6)
	moveq	#0, d0
	move.l	4(a6), a7
	rts
It's some seriously dodgy looking code, but it does some call-like stuff. Once I've got something a bit less crap working I'll submit the code to the git repo.
SainT is offline  
Old 09 July 2015, 00:36   #4
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
Quote:
Originally Posted by SainT View Post
It's some seriously dodgy looking code, but it does some call-like stuff. Once I've got something a bit less crap working I'll submit the code to the git repo.
It's not doing "call-like stuff" correctly. The main() function is "close" to putting the foo() parameters on the stack correctly (AT&T 68k ABI) although, I believe, the 12 should be sign extended before placing on the stack as a word ($0012) or longword ($00000012). It would be best to follow how GCC does this. Of course "call #foo" should be "bsr foo" in order to assemble.

The foo() function is majorly messed up. It looks like it is attempting to use A6 (stack frame pointer on non-Amiga 68k but should be A5 on an Amiga) instead of A7 (stack pointer) to access the arguments. GCC uses stack frames by default (and really can't be turned completely off) while vbcc has stack frame pointers turned off by default which is more efficient (there should be options for both methods and options for register arguments and RTD would be easier to implement early). The foo() variable needs to be allocated by LINK (with a stack frame pointer) or by SUB/LEA without. I believe the stack should have the return address, then the function arguments (for 68k ABI), and then space for local variables/storage which is not the case in the current code. Any MOVEM registers need to be accounted for on the stack as well. There is quite some work to do and it could be tricky to implement correct function calling with different options. I suggest you look at the same code output for different compilers with the same options turned on.
matthey is offline  
Old 09 July 2015, 05:15   #5
rlake
Hittin' the hardware...
 
rlake's Avatar
 
Join Date: Feb 2002
Location: Mountain View, CA
Age: 44
Posts: 156
Nice project, I take it you're starting from scratch? I wonder what state this is in and if it's worth building upon... http://sourceforge.net/projects/llvm68k/
rlake is offline  
Old 09 July 2015, 08:25   #6
SainT
Registered User
 
Join Date: Jul 2015
Location: UK
Posts: 10
@matthey, lol, I know it's not correct. It seems pretty complicated to get the LLVM backend to do what I want as I'm completely new to LLVM work. Trust me, this is a massive step in the right direction! it's extremely flexible though, so I don't think anything should be a problem. My main interest in this compiler is Atari related work though, so the exact register usage and ABI work for the Amiga will be done by someone else.

@rlake work is being done in https://github.com/SamuraiCrow/llvm-m68k . As soon as I have something useful, I will be committing.

Thanks for that source-forge link, though, that's slightly different to the above GitHub code -- although also very incomplete. I think I'm starting to understand LLVM a little more, and the source forge code is going about things in a better way than the existing code.

Last edited by SainT; 09 July 2015 at 08:34.
SainT is offline  
Old 09 July 2015, 09:36   #7
Locutus
Registered User
 
Join Date: Jul 2014
Location: Finland
Posts: 1,176
Thats a pretty awesome project, thanks! :-)
Locutus is offline  
Old 09 July 2015, 16:03   #8
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Quote:
Originally Posted by rlake View Post
Nice project, I take it you're starting from scratch? I wonder what state this is in and if it's worth building upon... http://sourceforge.net/projects/llvm68k/
That's an earlier attempt by myself and two other people. The one on GitHub is much more complete. Also, the GitHub ones are adapted from an incomplete classic Mac backend while the other is from scratch.
Samurai_Crow is offline  
Old 11 July 2015, 11:13   #9
SainT
Registered User
 
Join Date: Jul 2015
Location: UK
Posts: 10
Man, LLVM is complicated! I've stripped back the instruction definitions to a bare minimum for a piece of test code (basically just some move and add instructions) and am trying my best to figure out how everything hangs together. It's incredibly powerful, but also the definitions are very dense, so there's a lot to pick up. Plus the documentation, as far as I can find, generally doesn't tell me what I want to know...

The biggest thing for me currently is figuring out how I can represent all the addressing modes correctly. Once I can do that, it should be reasonably straight forward to implement all the opcodes. I've got an XML representation of the whole instruction set which I've used to generate the core for my 68000 emulator, so I may be able to use this to actually generate the tablegen definitions for the whole instruction set. That would be massively useful...

Getting there slowly.
SainT is offline  
Old 11 July 2015, 21:27   #10
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
You might try implementing the LEA opcode and using scratch registers as the closest equivalent to the GetElementPtr operation in the LLVM intermediate representation. Once you get that working, getting it to merge the LEA with the next instruction as an addressing mode of the second instruction should be simpler to do than trying to just "get the addressing modes working" in the abstract sense.
Samurai_Crow is offline  
Old 14 July 2015, 15:44   #11
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Update: The LLVM website is back up. You can view the documentation on the download page.
Samurai_Crow is offline  
Old 14 July 2015, 17:41   #12
SainT
Registered User
 
Join Date: Jul 2015
Location: UK
Posts: 10
I've just about given up now, I'm having a hard time getting it to do what I want. If you guys get something a bit more fleshed out working, I'll certainly help. Getting it into a state I'm happy with as a base to move forward just isn't happening.
SainT is offline  
Old 15 July 2015, 06:00   #13
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Don't be too depressed. It is a hard thing to do. Mike Ness is still interested in getting it to do something more, but he doesn't have much time to do it with. He still has 3 kids and a new full-time job so he has little free time to fix it with.
Samurai_Crow is offline  
Old 15 July 2015, 09:33   #14
SainT
Registered User
 
Join Date: Jul 2015
Location: UK
Posts: 10
Yeah, I'm in a similar situation -- although just the two kids... If you chaps get something started, I'll happily help out. I've got a reasonable handle on how things work now. Just not enough to get it into the shape I want.
SainT is offline  
Old 19 October 2016, 00:32   #15
copse
Registered User
 
Join Date: Jul 2009
Location: Lala Land
Posts: 520
Does anyone have an idea of the state of the kwaters fork on github? Can it disassemble/assemble/compile? What are the problems that remain to be resolved?
copse is offline  
Old 19 October 2016, 01:18   #16
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Mine is a fork of the kwaters version that only has the title changed and little else at this point. Last I checked, it has the same things outstanding as well.
Samurai_Crow is offline  
Old 19 October 2016, 02:31   #17
copse
Registered User
 
Join Date: Jul 2009
Location: Lala Land
Posts: 520
Yeah, that's why I asked about the kwaters port. I'll see if I can compile it, and try it out.
copse is offline  
Old 19 October 2016, 19:49   #18
nogginthenog
Amigan
 
Join Date: Feb 2012
Location: London
Posts: 1,309
It kind of works, but it's unusable.

I posted an example here:
http://eab.abime.net/showpost.php?p=1020998

C functions don't work. I think I posted an example in the thread.
nogginthenog is offline  
Old 01 February 2017, 17:17   #19
ardi
 
Posts: n/a
I'm also very interested in having a functional 68K LLVM backend. It seems there hasn't been any more commits in the above github repositories since 2015. How much work do you believe is still to be done? I've never written an LLVM backend, nor know IR either, so I'm not sure if I could do anything about this. Some comments in this thread, about the difficulty of writing an LLVM backend are discouraging to say the least...
 
Old 18 February 2017, 03:28   #20
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Backend code for LLVM requires knowledge of how to implement the IR in native code. From there, you would have to implement the peephole optimization yourself.

The reason that the backend in my GitHub repo has languished is that it is based on a very old version of LLVM and merging it with current code would be an ordeal in itself.
Samurai_Crow is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Where can I get the Progress.gadget from? Tony Landais request.Apps 6 16 December 2015 19:16
Work in progress. Cowcat Coders. General 7 18 February 2014 22:33
My A500+ progress so far. Mogsy Hardware pics 16 02 March 2013 09:20
My A1200 progress ck1200 Hardware mods 19 07 October 2010 18:29

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 18:37.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.09660 seconds with 15 queries