18bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan/* This file is distributed under the University of Illinois Open Source 28bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan * License. See LICENSE.TXT for details. 38bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan */ 4b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 58bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan/* long double __gcc_qdiv(long double x, long double y); 68bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan * This file implements the PowerPC 128-bit double-double division operation. 78bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!) 88bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan */ 9b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 10b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "DD.h" 11b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 12b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarlong double __gcc_qdiv(long double a, long double b) 13b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar static const uint32_t infinityHi = UINT32_C(0x7ff00000); 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar DD dst = { .ld = a }, src = { .ld = b }; 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 178bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan register double x = dst.s.hi, x1 = dst.s.lo, 188bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan y = src.s.hi, y1 = src.s.lo; 19b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar double yHi, yLo, qHi, qLo; 21b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar double yq, tmp, q; 22b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 23b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar q = x / y; 24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 258bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan /* Detect special cases */ 26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (q == 0.0) { 278bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan dst.s.hi = q; 288bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan dst.s.lo = 0.0; 29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return dst.ld; 30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const doublebits qBits = { .d = q }; 33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (((uint32_t)(qBits.x >> 32) & infinityHi) == infinityHi) { 348bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan dst.s.hi = q; 358bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan dst.s.lo = 0.0; 36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return dst.ld; 37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 38b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar yHi = high26bits(y); 40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar qHi = high26bits(q); 41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar yq = y * q; 43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar yLo = y - yHi; 44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar qLo = q - qHi; 45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar tmp = LOWORDER(yq, yHi, yLo, qHi, qLo); 47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar tmp = (x - yq) - tmp; 48b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar tmp = ((tmp + x1) - y1 * q) / y; 49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar x = q + tmp; 50b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 518bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan dst.s.lo = (q - x) + tmp; 528bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan dst.s.hi = x; 53b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return dst.ld; 55b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 56