162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2000 Hewlett-Packard Co 462306a36Sopenharmony_ci * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com> 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * 32-bit integer division. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This code is based on the application note entitled "Divide, Square Root 962306a36Sopenharmony_ci * and Remainder Algorithms for the IA-64 Architecture". This document 1062306a36Sopenharmony_ci * is available as Intel document number 248725-002 or via the web at 1162306a36Sopenharmony_ci * http://developer.intel.com/software/opensource/numerics/ 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * For more details on the theory behind these algorithms, see "IA-64 1462306a36Sopenharmony_ci * and Elementary Functions" by Peter Markstein; HP Professional Books 1562306a36Sopenharmony_ci * (http://www.goodreads.com/book/show/2019887.Ia_64_and_Elementary_Functions) 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include <linux/export.h> 1962306a36Sopenharmony_ci#include <asm/asmmacro.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#ifdef MODULO 2262306a36Sopenharmony_ci# define OP mod 2362306a36Sopenharmony_ci#else 2462306a36Sopenharmony_ci# define OP div 2562306a36Sopenharmony_ci#endif 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#ifdef UNSIGNED 2862306a36Sopenharmony_ci# define SGN u 2962306a36Sopenharmony_ci# define EXTEND zxt4 3062306a36Sopenharmony_ci# define INT_TO_FP(a,b) fcvt.xuf.s1 a=b 3162306a36Sopenharmony_ci# define FP_TO_INT(a,b) fcvt.fxu.trunc.s1 a=b 3262306a36Sopenharmony_ci#else 3362306a36Sopenharmony_ci# define SGN 3462306a36Sopenharmony_ci# define EXTEND sxt4 3562306a36Sopenharmony_ci# define INT_TO_FP(a,b) fcvt.xf a=b 3662306a36Sopenharmony_ci# define FP_TO_INT(a,b) fcvt.fx.trunc.s1 a=b 3762306a36Sopenharmony_ci#endif 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#define PASTE1(a,b) a##b 4062306a36Sopenharmony_ci#define PASTE(a,b) PASTE1(a,b) 4162306a36Sopenharmony_ci#define NAME PASTE(PASTE(__,SGN),PASTE(OP,si3)) 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ciGLOBAL_ENTRY(NAME) 4462306a36Sopenharmony_ci .regstk 2,0,0,0 4562306a36Sopenharmony_ci // Transfer inputs to FP registers. 4662306a36Sopenharmony_ci mov r2 = 0xffdd // r2 = -34 + 65535 (fp reg format bias) 4762306a36Sopenharmony_ci EXTEND in0 = in0 // in0 = a 4862306a36Sopenharmony_ci EXTEND in1 = in1 // in1 = b 4962306a36Sopenharmony_ci ;; 5062306a36Sopenharmony_ci setf.sig f8 = in0 5162306a36Sopenharmony_ci setf.sig f9 = in1 5262306a36Sopenharmony_ci#ifdef MODULO 5362306a36Sopenharmony_ci sub in1 = r0, in1 // in1 = -b 5462306a36Sopenharmony_ci#endif 5562306a36Sopenharmony_ci ;; 5662306a36Sopenharmony_ci // Convert the inputs to FP, to avoid FP software-assist faults. 5762306a36Sopenharmony_ci INT_TO_FP(f8, f8) 5862306a36Sopenharmony_ci INT_TO_FP(f9, f9) 5962306a36Sopenharmony_ci ;; 6062306a36Sopenharmony_ci setf.exp f7 = r2 // f7 = 2^-34 6162306a36Sopenharmony_ci frcpa.s1 f6, p6 = f8, f9 // y0 = frcpa(b) 6262306a36Sopenharmony_ci ;; 6362306a36Sopenharmony_ci(p6) fmpy.s1 f8 = f8, f6 // q0 = a*y0 6462306a36Sopenharmony_ci(p6) fnma.s1 f6 = f9, f6, f1 // e0 = -b*y0 + 1 6562306a36Sopenharmony_ci ;; 6662306a36Sopenharmony_ci#ifdef MODULO 6762306a36Sopenharmony_ci setf.sig f9 = in1 // f9 = -b 6862306a36Sopenharmony_ci#endif 6962306a36Sopenharmony_ci(p6) fma.s1 f8 = f6, f8, f8 // q1 = e0*q0 + q0 7062306a36Sopenharmony_ci(p6) fma.s1 f6 = f6, f6, f7 // e1 = e0*e0 + 2^-34 7162306a36Sopenharmony_ci ;; 7262306a36Sopenharmony_ci#ifdef MODULO 7362306a36Sopenharmony_ci setf.sig f7 = in0 7462306a36Sopenharmony_ci#endif 7562306a36Sopenharmony_ci(p6) fma.s1 f6 = f6, f8, f8 // q2 = e1*q1 + q1 7662306a36Sopenharmony_ci ;; 7762306a36Sopenharmony_ci FP_TO_INT(f6, f6) // q = trunc(q2) 7862306a36Sopenharmony_ci ;; 7962306a36Sopenharmony_ci#ifdef MODULO 8062306a36Sopenharmony_ci xma.l f6 = f6, f9, f7 // r = q*(-b) + a 8162306a36Sopenharmony_ci ;; 8262306a36Sopenharmony_ci#endif 8362306a36Sopenharmony_ci getf.sig r8 = f6 // transfer result to result register 8462306a36Sopenharmony_ci br.ret.sptk.many rp 8562306a36Sopenharmony_ciEND(NAME) 8662306a36Sopenharmony_ciEXPORT_SYMBOL(NAME) 87