Jump to page: 1 2 3
Thread overview
LDC with MSP430
Jun 20, 2017
Luís Marques
Jun 20, 2017
Nicholas Wilson
Jun 20, 2017
Luís Marques
Jun 20, 2017
Nicholas Wilson
Jun 20, 2017
Luís Marques
Jun 20, 2017
Luís Marques
Jun 20, 2017
David Nadlinger
Jun 20, 2017
Luís Marques
Jun 23, 2017
David Nadlinger
Jul 05, 2017
Luís Marques
Jul 05, 2017
Johan Engelen
Jul 05, 2017
Luís Marques
Jul 05, 2017
Johan Engelen
Jul 05, 2017
Luís Marques
Jul 06, 2017
Luís Marques
Jul 06, 2017
Luís Marques
Jul 06, 2017
David Nadlinger
Jun 20, 2017
Luís Marques
Jun 20, 2017
Johan Engelen
Jun 20, 2017
Luís Marques
Jun 20, 2017
David Nadlinger
June 20, 2017
Hello,

In the past I used LDC for bare metal programming of a RISC-V, simply by tweaking the white list of accepted architectures. I tried to do the same for the MSP430, but in this case it seems some other things will have to be tweaked. This might be something easy for someone more familiar with the LDC/LLVM codebase, so could anyone give a helping hand here?

The issue so far seems to be that LDC gets confused about the data type sizes, probably because the MSP430 has a 16-bit CPU core (C ints are 16 bit):

```
Assertion failed: (llSize <= dSize && "LLVM type is bigger than the corresponding D type, " "might lead to aggregate layout mismatch."), function getMemberSize, file ../gen/llvmhelpers.cpp, line 1351.
0  ldc2                     0x00000001034bbc9c llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 60
1  ldc2                     0x00000001034bc1e9 PrintStackTraceSignalHandler(void*) + 25
2  ldc2                     0x00000001034b8139 llvm::sys::RunSignalHandlers() + 425
3  ldc2                     0x00000001034bc642 SignalHandler(int) + 354
4  libsystem_platform.dylib 0x00007fffcee36b3a _sigtramp + 26
5  ldc2                     0x000000010396ce00 cppmain(int, char**)::DL + 48
6  libsystem_c.dylib        0x00007fffcecbb420 abort + 129
7  libsystem_c.dylib        0x00007fffcec82893 basename_r + 0
8  ldc2                     0x000000010145dbbf getMemberSize(Type*) + 175
9  ldc2                     0x000000010154ddc8 AggrTypeBuilder::addAggregate(AggregateDeclaration*, std::__1::map<VarDeclaration*, llvm::Constant*, std::__1::less<VarDeclaration*>, std::__1::allocator<std::__1::pair<VarDeclaration* const, llvm::Constant*> > > const*, AggrTypeBuilder::Aliases) + 2824
10 ldc2                     0x000000010154d2b6 AggrTypeBuilder::addAggregate(AggregateDeclaration*) + 38
11 ldc2                     0x000000010155199e IrTypeClass::addClassData(AggrTypeBuilder&, ClassDeclaration*) + 414
12 ldc2                     0x00000001015520f4 IrTypeClass::get(ClassDeclaration*) + 612
13 ldc2                     0x000000010150ae3e DtoType(Type*) + 958
14 ldc2                     0x0000000101549d0e IrFuncTyArg::IrFuncTyArg(Type*, bool, AttrBuilder) + 126
15 ldc2                     0x0000000101549dbc IrFuncTyArg::IrFuncTyArg(Type*, bool, AttrBuilder) + 44
16 ldc2                     0x000000010143eb3c DtoFunctionType(Type*, IrFuncTy&, Type*, Type*, bool, bool, bool, bool) + 3468
17 ldc2                     0x00000001015552ac IrTypeFunction::get(Type*) + 220
18 ldc2                     0x000000010150ae6e DtoType(Type*) + 1006
19 ldc2                     0x00000001014c6ce5 createFwdDecl(LINK, Type*, llvm::ArrayRef<llvm::StringRef>, llvm::ArrayRef<Type*>, llvm::ArrayRef<unsigned long>, AttrSet) + 373
20 ldc2                     0x00000001014b708f buildRuntimeModule() + 9327
21 ldc2                     0x00000001014b4c02 initRuntime() + 50
22 ldc2                     0x0000000101473178 codegenModule(IRState*, Module*) + 248
23 ldc2                     0x000000010158a3ac ldc::CodeGenerator::emit(Module*) + 300
24 ldc2                     0x00000001015d8e4e codegenModules(Array<Module*>&) + 574
25 ldc2                     0x00000001012949c0 mars_mainBody(Array<char const*>&, Array<char const*>&) + 5120
```

