11fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* ===-- mulvsi3.c - Implement __mulvsi3 -----------------------------------=== 21fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 31fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * The LLVM Compiler Infrastructure 41fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward 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. 71fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 81fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * ===----------------------------------------------------------------------=== 91fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 101fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * This file implements __mulvsi3 for the compiler_rt library. 111fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * 121fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan * ===----------------------------------------------------------------------=== 131fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan */ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h" 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 171fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* Returns: a * b */ 18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 191fcb40b79d8fbfcc9acb0966d5f9bba09431f832Edward O'Callaghan/* Effects: aborts if a * b overflows */ 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCOMPILER_RT_ABI si_int 22b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__mulvsi3(si_int a, si_int b) 23b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const int N = (int)(sizeof(si_int) * CHAR_BIT); 25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const si_int MIN = (si_int)1 << (N-1); 26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const si_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 si_int sa = a >> (N - 1); 40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar si_int abs_a = (a ^ sa) - sa; 41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar si_int sb = b >> (N - 1); 42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar si_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