Merge tag 'mmc-v5.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
[sfrench/cifs-2.6.git] / arch / c6x / lib / remi.S
1 ;; SPDX-License-Identifier: GPL-2.0-or-later
2 ;;  Copyright 2010  Free Software Foundation, Inc.
3 ;;  Contributed by Bernd Schmidt <bernds@codesourcery.com>.
4 ;;
5
6 #include <linux/linkage.h>
7
8         ;; ABI considerations for the divide functions
9         ;; The following registers are call-used:
10         ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
11         ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
12         ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
13         ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
14         ;;
15         ;; In our implementation, divu and remu are leaf functions,
16         ;; while both divi and remi call into divu.
17         ;; A0 is not clobbered by any of the functions.
18         ;; divu does not clobber B2 either, which is taken advantage of
19         ;; in remi.
20         ;; divi uses B5 to hold the original return address during
21         ;; the call to divu.
22         ;; remi uses B2 and A5 to hold the input values during the
23         ;; call to divu.  It stores B3 in on the stack.
24
25         .text
26
27 ENTRY(__c6xabi_remi)
28         stw     .d2t2   B3, *B15--[2]
29 ||      cmpgt   .l1     0, A4, A1
30 ||      cmpgt   .l2     0, B4, B2
31 ||      mv      .s1     A4, A5
32 ||      call    .s2     __c6xabi_divu
33
34    [A1] neg     .l1     A4, A4
35 || [B2] neg     .l2     B4, B4
36 ||      xor     .s2x    B2, A1, B0
37 ||      mv      .d2     B4, B2
38
39    [B0] addkpc  .s2     _divu_ret_1, B3, 1
40   [!B0] addkpc  .s2     _divu_ret_2, B3, 1
41         nop     2
42 _divu_ret_1:
43         neg     .l1     A4, A4
44 _divu_ret_2:
45         ldw     .d2t2   *++B15[2], B3
46
47         mpy32   .m1x    A4, B2, A6
48         nop             3
49         ret     .s2     B3
50         sub     .l1     A5, A6, A4
51         nop     4
52 ENDPROC(__c6xabi_remi)