(BTW, I used -mtriple=msp430, since `msp430-gcc -dumpmachine` gives out that "triple")
June 20, 2017
On Tuesday, 20 June 2017 at 01:51:14 UTC, Luís Marques wrote:
> Hello,
>
> In the past I used LDC for bare metal programming of a RISC-V, simply by tweaking the white list of accepted architectures. I tried to do the same for the MSP430, but in this case it seems some other things will have to be tweaked. This might be something easy for someone more familiar with the LDC/LLVM codebase, so could anyone give a helping hand here?
>
> The issue so far seems to be that LDC gets confused about the data type sizes, probably because the MSP430 has a 16-bit CPU core (C ints are 16 bit):
>
> ```
> Assertion failed: (llSize <= dSize && "LLVM type is bigger than the corresponding D type, " "might lead to aggregate layout mismatch."), function getMemberSize, file ../gen/llvmhelpers.cpp, line 1351.
> 0  ldc2                     0x00000001034bbc9c llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 60
> 1  ldc2                     0x00000001034bc1e9 PrintStackTraceSignalHandler(void*) + 25
> 2  ldc2                     0x00000001034b8139 llvm::sys::RunSignalHandlers() + 425
> 3  ldc2                     0x00000001034bc642 SignalHandler(int) + 354
> 4  libsystem_platform.dylib 0x00007fffcee36b3a _sigtramp + 26
> 5  ldc2                     0x000000010396ce00 cppmain(int, char**)::DL + 48
> 6  libsystem_c.dylib        0x00007fffcecbb420 abort + 129
> 7  libsystem_c.dylib        0x00007fffcec82893 basename_r + 0
> 8  ldc2                     0x000000010145dbbf getMemberSize(Type*) + 175
> 9  ldc2                     0x000000010154ddc8 AggrTypeBuilder::addAggregate(AggregateDeclaration*, std::__1::map<VarDeclaration*, llvm::Constant*, std::__1::less<VarDeclaration*>, std::__1::allocator<std::__1::pair<VarDeclaration* const, llvm::Constant*> > > const*, AggrTypeBuilder::Aliases) + 2824
> 10 ldc2                     0x000000010154d2b6 AggrTypeBuilder::addAggregate(AggregateDeclaration*) + 38
> 11 ldc2                     0x000000010155199e IrTypeClass::addClassData(AggrTypeBuilder&, ClassDeclaration*) + 414
> 12 ldc2                     0x00000001015520f4 IrTypeClass::get(ClassDeclaration*) + 612
> 13 ldc2                     0x000000010150ae3e DtoType(Type*) + 958
> 14 ldc2                     0x0000000101549d0e IrFuncTyArg::IrFuncTyArg(Type*, bool, AttrBuilder) + 126
> 15 ldc2                     0x0000000101549dbc IrFuncTyArg::IrFuncTyArg(Type*, bool, AttrBuilder) + 44
> 16 ldc2                     0x000000010143eb3c DtoFunctionType(Type*, IrFuncTy&, Type*, Type*, bool, bool, bool, bool) + 3468
> 17 ldc2                     0x00000001015552ac IrTypeFunction::get(Type*) + 220
> 18 ldc2                     0x000000010150ae6e DtoType(Type*) + 1006
> 19 ldc2                     0x00000001014c6ce5 createFwdDecl(LINK, Type*, llvm::ArrayRef<llvm::StringRef>, llvm::ArrayRef<Type*>, llvm::ArrayRef<unsigned long>, AttrSet) + 373
> 20 ldc2                     0x00000001014b708f buildRuntimeModule() + 9327
> 21 ldc2                     0x00000001014b4c02 initRuntime() + 50
> 22 ldc2                     0x0000000101473178 codegenModule(IRState*, Module*) + 248
> 23 ldc2                     0x000000010158a3ac ldc::CodeGenerator::emit(Module*) + 300
> 24 ldc2                     0x00000001015d8e4e codegenModules(Array<Module*>&) + 574
> 25 ldc2                     0x00000001012949c0 mars_mainBody(Array<char const*>&, Array<char const*>&) + 5120
> ```
>
> (BTW, I used -mtriple=msp430, since `msp430-gcc -dumpmachine` gives out that "triple")

