137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/*===-- mulvdi3.c - Implement __mulvdi3 -----------------------------------=== 237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * The LLVM Compiler Infrastructure 437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 59ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant * This file is dual licensed under the MIT and the University of Illinois Open 69ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant * Source Licenses. See LICENSE.TXT for details. 737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------=== 937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * This file implements __mulvdi3 for the compiler_rt library. 1137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------=== 1337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h" 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 1737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Returns: a * b */ 18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 1937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Effects: aborts if a * b overflows */ 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI di_int 22b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__mulvdi3(di_int a, di_int b) 23b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const int N = (int)(sizeof(di_int) * CHAR_BIT); 25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const di_int MIN = (di_int)1 << (N-1); 26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const di_int MAX = ~MIN; 27b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (a == MIN) 28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (b == 0 || b == 1) 30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return a * b; 3148f46ac1d9a82210f6e469567cb60aa7e7cd2f3bDaniel Dunbar compilerrt_abort(); 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (b == MIN) 34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (a == 0 || a == 1) 36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return a * b; 3748f46ac1d9a82210f6e469567cb60aa7e7cd2f3bDaniel Dunbar compilerrt_abort(); 38b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar di_int sa = a >> (N - 1); 40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar di_int abs_a = (a ^ sa) - sa; 41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar di_int sb = b >> (N - 1); 42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar di_int abs_b = (b ^ sb) - sb; 43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (abs_a < 2 || abs_b < 2) 44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return a * b; 45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (sa == sb) 46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (abs_a > MAX / abs_b) 4848f46ac1d9a82210f6e469567cb60aa7e7cd2f3bDaniel Dunbar compilerrt_abort(); 49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 50b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar else 51b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 52b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (abs_a > MIN / -abs_b) 5348f46ac1d9a82210f6e469567cb60aa7e7cd2f3bDaniel Dunbar compilerrt_abort(); 54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 55b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return a * b; 56b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 57