avr-llvm / llvm

[MERGED UPSTREAM] AVR backend for the LLVM compiler library
220 stars 21 forks source link

Division operations are being incorrectly lowered #70

Closed dylanmckay closed 9 years ago

dylanmckay commented 9 years ago

We are not handling the lowering of various instructions correctly.

This problem came about in this mailing list exchange.

Division is being lowered into a call to the libgcc function __udivqi3. This function does not exist. GCC instead lowers this to __divmodhi4, which is what we should be doing.

dylanmckay commented 9 years ago

We should be able to handle this by adding a case to the switch in AVRISelLowering::LowerOperation(). As @simonpcook said, custom lowering the divide may be the best solution.

See the ARMISelLowering::LowerOperation() for an example.

dylanmckay commented 9 years ago

Note that a number of the compiler runtime library functions do not follow the normal AVR ABI.

See the avr-gcc wiki, heading "Exceptions to the calling convention" for details.

dylanmckay commented 9 years ago

I believe the best way would be to create a custom calling convention which special cases all of the routines from the AVR-GCC wiki which do not follow the standard convention. This way libcalls would work as expected.

dylanmckay commented 9 years ago

I have implemented 8 and 16-bit division using custom lowering.

We cannot custom lower a 32-bit (or greater) values because the type is illegal. I am not sure how to go about this.

agnat commented 9 years ago

The follow-up is #149.

We cannot custom lower a 32-bit (or greater) values because the type is illegal. I am not sure how to go about this.

Hehe... The whole concept of "legal types" is ... I wouldn't say flawed... but it just doesn't cut it for small targets. It is exactly what I'm trying to hack up to get rid of the pseudo instructions. If I succeed handling the division library calls shouldn't be a problem.