What data layout is being used? Can you get clang to `-emit-llvm` and look at the resulting file 2nd line?

should look like target datalayout = "..." .Please post the ...

 also please also compile with `-vv` and post the last section of diagnostics printed (warning it spits out a lot), the length of the backtrace should suffice.

Nic
June 20, 2017
On Tuesday, 20 June 2017 at 06:52:05 UTC, Nicholas Wilson wrote:
> What data layout is being used? Can you get clang to `-emit-llvm` and look at the resulting file 2nd line?
>
> should look like target datalayout = "..." .Please post the ...

I was going to say that I hadn't built clang, only LLVM, but that you could find that info in the target:

LLVMTargetMachine(T, "e-m:e-p:16:16-i32:16:32-a:16-n8:16", TT, CPU, FS,
                        Options, getEffectiveRelocModel(RM), CM, OL),

...but I want to help and I was not 100% sure that was what you wanted, so I went the extra mile ;)

target datalayout = "e-m:e-p:16:16-i32:16:32-a:16-n8:16"

>  also please also compile with `-vv` and post the last section of diagnostics printed (warning it spits out a lot), the length of the backtrace should suffice.

This is the full output for an empty .d file:

$ ldc2 -mtriple=msp430 -c -betterC test.d -vv
Targeting 'msp430' (CPU '' with features '')
WARNING: Unknown ABI, guessing...
Building type: real
Building type: uint
CodeGenerator::emit(test)
* resetting 978 Dsymbols
* *** Initializing D runtime declarations ***
* * building runtime module
* * Building type: extern (C) void(void*, void*)
* * * DtoFunctionType(extern (C) void(void*, void*))
* * * * Building type: void
* * * * Building type: void*
* * * * Final function type: void (i8*, i8*)
* * Building type: extern (C) void(char[], uint)
* * * DtoFunctionType(extern (C) void(char[], uint))
* * * * Building type: char[]
* * * * * Building type: char
* * * * Final function type: void ({ i32, i8* }, i32)
* * Building type: extern (C) void(char[], char[], uint)
* * * DtoFunctionType(extern (C) void(char[], char[], uint))
* * * * Final function type: void ({ i32, i8* }, { i32, i8* }, i32)
* * Building type: extern (C) void(immutable ModuleInfo*, uint)
* * * DtoFunctionType(extern (C) void(immutable ModuleInfo*, uint))
* * * * Building type: ModuleInfo*
* * * * * Building type: ModuleInfo
* * * * * * Building struct type object.ModuleInfo @ /path/to/ldc/runtime/druntime/src/object.d(1517)
* * * * * * * Field priority for _flags: 1
* * * * * * * Field priority for _index: 1
* * * * * * * final struct type: %object.ModuleInfo = type { i32, i32 }
* * * * Final function type: void (%object.ModuleInfo*, i32)
* * Building type: extern (C) void*(uint)
* * * DtoFunctionType(extern (C) void*(uint))
* * * * Final function type: i8* (i32)
* * Building type: extern (C) void*(TypeInfo)
* * * DtoFunctionType(extern (C) void*(TypeInfo))
* * * * Building type: object.TypeInfo
* * * * * Building class type object.TypeInfo @ /path/to/ldc/runtime/druntime/src/object.d(242)
* * * * * * Instance size: 4
* * * * * * class type: %object.TypeInfo = type { [18 x i8*]*, i8* }
* * * * Final function type: i8* (%object.TypeInfo*)
* * Building type: extern (C) void[](const TypeInfo, uint)
* * * DtoFunctionType(extern (C) void[](const TypeInfo, uint))
* * * * Building type: void[]
* * * * Final function type: { i32, i8* } (%object.TypeInfo*, i32)
* * Building type: extern (C) void[](const TypeInfo, uint[])
* * * DtoFunctionType(extern (C) void[](const TypeInfo, uint[]))
* * * * Building type: uint[]
* * * * Final function type: { i32, i8* } (%object.TypeInfo*, { i32, i32* })
* * Building type: extern (C) void[](const TypeInfo, uint, void[]*)
* * * DtoFunctionType(extern (C) void[](const TypeInfo, uint, void[]*))
* * * * Building type: void[]*
* * * * Final function type: { i32, i8* } (%object.TypeInfo*, i32, { i32, i8* }*)
* * Building type: extern (C) void[](const TypeInfo, ref void[], uint)
* * * DtoFunctionType(extern (C) void[](const TypeInfo, ref void[], uint))
* * * * Final function type: { i32, i8* } (%object.TypeInfo*, { i32, i8* }*, i32)
* * Building type: extern (C) void[](const TypeInfo, ref void[], void[])
* * * DtoFunctionType(extern (C) void[](const TypeInfo, ref void[], void[]))
* * * * Final function type: { i32, i8* } (%object.TypeInfo*, { i32, i8* }*, { i32, i8* })
* * Building type: extern (C) void[](ref void[], dchar)
* * * DtoFunctionType(extern (C) void[](ref void[], dchar))
* * * * Building type: dchar
* * * * Final function type: { i32, i8* } ({ i32, i8* }*, i32)
* * Building type: extern (C) void[](const TypeInfo, void[], void[])
* * * DtoFunctionType(extern (C) void[](const TypeInfo, void[], void[]))
* * * * Final function type: { i32, i8* } (%object.TypeInfo*, { i32, i8* }, { i32, i8* })
* * Building type: extern (C) void[](const TypeInfo, void[][])
* * * DtoFunctionType(extern (C) void[](const TypeInfo, void[][]))
* * * * Building type: void[][]
* * * * Final function type: { i32, i8* } (%object.TypeInfo*, { i32, { i32, i8* }* })
* * Building type: extern (C) Object(const TypeInfo_Class)
* * * DtoFunctionType(extern (C) Object(const TypeInfo_Class))
* * * * Building type: object.Object
* * * * * Building class type object.Object @ /path/to/ldc/runtime/druntime/src/object.d(89)
* * * * * * Instance size: 4
* * * * * * class type: %object.Object = type { [5 x i8*]*, i8* }
* * * * Building type: object.TypeInfo_Class
* * * * * Building class type object.TypeInfo_Class @ /path/to/ldc/runtime/druntime/src/object.d(961)
* * * * * * Instance size: 40
* * * * * * Field priority for m_init: 1
* * * * * * Field priority for name: 1
* * * * * * Field priority for vtbl: 1
* * * * * * Field priority for interfaces: 1
* * * * * * Field priority for base: 1
* * * * * * Field priority for destructor: 1
* * * * * * Field priority for classInvariant: 1
* * * * * * Field priority for m_flags: 1
* * * * * * Field priority for deallocator: 1
* * * * * * Field priority for m_offTi: 1
* * * * * * Field priority for defaultConstructor: 1
* * * * * * Field priority for m_RTInfo: 1
* * * * * * Building type: byte[]
* * * * * * * Building type: byte
Assertion failed: (llSize <= dSize && "LLVM type is bigger than the corresponding D type, " "might lead to aggregate layout mismatch."), function getMemberSize, file ../gen/llvmhelpers.cpp, line 1351.
0  ldc2                     0x0000000111936c9c llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 60
1  ldc2                     0x00000001119371e9 PrintStackTraceSignalHandler(void*) + 25
2  ldc2                     0x0000000111933139 llvm::sys::RunSignalHandlers() + 425
3  ldc2                     0x0000000111937642 SignalHandler(int) + 354
4  libsystem_platform.dylib 0x00007fffcee36b3a _sigtramp + 26
5  ldc2                     0x0000000111de7e00 cppmain(int, char**)::DL + 48
6  libsystem_c.dylib        0x00007fffcecbb420 abort + 129
7  libsystem_c.dylib        0x00007fffcec82893 basename_r + 0
8  ldc2                     0x000000010f8d8bbf getMemberSize(Type*) + 175
9  ldc2                     0x000000010f9c8dc8 AggrTypeBuilder::addAggregate(AggregateDeclaration*, std::__1::map<VarDeclaration*, llvm::Constant*, std::__1::less<VarDeclaration*>, std::__1::allocator<std::__1::pair<VarDeclaration* const, llvm::Constant*> > > const*, AggrTypeBuilder::Aliases) + 2824
10 ldc2                     0x000000010f9c82b6 AggrTypeBuilder::addAggregate(AggregateDeclaration*) + 38
11 ldc2                     0x000000010f9cc99e IrTypeClass::addClassData(AggrTypeBuilder&, ClassDeclaration*) + 414
12 ldc2                     0x000000010f9cd0f4 IrTypeClass::get(ClassDeclaration*) + 612
13 ldc2                     0x000000010f985e3e DtoType(Type*) + 958
14 ldc2                     0x000000010f9c4d0e IrFuncTyArg::IrFuncTyArg(Type*, bool, AttrBuilder) + 126
15 ldc2                     0x000000010f9c4dbc IrFuncTyArg::IrFuncTyArg(Type*, bool, AttrBuilder) + 44
16 ldc2                     0x000000010f8b9b3c DtoFunctionType(Type*, IrFuncTy&, Type*, Type*, bool, bool, bool, bool) + 3468
17 ldc2                     0x000000010f9d02ac IrTypeFunction::get(Type*) + 220
18 ldc2                     0x000000010f985e6e DtoType(Type*) + 1006
19 ldc2                     0x000000010f941ce5 createFwdDecl(LINK, Type*, llvm::ArrayRef<llvm::StringRef>, llvm::ArrayRef<Type*>, llvm::ArrayRef<unsigned long>, AttrSet) + 373
20 ldc2                     0x000000010f93208f buildRuntimeModule() + 9327
21 ldc2                     0x000000010f92fc02 initRuntime() + 50
22 ldc2                     0x000000010f8ee178 codegenModule(IRState*, Module*) + 248
23 ldc2                     0x000000010fa053ac ldc::CodeGenerator::emit(Module*) + 300
24 ldc2                     0x000000010fa53e4e codegenModules(Array<Module*>&) + 574
25 ldc2                     0x000000010f70f9c0 mars_mainBody(Array<char const*>&, Array<char const*>&) + 5120
June 20, 2017
On Tuesday, 20 June 2017 at 08:59:05 UTC, Luís Marques wrote:
> On Tuesday, 20 June 2017 at 06:52:05 UTC, Nicholas Wilson wrote:
>> What data layout is being used? Can you get clang to `-emit-llvm` and look at the resulting file 2nd line?
>>
>> should look like target datalayout = "..." .Please post the ...
>
> I was going to say that I hadn't built clang, only LLVM, but that you could find that info in the target:
>
> LLVMTargetMachine(T, "e-m:e-p:16:16-i32:16:32-a:16-n8:16", TT, CPU, FS,
>                         Options, getEffectiveRelocModel(RM), CM, OL),
>
> ...but I want to help and I was not 100% sure that was what you wanted, so I went the extra mile ;)
>
> target datalayout = "e-m:e-p:16:16-i32:16:32-a:16-n8:16"
>
>>  also please also compile with `-vv` and post the last section of diagnostics printed (warning it spits out a lot), the length of the backtrace should suffice.
>
> This is the full output for an empty .d file:
> [...]

