jacobly0 / llvm-z80

(e)Z80 backend for llvm - Moved to https://github.com/jacobly0/llvm-project
Other
48 stars 3 forks source link

user guide? #7

Open pawosm-arm opened 6 years ago

pawosm-arm commented 6 years ago

Hello,

Any advice on how to use it?

Cheers, Paul

adriweb commented 6 years ago

I have some instructions from some time ago, available here: https://tiplanet.org/forum/viewtopic.php?t=18038#p214934 The svn revision might just need to be updated, but otherwise, it works.

That's basically how TI-Planet's Project Builder is set up (online IDE, with llvm-ez80 as an available backend)

drawkula commented 6 years ago

I got commit 71ec7b86e5aaf17b6f99b88c09793f850c7ccf3a + llvm-r316129 + cfe-r316129 built on Debian9/amd64.

Which newer combinations should work too?

adriweb commented 6 years ago

Looks like the latest commit here mentions svn id r318998.

drawkula commented 6 years ago

Looks like the latest commit here mentions svn id r318998.

It does.

But...

Building 6380335 (current master)

HEAD is now at 6380335... Merged with upstream r318998.

against llvm/cfe-r318998 on my Debian9/amd64 yields:

[ 31%] Building CXX object lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/TargetInstrInfo.cpp.o
[ 31%] Building CXX object lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/TargetLoweringBase.cpp.o
/opt/llvm-z80/src/llvm/lib/CodeGen/TargetLoweringBase.cpp: In member function 'llvm::TargetLoweringBase::LegalizeKind llvm::TargetLoweringBase::getTypeConversion(llvm::LLVMContext&, llvm::EVT) const':
/opt/llvm-z80/src/llvm/lib/CodeGen/TargetLoweringBase.cpp:700:19: error: 'LargestIntVT' was not declared in this scope
     if (VT.bitsGE(LargestIntVT)) {
                   ^~~~~~~~~~~~
/opt/llvm-z80/src/llvm/lib/CodeGen/TargetLoweringBase.cpp: In member function 'void llvm::TargetLoweringBase::computeRegisterProperties(const llvm::TargetRegisterInfo*)':
/opt/llvm-z80/src/llvm/lib/CodeGen/TargetLoweringBase.cpp:1001:3: error: 'LargestIntVT' was not declared in this scope
   LargestIntVT = (MVT::SimpleValueType)LargestIntReg;
   ^~~~~~~~~~~~
lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/build.make:3470: recipe for target 'lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/TargetLoweringBase.cpp.o' failed
make[2]: *** [lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/TargetLoweringBase.cpp.o] Error 1
CMakeFiles/Makefile2:1365: recipe for target 'lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/all' failed
make[1]: *** [lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/all] Error 2
Makefile:149: recipe for target 'all' failed
make: *** [all] Error 2

Building 71ec7b8 + llvm/cfe-r316129 works.

pawosm-arm commented 6 years ago

It's almost as good as I needed. I've managed to build r316129 as suggested, but it seems like it can't produce assembly (-S) for z80-unknown-coff triple that could be handled further by binutils...

fatal error: error in backend: Cannot initialize MC for non-Windows COFF object files.
clang-6.0: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 6.0.0 (trunk 316129)
Target: z80-unknown--coff
Thread model: posix
drawkula commented 6 years ago

https://github.com/jacobly0/llvm-z80/blob/c90bdd4a58483b56bb5488674724ce62296ea6d5/tools/clang/lib/Driver/ToolChains/ZDS.cpp#L44-L45

I probably can only wave goodbye... no Windows here...

jacobly0 commented 6 years ago

I never implemented coff because I haven't needed it. Wine can be used to run the zds toolchain. I have been working on an x86 linux/mac/win ZDS compatible hybrid assembler/linker at https://github.com/jacobly0/fasmg-ez80/blob/master/ld.fasmg. The general lack of docs/guides is due to nothing being terribly usable yet.

drawkula commented 6 years ago

Maybe I can throw the *.s files in binutils-z80's assembler or the one of sdcc or z80asm... Somewhen later...

I'll have a closer look at LLVM with some other backend first to get used to it.

pawosm-arm commented 6 years ago

I probably can only wave goodbye... no Windows here...

Funny thing, I haven't used Windows for the last 20yrs. Even this LLVM backend message is about non-Windows ('non-Windows COFF object files'). And indeed, ZDS runs on wine and working together with llvm-z80 they can emit .obj binaries. Thing is, I'm interested in old z80 binaries (not ez80) and I don't relly know ZDS's obj format. I can build binutils (on Linux or MacOSX) passing --target=z80-unknown-coff to its 'configure' which gives me assembly compiler that produces non-Windows COFF binaries I can handle further (and run in emulator at the end). What I need is the llvm backend capable to produce .s files binutils can understand...

cesss commented 6 years ago

A Z80 LLVM backend would be very useful for me too, so my most sincere congratulations for this project. As a total newcomer, I also find that a user guide would be necessary, in order to know what works and what doesn't, and also in order to document how the Z80 is used by this backend (considering that the Z80 is an 8bit processor with 16bit addressing, so it's necessary to know in advance how the code will be generated, or otherwise you can write C source that will work very inefficiently, or not at all).

