123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- ; Copyright (C) 2011-2022 Free Software Foundation, Inc.
- ; Contributed by Red Hat.
- ;
- ; This file is free software; you can redistribute it and/or modify it
- ; under the terms of the GNU General Public License as published by the
- ; Free Software Foundation; either version 3, or (at your option) any
- ; later version.
- ;
- ; This file is distributed in the hope that it will be useful, but
- ; WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- ; General Public License for more details.
- ;
- ; Under Section 7 of GPL version 3, you are granted additional
- ; permissions described in the GCC Runtime Library Exception, version
- ; 3.1, as published by the Free Software Foundation.
- ;
- ; You should have received a copy of the GNU General Public License and
- ; a copy of the GCC Runtime Library Exception along with this program;
- ; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- ; <http://www.gnu.org/licenses/>.
- ;; 32x32=32 multiply
- #include "vregs.h"
-
- ;----------------------------------------------------------------------
- ; Register use:
- ; RB0 RB1 RB2
- ; AX op2L res32L res32H
- ; BC op2H (resH) op1
- ; DE count (resL-tmp)
- ; HL [sp+4]
- ; Register use (G10):
- ;
- ; AX op2L
- ; BC op2H
- ; DE count
- ; HL [sp+4]
- ; r8/r9 res32L
- ; r10/r11 (resH)
- ; r12/r13 (resL-tmp)
- ; r16/r17 res32H
- ; r18/r19 op1
- START_FUNC ___mulsi3
- ;; A is at [sp+4]
- ;; B is at [sp+8]
- ;; result is in R8..R11
- #ifdef __RL78_G10__
- movw ax, r16
- push ax
- movw ax, r18
- push ax
- #else
- sel rb2
- push ax
- push bc
- sel rb0
- #endif
- clrw ax
- movw r8, ax
- movw r16, ax
- movw ax, [sp+14]
- cmpw ax, #0
- bz $1f
- cmpw ax, #0xffff
- bnz $2f
- movw ax, [sp+8]
- #ifdef __RL78_G10__
- push bc
- movw bc, r8
- xchw ax, bc
- subw ax, bc
- movw r8, ax
- movw ax, bc
- pop bc
- #else
- sel rb1
- subw ax, r_0
- sel rb0
- #endif
- br $1f
- 2:
- movw bc, ax
- movw ax, [sp+8]
- cmpw ax, #0
- skz
- call !.Lmul_hi
- 1:
- movw ax, [sp+10]
- cmpw ax, #0
- bz $1f
- cmpw ax, #0xffff
- bnz $2f
- movw ax, [sp+12]
- #ifdef __RL78_G10__
- push bc
- movw bc, r8
- xchw ax, bc
- subw ax, bc
- movw r8, ax
- movw ax, bc
- pop bc
- #else
- sel rb1
- subw ax, r_0
- sel rb0
- #endif
- br $1f
- 2:
- movw bc, ax
- movw ax, [sp+12]
- cmpw ax, #0
- skz
- call !.Lmul_hi
- 1:
- movw ax, r8
- movw r16, ax
- clrw ax
- movw r8, ax
- ;; now do R16:R8 += op1L * op2L
- ;; op1 is in AX.0 (needs to shrw)
- ;; op2 is in BC.2 and BC.1 (bc can shlw/rolcw)
- ;; res is in AX.2 and AX.1 (needs to addw)
- movw ax, [sp+8]
- movw r10, ax ; BC.1
- movw ax, [sp+12]
- cmpw ax, r10
- bc $.Lmul_hisi_top
- movw bc, r10
- movw r10, ax
- movw ax, bc
- .Lmul_hisi_top:
- movw bc, #0
- .Lmul_hisi_loop:
- shrw ax, 1
- #ifdef __RL78_G10__
- push ax
- bnc $.Lmul_hisi_no_add_g10
- movw ax, r8
- addw ax, r10
- movw r8, ax
- sknc
- incw r16
- movw ax, r16
- addw ax, r_2
- movw r16, ax
- .Lmul_hisi_no_add_g10:
- movw ax, r10
- shlw ax, 1
- movw r10, ax
- pop ax
- #else
- bnc $.Lmul_hisi_no_add
- sel rb1
- addw ax, bc
- sel rb2
- sknc
- incw ax
- addw ax, r_2
- .Lmul_hisi_no_add:
- sel rb1
- shlw bc, 1
- sel rb0
- #endif
- rolwc bc, 1
- cmpw ax, #0
- bz $.Lmul_hisi_done
- shrw ax, 1
- #ifdef __RL78_G10__
- push ax
- bnc $.Lmul_hisi_no_add2_g10
- movw ax, r8
- addw ax, r10
- movw r8, ax
- movw ax, r16
- sknc
- incw ax
- addw ax, r_2
- movw r16, ax
- .Lmul_hisi_no_add2_g10:
- movw ax, r10
- shlw ax, 1
- movw r10, ax
- pop ax
- #else
- bnc $.Lmul_hisi_no_add2
- sel rb1
- addw ax, bc
- sel rb2
- sknc
- incw ax
- addw ax, r_2
- .Lmul_hisi_no_add2:
- sel rb1
- shlw bc, 1
- sel rb0
- #endif
- rolwc bc, 1
- cmpw ax, #0
- bnz $.Lmul_hisi_loop
- .Lmul_hisi_done:
- movw ax, r16
- movw r10, ax
- #ifdef __RL78_G10__
- pop ax
- movw r18, ax
- pop ax
- movw r16, ax
- #else
- sel rb2
- pop bc
- pop ax
- sel rb0
- #endif
- ret
- END_FUNC ___mulsi3
- ;----------------------------------------------------------------------
- START_FUNC ___mulhi3
- movw r8, #0
- movw ax, [sp+6]
- movw bc, ax
- movw ax, [sp+4]
- ;; R8 += AX * BC
- .Lmul_hi:
- cmpw ax, bc
- skc
- xchw ax, bc
- br $.Lmul_hi_loop
-
- .Lmul_hi_top:
- #ifdef __RL78_G10__
- push ax
- movw ax, r8
- addw ax, r_2
- movw r8, ax
- pop ax
- #else
- sel rb1
- addw ax, r_2
- sel rb0
- #endif
- .Lmul_hi_no_add:
- shlw bc, 1
- .Lmul_hi_loop:
- shrw ax, 1
- bc $.Lmul_hi_top
- cmpw ax, #0
- bz $.Lmul_hi_done
- shlw bc, 1
- shrw ax, 1
- bc $.Lmul_hi_top
- cmpw ax, #0
- bnz $.Lmul_hi_no_add
- .Lmul_hi_done:
- ret
- END_FUNC ___mulhi3
- ;;; --------------------------------------
- #ifdef __RL78_G10__
- START_FUNC ___mulqi3
- mov a, [sp+4]
- mov r9, a
- mov a, [sp+6]
- mov r10, a
- mov a, #9
- mov r11, a
- clrb a
- mov r8, a
- .L2:
- cmp0 r10
- skz
- dec r11
- sknz
- ret
- mov a, r10
- and a, #1
- mov r12, a
- cmp0 r12
- sknz
- br !!.L3
- mov a, r9
- mov l, a
- mov a, r8
- add a, l
- mov r8, a
- .L3:
- mov a, r9
- add a, a
- mov r9, a
- mov a, r10
- shr a, 1
- mov r10, a
- br !!.L2
- END_FUNC ___mulqi3
- #endif
|