Hmm it strikes me as odd that it handles char[] fine but not byte[].

Might want to confirm the types and sizes involved by adding:

Logger::cout() << "getMemberSize: D type " << type->toChars() << " ("<< dSize<<" bytes)" <<" LL type " << *llType <<"(" << llSize<< " bytes)\n";

(I hope I have that right to just copy & paste) between the call to

gDataLayout->getTypeAllocSize(llType);

and the assert on line 1348 of llvmhelpers.cpp



June 20, 2017
On Tuesday, 20 June 2017 at 10:52:14 UTC, Nicholas Wilson wrote:
> Might want to confirm the types and sizes involved by adding:
>
> Logger::cout() << "getMemberSize: D type " << type->toChars() << " ("<< dSize<<" bytes)" <<" LL type " << *llType <<"(" << llSize<< " bytes)\n";
>
> (I hope I have that right to just copy & paste) between the call to
>
> gDataLayout->getTypeAllocSize(llType);
>
> and the assert on line 1348 of llvmhelpers.cpp

Yup, this isn't going to fly:

* * * * * * getMemberSize: D type byte[] (4 bytes) LL type { i32, i8* }(6 bytes)

According to msp430-gcc, #define __SIZEOF_SIZE_T__ 2, so it's the LLVM side that's wrong.

