digitalmars.D.ldc - Runtime for ARM
- Paolo Invernizzi (15/15) Feb 15 2013 Hi all,
- Kai Nacke (22/37) Feb 15 2013 Hi Paolo!
- Paolo Invernizzi (95/105) Feb 16 2013 Hi Kai,
- Kai Nacke (23/28) Feb 16 2013 Hi Paolo!
- Paolo Invernizzi (19/42) Feb 16 2013 Hi Kay,
- Kai Nacke (6/18) Feb 16 2013 I try this. I always built LLLVm and LDC with ARM support. Let's
- Kai Nacke (37/49) Feb 17 2013 Hi Paolo!
- Paolo Invernizzi (6/43) Feb 18 2013 Hi Kai,
- Paolo Invernizzi (8/13) Feb 18 2013 Kai,
- Kai Nacke (6/21) Feb 18 2013 Hi Paolo,
- Paolo Invernizzi (4/7) Feb 18 2013 Thanks Kai, bug added:
- David Nadlinger (9/11) Mar 04 2013 Does using llvm::CallingConv::C by default help as a workaround
- Paolo Invernizzi (9/21) Mar 05 2013 Hi David,
- Kai Nacke (10/19) Mar 23 2013 Hi Paolo!
- David Nadlinger (13/18) Apr 06 2013 The patch is still being discussed on the LLVM lists, and it
- Kai Nacke (3/21) May 05 2013 PR15293 should now be fixed with r181148 from yesterday.
- David Nadlinger (4/31) May 06 2013 I don't think this helps us much at all, since the ABI for
- Kai Nacke (8/15) May 06 2013 The commit log says:
- David Nadlinger (6/12) May 06 2013 Doesn't LLVM suffer from the same conceptual problem as on x86_64
- Joseph Rushton Wakeling (5/8) May 06 2013 Naive question -- why not have D fallback versions of the
Hi all, I've read that *maybe* it's possible to use LDC for ARM, so I'm investigating the port effort of an actual D application. I've compiled the actual 'merge-2.061-2' and ldc has produced an ARM object file: ldc2 -march=arm -mtriple=arm-linux-gnueabi -c main.d file main.o main.o: ELF 32-bit LSB relocatable, ARM, version 1 (GNU/Linux), not stripped So now, just before starting to attach the runtime compilation, I'm asking of someone has a ready-to-use tutorial/patch-for-CMakeLists/blogpost or similar for such a things... Thanks, Paolo
Feb 15 2013
On Friday, 15 February 2013 at 09:54:11 UTC, Paolo Invernizzi wrote:Hi all, I've read that *maybe* it's possible to use LDC for ARM, so I'm investigating the port effort of an actual D application. I've compiled the actual 'merge-2.061-2' and ldc has produced an ARM object file: ldc2 -march=arm -mtriple=arm-linux-gnueabi -c main.d file main.o main.o: ELF 32-bit LSB relocatable, ARM, version 1 (GNU/Linux), not stripped So now, just before starting to attach the runtime compilation, I'm asking of someone has a ready-to-use tutorial/patch-for-CMakeLists/blogpost or similar for such a things... Thanks, PaoloHi Paolo! Nice to here that you like to work on the ARM port. As to my knowledge there is no tutorial or patch list. From my experience with PowerPC-64bit I can tell you that one of the first things you need to do is checking the vararg interface (core.vararg, core.stdc.stdarg). It is imported in many files - you get a lot of compile errors if this is missing/not working. Next step in druntime is to look at thread support and GC. For ARM, there is already some code. Maybe it works out of the box. (You can also choose to postpone this work and use the dummy GC as I did.) In Phobos the module which can make trouble is std.math. It is also included in many other modules and contains a fair amount of assembler code. If you solve these issues then you will get a compiling/working druntime/phobos library. After that you can find the remaining bugs with the help of the test suite and then add some more nice stuff (e.g. ARM support in core.cpuid :-) ) Regards Kai
Feb 15 2013
On Friday, 15 February 2013 at 15:51:20 UTC, Kai Nacke wrote:As to my knowledge there is no tutorial or patch list. From my experience with PowerPC-64bit I can tell you that one of the first things you need to do is checking the vararg interface (core.vararg, core.stdc.stdarg). It is imported in many files - you get a lot of compile errors if this is missing/not working. Next step in druntime is to look at thread support and GC. For ARM, there is already some code. Maybe it works out of the box. (You can also choose to postpone this work and use the dummy GC as I did.)Hi Kai, Right now the first problem is that I've a bunch of: Assertion failed: (size >= excess && "expected larger existing stack allocation"), function HandleByVal, file ARMISelLowering.cpp, line 1681. In the runtime they are in the debug version (for example, trying to build aAA.d), that can avoid, but in phobos they are in the release version also (for example, in std.conv). I'm not sure if this is a ldc problem or llvm problem... full stack below. Cheers, Paolo Assertion failed: (size >= excess && "expected larger existing stack allocation"), function HandleByVal, file ARMISelLowering.cpp, line 1681. 0 ldc2 0x000000010bcaf819 PrintStackTrace(void*) + 37 1 ldc2 0x000000010bcafbac SignalHandler(int) + 241 2 libsystem_c.dylib 0x00007fff8c4148ea _sigtramp + 26 3 ldc2 0x000000010b81c8c1 AddNodeIDCustom(llvm::FoldingSetNodeID&, llvm::SDNode const*) + 823 4 ldc2 0x000000010bcafa24 abort + 22 5 ldc2 0x000000010bcafa0e abort + 0 6 ldc2 0x000000010b639322 llvm::ARMTargetLowering::LowerReturn(llvm::SDValue, llvm::CallingConv::ID, bool, llvm::SmallVectorImpl<llvm::ISD::OutputArg> const&, llvm::SmallVectorImpl<llvm::SDValue> const&, llvm::DebugLoc, llvm::SelectionDAG&) const + 0 7 ldc2 0x000000010b8d6bff llvm::CCState::HandleByVal(unsigned int, llvm::MVT, llvm::MVT, llvm::CCValAssign::LocInfo, int, int, llvm::ISD::ArgFlagsTy) + 127 8 ldc2 0x000000010b63573a CC_ARM_AAPCS(unsigned int, llvm::MVT, llvm::MVT, llvm::CCValAssign::LocInfo, llvm::ISD::ArgFlagsTy, llvm::CCState&) + 80 9 ldc2 0x000000010b8d7010 llvm::CCState::AnalyzeCallOperands(llvm::SmallVectorImpl<llvm::ISD::OutputArg> const&, bool (*)(unsigned int, llvm::MVT, llvm::MVT, llvm::CCValAssign::LocInfo, llvm::ISD::ArgFlagsTy, llvm::CCState&)) + 108 10 ldc2 0x000000010b636907 llvm::ARMTargetLowering::LowerCall(llvm::TargetLowering::CallLoweringInfo&, llvm::SmallVectorImpl<llvm::SDValue>&) const + 593 11 ldc2 0x000000010b85a1b8 llvm::TargetLowering::LowerCallTo(llvm::TargetLowering::CallLoweringInfo&) const + 2004 12 ldc2 0x000000010b84b360 llvm::SelectionDAGBuilder::LowerCallTo(llvm::ImmutableCallSite, llvm::SDValue, bool, llvm::MachineBasicBlock*) + 1676 13 ldc2 0x000000010b83fefd llvm::SelectionDAGBuilder::visitCall(llvm::CallInst const&) + 563 14 ldc2 0x000000010b83b78c llvm::SelectionDAGBuilder::visit(unsigned int, llvm::User const&) + 856 15 ldc2 0x000000010b83af13 llvm::SelectionDAGBuilder::visit(llvm::Instruction const&) + 71 16 ldc2 0x000000010b86a81d llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator<llvm::Instruction const>, llvm::ilist_iterator<llvm::Instruction const>, bool&) + 33 17 ldc2 0x000000010b86a5d6 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 3490 18 ldc2 0x000000010b8690be llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 734 19 ldc2 0x000000010b92d870 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 48 20 ldc2 0x000000010bc3f8a0 llvm::FPPassManager::runOnFunction(llvm::Function&) + 292 21 ldc2 0x000000010bc3f35b llvm::FunctionPassManagerImpl::run(llvm::Function&) + 87 22 ldc2 0x000000010bc3f20d llvm::FunctionPassManager::run(llvm::Function&) + 89 23 ldc2 0x000000010b2cd167 emit_file(llvm::TargetMachine&, llvm::Module&, llvm::raw_fd_ostream&, llvm::TargetMachine::CodeGenFileType) + 343 24 ldc2 0x000000010b2ccb3a writeModule(llvm::Module*, std::string) + 1066 25 ldc2 0x000000010b2d5c6f main + 11279 26 libdyld.dylib 0x00007fff9785b7e1 start + 0 27 libdyld.dylib 0x000000000000000f start + 18446603337974040622 Stack dump: 0. Running pass 'ARM Instruction Selection' on function ' _D3std4conv16testEmplaceChunkFAvkkAyaZv' /bin/sh: line 1: 14339 Illegal instruction: 4 /Users/Melkor/Tmp/ldc-trunk/ldc/barm1/bin/ldc2 --output-o -c -I/Users/Melkor/Projects/External/druntime/src -I/Users/Melkor/Projects/External/druntime/src/gc /Users/Melkor/Projects/External/phobos/std/conv.d -of/Users/Melkor/Tmp/ldc-trunk/ldc/barm1/runtime/std/conv.o -w -d -march=arm -mtriple=arm-linux-gnueabi -d-version=LDC_LLVM_303 -O3 -release -I/Users/Melkor/Projects/External/phobos
Feb 16 2013
On Saturday, 16 February 2013 at 18:38:49 UTC, Paolo Invernizzi wrote:Right now the first problem is that I've a bunch of: Assertion failed: (size >= excess && "expected larger existing stack allocation"), function HandleByVal, file ARMISelLowering.cpp, line 1681.Hi Paolo! Just an assumption: You need to write an ABI class for ARM. HandleByVal is called during argument lowering in LLVM. The comment of this function says: /// HandleByVal - Every parameter *after* a byval parameter is passed /// on the stack. Remember the next parameter register to allocate, /// and then confiscate the rest of the parameter registers to insure /// this. I can imagine that there is something wrong with the calling convention in LDC. You should look at gen/abi-x86.cpp and gen/abi-x86-64.cpp to get a feeling what you need to do. Then write an abi-arm which models the ARM calling convention. It is really easy if you have an understanding of the used calling convention. But remember: this is only a shot in the dark from me. I never got that far on my ARM box... Regards Kai
Feb 16 2013
On Saturday, 16 February 2013 at 23:35:58 UTC, Kai Nacke wrote:On Saturday, 16 February 2013 at 18:38:49 UTC, Paolo Invernizzi wrote: Hi Paolo! Just an assumption: You need to write an ABI class for ARM. HandleByVal is called during argument lowering in LLVM. The comment of this function says: /// HandleByVal - Every parameter *after* a byval parameter is passed /// on the stack. Remember the next parameter register to allocate, /// and then confiscate the rest of the parameter registers to insure /// this. I can imagine that there is something wrong with the calling convention in LDC. You should look at gen/abi-x86.cpp and gen/abi-x86-64.cpp to get a feeling what you need to do. Then write an abi-arm which models the ARM calling convention. It is really easy if you have an understanding of the used calling convention. But remember: this is only a shot in the dark from me. I never got that far on my ARM box... Regards KaiHi Kay, Thanks for the tip, I'm really an ARM newbie, but I'll give a look to gen/abi and I'll try to find out something about the ARM calling convention... Right now I've reduced the ice to something like: template Rebindable(T) { struct Rebindable { void opAssign(Rebindable ) {} } } struct SysTime { Rebindable!(TimeZone) _timezone; } class TimeZone {} ice with ldc2 -c ice.d -march=arm -mcpu=cortex-a9 -mtriple=arm-linux-gnueabihf Cheers, Paolo
Feb 16 2013
On Saturday, 16 February 2013 at 23:45:55 UTC, Paolo Invernizzi wrote:Right now I've reduced the ice to something like: template Rebindable(T) { struct Rebindable { void opAssign(Rebindable ) {} } } struct SysTime { Rebindable!(TimeZone) _timezone; } class TimeZone {} ice with ldc2 -c ice.d -march=arm -mcpu=cortex-a9 -mtriple=arm-linux-gnueabihfI try this. I always built LLLVm and LDC with ARM support. Let's see what happens... Regards Kai
Feb 16 2013
On Saturday, 16 February 2013 at 23:45:55 UTC, Paolo Invernizzi wrote:Right now I've reduced the ice to something like: template Rebindable(T) { struct Rebindable { void opAssign(Rebindable ) {} } } struct SysTime { Rebindable!(TimeZone) _timezone; } class TimeZone {} ice with ldc2 -c ice.d -march=arm -mcpu=cortex-a9 -mtriple=arm-linux-gnueabihfHi Paolo! It is a LLVM bug. I used bugpoint and a bit of editing to derive this IR file: ; ModuleID = 'bugpoint-reduced-simplified.bc' target datalayout = "e-p:32:32:32-S64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:64:128-a0:0:64-n32" target triple = "arm--linux-gnueabihf" %"armbug.Rebindable!(TimeZone).Rebindable" = type <{ i8 }> %armbug.SysTime = type <{ %"armbug.Rebindable!(TimeZone).Rebindable" }> %armbug.TimeZone = type { i8* } declare fastcc void opAssign(%"armbug.Rebindable!(TimeZone).Rebindable"*, %"armbug.Rebindable!(TimeZone).Rebindable"* byval) define fastcc %armbug.SysTime* doOpAssign(%armbug.SysTime* %.this_arg, %armbug.SysTime* byval %p_arg) { entry: br i1 undef, label %noassert, label %assert assert: ; preds = %entry unreachable noassert: ; preds = %entry call fastcc void opAssign(%"armbug.Rebindable!(TimeZone).Rebindable"* undef, %"armbug.Rebindable!(TimeZone).Rebindable"* byval undef) ret %armbug.SysTime* %.this_arg } You get the assertion failure if you use llc to compile this file. This does not happen on X86_64 - it is a bug! Please, could you file a bug report for LLVM: http://llvm.org/bugs/ BTW: This is quite natural. LDC uses LLVM in some other way then clang. This may raise otherwise unnoticed bugs. For PPC64, I currently work on the 3rd LLVM bug... Regards Kai
Feb 17 2013
On Sunday, 17 February 2013 at 14:15:57 UTC, Kai Nacke wrote:Hi Paolo! It is a LLVM bug. I used bugpoint and a bit of editing to derive this IR file: ; ModuleID = 'bugpoint-reduced-simplified.bc' target datalayout = "e-p:32:32:32-S64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:64:128-a0:0:64-n32" target triple = "arm--linux-gnueabihf" %"armbug.Rebindable!(TimeZone).Rebindable" = type <{ i8 }> %armbug.SysTime = type <{ %"armbug.Rebindable!(TimeZone).Rebindable" }> %armbug.TimeZone = type { i8* } declare fastcc void opAssign(%"armbug.Rebindable!(TimeZone).Rebindable"*, %"armbug.Rebindable!(TimeZone).Rebindable"* byval) define fastcc %armbug.SysTime* doOpAssign(%armbug.SysTime* %.this_arg, %armbug.SysTime* byval %p_arg) { entry: br i1 undef, label %noassert, label %assert assert: ; preds = %entry unreachable noassert: ; preds = %entry call fastcc void opAssign(%"armbug.Rebindable!(TimeZone).Rebindable"* undef, %"armbug.Rebindable!(TimeZone).Rebindable"* byval undef) ret %armbug.SysTime* %.this_arg } You get the assertion failure if you use llc to compile this file. This does not happen on X86_64 - it is a bug! Please, could you file a bug report for LLVM: http://llvm.org/bugs/ BTW: This is quite natural. LDC uses LLVM in some other way then clang. This may raise otherwise unnoticed bugs. For PPC64, I currently work on the 3rd LLVM bug... Regards KaiHi Kai, I'll post a bug report for LLVM... Thank you for your help in this! Regards, Paolo
Feb 18 2013
On Monday, 18 February 2013 at 10:36:12 UTC, Paolo Invernizzi wrote:Hi Kai, I'll post a bug report for LLVM... Thank you for your help in this! Regards, PaoloKai, Only one thing, as It's my first LLVM bug report: do you have tried it with 3.2, or trunk? If 3.2, do you think is it best for me to try with latest trunk? Thanks again, Paolo
Feb 18 2013
On Monday, 18 February 2013 at 11:34:14 UTC, Paolo Invernizzi wrote:On Monday, 18 February 2013 at 10:36:12 UTC, Paolo Invernizzi wrote:Hi Paolo, I tried it with trunk. Regards KaiHi Kai, I'll post a bug report for LLVM... Thank you for your help in this! Regards, PaoloKai, Only one thing, as It's my first LLVM bug report: do you have tried it with 3.2, or trunk? If 3.2, do you think is it best for me to try with latest trunk? Thanks again, Paolo
Feb 18 2013
On Monday, 18 February 2013 at 11:44:03 UTC, Kai Nacke wrote:I tried it with trunk. Regards KaiThanks Kai, bug added: http://llvm.org/bugs/show_bug.cgi?id=15293 Cheers, Paolo
Feb 18 2013
On Monday, 18 February 2013 at 13:03:46 UTC, Paolo Invernizzi wrote:Thanks Kai, bug added: http://llvm.org/bugs/show_bug.cgi?id=15293Does using llvm::CallingConv::C by default help as a workaround (https://github.com/ldc-developers/ldc/blob/master/gen/abi.cpp#L53)? As the official docs should say that »the extern (D) calling convention matches the C calling convention used by the supported C compiler on the host system«, this should probably be changed anyway. David
Mar 04 2013
On Monday, 4 March 2013 at 13:13:15 UTC, David Nadlinger wrote:On Monday, 18 February 2013 at 13:03:46 UTC, Paolo Invernizzi wrote:Hi David, I've tried with the latest master, changing the LINKdefault from Fast to C, but I have the same ice, on the reduced example I've posted above. The problem is that right now I'm a little under pressure on work, so I've almost no time to dig into LLVM for trying to resolve the bug... *sigh* /PaoloThanks Kai, bug added: http://llvm.org/bugs/show_bug.cgi?id=15293Does using llvm::CallingConv::C by default help as a workaround (https://github.com/ldc-developers/ldc/blob/master/gen/abi.cpp#L53)? As the official docs should say that »the extern (D) calling convention matches the C calling convention used by the supported C compiler on the host system«, this should probably be changed anyway. David
Mar 05 2013
On Monday, 18 February 2013 at 13:03:46 UTC, Paolo Invernizzi wrote:On Monday, 18 February 2013 at 11:44:03 UTC, Kai Nacke wrote:Hi Paolo! There is now a patch available in the bug report. At first look it seems that it fixes the problem. I tried to compile druntime but (as usual) I get a lot of "error: undefined identifier va_list" messages. That was the same with PPC64.... Regards KaiI tried it with trunk. Regards KaiThanks Kai, bug added: http://llvm.org/bugs/show_bug.cgi?id=15293 Cheers, Paolo
Mar 23 2013
On Saturday, 23 March 2013 at 15:12:29 UTC, Kai Nacke wrote:There is now a patch available in the bug report. At first look it seems that it fixes the problem. I tried to compile druntime but (as usual) I get a lot of "error: undefined identifier va_list" messages. That was the same with PPC64....The patch is still being discussed on the LLVM lists, and it looks like it is a very incomplete solution. In any case, it shouldn't really be a blocker for us, as we need to implement ABI transforms similar to x86_64 anyway to handle the ARM EABI (with and without VFP/hardfloat): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf (see e.g. section 5.5) The Clang source has a couple of interesting test cases, for example: https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/arm-arguments.c https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/arm-aapcs-vfp.c David
Apr 06 2013
On Sunday, 7 April 2013 at 00:05:15 UTC, David Nadlinger wrote:On Saturday, 23 March 2013 at 15:12:29 UTC, Kai Nacke wrote:PR15293 should now be fixed with r181148 from yesterday. KaiThere is now a patch available in the bug report. At first look it seems that it fixes the problem. I tried to compile druntime but (as usual) I get a lot of "error: undefined identifier va_list" messages. That was the same with PPC64....The patch is still being discussed on the LLVM lists, and it looks like it is a very incomplete solution. In any case, it shouldn't really be a blocker for us, as we need to implement ABI transforms similar to x86_64 anyway to handle the ARM EABI (with and without VFP/hardfloat): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf (see e.g. section 5.5) The Clang source has a couple of interesting test cases, for example: https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/arm-arguments.c https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/arm-aapcs-vfp.c David
May 05 2013
On Monday, 6 May 2013 at 05:16:39 UTC, Kai Nacke wrote:On Sunday, 7 April 2013 at 00:05:15 UTC, David Nadlinger wrote:I don't think this helps us much at all, since the ABI for (small) structs would still be wrong, no? DavidOn Saturday, 23 March 2013 at 15:12:29 UTC, Kai Nacke wrote:PR15293 should now be fixed with r181148 from yesterday. KaiThere is now a patch available in the bug report. At first look it seems that it fixes the problem. I tried to compile druntime but (as usual) I get a lot of "error: undefined identifier va_list" messages. That was the same with PPC64....The patch is still being discussed on the LLVM lists, and it looks like it is a very incomplete solution. In any case, it shouldn't really be a blocker for us, as we need to implement ABI transforms similar to x86_64 anyway to handle the ARM EABI (with and without VFP/hardfloat): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf (see e.g. section 5.5) The Clang source has a couple of interesting test cases, for example: https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/arm-arguments.c https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/arm-aapcs-vfp.c David
May 06 2013
On Monday, 6 May 2013 at 08:42:44 UTC, David Nadlinger wrote:On Monday, 6 May 2013 at 05:16:39 UTC, Kai Nacke wrote:The commit log says: For ARM backend, fixed "byval" attribute support. Now even the small structures could be passed within byval (small enough to be stored in GPRs). I conclude that the ABI for small structs should be fine now. KaiPR15293 should now be fixed with r181148 from yesterday. KaiI don't think this helps us much at all, since the ABI for (small) structs would still be wrong, no? David
May 06 2013
On Monday, 6 May 2013 at 11:01:45 UTC, Kai Nacke wrote:The commit log says: For ARM backend, fixed "byval" attribute support. Now even the small structures could be passed within byval (small enough to be stored in GPRs). I conclude that the ABI for small structs should be fine now.Doesn't LLVM suffer from the same conceptual problem as on x86_64 here, i.e. the C struct { char a, b, c, d; } being mapped to four registers instead of one if the obvious LLVM representation is chosen? David
May 06 2013
On Friday, 15 February 2013 at 15:51:20 UTC, Kai Nacke wrote:In Phobos the module which can make trouble is std.math. It is also included in many other modules and contains a fair amount of assembler code.Naive question -- why not have D fallback versions of the assembler parts of Phobos, druntime etc.? Even if it means very slow code for some cases, it would surely simplify getting a basic working system up and running on different platforms.
May 06 2013