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