Do you know where to change this?
June 20, 2017
On Tuesday, 20 June 2017 at 15:08:26 UTC, Luís Marques wrote:
> Do you know where to change this?

Found it. tollvm.cpp:260:

    t = (global.params.isLP64) ? LLType::getInt64Ty(gIR->context())
                               : LLType::getInt32Ty(gIR->context());
June 20, 2017
Hi Luís,

On 20 Jun 2017, at 16:08, Luís Marques via digitalmars-d-ldc wrote:
> According to msp430-gcc, #define __SIZEOF_SIZE_T__ 2, so it's the LLVM side that's wrong.
>
> Do you know where to change this?

DtoSize_t() in gen/tollvm.cpp.

However, note that there are currently no supported 16 bit targets (and indeed, only 32 bit and up is supported as per the D spec, although that doesn't mean it can't be usefully targeted in an embedded context), so there is a chance there are related bugs in other places.

Best,
David
June 20, 2017
On Tuesday, 20 June 2017 at 15:19:07 UTC, David Nadlinger wrote:
> However, note that there are currently no supported 16 bit targets (and indeed, only 32 bit and up is supported as per the D spec, although that doesn't mean it can't be usefully targeted in an embedded context), so there is a chance there are related bugs in other places.

Don't worry, I'll bug you guys ;-)

