1*d69aaee6Sguenther/* $OpenBSD: divsi3.S,v 1.6 2022/05/24 17:19:46 guenther Exp $ */ 2d987040fSdrahn/* $NetBSD: divsi3.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $ */ 3d987040fSdrahn 4d987040fSdrahn/* 5d987040fSdrahn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 6d987040fSdrahn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 7d987040fSdrahn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 8d987040fSdrahn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 9d987040fSdrahn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 10d987040fSdrahn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 11d987040fSdrahn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 12d987040fSdrahn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 13d987040fSdrahn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 14d987040fSdrahn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 15d987040fSdrahn * SUCH DAMAGE. 16d987040fSdrahn */ 17d987040fSdrahn 1838848718Sguenther#include "DEFS.h" 19d987040fSdrahn 20d987040fSdrahn/* 21d987040fSdrahn * stack is aligned as there's a possibility of branching to .L_overflow 22d987040fSdrahn * which makes a C call 23d987040fSdrahn */ 24d987040fSdrahn 25d987040fSdrahnENTRY(__umodsi3) 26d987040fSdrahn stmfd sp!, {lr} 27d987040fSdrahn sub sp, sp, #4 /* align stack */ 28d987040fSdrahn bl .L_udivide 29d987040fSdrahn add sp, sp, #4 /* unalign stack */ 30d987040fSdrahn mov r0, r1 31d987040fSdrahn ldmfd sp!, {pc} 32*d69aaee6SguentherEND(__umodsi3) 33d987040fSdrahn 34d987040fSdrahnENTRY(__modsi3) 35d987040fSdrahn stmfd sp!, {lr} 36d987040fSdrahn sub sp, sp, #4 /* align stack */ 37d987040fSdrahn bl .L_divide 38d987040fSdrahn add sp, sp, #4 /* unalign stack */ 39d987040fSdrahn mov r0, r1 40d987040fSdrahn ldmfd sp!, {pc} 41*d69aaee6SguentherEND(__modsi3) 42d987040fSdrahn 43d987040fSdrahn.L_overflow: 44d987040fSdrahn#if !defined(_KERNEL) && !defined(_STANDALONE) 45d987040fSdrahn mov r0, #8 /* SIGFPE */ 4638848718Sguenther bl _HIDDEN(raise) /* raise it */ 47d987040fSdrahn mov r0, #0 48d987040fSdrahn#else 49d987040fSdrahn /* XXX should cause a fatal error */ 50d987040fSdrahn mvn r0, #0 51d987040fSdrahn#endif 52d987040fSdrahn mov pc, lr 53d987040fSdrahn 54d987040fSdrahnENTRY(__udivsi3) 55d987040fSdrahn.L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */ 56d987040fSdrahn eor r0, r1, r0 57d987040fSdrahn eor r1, r0, r1 58d987040fSdrahn eor r0, r1, r0 59d987040fSdrahn /* r0 = r1 / r0; r1 = r1 % r0 */ 60d987040fSdrahn cmp r0, #1 61d987040fSdrahn bcc .L_overflow 62d987040fSdrahn beq .L_divide_l0 63d987040fSdrahn mov ip, #0 64d987040fSdrahn movs r1, r1 65d987040fSdrahn bpl .L_divide_l1 66d987040fSdrahn orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */ 67d987040fSdrahn movs r1, r1, lsr #1 68d987040fSdrahn orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */ 69d987040fSdrahn b .L_divide_l1 70d987040fSdrahn 71d987040fSdrahn.L_divide_l0: /* r0 == 1 */ 72d987040fSdrahn mov r0, r1 73d987040fSdrahn mov r1, #0 74d987040fSdrahn mov pc, lr 75*d69aaee6SguentherEND(__udivsi3) 76d987040fSdrahn 77d987040fSdrahnENTRY(__divsi3) 78d987040fSdrahn.L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */ 79d987040fSdrahn eor r0, r1, r0 80d987040fSdrahn eor r1, r0, r1 81d987040fSdrahn eor r0, r1, r0 82d987040fSdrahn /* r0 = r1 / r0; r1 = r1 % r0 */ 83d987040fSdrahn cmp r0, #1 84d987040fSdrahn bcc .L_overflow 85d987040fSdrahn beq .L_divide_l0 86d987040fSdrahn ands ip, r0, #0x80000000 87d987040fSdrahn rsbmi r0, r0, #0 88d987040fSdrahn ands r2, r1, #0x80000000 89d987040fSdrahn eor ip, ip, r2 90d987040fSdrahn rsbmi r1, r1, #0 91d987040fSdrahn orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */ 92d987040fSdrahn /* ip bit 0x80000000 = -ve remainder */ 93d987040fSdrahn 94d987040fSdrahn.L_divide_l1: 95d987040fSdrahn mov r2, #1 96d987040fSdrahn mov r3, #0 97d987040fSdrahn 98d987040fSdrahn /* 99d987040fSdrahn * If the highest bit of the dividend is set, we have to be 100d987040fSdrahn * careful when shifting the divisor. Test this. 101d987040fSdrahn */ 102d987040fSdrahn movs r1,r1 103d987040fSdrahn bpl .L_old_code 104d987040fSdrahn 105d987040fSdrahn /* 106d987040fSdrahn * At this point, the highest bit of r1 is known to be set. 107d987040fSdrahn * We abuse this below in the tst instructions. 108d987040fSdrahn */ 109d987040fSdrahn tst r1, r0 /*, lsl #0 */ 110d987040fSdrahn bmi .L_divide_b1 111d987040fSdrahn tst r1, r0, lsl #1 112d987040fSdrahn bmi .L_divide_b2 113d987040fSdrahn tst r1, r0, lsl #2 114d987040fSdrahn bmi .L_divide_b3 115d987040fSdrahn tst r1, r0, lsl #3 116d987040fSdrahn bmi .L_divide_b4 117d987040fSdrahn tst r1, r0, lsl #4 118d987040fSdrahn bmi .L_divide_b5 119d987040fSdrahn tst r1, r0, lsl #5 120d987040fSdrahn bmi .L_divide_b6 121d987040fSdrahn tst r1, r0, lsl #6 122d987040fSdrahn bmi .L_divide_b7 123d987040fSdrahn tst r1, r0, lsl #7 124d987040fSdrahn bmi .L_divide_b8 125d987040fSdrahn tst r1, r0, lsl #8 126d987040fSdrahn bmi .L_divide_b9 127d987040fSdrahn tst r1, r0, lsl #9 128d987040fSdrahn bmi .L_divide_b10 129d987040fSdrahn tst r1, r0, lsl #10 130d987040fSdrahn bmi .L_divide_b11 131d987040fSdrahn tst r1, r0, lsl #11 132d987040fSdrahn bmi .L_divide_b12 133d987040fSdrahn tst r1, r0, lsl #12 134d987040fSdrahn bmi .L_divide_b13 135d987040fSdrahn tst r1, r0, lsl #13 136d987040fSdrahn bmi .L_divide_b14 137d987040fSdrahn tst r1, r0, lsl #14 138d987040fSdrahn bmi .L_divide_b15 139d987040fSdrahn tst r1, r0, lsl #15 140d987040fSdrahn bmi .L_divide_b16 141d987040fSdrahn tst r1, r0, lsl #16 142d987040fSdrahn bmi .L_divide_b17 143d987040fSdrahn tst r1, r0, lsl #17 144d987040fSdrahn bmi .L_divide_b18 145d987040fSdrahn tst r1, r0, lsl #18 146d987040fSdrahn bmi .L_divide_b19 147d987040fSdrahn tst r1, r0, lsl #19 148d987040fSdrahn bmi .L_divide_b20 149d987040fSdrahn tst r1, r0, lsl #20 150d987040fSdrahn bmi .L_divide_b21 151d987040fSdrahn tst r1, r0, lsl #21 152d987040fSdrahn bmi .L_divide_b22 153d987040fSdrahn tst r1, r0, lsl #22 154d987040fSdrahn bmi .L_divide_b23 155d987040fSdrahn tst r1, r0, lsl #23 156d987040fSdrahn bmi .L_divide_b24 157d987040fSdrahn tst r1, r0, lsl #24 158d987040fSdrahn bmi .L_divide_b25 159d987040fSdrahn tst r1, r0, lsl #25 160d987040fSdrahn bmi .L_divide_b26 161d987040fSdrahn tst r1, r0, lsl #26 162d987040fSdrahn bmi .L_divide_b27 163d987040fSdrahn tst r1, r0, lsl #27 164d987040fSdrahn bmi .L_divide_b28 165d987040fSdrahn tst r1, r0, lsl #28 166d987040fSdrahn bmi .L_divide_b29 167d987040fSdrahn tst r1, r0, lsl #29 168d987040fSdrahn bmi .L_divide_b30 169d987040fSdrahn tst r1, r0, lsl #30 170d987040fSdrahn bmi .L_divide_b31 171d987040fSdrahn/* 172d987040fSdrahn * instead of: 173d987040fSdrahn * tst r1, r0, lsl #31 174d987040fSdrahn * bmi .L_divide_b32 175d987040fSdrahn */ 176d987040fSdrahn b .L_divide_b32 177d987040fSdrahn 178d987040fSdrahn.L_old_code: 179d987040fSdrahn cmp r1, r0 180d987040fSdrahn bcc .L_divide_b0 181d987040fSdrahn cmp r1, r0, lsl #1 182d987040fSdrahn bcc .L_divide_b1 183d987040fSdrahn cmp r1, r0, lsl #2 184d987040fSdrahn bcc .L_divide_b2 185d987040fSdrahn cmp r1, r0, lsl #3 186d987040fSdrahn bcc .L_divide_b3 187d987040fSdrahn cmp r1, r0, lsl #4 188d987040fSdrahn bcc .L_divide_b4 189d987040fSdrahn cmp r1, r0, lsl #5 190d987040fSdrahn bcc .L_divide_b5 191d987040fSdrahn cmp r1, r0, lsl #6 192d987040fSdrahn bcc .L_divide_b6 193d987040fSdrahn cmp r1, r0, lsl #7 194d987040fSdrahn bcc .L_divide_b7 195d987040fSdrahn cmp r1, r0, lsl #8 196d987040fSdrahn bcc .L_divide_b8 197d987040fSdrahn cmp r1, r0, lsl #9 198d987040fSdrahn bcc .L_divide_b9 199d987040fSdrahn cmp r1, r0, lsl #10 200d987040fSdrahn bcc .L_divide_b10 201d987040fSdrahn cmp r1, r0, lsl #11 202d987040fSdrahn bcc .L_divide_b11 203d987040fSdrahn cmp r1, r0, lsl #12 204d987040fSdrahn bcc .L_divide_b12 205d987040fSdrahn cmp r1, r0, lsl #13 206d987040fSdrahn bcc .L_divide_b13 207d987040fSdrahn cmp r1, r0, lsl #14 208d987040fSdrahn bcc .L_divide_b14 209d987040fSdrahn cmp r1, r0, lsl #15 210d987040fSdrahn bcc .L_divide_b15 211d987040fSdrahn cmp r1, r0, lsl #16 212d987040fSdrahn bcc .L_divide_b16 213d987040fSdrahn cmp r1, r0, lsl #17 214d987040fSdrahn bcc .L_divide_b17 215d987040fSdrahn cmp r1, r0, lsl #18 216d987040fSdrahn bcc .L_divide_b18 217d987040fSdrahn cmp r1, r0, lsl #19 218d987040fSdrahn bcc .L_divide_b19 219d987040fSdrahn cmp r1, r0, lsl #20 220d987040fSdrahn bcc .L_divide_b20 221d987040fSdrahn cmp r1, r0, lsl #21 222d987040fSdrahn bcc .L_divide_b21 223d987040fSdrahn cmp r1, r0, lsl #22 224d987040fSdrahn bcc .L_divide_b22 225d987040fSdrahn cmp r1, r0, lsl #23 226d987040fSdrahn bcc .L_divide_b23 227d987040fSdrahn cmp r1, r0, lsl #24 228d987040fSdrahn bcc .L_divide_b24 229d987040fSdrahn cmp r1, r0, lsl #25 230d987040fSdrahn bcc .L_divide_b25 231d987040fSdrahn cmp r1, r0, lsl #26 232d987040fSdrahn bcc .L_divide_b26 233d987040fSdrahn cmp r1, r0, lsl #27 234d987040fSdrahn bcc .L_divide_b27 235d987040fSdrahn cmp r1, r0, lsl #28 236d987040fSdrahn bcc .L_divide_b28 237d987040fSdrahn cmp r1, r0, lsl #29 238d987040fSdrahn bcc .L_divide_b29 239d987040fSdrahn cmp r1, r0, lsl #30 240d987040fSdrahn bcc .L_divide_b30 241d987040fSdrahn.L_divide_b32: 242d987040fSdrahn cmp r1, r0, lsl #31 243d987040fSdrahn subhs r1, r1,r0, lsl #31 244d987040fSdrahn addhs r3, r3,r2, lsl #31 245d987040fSdrahn.L_divide_b31: 246d987040fSdrahn cmp r1, r0, lsl #30 247d987040fSdrahn subhs r1, r1,r0, lsl #30 248d987040fSdrahn addhs r3, r3,r2, lsl #30 249d987040fSdrahn.L_divide_b30: 250d987040fSdrahn cmp r1, r0, lsl #29 251d987040fSdrahn subhs r1, r1,r0, lsl #29 252d987040fSdrahn addhs r3, r3,r2, lsl #29 253d987040fSdrahn.L_divide_b29: 254d987040fSdrahn cmp r1, r0, lsl #28 255d987040fSdrahn subhs r1, r1,r0, lsl #28 256d987040fSdrahn addhs r3, r3,r2, lsl #28 257d987040fSdrahn.L_divide_b28: 258d987040fSdrahn cmp r1, r0, lsl #27 259d987040fSdrahn subhs r1, r1,r0, lsl #27 260d987040fSdrahn addhs r3, r3,r2, lsl #27 261d987040fSdrahn.L_divide_b27: 262d987040fSdrahn cmp r1, r0, lsl #26 263d987040fSdrahn subhs r1, r1,r0, lsl #26 264d987040fSdrahn addhs r3, r3,r2, lsl #26 265d987040fSdrahn.L_divide_b26: 266d987040fSdrahn cmp r1, r0, lsl #25 267d987040fSdrahn subhs r1, r1,r0, lsl #25 268d987040fSdrahn addhs r3, r3,r2, lsl #25 269d987040fSdrahn.L_divide_b25: 270d987040fSdrahn cmp r1, r0, lsl #24 271d987040fSdrahn subhs r1, r1,r0, lsl #24 272d987040fSdrahn addhs r3, r3,r2, lsl #24 273d987040fSdrahn.L_divide_b24: 274d987040fSdrahn cmp r1, r0, lsl #23 275d987040fSdrahn subhs r1, r1,r0, lsl #23 276d987040fSdrahn addhs r3, r3,r2, lsl #23 277d987040fSdrahn.L_divide_b23: 278d987040fSdrahn cmp r1, r0, lsl #22 279d987040fSdrahn subhs r1, r1,r0, lsl #22 280d987040fSdrahn addhs r3, r3,r2, lsl #22 281d987040fSdrahn.L_divide_b22: 282d987040fSdrahn cmp r1, r0, lsl #21 283d987040fSdrahn subhs r1, r1,r0, lsl #21 284d987040fSdrahn addhs r3, r3,r2, lsl #21 285d987040fSdrahn.L_divide_b21: 286d987040fSdrahn cmp r1, r0, lsl #20 287d987040fSdrahn subhs r1, r1,r0, lsl #20 288d987040fSdrahn addhs r3, r3,r2, lsl #20 289d987040fSdrahn.L_divide_b20: 290d987040fSdrahn cmp r1, r0, lsl #19 291d987040fSdrahn subhs r1, r1,r0, lsl #19 292d987040fSdrahn addhs r3, r3,r2, lsl #19 293d987040fSdrahn.L_divide_b19: 294d987040fSdrahn cmp r1, r0, lsl #18 295d987040fSdrahn subhs r1, r1,r0, lsl #18 296d987040fSdrahn addhs r3, r3,r2, lsl #18 297d987040fSdrahn.L_divide_b18: 298d987040fSdrahn cmp r1, r0, lsl #17 299d987040fSdrahn subhs r1, r1,r0, lsl #17 300d987040fSdrahn addhs r3, r3,r2, lsl #17 301d987040fSdrahn.L_divide_b17: 302d987040fSdrahn cmp r1, r0, lsl #16 303d987040fSdrahn subhs r1, r1,r0, lsl #16 304d987040fSdrahn addhs r3, r3,r2, lsl #16 305d987040fSdrahn.L_divide_b16: 306d987040fSdrahn cmp r1, r0, lsl #15 307d987040fSdrahn subhs r1, r1,r0, lsl #15 308d987040fSdrahn addhs r3, r3,r2, lsl #15 309d987040fSdrahn.L_divide_b15: 310d987040fSdrahn cmp r1, r0, lsl #14 311d987040fSdrahn subhs r1, r1,r0, lsl #14 312d987040fSdrahn addhs r3, r3,r2, lsl #14 313d987040fSdrahn.L_divide_b14: 314d987040fSdrahn cmp r1, r0, lsl #13 315d987040fSdrahn subhs r1, r1,r0, lsl #13 316d987040fSdrahn addhs r3, r3,r2, lsl #13 317d987040fSdrahn.L_divide_b13: 318d987040fSdrahn cmp r1, r0, lsl #12 319d987040fSdrahn subhs r1, r1,r0, lsl #12 320d987040fSdrahn addhs r3, r3,r2, lsl #12 321d987040fSdrahn.L_divide_b12: 322d987040fSdrahn cmp r1, r0, lsl #11 323d987040fSdrahn subhs r1, r1,r0, lsl #11 324d987040fSdrahn addhs r3, r3,r2, lsl #11 325d987040fSdrahn.L_divide_b11: 326d987040fSdrahn cmp r1, r0, lsl #10 327d987040fSdrahn subhs r1, r1,r0, lsl #10 328d987040fSdrahn addhs r3, r3,r2, lsl #10 329d987040fSdrahn.L_divide_b10: 330d987040fSdrahn cmp r1, r0, lsl #9 331d987040fSdrahn subhs r1, r1,r0, lsl #9 332d987040fSdrahn addhs r3, r3,r2, lsl #9 333d987040fSdrahn.L_divide_b9: 334d987040fSdrahn cmp r1, r0, lsl #8 335d987040fSdrahn subhs r1, r1,r0, lsl #8 336d987040fSdrahn addhs r3, r3,r2, lsl #8 337d987040fSdrahn.L_divide_b8: 338d987040fSdrahn cmp r1, r0, lsl #7 339d987040fSdrahn subhs r1, r1,r0, lsl #7 340d987040fSdrahn addhs r3, r3,r2, lsl #7 341d987040fSdrahn.L_divide_b7: 342d987040fSdrahn cmp r1, r0, lsl #6 343d987040fSdrahn subhs r1, r1,r0, lsl #6 344d987040fSdrahn addhs r3, r3,r2, lsl #6 345d987040fSdrahn.L_divide_b6: 346d987040fSdrahn cmp r1, r0, lsl #5 347d987040fSdrahn subhs r1, r1,r0, lsl #5 348d987040fSdrahn addhs r3, r3,r2, lsl #5 349d987040fSdrahn.L_divide_b5: 350d987040fSdrahn cmp r1, r0, lsl #4 351d987040fSdrahn subhs r1, r1,r0, lsl #4 352d987040fSdrahn addhs r3, r3,r2, lsl #4 353d987040fSdrahn.L_divide_b4: 354d987040fSdrahn cmp r1, r0, lsl #3 355d987040fSdrahn subhs r1, r1,r0, lsl #3 356d987040fSdrahn addhs r3, r3,r2, lsl #3 357d987040fSdrahn.L_divide_b3: 358d987040fSdrahn cmp r1, r0, lsl #2 359d987040fSdrahn subhs r1, r1,r0, lsl #2 360d987040fSdrahn addhs r3, r3,r2, lsl #2 361d987040fSdrahn.L_divide_b2: 362d987040fSdrahn cmp r1, r0, lsl #1 363d987040fSdrahn subhs r1, r1,r0, lsl #1 364d987040fSdrahn addhs r3, r3,r2, lsl #1 365d987040fSdrahn.L_divide_b1: 366d987040fSdrahn cmp r1, r0 367d987040fSdrahn subhs r1, r1, r0 368d987040fSdrahn addhs r3, r3, r2 369d987040fSdrahn.L_divide_b0: 370d987040fSdrahn 371d987040fSdrahn tst ip, #0x20000000 372d987040fSdrahn bne .L_udivide_l1 373d987040fSdrahn mov r0, r3 374d987040fSdrahn cmp ip, #0 375d987040fSdrahn rsbmi r1, r1, #0 376d987040fSdrahn movs ip, ip, lsl #1 377d987040fSdrahn bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */ 378d987040fSdrahn rsbmi r0, r0, #0 379d987040fSdrahn mov pc, lr 380d987040fSdrahn 381d987040fSdrahn.L_udivide_l1: 382d987040fSdrahn tst ip, #0x10000000 383d987040fSdrahn mov r1, r1, lsl #1 384d987040fSdrahn orrne r1, r1, #1 385d987040fSdrahn mov r3, r3, lsl #1 386d987040fSdrahn cmp r1, r0 387d987040fSdrahn subhs r1, r1, r0 388d987040fSdrahn addhs r3, r3, r2 389d987040fSdrahn mov r0, r3 390d987040fSdrahn mov pc, lr 391*d69aaee6SguentherEND(__divsi3) 39253490952Skettenis 39353490952SkettenisSTRONG_ALIAS(__aeabi_idiv, __divsi3) 39453490952SkettenisSTRONG_ALIAS(__aeabi_idivmod, __divsi3) 39553490952SkettenisSTRONG_ALIAS(__aeabi_uidiv, __udivsi3) 39653490952SkettenisSTRONG_ALIAS(__aeabi_uidivmod, __udivsi3) 39700b6e344Sguenther 39800b6e344Sguenther .protected __aeabi_idiv, __aeabi_idivmod 39900b6e344Sguenther .protected __aeabi_uidiv, __aeabi_uidivmod 400