__mulqi3: int8 multiplication __mulhi3: int16 multiplication _exit : golobal terminator
Details
Diff Detail
Event Timeline
Build libclang_rt.builtins-avr.a for target AVR, which contains math functions, such as mulsi3, divmodsi4, mulsf3, ...
What about chip families other than avr2 (the default)? Some have a different PC pointer size (1-3 bytes, therefore affecting the ABI), some have different instructions, etc.
There are two options CMAKE_CXX_FLAGS and CMAKE_C_FLAGS can be specified when doing cmake against compiler-rt, we can specify -mmcu=avrX via them.
Since libgcc-avr has unique source code but built/distributed into several different libgcc.a files with different instruction set, I expect compiler-rt would be done in the way.
And of cource this patch just is an initial support, we still need much more patches to make it fully functional.
Initial support for a new target has a high standard. It needs to show decent support, otherwise it may just invite fixups which may in the end waste review resources.
Showing that these files buildable is far from enough. You'd need to show that the run-time tests actually work.
clang/lib/Basic/Targets/AVR.cpp | ||
---|---|---|
380 | The clang preprocessor changes are unrelated to compiler-rt and should be contribute separated with tests. |
clang/lib/Basic/Targets/AVR.cpp | ||
---|---|---|
380 | I have created another patch as you suggested, thanks. |
Could you please tell me more about show that the run-time tests actually work ? AVR is 8-bit MCU with any OS, so I just want some math functions in compiler-rt/lib/builtins, to avoid linking to libgcc.a.
I have checked that there are tests at compiler-rt/test/builtins/Unit/arm, and I guess them to be run on a ARM host. So I have to make a new directory compiler-rt/test/builtins/Unit/avr with some test cases, and promiss that they can run on an AVR board? (https://www.arduino.cc/en/hardware#boards-1)
I added three functions
__mulqi3: int8 multiplication __mulhi3: int16 multiplication _exit : golobal terminator
All of them are contained in libgcc and are necessary.
Some key points,
- The functions are written in the minimal avrtiny instruction set, so they should be compatible for all devices.
- We build them to higher/upper AVR ELF files by specifying CMAKE_CXX_FLAGS and CMAKE_C_FLAGS when doing cmake.
- I have refered to libgcc, but not simply copy. Actually my implementation is shorter than libgcc's, but may cost more cycles. However this is something about tradeoff.
- I have tested against avr hardware multiplier, the results are all the same on ArduinoNano (atmega328).
- My test program locates at https://github.com/benshi001/avr-test/blob/main/mul_int16_int8.ino, I only added 300 pairs of random numbers as test cases, due to the limitation of my device (atmega328 has only 2KB SRAM, more test cases will lead to too large data section). Acutally I have tested 900 pairs.
compiler-rt/cmake/Modules/CompilerRTUtils.cmake | ||
---|---|---|
171 | Keep the list in alphabetical order. Move avr to the beginning. Ignore some entries which are unordered. | |
216 | Keep the list in alphabetical order. Move avr to the beginning. Ignore some entries which are unordered. | |
compiler-rt/cmake/builtin-config-ix.cmake | ||
55 | Keep the list in alphabetical order. Move avr to the beginning. Ignore some entries which are unordered. | |
compiler-rt/lib/builtins/CMakeLists.txt | ||
671 | Keep the *_SOURCES in alphabetical order. Move avr to the beginning. Ignore some entries which are unordered. |
compiler-rt/lib/builtins/CMakeLists.txt | ||
---|---|---|
671 | I will fix all your concerns about "alphabetical order" when committing. |
@benshi001 I have been looking through the GCC code and I think avr-gcc also has a special calling convention for many other functions, including __mulqi3 and __mulhi3.
Source:
- I think this is where the ABI is specified in the compiler: https://github.com/gcc-mirror/gcc/blob/releases/gcc-5.4.0/gcc/config/avr/avr.md#L1543-L1549 You can see that it multiplies R24 with R22 and stores the result in R24, and clobbers R22 in the process. But no other registers.
- In this code sample, avr-gcc doesn't save char c (r20) across the __mulqi3 and __mulhi3 calls, which is normally call-clobbered.
Therefore, I think we need to be a bit more careful with defining these AVR builtins and check the ABI in avr-gcc first.
Also, we can make use of this and optimize the AVR backend more (you can see that the Clang generated code is much worse than avr-gcc in the above examples).
The clang preprocessor changes are unrelated to compiler-rt and should be contribute separated with tests.