BTW, what part of the D spec that isn't x86 specific clashes with 16 bit? Over the years I've seen people saying that D can't be used for <32 bits, but I don't remember seeing anything in the spec that was actually a problem. Now, if we were talking about weird type sizes (9-bit chars...) that would be different.

FYI: My first quick test compiled fine (to assembly; I don't think the target supports object file generation; I have to finish assembly and linking with the gnu tools, like I did for RISC-V).
June 20, 2017
On Tuesday, 20 June 2017 at 01:51:14 UTC, Luís Marques wrote:
> In the past I used LDC for bare metal programming of a RISC-V, simply by tweaking the white list of accepted architectures. I tried to do the same for the MSP430, but in this case it seems some other things will have to be tweaked. This might be something easy for someone more familiar with the LDC/LLVM codebase, so could anyone give a helping hand here?

BTW, is there a flag to avoid trying to build Phobos and druntime, since those fail with an unsupported target?
June 20, 2017
On Tuesday, 20 June 2017 at 16:31:28 UTC, Luís Marques wrote:
> On Tuesday, 20 June 2017 at 01:51:14 UTC, Luís Marques wrote:
>> In the past I used LDC for bare metal programming of a RISC-V, simply by tweaking the white list of accepted architectures. I tried to do the same for the MSP430, but in this case it seems some other things will have to be tweaked. This might be something easy for someone more familiar with the LDC/LLVM codebase, so could anyone give a helping hand here?
>
> BTW, is there a flag to avoid trying to build Phobos and druntime, since those fail with an unsupported target?

Not the answer you are looking for ("PRs welcome" ;-), but:
does `make ldc2` do the trick?

;)
 Johan

« First   ‹ Prev
1 2 3