COMPILER_RT_ABI di_int __mulvdi3(di_int a, di_int b) { const int N = (int)(sizeof(di_int) * CHAR_BIT); const di_int MIN = (di_int)1 << (N - 1); const di_int MAX = ~MIN; if (a == MIN) { if (b == 0 || b == 1) return a * b; compilerrt_abort(); } if (b == MIN) { if (a == 0 || a == 1) return a * b; compilerrt_abort(); } di_int sa = a >> (N - 1); di_int abs_a = (a ^ sa) - sa; di_int sb = b >> (N - 1); di_int abs_b = (b ^ sb) - sb; if (abs_a < 2 || abs_b < 2) return a * b; if (sa == sb) { if (abs_a > MAX / abs_b) compilerrt_abort(); } else { if (abs_a > MIN / -abs_b) compilerrt_abort(); } return a * b; }
COMPILER_RT_ABI ti_int __subvti3(ti_int a, ti_int b) { ti_int s = a - b; if (b >= 0) { if (s > a) compilerrt_abort(); } else { if (s <= a) compilerrt_abort(); } return s; }
ti_int __addvti3(ti_int a, ti_int b) { ti_int s = a + b; if (b >= 0) { if (s < a) compilerrt_abort(); } else { if (s >= a) compilerrt_abort(); } return s; }
void __eprintf(const char* format, const char* assertion_expression, const char* line, const char* file) { fprintf(stderr, format, assertion_expression, line, file); fflush(stderr); compilerrt_abort(); }
COMPILER_RT_ABI si_int __subvsi3(si_int a, si_int b) { si_int s = a - b; if (b >= 0) { if (s > a) compilerrt_abort(); } else { if (s <= a) compilerrt_abort(); } return s; }
ti_int __negvti2(ti_int a) { const ti_int MIN = (ti_int)1 << ((int)(sizeof(ti_int) * CHAR_BIT)-1); if (a == MIN) compilerrt_abort(); return -a; }
ti_int __absvti2(ti_int a) { const int N = (int)(sizeof(ti_int) * CHAR_BIT); if (a == ((ti_int)1 << (N-1))) compilerrt_abort(); const ti_int s = a >> (N - 1); return (a ^ s) - s; }
COMPILER_RT_ABI si_int __absvsi2(si_int a) { const int N = (int)(sizeof(si_int) * CHAR_BIT); if (a == (1 << (N-1))) compilerrt_abort(); const si_int t = a >> (N - 1); return (a ^ t) - t; }
void __clear_cache(void* start, void* end) { #if __i386__ || __x86_64__ /* * Intel processors have a unified instruction and data cache * so there is nothing to do */ #else #if __APPLE__ /* On Darwin, sys_icache_invalidate() provides this functionality */ sys_icache_invalidate(start, end-start); #else compilerrt_abort(); #endif #endif }
void __clear_cache(void* start, void* end) { #if __i386__ || __x86_64__ /* * Intel processors have a unified instruction and data cache * so there is nothing to do */ #elif defined(__NetBSD__) && defined(__arm__) struct arm_sync_icache_args arg; arg.addr = (uintptr_t)start; arg.len = (uintptr_t)end - (uintptr_t)start; sysarch(ARM_SYNC_ICACHE, &arg); #else #if __APPLE__ /* On Darwin, sys_icache_invalidate() provides this functionality */ sys_icache_invalidate(start, end-start); #else compilerrt_abort(); #endif #endif }
/* read a pointer encoded value and advance pointer */ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding) { const uint8_t* p = *data; uintptr_t result = 0; if ( encoding == DW_EH_PE_omit ) return 0; /* first get value */ switch (encoding & 0x0F) { case DW_EH_PE_absptr: result = *((const uintptr_t*)p); p += sizeof(uintptr_t); break; case DW_EH_PE_uleb128: result = readULEB128(&p); break; case DW_EH_PE_udata2: result = *((const uint16_t*)p); p += sizeof(uint16_t); break; case DW_EH_PE_udata4: result = *((const uint32_t*)p); p += sizeof(uint32_t); break; case DW_EH_PE_udata8: result = *((const uint64_t*)p); p += sizeof(uint64_t); break; case DW_EH_PE_sdata2: result = *((const int16_t*)p); p += sizeof(int16_t); break; case DW_EH_PE_sdata4: result = *((const int32_t*)p); p += sizeof(int32_t); break; case DW_EH_PE_sdata8: result = *((const int64_t*)p); p += sizeof(int64_t); break; case DW_EH_PE_sleb128: default: /* not supported */ compilerrt_abort(); break; } /* then add relative offset */ switch ( encoding & 0x70 ) { case DW_EH_PE_absptr: /* do nothing */ break; case DW_EH_PE_pcrel: result += (uintptr_t)(*data); break; case DW_EH_PE_textrel: case DW_EH_PE_datarel: case DW_EH_PE_funcrel: case DW_EH_PE_aligned: default: /* not supported */ compilerrt_abort(); break; } /* then apply indirection */ if (encoding & DW_EH_PE_indirect) { result = *((const uintptr_t*)result); } *data = p; return result; }