| Nick Kledzik | dada275 | 2010-07-27 06:24:32 +0000 | [diff] [blame] | 1 | //===-------- modsi3.S - Implement modsi3 ---------------------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #include "../assembly.h" |
| 11 | |
| 12 | // |
| 13 | // extern int32_t __modsi3(int32_t a, int32_t b); |
| 14 | // |
| 15 | // Returns the remainder when dividing two 32-bit signed integers. |
| 16 | // Conceptually, the function is: { return a - (a / b) * b; } |
| 17 | // But if you write that in C, llvm compiles it to a call to __modsi3... |
| 18 | // |
| 19 | .align 2 |
| 20 | DEFINE_COMPILERRT_FUNCTION(__modsi3) |
| 21 | push {r4, r5, r7, lr} |
| 22 | add r7, sp, #8 // set stack frame |
| 23 | mov r5, r0 // save a |
| 24 | mov r4, r1 // save b |
| 25 | bl ___divsi3 // compute a/b |
| 26 | #if __ARM_ARCH_7A__ |
| 27 | mls r0, r4, r0, r5 // mulitple result * b and subtract from a |
| 28 | #else |
| 29 | // before armv7, does not have "mls" instruction |
| 30 | mul r3, r0, r4 // multiple result * b |
| 31 | sub r0, r5, r3 // a - result |
| 32 | #endif |
| 33 | pop {r4, r5, r7, pc} |
| 34 | |
| 35 | |
| 36 | |