;;; TOOL: run-wasm-decompile

(module
  (memory $m1 1)

  (data 0 (offset (i32.const 10)) "Hello, World!\n\00")

  (func $f (param i32 i32) (result) (local i32 i32 i32 i32 i32 i32)
    ;; Test regular accesses that become a struct.
    local.get 0
    f32.load offset=0
    local.get 2
    f32.load offset=0
    f32.add
    local.get 0
    f32.load offset=4
    local.get 2
    f32.load offset=4
    f32.add
    f32.add
    drop
    local.get 1
    i64.load16_u offset=0
    local.get 3
    i64.load16_u offset=0
    i64.add
    local.get 1
    i64.load offset=8
    local.get 3
    i64.load offset=8
    i64.add
    i64.add
    drop
    ;; Test things that do not become a struct for various reasons.
    ;; 1) Mixed type access.
    local.get 4
    i32.load offset=0
    drop
    local.get 4
    f32.load offset=0
    drop
    ;; 2) Mixed size access.
    local.get 5
    i32.load offset=0
    drop
    local.get 5
    i32.load16_s offset=0
    drop
    ;; 3) Mixed align requirement access.
    local.get 6
    i32.load offset=0
    drop
    local.get 6
    i32.load offset=0 align=1
    drop
    ;; 4) Unaligned access / access with unexpected gaps.
    local.get 7
    f32.load offset=1 align=1
    drop
    ;; Test index rewriting.
    ;; code that does (base + (index << 2))[0]:int is super common.
    local.get 0
    local.get 1
    i32.const 2
    i32.shl
    i32.add
    local.get 0
    local.get 1
    i32.const 2
    i32.shl
    i32.add
    i32.load offset=0
    i32.store offset=0
    ;; Same with non-zero offsets.
    local.get 0
    local.get 1
    i32.const 2
    i32.shl
    i32.add
    local.get 0
    local.get 1
    i32.const 2
    i32.shl
    i32.add
    i32.load offset=4
    i32.store offset=4
    ;; If the shift amount does not match, it doesn't work.
    local.get 0
    local.get 1
    i32.const 3
    i32.shl
    i32.add
    local.get 0
    local.get 1
    i32.const 2
    i32.shl
    i32.add
    i32.load offset=4
    i32.store offset=4
    ;; Test naming of absolute addresses referring to data sections.
    i32.const 16
    i32.load8_u offset=1  ;; Refers to the 'W'
    drop
  )
  (export "f" (func $f))
)

(;; STDOUT ;;;
memory M_a(initial: 1, max: 0);

data d_HelloWorld(offset: 10) = "Hello, World!\0a\00";

export function f(a:{ a:float, b:float }, b:{ a:ushort, b:long }) { // func0
  var c:{ a:float, b:float }
  var d:{ a:ushort, b:long }
  var e:int;
  var f:int;
  var g:int;
  var h:float_ptr@1;
  a.a + c.a + a.b + c.b;
  b.a + d.a + b.b + d.b;
  e[0]:int;
  e[0]:float;
  f[0]:int;
  f[0]:short;
  g[0]:int;
  g[0]:int@1;
  h[1];
  a[b]:int = a[b]:int;
  a[b + 1]:int = a[b + 1]:int;
  (a + (b << 3))[1]:int = a[b + 1]:int;
  d_HelloWorld[7]:ubyte;
}

;;; STDOUT ;;)