BTW, is this backend in a usable status, or not yet?

jacobly0 commented 6 years ago

This project is mostly on hold until global isel matures in llvm. Also, the z80 mode is much less tested, and so probably has more bugs than the ez80 mode, which is what is having architectural issues with non-power-of-two bit widths in llvm.

Serentty commented 6 years ago

@jacobly0

How is global ISEL coming along in LLVM? I know that this is completely out of your control. I would really love to see this project succeed, since it opens up a whole world of possibilities for a lot of devices throughout history.

uyjulian commented 6 years ago

FIX for LargestIntVT issue: add MVT LargestIntVT; to line 2337 of llvm/include/llvm/CodeGen/TargetLowering.h
FIX for isDesirableToShrinkOp issue: add

  /// Return true if x op y -> (SrcVT)((DstVT)x op (DstVT)y) is beneficial.
  virtual bool isDesirableToShrinkOp(unsigned /*Opc*/, EVT SrcVT, EVT DstVT) const {
    return isTruncateFree(SrcVT, DstVT) && isZExtFree(DstVT, SrcVT);
  }

to line 2810 of llvm/include/llvm/CodeGen/TargetLowering.h

joshhansen commented 5 years ago

Can someone point me in the right direction on how to even build this code? I've tried building it directly while including LLVM as a library. I've tried overlaying it atop vanilla LLVM source. I can't seem to make anything work.

uyjulian commented 5 years ago

Try 0dcad6c22b578f076756d67605bca3d931786ef9 with LLVM revision 316129.

joshhansen commented 5 years ago

@uyjulian Can you step me through it in a little more detail?

git clone https://github.com/llvm-mirror/llvm.git
cd llvm
git checkout b5cb868aaa03172b5f83ce48b574bdcad6377b7c
cd ..
git clone https://github.com/jacobly0/llvm-z80.git

