@@ -47,7 +47,7 @@ typedef struct unsigned_int_struct {
47
47
} unsigned_int_struct ;
48
48
49
49
#define REGS_RETURN (name , type ) \
50
- void name ## _return(type ret) {}
50
+ static void name ## _return(type ret) {}
51
51
52
52
53
53
/* Float helper functions */
@@ -339,7 +339,7 @@ __AEABI_XL2D(ul2d, 0)
339
339
/* long long to double conversion */
340
340
__AEABI_XL2D (l2d , 1 )
341
341
342
-
342
+ #if 1
343
343
/* Long long helper functions */
344
344
345
345
/* TODO: add error in case of den == 0 (see §4.3.1 and §4.3.2) */
@@ -474,6 +474,7 @@ void __aeabi_lasr(unsigned_int_struct val, int shift)
474
474
475
475
/* Integer division functions */
476
476
477
+ #if 0 /* very slow */
477
478
AEABI_UXDIVMOD (uidivmod , unsigned , uidiv_t , UINT )
478
479
479
480
int __aeabi_idiv (int numerator , int denominator )
@@ -506,6 +507,9 @@ void __aeabi_uidivmod(unsigned num, unsigned den)
506
507
{
507
508
uidiv_t_return (aeabi_uidivmod (num , den ));
508
509
}
510
+ #else
511
+ # define UIDIVMOD_ASM 1
512
+ #endif
509
513
510
514
/* Some targets do not have all eabi calls (OpenBSD) */
511
515
typedef __SIZE_TYPE__ size_t ;
@@ -542,3 +546,97 @@ __aeabi_memset (void *s, size_t n, int c)
542
546
{
543
547
return memset (s , c , n );
544
548
}
549
+
550
+ /* ***************************************************************** */
551
+ #if UIDIVMOD_ASM
552
+ #include <config.h>
553
+ __asm__(
554
+ "\n .global __aeabi_idiv, __aeabi_idivmod"
555
+ "\n .global __aeabi_uidiv, __aeabi_uidivmod"
556
+ #if __ARM_FEATURE_IDIV
557
+ "\n__aeabi_idiv:"
558
+ "\n__aeabi_idivmod:"
559
+ "\n mov r2, r0"
560
+ "\n sdiv r0, r0, r1"
561
+ "\n mls r1, r1, r0, r2"
562
+ "\n bx lr"
563
+
564
+ "\n__aeabi_uidiv:"
565
+ "\n__aeabi_uidivmod:"
566
+ "\n mov r2, r0"
567
+ "\n udiv r0, r0, r1"
568
+ "\n mls r1, r1, r0, r2"
569
+ "\n bx lr"
570
+ #else
571
+ /* Runtime ABI for the ARM Cortex-M0
572
+ * idivmod.S: signed 32 bit division (quotient and remainder)
573
+ *
574
+ * Copyright (c) 2012 Jörg Mische <[email protected] >
575
+ *
576
+ * Permission to use, copy, modify, and/or distribute this software for any
577
+ * purpose with or without fee is hereby granted, provided that the above
578
+ * copyright notice and this permission notice appear in all copies.
579
+ */
580
+ "\n__aeabi_idiv:"
581
+ "\n__aeabi_idivmod:"
582
+ "\n cmp r0, #0"
583
+ "\n bge .Lnumerator_pos"
584
+ "\n rsb r0, r0, #0" // num = -num
585
+ "\n cmp r1, #0"
586
+ "\n bge .Lboth_neg"
587
+ "\n rsb r1, r1, #0" // den = -den
588
+ "\n push {lr}"
589
+ "\n bl __aeabi_uidivmod"
590
+ "\n rsb r1, r1, #0" // rem = -rem
591
+ "\n pop {pc}"
592
+ "\n.Lboth_neg:"
593
+ "\n push {lr}"
594
+ "\n bl __aeabi_uidivmod"
595
+ "\n rsb r0, r0, #0" // quot = -quot
596
+ "\n rsb r1, r1, #0" // rem = -rem
597
+ "\n pop {pc}"
598
+ "\n.Ldenom_neg:"
599
+ "\n rsb r1, r1, #0" // den = -den
600
+ "\n push {lr}"
601
+ "\n bl __aeabi_uidivmod"
602
+ "\n rsb r0, r0, #0" // quot = -quot
603
+ "\n pop {pc}"
604
+ "\n.Lnumerator_pos:"
605
+ "\n cmp r1, #0"
606
+ "\n blt .Ldenom_neg"
607
+
608
+ // Divide r0 by r1 and return the quotient in r0 and the remainder in r1
609
+ "\n__aeabi_uidiv:"
610
+ "\n__aeabi_uidivmod:"
611
+ // Shift left the denominator until it is greater than the numerator
612
+ "\n mov r2, #1" // counter
613
+ "\n mov r3, #0" // result
614
+ "\n cmp r0, r1"
615
+ "\n bls .Lsub_loop"
616
+ "\n adds r1, #0" // dont shift if denominator would overflow
617
+ "\n bmi .Lsub_loop"
618
+ "\n beq .Luidiv0"
619
+ "\n.Ldenom_shift_loop:"
620
+ "\n lsl r2, #1"
621
+ "\n lsls r1, #1"
622
+ "\n bmi .Lsub_loop"
623
+ "\n cmp r0, r1"
624
+ "\n bhi .Ldenom_shift_loop"
625
+ "\n.Lsub_loop:"
626
+ "\n cmp r0, r1" // if (num >= den)...
627
+ "\n subcs r0, r1" // numerator -= denom
628
+ "\n orrcs r3, r2" // result(r3) |= bitmask(r2)
629
+ "\n lsr r1, #1" // denom(r1) >>= 1
630
+ "\n lsrs r2, #1" // bitmask(r2) >>= 1
631
+ "\n bne .Lsub_loop"
632
+ "\n mov r1, r0" // remainder(r1) = numerator(r0)
633
+ "\n mov r0, r3" // quotient(r0) = result(r3)
634
+ "\n bx lr"
635
+ "\n.Luidiv0:" // XXX: division by zero
636
+ "\n mov r0, #0"
637
+ "\n bx lr"
638
+ #endif
639
+ );
640
+ #endif /* UIDIVMOD_ASM */
641
+ /* ***************************************************************** */
642
+ #endif
0 commit comments