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