Annotation of funnyos/libkern/divsi3.S, Revision 1.1
1.1 ! init 1: /* $Id: divsi3.S,v 1.1.1.1 2007/10/12 08:40:42 init Exp $ */
! 2: /* $OpenBSD: divsi3.S,v 1.2 2004/02/01 05:47:10 drahn Exp $ */
! 3: /* $NetBSD: divsi3.S,v 1.2 2001/11/13 20:06:40 chris Exp $ */
! 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 <libkern/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: #if 0
! 53: bl PIC_SYM(_C_LABEL(raise), PLT) /* raise it */
! 54: #endif
! 55: mov r0, #0
! 56: #else
! 57: /* XXX should cause a fatal error */
! 58: mvn r0, #0
! 59: #endif
! 60: #ifdef __APCS_26__
! 61: movs pc, lr
! 62: #else
! 63: mov pc, lr
! 64: #endif
! 65:
! 66: ENTRY(__udivsi3)
! 67: L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */
! 68: eor r0, r1, r0
! 69: eor r1, r0, r1
! 70: eor r0, r1, r0
! 71: /* r0 = r1 / r0; r1 = r1 % r0 */
! 72: cmp r0, #1
! 73: bcc L_overflow
! 74: beq L_divide_l0
! 75: mov ip, #0
! 76: movs r1, r1
! 77: bpl L_divide_l1
! 78: orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
! 79: movs r1, r1, lsr #1
! 80: orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
! 81: b L_divide_l1
! 82:
! 83: L_divide_l0: /* r0 == 1 */
! 84: mov r0, r1
! 85: mov r1, #0
! 86: #ifdef __APCS_26__
! 87: movs pc, lr
! 88: #else
! 89: mov pc, lr
! 90: #endif
! 91:
! 92: ENTRY(__divsi3)
! 93: L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */
! 94: eor r0, r1, r0
! 95: eor r1, r0, r1
! 96: eor r0, r1, r0
! 97: /* r0 = r1 / r0; r1 = r1 % r0 */
! 98: cmp r0, #1
! 99: bcc L_overflow
! 100: beq L_divide_l0
! 101: ands ip, r0, #0x80000000
! 102: rsbmi r0, r0, #0
! 103: ands r2, r1, #0x80000000
! 104: eor ip, ip, r2
! 105: rsbmi r1, r1, #0
! 106: orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
! 107: /* ip bit 0x80000000 = -ve remainder */
! 108:
! 109: L_divide_l1:
! 110: mov r2, #1
! 111: mov r3, #0
! 112:
! 113: /*
! 114: * If the highest bit of the dividend is set, we have to be
! 115: * careful when shifting the divisor. Test this.
! 116: */
! 117: movs r1,r1
! 118: bpl L_old_code
! 119:
! 120: /*
! 121: * At this point, the highest bit of r1 is known to be set.
! 122: * We abuse this below in the tst instructions.
! 123: */
! 124: tst r1, r0 /*, lsl #0 */
! 125: bmi L_divide_b1
! 126: tst r1, r0, lsl #1
! 127: bmi L_divide_b2
! 128: tst r1, r0, lsl #2
! 129: bmi L_divide_b3
! 130: tst r1, r0, lsl #3
! 131: bmi L_divide_b4
! 132: tst r1, r0, lsl #4
! 133: bmi L_divide_b5
! 134: tst r1, r0, lsl #5
! 135: bmi L_divide_b6
! 136: tst r1, r0, lsl #6
! 137: bmi L_divide_b7
! 138: tst r1, r0, lsl #7
! 139: bmi L_divide_b8
! 140: tst r1, r0, lsl #8
! 141: bmi L_divide_b9
! 142: tst r1, r0, lsl #9
! 143: bmi L_divide_b10
! 144: tst r1, r0, lsl #10
! 145: bmi L_divide_b11
! 146: tst r1, r0, lsl #11
! 147: bmi L_divide_b12
! 148: tst r1, r0, lsl #12
! 149: bmi L_divide_b13
! 150: tst r1, r0, lsl #13
! 151: bmi L_divide_b14
! 152: tst r1, r0, lsl #14
! 153: bmi L_divide_b15
! 154: tst r1, r0, lsl #15
! 155: bmi L_divide_b16
! 156: tst r1, r0, lsl #16
! 157: bmi L_divide_b17
! 158: tst r1, r0, lsl #17
! 159: bmi L_divide_b18
! 160: tst r1, r0, lsl #18
! 161: bmi L_divide_b19
! 162: tst r1, r0, lsl #19
! 163: bmi L_divide_b20
! 164: tst r1, r0, lsl #20
! 165: bmi L_divide_b21
! 166: tst r1, r0, lsl #21
! 167: bmi L_divide_b22
! 168: tst r1, r0, lsl #22
! 169: bmi L_divide_b23
! 170: tst r1, r0, lsl #23
! 171: bmi L_divide_b24
! 172: tst r1, r0, lsl #24
! 173: bmi L_divide_b25
! 174: tst r1, r0, lsl #25
! 175: bmi L_divide_b26
! 176: tst r1, r0, lsl #26
! 177: bmi L_divide_b27
! 178: tst r1, r0, lsl #27
! 179: bmi L_divide_b28
! 180: tst r1, r0, lsl #28
! 181: bmi L_divide_b29
! 182: tst r1, r0, lsl #29
! 183: bmi L_divide_b30
! 184: tst r1, r0, lsl #30
! 185: bmi L_divide_b31
! 186: /*
! 187: * instead of:
! 188: * tst r1, r0, lsl #31
! 189: * bmi L_divide_b32
! 190: */
! 191: b L_divide_b32
! 192:
! 193: L_old_code:
! 194: cmp r1, r0
! 195: bcc L_divide_b0
! 196: cmp r1, r0, lsl #1
! 197: bcc L_divide_b1
! 198: cmp r1, r0, lsl #2
! 199: bcc L_divide_b2
! 200: cmp r1, r0, lsl #3
! 201: bcc L_divide_b3
! 202: cmp r1, r0, lsl #4
! 203: bcc L_divide_b4
! 204: cmp r1, r0, lsl #5
! 205: bcc L_divide_b5
! 206: cmp r1, r0, lsl #6
! 207: bcc L_divide_b6
! 208: cmp r1, r0, lsl #7
! 209: bcc L_divide_b7
! 210: cmp r1, r0, lsl #8
! 211: bcc L_divide_b8
! 212: cmp r1, r0, lsl #9
! 213: bcc L_divide_b9
! 214: cmp r1, r0, lsl #10
! 215: bcc L_divide_b10
! 216: cmp r1, r0, lsl #11
! 217: bcc L_divide_b11
! 218: cmp r1, r0, lsl #12
! 219: bcc L_divide_b12
! 220: cmp r1, r0, lsl #13
! 221: bcc L_divide_b13
! 222: cmp r1, r0, lsl #14
! 223: bcc L_divide_b14
! 224: cmp r1, r0, lsl #15
! 225: bcc L_divide_b15
! 226: cmp r1, r0, lsl #16
! 227: bcc L_divide_b16
! 228: cmp r1, r0, lsl #17
! 229: bcc L_divide_b17
! 230: cmp r1, r0, lsl #18
! 231: bcc L_divide_b18
! 232: cmp r1, r0, lsl #19
! 233: bcc L_divide_b19
! 234: cmp r1, r0, lsl #20
! 235: bcc L_divide_b20
! 236: cmp r1, r0, lsl #21
! 237: bcc L_divide_b21
! 238: cmp r1, r0, lsl #22
! 239: bcc L_divide_b22
! 240: cmp r1, r0, lsl #23
! 241: bcc L_divide_b23
! 242: cmp r1, r0, lsl #24
! 243: bcc L_divide_b24
! 244: cmp r1, r0, lsl #25
! 245: bcc L_divide_b25
! 246: cmp r1, r0, lsl #26
! 247: bcc L_divide_b26
! 248: cmp r1, r0, lsl #27
! 249: bcc L_divide_b27
! 250: cmp r1, r0, lsl #28
! 251: bcc L_divide_b28
! 252: cmp r1, r0, lsl #29
! 253: bcc L_divide_b29
! 254: cmp r1, r0, lsl #30
! 255: bcc L_divide_b30
! 256: L_divide_b32:
! 257: cmp r1, r0, lsl #31
! 258: subhs r1, r1,r0, lsl #31
! 259: addhs r3, r3,r2, lsl #31
! 260: L_divide_b31:
! 261: cmp r1, r0, lsl #30
! 262: subhs r1, r1,r0, lsl #30
! 263: addhs r3, r3,r2, lsl #30
! 264: L_divide_b30:
! 265: cmp r1, r0, lsl #29
! 266: subhs r1, r1,r0, lsl #29
! 267: addhs r3, r3,r2, lsl #29
! 268: L_divide_b29:
! 269: cmp r1, r0, lsl #28
! 270: subhs r1, r1,r0, lsl #28
! 271: addhs r3, r3,r2, lsl #28
! 272: L_divide_b28:
! 273: cmp r1, r0, lsl #27
! 274: subhs r1, r1,r0, lsl #27
! 275: addhs r3, r3,r2, lsl #27
! 276: L_divide_b27:
! 277: cmp r1, r0, lsl #26
! 278: subhs r1, r1,r0, lsl #26
! 279: addhs r3, r3,r2, lsl #26
! 280: L_divide_b26:
! 281: cmp r1, r0, lsl #25
! 282: subhs r1, r1,r0, lsl #25
! 283: addhs r3, r3,r2, lsl #25
! 284: L_divide_b25:
! 285: cmp r1, r0, lsl #24
! 286: subhs r1, r1,r0, lsl #24
! 287: addhs r3, r3,r2, lsl #24
! 288: L_divide_b24:
! 289: cmp r1, r0, lsl #23
! 290: subhs r1, r1,r0, lsl #23
! 291: addhs r3, r3,r2, lsl #23
! 292: L_divide_b23:
! 293: cmp r1, r0, lsl #22
! 294: subhs r1, r1,r0, lsl #22
! 295: addhs r3, r3,r2, lsl #22
! 296: L_divide_b22:
! 297: cmp r1, r0, lsl #21
! 298: subhs r1, r1,r0, lsl #21
! 299: addhs r3, r3,r2, lsl #21
! 300: L_divide_b21:
! 301: cmp r1, r0, lsl #20
! 302: subhs r1, r1,r0, lsl #20
! 303: addhs r3, r3,r2, lsl #20
! 304: L_divide_b20:
! 305: cmp r1, r0, lsl #19
! 306: subhs r1, r1,r0, lsl #19
! 307: addhs r3, r3,r2, lsl #19
! 308: L_divide_b19:
! 309: cmp r1, r0, lsl #18
! 310: subhs r1, r1,r0, lsl #18
! 311: addhs r3, r3,r2, lsl #18
! 312: L_divide_b18:
! 313: cmp r1, r0, lsl #17
! 314: subhs r1, r1,r0, lsl #17
! 315: addhs r3, r3,r2, lsl #17
! 316: L_divide_b17:
! 317: cmp r1, r0, lsl #16
! 318: subhs r1, r1,r0, lsl #16
! 319: addhs r3, r3,r2, lsl #16
! 320: L_divide_b16:
! 321: cmp r1, r0, lsl #15
! 322: subhs r1, r1,r0, lsl #15
! 323: addhs r3, r3,r2, lsl #15
! 324: L_divide_b15:
! 325: cmp r1, r0, lsl #14
! 326: subhs r1, r1,r0, lsl #14
! 327: addhs r3, r3,r2, lsl #14
! 328: L_divide_b14:
! 329: cmp r1, r0, lsl #13
! 330: subhs r1, r1,r0, lsl #13
! 331: addhs r3, r3,r2, lsl #13
! 332: L_divide_b13:
! 333: cmp r1, r0, lsl #12
! 334: subhs r1, r1,r0, lsl #12
! 335: addhs r3, r3,r2, lsl #12
! 336: L_divide_b12:
! 337: cmp r1, r0, lsl #11
! 338: subhs r1, r1,r0, lsl #11
! 339: addhs r3, r3,r2, lsl #11
! 340: L_divide_b11:
! 341: cmp r1, r0, lsl #10
! 342: subhs r1, r1,r0, lsl #10
! 343: addhs r3, r3,r2, lsl #10
! 344: L_divide_b10:
! 345: cmp r1, r0, lsl #9
! 346: subhs r1, r1,r0, lsl #9
! 347: addhs r3, r3,r2, lsl #9
! 348: L_divide_b9:
! 349: cmp r1, r0, lsl #8
! 350: subhs r1, r1,r0, lsl #8
! 351: addhs r3, r3,r2, lsl #8
! 352: L_divide_b8:
! 353: cmp r1, r0, lsl #7
! 354: subhs r1, r1,r0, lsl #7
! 355: addhs r3, r3,r2, lsl #7
! 356: L_divide_b7:
! 357: cmp r1, r0, lsl #6
! 358: subhs r1, r1,r0, lsl #6
! 359: addhs r3, r3,r2, lsl #6
! 360: L_divide_b6:
! 361: cmp r1, r0, lsl #5
! 362: subhs r1, r1,r0, lsl #5
! 363: addhs r3, r3,r2, lsl #5
! 364: L_divide_b5:
! 365: cmp r1, r0, lsl #4
! 366: subhs r1, r1,r0, lsl #4
! 367: addhs r3, r3,r2, lsl #4
! 368: L_divide_b4:
! 369: cmp r1, r0, lsl #3
! 370: subhs r1, r1,r0, lsl #3
! 371: addhs r3, r3,r2, lsl #3
! 372: L_divide_b3:
! 373: cmp r1, r0, lsl #2
! 374: subhs r1, r1,r0, lsl #2
! 375: addhs r3, r3,r2, lsl #2
! 376: L_divide_b2:
! 377: cmp r1, r0, lsl #1
! 378: subhs r1, r1,r0, lsl #1
! 379: addhs r3, r3,r2, lsl #1
! 380: L_divide_b1:
! 381: cmp r1, r0
! 382: subhs r1, r1, r0
! 383: addhs r3, r3, r2
! 384: L_divide_b0:
! 385:
! 386: tst ip, #0x20000000
! 387: bne L_udivide_l1
! 388: mov r0, r3
! 389: cmp ip, #0
! 390: rsbmi r1, r1, #0
! 391: movs ip, ip, lsl #1
! 392: bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
! 393: rsbmi r0, r0, #0
! 394: #ifdef __APCS_26__
! 395: movs pc, lr
! 396: #else
! 397: mov pc, lr
! 398: #endif
! 399:
! 400: L_udivide_l1:
! 401: tst ip, #0x10000000
! 402: mov r1, r1, lsl #1
! 403: orrne r1, r1, #1
! 404: mov r3, r3, lsl #1
! 405: cmp r1, r0
! 406: subhs r1, r1, r0
! 407: addhs r3, r3, r2
! 408: mov r0, r3
! 409: #ifdef __APCS_26__
! 410: movs pc, lr
! 411: #else
! 412: mov pc, lr
! 413: #endif
CVSweb