What do I do next? cp -r ./llvm/* ./llvm-z80/* ?

uyjulian commented 5 years ago

@joshhansen look here https://tiplanet.org/forum/viewtopic.php?t=18038#p214934

joshhansen commented 5 years ago

I ran the commands on that post with the exception that I did not use -GNinja (I built it with Make):

git clone https://github.com/jacobly0/llvm-z80.git llvm && svn co http://llvm.org/svn/llvm-project/llvm/trunk -r 318998 --force llvm && svn co http://llvm.org/svn/llvm-project/cfe/trunk -r 318998 --force llvm/tools/clang
cmake ../..  -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLLVM_ENABLE_ASSERTIONS=On -DLLVM_ENABLE_PEDANTIC=Off -DLLVM_ENABLE_WARNINGS=Off -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=Z80 -DLLVM_PARALLEL_COMPILE_JOBS=4 -DLLVM_PARALLEL_LINK_JOBS=1 -DBUILD_SHARED_LIBS=ON && cmake --build .

Then I added the fixes @uyjulian listed above. But I get this error:

[ 31%] Building CXX object lib/CodeGen/SelectionDAG/CMakeFiles/LLVMSelectionDAG.dir/SelectionDAGBuilder.cpp.o
/home/user/code/z80/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp: In function ‘void getCopyToParts(llvm::SelectionDAG&, const llvm::SDLoc&, llvm::SDValue, llvm::SDValue*, unsigned int, llvm::MVT, const llvm::Value*, llvm::ISD::NodeType, bool)’:
/home/user/code/z80/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:497:31: error: ‘const class llvm::TargetLowering’ has no member named ‘AdjustParts’
   DAG.getTargetLoweringInfo().AdjustParts({Parts, NumParts},
                               ^~~~~~~~~~~
make[2]: *** [lib/CodeGen/SelectionDAG/CMakeFiles/LLVMSelectionDAG.dir/build.make:271: lib/CodeGen/SelectionDAG/CMakeFiles/LLVMSelectionDAG.dir/SelectionDAGBuilder.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:1498: lib/CodeGen/SelectionDAG/CMakeFiles/LLVMSelectionDAG.dir/all] Error 2
make: *** [Makefile:152: all] Error 2

cmake 3.14.5

uyjulian commented 5 years ago

Use LLVM revision 316129.

joshhansen commented 5 years ago

@uyjulian Ah yes, of course, I wasn't thinking. That plus the version of this repo you recommended above got things going for me. Many thanks for your help on this!

Here are all of my commands in one place in case that's helpful for people, not including the fixes to TargetLowering.h described by @uyjulian above.:

$ git clone https://github.com/jacobly0/llvm-z80.git llvm && cd llvm
$ git checkout 0dcad6c22b578f076756d67605bca3d931786ef9 && cd ..
$ svn co http://llvm.org/svn/llvm-project/llvm/trunk -r 316129 --force llvm && svn co http://llvm.org/svn/llvm-project/cfe/trunk -r 316129 --force llvm/tools/clang
$ mkdir -p llvm/build/Debug && cd llvm/build/Debug && cmake ../..  -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLLVM_ENABLE_ASSERTIONS=On -DLLVM_ENABLE_PEDANTIC=Off -DLLVM_ENABLE_WARNINGS=Off -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=Z80 -DLLVM_PARALLEL_COMPILE_JOBS=4 -DLLVM_PARALLEL_LINK_JOBS=1 -DBUILD_SHARED_LIBS=ON && cmake --build .
$ ./bin/clang -target z80 -xc - -S -o hello.asm <<<'void test(){printf("Hello, world");}'
$ cat hello.asm
    SEGMENT CODE
    .file   "-"
    XDEF    _test
_test:
    push    ix
    ld  ix, 0
    add ix, sp
    push    hl
    ld  hl, L_.str
    push    hl
    call    _printf
    pop iy
    ld  (ix + -2), l
    ld  (ix + -1), h
    ld  sp, ix
    pop ix
    ret

    SEGMENT TEXT
L_.str:
    DB  72
    DB  101
    DB  108
    DB  108
    DB  111
    DB  44
    DB  32
    DB  119
    DB  111
    DB  114
    DB  108
    DB  100
    DB  0

    XREF    _printf

Apparently that's "Hello, world" in Z80 assembly? (Use -target ez80 for the newer processor). But it includes some directives that the GNU z80asm chokes on:

$ z80asm hello.asm
hello.asm:1: error: command or comment expected (was SEGMENT    CODE )
hello.asm:2: error: command or comment expected (was .file  "-" )
hello.asm:3: error: command or comment expected (was XDEF   _test )
hello.asm:19: error: command or comment expected (was SEGMENT   TEXT )
hello.asm:36: error: command or comment expected (was XREF  _printf )
hello.asm:36: error: unable to resolve reference: _printf 
*** 6 errors found ***

Any tips on how to get this assembled?

uyjulian commented 5 years ago

https://github.com/CE-Programming/toolchain/releases/tag/v7.4.2

Place ez80asm.exe where clang can find it

joshhansen commented 5 years ago

That did the trick. I got it working in Linux using Wine. My ultimate goal is to generate Z80 code. I assume that the EZ80 code generated by this won't run on my target device (a lowly old TI-85, ha!)

It seems the path for Z80 would be to either get LLVM to stop outputting the directives that the GNU assembler doesn't recognize, or adapt the GNU assembler to recognize them.

I also tried the spasm-ng assembler, and it chokes on the same stuff as the GNU assembler. There seems to be something non-regular-Z80 about the output of this LLVM backend. The SEGMENT stuff seems to be the main issue.

adriweb commented 5 years ago

Well yes, the output is tailored for use with the CE toolchain that at the time relied exclusively on ZDS tools as we didn't have anything better at the time (we do now).

LepelTsmok commented 5 years ago

Heyho :3

I'm currently trying to develop a game for the SEGA Master System and used the SDCC compiler for it. However, I'm a big fan of the LLVM and Clang (but not much expierenced :<) and wanted to try out this backend.

I used the following command to checkout the source files - basicly what joshhansen suggested but I also added the lld because I want to link my files.

git clone https://github.com/jacobly0/llvm-z80.git llvm && svn co http://llvm.org/svn/llvm-project/llvm/trunk -r 318998 --force llvm && svn co http://llvm.org/svn/llvm-project/cfe/trunk -r 318998 --force llvm/tools/clang && svn co http://llvm.org/svn/llvm-project/lld/trunk -r 318998 --force llvm/tools/lld

I configurated CMake via the GUI, but turned Warnings and the pedantic mode off - also I enabled the experimental Z80 build. I generated a Visual Studio 2017 solution file, creating a 32bit compiler.

Sadly... The compilation process fails. For example "LLVMZ80CodeGen":

1>------ Build started: Project: intrinsics_gen, Configuration: Release Win32 ------
2>------ Build started: Project: Z80CommonTableGen, Configuration: Release Win32 ------
3>------ Build started: Project: LLVMZ80CodeGen, Configuration: Release Win32 ------
3>Z80AsmPrinter.cpp
3>Z80ExpandPseudo.cpp
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80AsmPrinter.cpp)
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80ExpandPseudo.cpp)
3>Z80FrameLowering.cpp
3>Z80ISelDAGToDAG.cpp
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80FrameLowering.cpp)
3>Z80ISelLowering.cpp
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80ISelDAGToDAG.cpp)
3>Z80InstrInfo.cpp
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80ISelLowering.cpp)
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.cpp(411): warning C4018: '>': signed/unsigned mismatch
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.cpp(451): warning C4018: '>': signed/unsigned mismatch
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.cpp(892): warning C4138: '*/' found outside of comment
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.cpp(1206): warning C4060: switch statement contains no 'case' or 'default' labels
3>Z80MCInstLower.cpp
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80InstrInfo.cpp)
3>Z80RegisterInfo.cpp
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80MCInstLower.cpp)
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80RegisterInfo.cpp)
3>Z80Subtarget.cpp
3>Z80TargetMachine.cpp
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80Subtarget.cpp)
3>c:\program files\llvm\z80\llvm\lib\target\z80\z80isellowering.h(194): error C3668: 'llvm::Z80TargetLowering::isDesirableToShrinkOp': method with override specifier 'override' did not override any base class methods (compiling source file C:\Program Files\LLVM\Z80\llvm\lib\Target\Z80\Z80TargetMachine.cpp)
3>Done building project "LLVMZ80CodeGen.vcxproj" -- FAILED.

