Thread overview | |||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 20, 2017 LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
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 Re: LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | 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 Re: LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | 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 Re: LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | 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 Re: LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: LDC with MSP430 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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
|
Copyright © 1999-2021 by the D Language Foundation