15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*===-- mulodi4.c - Implement __mulodi4 -----------------------------------=== 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This file is dual licensed under the MIT and the University of Illinois Open 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Source Licenses. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * ===----------------------------------------------------------------------=== 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This file implements __mulodi4 for the compiler_rt library. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * ===----------------------------------------------------------------------=== 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "int_lib.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Returns: a * b */ 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Effects: sets *overflow to 1 if a * b overflows */ 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochCOMPILER_RT_ABI di_int 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)__mulodi4(di_int a, di_int b, int* overflow) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int N = (int)(sizeof(di_int) * CHAR_BIT); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const di_int MIN = (di_int)1 << (N-1); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const di_int MAX = ~MIN; 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *overflow = 0; 28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch di_int result = a * b; 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (a == MIN) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (b != 0 && b != 1) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *overflow = 1; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return result; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (b == MIN) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a != 0 && a != 1) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *overflow = 1; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) di_int sa = a >> (N - 1); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) di_int abs_a = (a ^ sa) - sa; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) di_int sb = b >> (N - 1); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) di_int abs_b = (b ^ sb) - sb; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (abs_a < 2 || abs_b < 2) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (sa == sb) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (abs_a > MAX / abs_b) 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *overflow = 1; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (abs_a > MIN / -abs_b) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *overflow = 1; 56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)