3

I'm trying to generate a .wat file with i64, but it is just compiling to i32.

In the C code I tested using int and int64_t, but I haven't success.

This is the C code:

#include <stdio.h>
#include <stdint.h>

#define MAX 64

int main(void) {
    int64_t v1[MAX], v2[MAX], v3[MAX];
    int64_t i;

    for(i = 0; i < MAX; i++)
       v3[i] = v1[i] + v2[i];

    for(i = 0; i < MAX; i++)
        printf("%llu\n", v3[i]);

    return 0;
}

Then I use the CLI to compile to .wasm and .wat format:

$ emcc -Oz ex1.c -s WASM=1 -s SIDE_MODULE=1 -s ONLY_MY_CODE=1 -o ex1.wasm
$ wasm2wat ex1.wasm -o ex1.wat

This is the .wat file compiled:

(module
(type (;0;) (func (result i32)))
(type (;1;) (func (param i32 i32 i32 i32) (result i32)))
(type (;2;) (func (param i32 i32) (result i32)))
(type (;3;) (func))
(import "env" "getTempRet0" (func (;0;) (type 0)))
(import "env" "_i64Add" (func (;1;) (type 1)))
(import "env" "_printf" (func (;2;) (type 2)))
(import "env" "memoryBase" (global (;0;) i32))
(import "env" "memory" (memory (;0;) 256))
(func (;3;) (type 0) (result i32)
    (local i32 i32 i32 i32 i32 i32 i32 i32 i32)
    get_global 1
    set_local 2
    get_global 1
    i32.const 1552
    i32.add
    set_global 1
    get_local 2
    i32.const 1536
    i32.add
    set_local 5
    get_local 2
    i32.const 1024
    i32.add
    set_local 7
    get_local 2
    i32.const 512
    i32.add
    set_local 8
    loop  ;; label = @1
    get_local 4
    i32.const 0
    i32.lt_u
    get_local 4
    i32.eqz
    get_local 0
    i32.const 64
    i32.lt_u
    i32.and
    i32.or
    if  ;; label = @2
    get_local 8
    get_local 0
    i32.const 3
    i32.shl
    i32.add
    tee_local 1
    i32.load
    get_local 1
    i32.load offset=4
    get_local 7
    get_local 0
    i32.const 3
    i32.shl
    i32.add
    tee_local 1
    i32.load
    get_local 1
    i32.load offset=4
    call 1
    set_local 3
    call 0
    set_local 6
    get_local 2
    get_local 0
    i32.const 3
    i32.shl
    i32.add
    tee_local 1
    get_local 3
    i32.store
    get_local 1
    get_local 6
    i32.store offset=4
    get_local 0
    get_local 4
    i32.const 1
    i32.const 0
    call 1
    set_local 0
    call 0
    set_local 4
    br 1 (;@1;)
    end
    end
    i32.const 0
    set_local 3
    i32.const 0
    set_local 0
    loop  ;; label = @1
    get_local 3
    i32.const 0
    i32.lt_u
    get_local 3
    i32.eqz
    get_local 0
    i32.const 64
    i32.lt_u
    i32.and
    i32.or
    if  ;; label = @2
    get_local 2
    get_local 0
    i32.const 3
    i32.shl
    i32.add
    tee_local 6
    i32.load offset=4
    set_local 1
    get_local 5
    get_local 6
    i32.load
    i32.store
    get_local 5
    get_local 1
    i32.store offset=4
    get_global 0
    get_local 5
    call 2
    drop
    get_local 0
    get_local 3
    i32.const 1
    i32.const 0
    call 1
    set_local 0
    call 0
    set_local 3
    br 1 (;@1;)
    end
    end
    get_local 2
    set_global 1
    i32.const 0)
    (func (;4;) (type 3)
          get_global 0
          i32.const 16
          i32.add
          set_global 1
          get_global 1
          i32.const 5242880
          i32.add
          set_global 2)
    (global (;1;) (mut i32) (i32.const 0))
(global (;2;) (mut i32) (i32.const 0))
(export "__post_instantiate" (func 4))
(export "_main" (func 3))
(data (get_global 0) "%llu\0a"))

