1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ASM_ARM_DIV64 2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __ASM_ARM_DIV64 3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/system.h> 5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The semantics of do_div() are: 8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * uint32_t do_div(uint64_t *n, uint32_t base) 10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * { 11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * uint32_t remainder = *n % base; 12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * *n = *n / base; 13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * return remainder; 14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * } 15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * In other words, a 64-bit dividend with a 32-bit divisor producing 17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * a 64-bit result and a 32-bit remainder. To accomplish this optimally 18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * we call a special __do_div64 helper with completely non standard 19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * calling convention for arguments and results (beware). 20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef __ARMEB__ 23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __xh "r0" 24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __xl "r1" 25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __xl "r0" 27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __xh "r1" 28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define do_div(n,base) \ 31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru register unsigned int __base asm("r4") = base; \ 33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru register unsigned long long __n asm("r0") = n; \ 34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru register unsigned long long __res asm("r2"); \ 35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru register unsigned int __rem asm(__xh); \ 36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm( __asmeq("%0", __xh) \ 37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asmeq("%1", "r2") \ 38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asmeq("%2", "r0") \ 39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asmeq("%3", "r4") \ 40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "bl __do_div64" \ 41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (__rem), "=r" (__res) \ 42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (__n), "r" (__base) \ 43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "ip", "lr", "cc"); \ 44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru n = __res; \ 45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __rem; \ 46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 49