To me this are C++ related errors and not because my target is Windows. Does anyone have an idea what is going on? And... Will this project continue?

Edit: Used the markdown correctly - to make my post more readable

uyjulian commented 5 years ago

Use LLVM revision 316129.

LepelTsmok commented 5 years ago

Use LLVM revision 316129.

Thanks for the tipp! I tried the following command now:

git clone https://github.com/jacobly0/llvm-z80.git llvm && svn co http://llvm.org/svn/llvm-project/llvm/trunk -r 316129 --force llvm && svn co http://llvm.org/svn/llvm-project/cfe/trunk -r 316129 --force llvm/tools/clang && svn co http://llvm.org/svn/llvm-project/lld/trunk -r 316129 --force llvm/tools/lld

But this didn't worked quite well - first of all I had to remove a non existing source file from CMake, but now also the build fails complaining about missing files in various projects. I have over 1500 errors but they seem to always refere to *.gen files. This for example

Cannot open include file: 'llvm/IR/Attributes.gen': No such file or directory (compiling source file C:\Program Files\LLVM\Z80\Source\llvm\lib\Target\MSP430\MSP430MCInstLower.cpp) LLVMMSP430CodeGen   

This time I targeted a 64bit build - but I don't even understand why revision 318998 was not okay either, because it was mentioned in the last commit.