diff --git a/src/library.js b/src/library.js index a33d875c347bb..1439550613a31 100644 --- a/src/library.js +++ b/src/library.js @@ -946,6 +946,22 @@ LibraryManager.library = { {{{ makeStructuralReturn(['retl', 'reth']) }}}; }, + llvm_ctlz_i8__asm: true, + llvm_ctlz_i8__sig: 'ii', + llvm_ctlz_i8: function(x, isZeroUndef) { + x = x | 0; + isZeroUndef = isZeroUndef | 0; + return (Math_clz32(x) | 0) - 24 | 0; + }, + + llvm_ctlz_i16__asm: true, + llvm_ctlz_i16__sig: 'ii', + llvm_ctlz_i16: function(x, isZeroUndef) { + x = x | 0; + isZeroUndef = isZeroUndef | 0; + return (Math_clz32(x) | 0) - 16 | 0 + }, + llvm_ctlz_i64__asm: true, llvm_ctlz_i64__sig: 'iii', llvm_ctlz_i64: function(l, h, isZeroUndef) { @@ -1462,6 +1478,21 @@ LibraryManager.library = { llvm_floor_f32: 'Math_floor', llvm_floor_f64: 'Math_floor', + llvm_exp2_f32: function(x) { + return Math.pow(2, x); + }, + llvm_exp2_f64: 'llvm_exp2_f32', + + llvm_log2_f32: function(x) { + return Math.log(x) / Math.LN2; // TODO: Math.log2, when browser support is there + }, + llvm_log2_f64: 'llvm_log2_f32', + + llvm_log10_f32: function(x) { + return Math.log(x) / Math.LN10; // TODO: Math.log10, when browser support is there + }, + llvm_log10_f64: 'llvm_log10_f32', + llvm_copysign_f32: function(x, y) { return y < 0 || (y === 0 && 1/y < 0) ? -Math_abs(x) : Math_abs(x); }, diff --git a/tests/core/test_llvm_intrinsics.c b/tests/core/test_llvm_intrinsics.c index a0df641f786d6..5556d89f746e4 100644 --- a/tests/core/test_llvm_intrinsics.c +++ b/tests/core/test_llvm_intrinsics.c @@ -4,6 +4,8 @@ extern "C" { extern unsigned short llvm_bswap_i16(unsigned short x); extern unsigned int llvm_bswap_i32(unsigned int x); +extern int32_t llvm_ctlz_i8(int8_t x, int izZeroUndef); +extern int32_t llvm_ctlz_i16(int16_t x, int izZeroUndef); extern int32_t llvm_ctlz_i32(int32_t x, int izZeroUndef); extern int64_t llvm_ctlz_i64(int64_t x, int izZeroUndef); extern int32_t llvm_cttz_i32(int32_t x, int izZeroUndef); @@ -19,6 +21,12 @@ extern float llvm_floor_f32(float x); extern double llvm_floor_f64(double x); extern float llvm_sin_f32(float x); extern double llvm_sin_f64(double x); +extern float llvm_exp2_f32(float x); +extern double llvm_exp2_f64(double x); +extern float llvm_log2_f32(float x); +extern double llvm_log2_f64(double x); +extern float llvm_log10_f32(float x); +extern double llvm_log10_f64(double x); } int main(void) { @@ -41,6 +49,8 @@ int main(void) { printf("%d,%d\n", (int)llvm_ctpop_i64((0x3101ULL << 32) | 1), llvm_ctpop_i32(0x3101)); + printf("small ctlz: %d,%d\n", (int)llvm_ctlz_i8(2, 0), llvm_ctlz_i16(2, 0)); + printf("llvm_ctpop_i32:\n"); printf("%d\n", (int)llvm_ctpop_i32(-594093059)); // 22 printf("%d\n", (int)llvm_ctpop_i32(0xdeadbeef)); // 24 @@ -67,5 +77,14 @@ int main(void) { printf("%.1f\n", llvm_sin_f32(90.0f * 3.14/180)); printf("%.1f\n", llvm_sin_f64(270.0 * 3.14/180)); + printf("exp2_f32 %.1f\n", llvm_exp2_f32(3)); + printf("exp2_f64 %.1f\n", llvm_exp2_f64(4.5)); + printf("log2_f32 %.1f\n", llvm_log2_f32(16)); + printf("log2_f64 %.1f\n", llvm_log2_f64(20)); + printf("log10_f32 %.1f\n", llvm_log10_f32(1000)); + printf("log10_f64 %.1f\n", llvm_log10_f64(2000)); + + printf("ok.\n"); + return 0; } diff --git a/tests/core/test_llvm_intrinsics.out b/tests/core/test_llvm_intrinsics.out index 157433ceb7a6e..0cb78114afa9c 100644 --- a/tests/core/test_llvm_intrinsics.out +++ b/tests/core/test_llvm_intrinsics.out @@ -5,6 +5,7 @@ c5,de,15,8a 23,21 40,10 5,4 +small ctlz: 6,14 llvm_ctpop_i32: 22 24 @@ -26,3 +27,10 @@ llvm_expect_i32: -9 1.0 -1.0 +exp2_f32 8.0 +exp2_f64 22.6 +log2_f32 4.0 +log2_f64 4.3 +log10_f32 3.0 +log10_f64 3.3 +ok.