Firefox 如何从C代码生成i64而不是i32的Webassembly(WAT)

Firefox 如何从C代码生成i64而不是i32的Webassembly(WAT),firefox,x86-64,emscripten,webassembly,Firefox,X86 64,Emscripten,Webassembly,我试图用i64生成一个.wat文件,但它只是编译成i32 在C代码中,我使用int和int64\t进行了测试,但没有成功 这是C代码: #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[

我试图用i64生成一个.wat文件,但它只是编译成i32

在C代码中,我使用int和int64\t进行了测试,但没有成功

这是C代码:

#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;
}
$ 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
(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"))
这是编译的.wat文件:

#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;
}
$ 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
(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"))
我正在研究MBebineta WebAssembly Explorer代码,但我有点困惑,但我知道它同时生成i64和x86程序集


我知道我可以使用WebAssembly Explorer生成.wat文件和x86程序集,但在我的情况下,我需要使用CLI进行编译。

当默认情况下使用SIDE_MODULE=1构建时,emscripten将构建一个默认情况下与asmjs兼容的模块,这意味着它不会采用本机64位支持

似乎有一个计划来修复此限制:


看起来,如果您想要本机i64支持,您今天就不能使用SIDE_模块。

当您说“i64和x86汇编”时,您希望是指x86-64。这不一定与使用32位类型的WASM有关;希望智能编译器能够将WASM中的带进位的
i32
add+add优化为单个64位插件x86-64 asm。WASM确实允许使用
i64
类型:我不知道我是否正确,但当我指的是i64(inside.wast)时,WasmExplorer上的yout代码显示如下:(模块(表0 anyfunc)(内存$0 1)(导出“内存”)(内存0美元)(导出)“Z3ADDX”(FUNC$Z3ADDX(0;)(PARAM 0 I64)(结果I64)(I64.SHIL(GETSHIVE ONTHORY 0))(I64.CONST 1))WASMExcel已经有一个窗格,显示CLAN/LVVM输出,直接用于C++ +X8664 ASM。即使对于那个微不足道的<代码>返回x+x/c>函数,使用一个代码> LEARAX,[RDI+RDI] < /COD>而不是多个无用的<代码> MOV < /C> >围绕<代码> >添加< /代码>。但是对于C++/x++,有一个更好的站点,可以指向x86 32位、x86—64、ARM、PowerPC或任何ASM:Matt Godbolt的编译器资源管理器站点:参见。“-s LEGALIZE_JS_FFI=0”对我来说很有效。但是“-s ONLY_MY_CODE=1”会导致该选项出错。