162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (C) 2000, 2004, 2021 Maciej W. Rozycki 362306a36Sopenharmony_ci * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 662306a36Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 762306a36Sopenharmony_ci * for more details. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci#ifndef __ASM_DIV64_H 1062306a36Sopenharmony_ci#define __ASM_DIV64_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <asm/bitsperlong.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#if BITS_PER_LONG == 32 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* 1762306a36Sopenharmony_ci * No traps on overflows for any of these... 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define do_div64_32(res, high, low, base) ({ \ 2162306a36Sopenharmony_ci unsigned long __cf, __tmp, __tmp2, __i; \ 2262306a36Sopenharmony_ci unsigned long __quot32, __mod32; \ 2362306a36Sopenharmony_ci \ 2462306a36Sopenharmony_ci __asm__( \ 2562306a36Sopenharmony_ci " .set push \n" \ 2662306a36Sopenharmony_ci " .set noat \n" \ 2762306a36Sopenharmony_ci " .set noreorder \n" \ 2862306a36Sopenharmony_ci " move %2, $0 \n" \ 2962306a36Sopenharmony_ci " move %3, $0 \n" \ 3062306a36Sopenharmony_ci " b 1f \n" \ 3162306a36Sopenharmony_ci " li %4, 0x21 \n" \ 3262306a36Sopenharmony_ci "0: \n" \ 3362306a36Sopenharmony_ci " sll $1, %0, 0x1 \n" \ 3462306a36Sopenharmony_ci " srl %3, %0, 0x1f \n" \ 3562306a36Sopenharmony_ci " or %0, $1, %5 \n" \ 3662306a36Sopenharmony_ci " sll %1, %1, 0x1 \n" \ 3762306a36Sopenharmony_ci " sll %2, %2, 0x1 \n" \ 3862306a36Sopenharmony_ci "1: \n" \ 3962306a36Sopenharmony_ci " bnez %3, 2f \n" \ 4062306a36Sopenharmony_ci " sltu %5, %0, %z6 \n" \ 4162306a36Sopenharmony_ci " bnez %5, 3f \n" \ 4262306a36Sopenharmony_ci "2: \n" \ 4362306a36Sopenharmony_ci " addiu %4, %4, -1 \n" \ 4462306a36Sopenharmony_ci " subu %0, %0, %z6 \n" \ 4562306a36Sopenharmony_ci " addiu %2, %2, 1 \n" \ 4662306a36Sopenharmony_ci "3: \n" \ 4762306a36Sopenharmony_ci " bnez %4, 0b \n" \ 4862306a36Sopenharmony_ci " srl %5, %1, 0x1f \n" \ 4962306a36Sopenharmony_ci " .set pop" \ 5062306a36Sopenharmony_ci : "=&r" (__mod32), "=&r" (__tmp), \ 5162306a36Sopenharmony_ci "=&r" (__quot32), "=&r" (__cf), \ 5262306a36Sopenharmony_ci "=&r" (__i), "=&r" (__tmp2) \ 5362306a36Sopenharmony_ci : "Jr" (base), "0" (high), "1" (low)); \ 5462306a36Sopenharmony_ci \ 5562306a36Sopenharmony_ci (res) = __quot32; \ 5662306a36Sopenharmony_ci __mod32; \ 5762306a36Sopenharmony_ci}) 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#define __div64_32(n, base) ({ \ 6062306a36Sopenharmony_ci unsigned long __upper, __low, __high, __radix; \ 6162306a36Sopenharmony_ci unsigned long long __quot; \ 6262306a36Sopenharmony_ci unsigned long long __div; \ 6362306a36Sopenharmony_ci unsigned long __mod; \ 6462306a36Sopenharmony_ci \ 6562306a36Sopenharmony_ci __div = (*n); \ 6662306a36Sopenharmony_ci __radix = (base); \ 6762306a36Sopenharmony_ci \ 6862306a36Sopenharmony_ci __high = __div >> 32; \ 6962306a36Sopenharmony_ci __low = __div; \ 7062306a36Sopenharmony_ci \ 7162306a36Sopenharmony_ci if (__high < __radix) { \ 7262306a36Sopenharmony_ci __upper = __high; \ 7362306a36Sopenharmony_ci __high = 0; \ 7462306a36Sopenharmony_ci } else { \ 7562306a36Sopenharmony_ci __upper = __high % __radix; \ 7662306a36Sopenharmony_ci __high /= __radix; \ 7762306a36Sopenharmony_ci } \ 7862306a36Sopenharmony_ci \ 7962306a36Sopenharmony_ci __mod = do_div64_32(__low, __upper, __low, __radix); \ 8062306a36Sopenharmony_ci \ 8162306a36Sopenharmony_ci __quot = __high; \ 8262306a36Sopenharmony_ci __quot = __quot << 32 | __low; \ 8362306a36Sopenharmony_ci (*n) = __quot; \ 8462306a36Sopenharmony_ci __mod; \ 8562306a36Sopenharmony_ci}) 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#endif /* BITS_PER_LONG == 32 */ 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci#include <asm-generic/div64.h> 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci#endif /* __ASM_DIV64_H */ 92