avr-llvm / llvm

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

[AVR] Fix function call for 8-bit division. #74

Closed simonpcook closed 9 years ago

simonpcook commented 9 years ago

This patch fixes the case described in bug #70. If any other functions have a similar issue, setLibCallName can also be used to substitute these for the correct versions.

dylanmckay commented 9 years ago

I don't think the __udivqi3 function has the same signature as __divmodhi4.

The q in qi3 stands for "quarter-integer" (integer being 4 bytes), so this function is for dividing one byte by another. The h in hi4 stands for "half-integer", and so this function operates on two 16-bit values.

Also, the __udivqi3 function performs division and returns the result as a primitive type. The __divmodhi4 function performs division and modulus, returning the result as a struct containing the division result, and the remainder, as two separate 16-bit fields.

It may be possible to instead call setLibcallName(RTLIB::UDIVREM_I16, "__divmodhi4"), because this would be the appropriate libcall for the operation, but the question is that will LLVM lower a division operation to a call to RTLIB::UDIV_I16 or RTLIB::UDIVREM_16?

AVR-GCC's runtime library does not have functions which compute only the result of division or the modulus seperately, they only have the combined __divmod functions which return both.

We need a way of telling LLVM that the RTLIB::UDIV_I16 and RTLIB::UREM_I16 functions are not implemented, so that it can try and fallback to RTLIB::UDIVMOD_I16.

simonpcook commented 9 years ago

Aah got it, I read the bug report and misinterpreted it as a simple case of calling the wrong function (though the h/q should have indicated to me sooner it wasn't).

I shall look then at a patch for the legalizer (most likely custom lowering that divide) to allow us to make that connection then.