How to add new target?

Hi all,
First, since it’s my first post here, I’d like to say hello!

I’ve started to write LLVM backend for our processor some time ago and I can produce correct (most of the time :wink: ) code.
What I need now, is to add my target processor to cfe - I’ve already added a class to lib/Basic/Targets.cpp.

Could anyone write in points what should be done in Clang to add new target support (especially target specific builtins) and how to force clang to act as a cross-compiler?
Thanks a lot for your help

Artur

Hi all,
so after “greping” the code I was able to do (more or less) everything I wanted to do.

Cheers,
Artur

Hi Artur,

Hi all,
First, since it's my first post here, I'd like to say hello!

I've started to write LLVM backend for our processor some time ago and I
can produce correct (most of the time :wink: ) code.
What I need now, is to add my target processor to cfe - I've already added
a class to lib/Basic/Targets.cpp.

Could anyone write in points what should be done in Clang to add new
target support (especially target specific builtins) and how to force clang
to act as a cross-compiler?
Thanks a lot for your help

Artur

Hi all,
so after "greping" the code I was able to do (more or less) everything I
wanted to do.

As you have discovered, this stuff isn't very well documented yet. Do
you feel like writing up a blurb we could add to our Internals Manual
describing what you have discovered?

- Daniel

Hi Artur,

Hi Daniel

Hi all,
so after “greping” the code I was able to do (more or less) everything I
wanted to do.

As you have discovered, this stuff isn’t very well documented yet. Do
you feel like writing up a blurb we could add to our Internals Manual
describing what you have discovered?

I’ll try when I’ll make it work correct :wink:

BTW I’ve noticed strange behaviour. When I switched from llvm-gcc to clang, my benchmarks stopped working. When I compile simple code:

char array[] = “+0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz”;

int main() {
return array[31];
}

like this:
clang -ccc-host-triple mycpu -O0 -S hello.c -o hello.s

The code is wrong, to be precise in one instruction I get
lbs $r16 = 0[$r17] instead of lbs $r16 = 31[$r17]

but the code is correct when I do it like this:
clang -ccc-host-triple mycpu -O0 hello.c -c -emit-llvm -o hello.bc
llc -march=mycpu hello.bc -o hello.s

Am I missing something? Shouldn’t these two be equivalent?
Thanks in advance.

Artur

Hi Artur,

Hi Daniel

> Hi all,
> so after "greping" the code I was able to do (more or less) everything I
> wanted to do.

As you have discovered, this stuff isn't very well documented yet. Do
you feel like writing up a blurb we could add to our Internals Manual
describing what you have discovered?

I'll try when I'll make it work correct :wink:

BTW I've noticed strange behaviour. When I switched from llvm-gcc to clang,
my benchmarks stopped working. When I compile simple code:

char array[] =
"+0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";

int main() {
return array[31];
}

like this:
clang -ccc-host-triple mycpu -O0 -S hello.c -o hello.s

The code is wrong, to be precise in one instruction I get
lbs $r16 = 0[$r17] instead of lbs $r16 = 31[$r17]

but the code is correct when I do it like this:
clang -ccc-host-triple mycpu -O0 hello.c -c -emit-llvm -o hello.bc
llc -march=mycpu hello.bc -o hello.s

Am I missing something? Shouldn't these two be equivalent?

Unfortunately, no. The driver sets a variety of options in the LLVM
backend that you would need to pass to llc by hand. Try running
$ clang -ccc-host-triple mycpu -O0 hello.c -c -emit-llvm -o hello.bc -###
to see how clang is calling the compiler (clang -cc1), and look for -m
arguments. For example, -mcpu sets the CPU to target, and other -m
options do things like disable use of a frame pointer.

- Daniel

Thanks for advice, there was a bug in relocation in my backend and indeed clang was triggering it by passing different options than llc.

Now I’m trying to find another bug. I don’t know why I’m ending up with reg to reg copy from 64bit to 32bit register class but only using clang and turned on optimization (when i compile with llvm-gcc or again with clang to bitcode and then using llc the problem does not occur).
I’ve tried to change options given to compiler, but this changes nothing.
The code I try to compile has castings from i8* to i64*.
Any ideas what could trigger that?
Is there a way to force clang to dump debug information similar to “llc -debug”?

Once more, thanks for your help!
Artur

So forget about that 64bit to 32bit question. It was a bug in conditional branch implementation.

But still, is there a way to produce the debug output with clang as with llc?

Thanks

>> Hi Artur,
>
> Hi Daniel
>
>>
>> > Hi all,
>> > so after "greping" the code I was able to do (more or less)
>> > everything I
>> > wanted to do.
>>
>> As you have discovered, this stuff isn't very well documented yet. Do
>> you feel like writing up a blurb we could add to our Internals Manual
>> describing what you have discovered?
>
> I'll try when I'll make it work correct :wink:
>
> BTW I've noticed strange behaviour. When I switched from llvm-gcc to
> clang,
> my benchmarks stopped working. When I compile simple code:
>
> char array[] =
> "+0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
>
> int main() {
> return array[31];
> }
>
> like this:
> clang -ccc-host-triple mycpu -O0 -S hello.c -o hello.s
>
> The code is wrong, to be precise in one instruction I get
> lbs $r16 = 0[$r17] instead of lbs $r16 = 31[$r17]
>
> but the code is correct when I do it like this:
> clang -ccc-host-triple mycpu -O0 hello.c -c -emit-llvm -o hello.bc
> llc -march=mycpu hello.bc -o hello.s
>
>
> Am I missing something? Shouldn't these two be equivalent?

Unfortunately, no. The driver sets a variety of options in the LLVM
backend that you would need to pass to llc by hand. Try running
$ clang -ccc-host-triple mycpu -O0 hello.c -c -emit-llvm -o hello.bc -###
to see how clang is calling the compiler (clang -cc1), and look for -m
arguments. For example, -mcpu sets the CPU to target, and other -m
options do things like disable use of a frame pointer.

- Daniel

Thanks for advice, there was a bug in relocation in my backend and indeed
clang was triggering it by passing different options than llc.

Now I'm trying to find another bug. I don't know why I'm ending up with
reg to reg copy from 64bit to 32bit register class but only using clang and
turned on optimization (when i compile with llvm-gcc or again with clang to
bitcode and then using llc the problem does not occur).
I've tried to change options given to compiler, but this changes nothing.
The code I try to compile has castings from i8* to i64*.
Any ideas what could trigger that?
Is there a way to force clang to dump debug information similar to "llc
-debug"?

So forget about that 64bit to 32bit question. It was a bug in conditional
branch implementation.

But still, is there a way to produce the debug output with clang as with
llc?

Not currently, no. At the moment clang doesn't expose a way to pass
arbitrary options to LLVM's CommandLine module, which is how a lot of
the backend tools get those extra options. You can file a bug for this
if you like, its been on my list to add or think about.

- Daniel