Jump to page: 1 2
Thread overview
Runtime for ARM
Feb 15, 2013
Paolo Invernizzi
Feb 15, 2013
Kai Nacke
Feb 16, 2013
Paolo Invernizzi
Feb 16, 2013
Kai Nacke
Feb 16, 2013
Paolo Invernizzi
Feb 16, 2013
Kai Nacke
Feb 17, 2013
Kai Nacke
Feb 18, 2013
Paolo Invernizzi
Feb 18, 2013
Paolo Invernizzi
Feb 18, 2013
Kai Nacke
Feb 18, 2013
Paolo Invernizzi
Mar 04, 2013
David Nadlinger
Mar 05, 2013
Paolo Invernizzi
Mar 23, 2013
Kai Nacke
Apr 07, 2013
David Nadlinger
May 06, 2013
Kai Nacke
May 06, 2013
David Nadlinger
May 06, 2013
Kai Nacke
May 06, 2013
David Nadlinger
February 15, 2013
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
February 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,
> Paolo

Hi 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
February 16, 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

February 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
February 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
> Kai

Hi 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
February 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-gnueabihf

I try this. I always built LLLVm and LDC with ARM support. Let's see what happens...

Regards
Kai
February 17, 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-gnueabihf

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
Kai
February 18, 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
> Kai

Hi Kai,

I'll post a bug report for LLVM...
Thank you for your help in this!

Regards,
Paolo


February 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,
> Paolo

Kai,

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

February 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 Kai,
>>
>> I'll post a bug report for LLVM...
>> Thank you for your help in this!
>>
>> Regards,
>> Paolo
>
> Kai,
>
> 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

Hi Paolo,

I tried it with trunk.

Regards
Kai
« First   ‹ Prev
1 2