I was looking into mbebenita WebAssembly Explorer code, but it is a little confused to me, but I know it generates both i64 and x86 Assembly.

I know I can use WebAssembly Explorer to generate my .wat file and x86 assembly, but in my case, I need to compile using CLI for that.

Clauber Stipkovic
  • 123
  • 1
  • 1
  • 8
  • 2
    When you say "both i64 and x86 Assembly.", you hopefully mean x86-64. That's not necessarily related to the WASM using 32-bit types; hopefully a smart compiler could optimize `i32` add + add-with-carry in the WASM into a single 64-bit add in x86-64 asm. – Peter Cordes Oct 29 '18 at 21:07
  • 1
    WASM does allow using `i64` types: https://mbebenita.github.io/WasmExplorer/?state=%7B%22options%22%3A%7B%22showGutter%22%3Atrue%2C%22showConsole%22%3Atrue%2C%22showOptions%22%3Atrue%2C%22autoCompile%22%3Atrue%2C%22showLLVM%22%3Atrue%2C%22darkMode%22%3Atrue%2C%22fastMath%22%3Afalse%2C%22noInline%22%3Afalse%2C%22noRTTI%22%3Afalse%2C%22noExceptions%22%3Afalse%2C%22cleanWast%22%3Afalse%2C%22wasmBaseline%22%3Afalse%2C%22dialect%22%3A%22C%2B%2B11%22%2C%22optimizationLevel%22%3A%223%22%7D%2C%22source%22%3A%22long%20long%20add(long%20long%20a)%20%7B%20return%20a%2Ba%3B%20%7D%22%7D – Peter Cordes Oct 29 '18 at 21:12
  • I don't know if I'm right but when I mean i64 (inside .wast), yout code on WasmExplorer shows this: (module (table 0 anyfunc) (memory $0 1) (export "memory" (memory $0)) (export "_Z3addx" (func $_Z3addx)) (func $_Z3addx (; 0 ;) (param $0 i64) (result i64) (i64.shl (get_local $0) (i64.const 1) ) ) ) – Clauber Stipkovic Oct 29 '18 at 23:09
  • Another question, there is some whey to get a C code and compile it to x86-64 asm? – Clauber Stipkovic Oct 29 '18 at 23:12
  • 1
    WasmExplorer already has a pane that shows clang/LLVM output for C++ -> x86-64 asm directly. As you can see, it's more efficient than "Firefox x86-64" even for that trivial `return x+x` function, using one `lea rax, [rdi + rdi]` instead of multiple useless `mov` instructions around an `add`. But **there's an even nicer site for C / C++ to x86 32-bit, x86-64, ARM, PowerPC, or whatever asm: Matt Godbolt's compiler explorer site: https://godbolt.org/** See [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116). – Peter Cordes Oct 29 '18 at 23:27
  • 1
    " -s LEGALIZE_JS_FFI=0" works for me. But '-s ONLY_MY_CODE=1' causes error with that option. – zakki Nov 01 '18 at 06:51

1 Answers1

5

When you build with SIDE_MODULE=1 by default emscripten will build a module that is compatible with asmjs by default which means it won't assume native 64-bit support.

It looks like there is a plan to fix this limitation: https://github.com/kripken/emscripten/blob/fd38f3bbf1fdc2f48078f641eb57b1c6fa2a538f/tools/shared.py#L2316 https://github.com/kripken/emscripten/blob/fd38f3bbf1fdc2f48078f641eb57b1c6fa2a538f/emscripten.py#L485

Looks like like if you want native i64 support you can't use SIDE_MODULE today.

sbc100
  • 2,619
  • 14
  • 11