18c2ecf20Sopenharmony_ci/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and 28c2ecf20Sopenharmony_ci gcc-2.7.2.3/longlong.h which is: */ 38c2ecf20Sopenharmony_ci/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciThis file is part of GNU CC. 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciGNU CC is free software; you can redistribute it and/or modify 88c2ecf20Sopenharmony_ciit under the terms of the GNU General Public License as published by 98c2ecf20Sopenharmony_cithe Free Software Foundation; either version 2, or (at your option) 108c2ecf20Sopenharmony_ciany later version. 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ciGNU CC is distributed in the hope that it will be useful, 138c2ecf20Sopenharmony_cibut WITHOUT ANY WARRANTY; without even the implied warranty of 148c2ecf20Sopenharmony_ciMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 158c2ecf20Sopenharmony_ciGNU General Public License for more details. */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <linux/compiler.h> 188c2ecf20Sopenharmony_ci#include <linux/export.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_HAS_NO_MULDIV64 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define SI_TYPE_SIZE 32 238c2ecf20Sopenharmony_ci#define __BITS4 (SI_TYPE_SIZE / 4) 248c2ecf20Sopenharmony_ci#define __ll_B (1L << (SI_TYPE_SIZE / 2)) 258c2ecf20Sopenharmony_ci#define __ll_lowpart(t) ((USItype) (t) % __ll_B) 268c2ecf20Sopenharmony_ci#define __ll_highpart(t) ((USItype) (t) / __ll_B) 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define umul_ppmm(w1, w0, u, v) \ 298c2ecf20Sopenharmony_ci do { \ 308c2ecf20Sopenharmony_ci USItype __x0, __x1, __x2, __x3; \ 318c2ecf20Sopenharmony_ci USItype __ul, __vl, __uh, __vh; \ 328c2ecf20Sopenharmony_ci \ 338c2ecf20Sopenharmony_ci __ul = __ll_lowpart (u); \ 348c2ecf20Sopenharmony_ci __uh = __ll_highpart (u); \ 358c2ecf20Sopenharmony_ci __vl = __ll_lowpart (v); \ 368c2ecf20Sopenharmony_ci __vh = __ll_highpart (v); \ 378c2ecf20Sopenharmony_ci \ 388c2ecf20Sopenharmony_ci __x0 = (USItype) __ul * __vl; \ 398c2ecf20Sopenharmony_ci __x1 = (USItype) __ul * __vh; \ 408c2ecf20Sopenharmony_ci __x2 = (USItype) __uh * __vl; \ 418c2ecf20Sopenharmony_ci __x3 = (USItype) __uh * __vh; \ 428c2ecf20Sopenharmony_ci \ 438c2ecf20Sopenharmony_ci __x1 += __ll_highpart (__x0);/* this can't give carry */ \ 448c2ecf20Sopenharmony_ci __x1 += __x2; /* but this indeed can */ \ 458c2ecf20Sopenharmony_ci if (__x1 < __x2) /* did we get it? */ \ 468c2ecf20Sopenharmony_ci __x3 += __ll_B; /* yes, add it in the proper pos. */ \ 478c2ecf20Sopenharmony_ci \ 488c2ecf20Sopenharmony_ci (w1) = __x3 + __ll_highpart (__x1); \ 498c2ecf20Sopenharmony_ci (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ 508c2ecf20Sopenharmony_ci } while (0) 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#else 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci#define umul_ppmm(w1, w0, u, v) \ 558c2ecf20Sopenharmony_ci __asm__ ("mulu%.l %3,%1:%0" \ 568c2ecf20Sopenharmony_ci : "=d" ((USItype)(w0)), \ 578c2ecf20Sopenharmony_ci "=d" ((USItype)(w1)) \ 588c2ecf20Sopenharmony_ci : "%0" ((USItype)(u)), \ 598c2ecf20Sopenharmony_ci "dmi" ((USItype)(v))) 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#endif 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci#define __umulsidi3(u, v) \ 648c2ecf20Sopenharmony_ci ({DIunion __w; \ 658c2ecf20Sopenharmony_ci umul_ppmm (__w.s.high, __w.s.low, u, v); \ 668c2ecf20Sopenharmony_ci __w.ll; }) 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_citypedef int SItype __mode(SI); 698c2ecf20Sopenharmony_citypedef unsigned int USItype __mode(SI); 708c2ecf20Sopenharmony_citypedef int DItype __mode(DI); 718c2ecf20Sopenharmony_citypedef int word_type __mode(__word__); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistruct DIstruct {SItype high, low;}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_citypedef union 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci struct DIstruct s; 788c2ecf20Sopenharmony_ci DItype ll; 798c2ecf20Sopenharmony_ci} DIunion; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciDItype 828c2ecf20Sopenharmony_ci__muldi3 (DItype u, DItype v) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci DIunion w; 858c2ecf20Sopenharmony_ci DIunion uu, vv; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci uu.ll = u, 888c2ecf20Sopenharmony_ci vv.ll = v; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci w.ll = __umulsidi3 (uu.s.low, vv.s.low); 918c2ecf20Sopenharmony_ci w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high 928c2ecf20Sopenharmony_ci + (USItype) uu.s.high * (USItype) vv.s.low); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci return w.ll; 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__muldi3); 97