Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is our handling of % correct? #32

Open
captbaritone opened this issue Jul 1, 2020 · 3 comments
Open

Is our handling of % correct? #32

captbaritone opened this issue Jul 1, 2020 · 3 comments

Comments

@captbaritone
Copy link
Owner

Trying compile C's fmod to wasm results in dramatically more code:

Try the following in https://webassembly.studio/

#define WASM_EXPORT __attribute__((visibility("default")))
#include <math.h>

WASM_EXPORT
double mod(double a, double b)
{
    return fmod(a, b);
}

WASM_EXPORT
int main()
{
    return 42;
}

And you will get the following wat:

(module
  (type $t0 (func))
  (type $t1 (func (param f64 f64) (result f64)))
  (type $t2 (func (result i32)))
  (func $__wasm_call_ctors (type $t0))
  (func $mod (export "mod") (type $t1) (param $p0 f64) (param $p1 f64) (result f64)
    get_local $p0
    get_local $p1
    call $fmod)
  (func $main (export "main") (type $t2) (result i32)
    i32.const 42)
  (func $fmod (type $t1) (param $p0 f64) (param $p1 f64) (result f64)
    (local $l0 i64) (local $l1 i64) (local $l2 i64) (local $l3 i32) (local $l4 i64) (local $l5 i32) (local $l6 i32)
    block $B0
      block $B1
        block $B2
          block $B3
            block $B4
              block $B5
                get_local $p1
                i64.reinterpret/f64
                tee_local $l0
                i64.const 1
                i64.shl
                tee_local $l1
                i64.eqz
                br_if $B5
                get_local $l0
                i64.const 9223372036854775807
                i64.and
                i64.const 9218868437227405312
                i64.gt_u
                br_if $B5
                get_local $p0
                i64.reinterpret/f64
                tee_local $l2
                i64.const 52
                i64.shr_u
                i32.wrap/i64
                i32.const 2047
                i32.and
                tee_local $l3
                i32.const 2047
                i32.eq
                br_if $B5
                get_local $l2
                i64.const 1
                i64.shl
                tee_local $l4
                get_local $l1
                i64.le_u
                br_if $B4
                get_local $l0
                i64.const 52
                i64.shr_u
                i32.wrap/i64
                i32.const 2047
                i32.and
                set_local $l5
                get_local $l3
                i32.eqz
                br_if $B3
                get_local $l2
                i64.const 4503599627370495
                i64.and
                i64.const 4503599627370496
                i64.or
                set_local $l1
                get_local $l5
                i32.eqz
                br_if $B2
                br $B1
              end
              get_local $p0
              get_local $p1
              f64.mul
              tee_local $p1
              get_local $p1
              f64.div
              return
            end
            get_local $p0
            f64.const 0x0p+0 (;=0;)
            f64.mul
            get_local $p0
            get_local $l4
            get_local $l1
            i64.eq
            select
            return
          end
          i32.const 0
          set_local $l3
          block $B6
            get_local $l2
            i64.const 12
            i64.shl
            tee_local $l1
            i64.const 0
            i64.lt_s
            br_if $B6
            loop $L7
              get_local $l3
              i32.const -1
              i32.add
              set_local $l3
              get_local $l1
              i64.const 1
              i64.shl
              tee_local $l1
              i64.const -1
              i64.gt_s
              br_if $L7
            end
          end
          get_local $l2
          i32.const 1
          get_local $l3
          i32.sub
          i64.extend_u/i32
          i64.shl
          set_local $l1
          get_local $l5
          br_if $B1
        end
        i32.const 0
        set_local $l5
        block $B8
          get_local $l0
          i64.const 12
          i64.shl
          tee_local $l4
          i64.const 0
          i64.lt_s
          br_if $B8
          loop $L9
            get_local $l5
            i32.const -1
            i32.add
            set_local $l5
            get_local $l4
            i64.const 1
            i64.shl
            tee_local $l4
            i64.const -1
            i64.gt_s
            br_if $L9
          end
        end
        get_local $l0
        i32.const 1
        get_local $l5
        i32.sub
        i64.extend_u/i32
        i64.shl
        set_local $l0
        br $B0
      end
      get_local $l0
      i64.const 4503599627370495
      i64.and
      i64.const 4503599627370496
      i64.or
      set_local $l0
    end
    get_local $l1
    get_local $l0
    i64.sub
    tee_local $l4
    i64.const -1
    i64.gt_s
    set_local $l6
    block $B10
      block $B11
        block $B12
          get_local $l3
          get_local $l5
          i32.le_s
          br_if $B12
          loop $L13
            block $B14
              get_local $l6
              i32.const 1
              i32.and
              i32.eqz
              br_if $B14
              get_local $l4
              set_local $l1
              get_local $l4
              i64.const 0
              i64.eq
              br_if $B11
            end
            get_local $l1
            i64.const 1
            i64.shl
            tee_local $l1
            get_local $l0
            i64.sub
            tee_local $l4
            i64.const -1
            i64.gt_s
            set_local $l6
            get_local $l3
            i32.const -1
            i32.add
            tee_local $l3
            get_local $l5
            i32.gt_s
            br_if $L13
          end
        end
        block $B15
          get_local $l6
          i32.eqz
          br_if $B15
          get_local $l4
          set_local $l1
          get_local $l4
          i64.const 0
          i64.eq
          br_if $B10
        end
        block $B16
          get_local $l1
          i64.const 4503599627370495
          i64.gt_u
          br_if $B16
          loop $L17
            get_local $l3
            i32.const -1
            i32.add
            set_local $l3
            get_local $l1
            i64.const 1
            i64.shl
            tee_local $l1
            i64.const 4503599627370496
            i64.lt_u
            br_if $L17
          end
        end
        get_local $l2
        i64.const -9223372036854775808
        i64.and
        set_local $l4
        block $B18
          get_local $l3
          i32.const 1
          i32.lt_s
          br_if $B18
          get_local $l1
          i64.const -4503599627370496
          i64.add
          get_local $l3
          i64.extend_u/i32
          i64.const 52
          i64.shl
          i64.or
          get_local $l4
          i64.or
          f64.reinterpret/i64
          return
        end
        get_local $l1
        i32.const 1
        get_local $l3
        i32.sub
        i64.extend_u/i32
        i64.shr_u
        get_local $l4
        i64.or
        f64.reinterpret/i64
        return
      end
      get_local $p0
      f64.const 0x0p+0 (;=0;)
      f64.mul
      return
    end
    get_local $p0
    f64.const 0x0p+0 (;=0;)
    f64.mul)
  (table $T0 1 1 anyfunc)
  (memory $memory (export "memory") 2)
  (global $g0 (mut i32) (i32.const 66560))
  (global $__heap_base (export "__heap_base") i32 (i32.const 66560))
  (global $__data_end (export "__data_end") i32 (i32.const 1024)))
@captbaritone
Copy link
Owner Author

@captbaritone
Copy link
Owner Author

void nseel_asm_mod(void)
{
  __asm__(
    "fld" EEL_F_SUFFIX " (%edi)\n"
    "fld" EEL_F_SUFFIX " (%eax)\n"
    "fabs\n"
    "fistpl (%esi)\n"
    "fabs\n"
    "fistpl 4(%esi)\n"
    "xorl %edx, %edx\n"
#ifdef TARGET_X64
    "subl %eax, %eax\n"
#endif
    "cmpl $0, (%esi)\n"
    "je 0f\n" // skip devide, set return to 0
    "movl 4(%esi), %eax\n"
    "divl (%esi)\n"
    "0:\n"
    "movl %edx, (%esi)\n"
    "fildl (%esi)\n"
    "movl %esi, %eax\n"
    "fstp" EEL_F_SUFFIX " (%esi)\n"
    "addl $" EEL_F_SSTR ", %esi\n"
  );
}

@captbaritone
Copy link
Owner Author

Auto-close was due to a typo in commit message

@captbaritone captbaritone reopened this May 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant