Take advantage of smaller integer load and store ops

This commit is contained in:
dcodeIO 2018-01-23 15:44:25 +01:00
parent 5d142ba647
commit 2fa7fc7885
13 changed files with 719 additions and 124 deletions

View File

@ -21,9 +21,11 @@ export function step(): void {
for (var x: u32 = 0; x < w; ++x) {
var xm1 = select<u32>(wm1, x - 1, x == 0),
xp1 = select<u32>(0, x + 1, x == wm1);
var n = load<u8>(ym1 * w + xm1) + load<u8>(ym1 * w + x) + load<u8>(ym1 * w + xp1)
+ load<u8>(y * w + xm1) + load<u8>(y * w + xp1)
+ load<u8>(yp1 * w + xm1) + load<u8>(yp1 * w + x) + load<u8>(yp1 * w + xp1);
var n = (
load<u8>(ym1 * w + xm1) + load<u8>(ym1 * w + x) + load<u8>(ym1 * w + xp1) +
load<u8>(y * w + xm1) + load<u8>(y * w + xp1) +
load<u8>(yp1 * w + xm1) + load<u8>(yp1 * w + x) + load<u8>(yp1 * w + xp1)
);
if (load<u8>(y * w + x)) {
if (n < 2 || n > 3)
store<u8>(s + y * w + x, 0);

View File

@ -1338,7 +1338,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
// memory access
case "load": // load<T!>(offset: usize, constantOffset?: usize) -> T
case "load": // load<T!>(offset: usize, constantOffset?: usize) -> *
if (operands.length < 1 || operands.length > 2) {
if (!(typeArguments && typeArguments.length == 1))
compiler.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0");
@ -1358,37 +1358,43 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
offset = operands.length == 2 ? evaluateConstantOffset(compiler, operands[1]) : 0; // reports
if (offset < 0)
return module.createUnreachable();
compiler.currentType = typeArguments[0];
return module.createLoad(typeArguments[0].byteSize, typeArguments[0].is(TypeFlags.SIGNED | TypeFlags.INTEGER), arg0, typeArguments[0].toNativeType(), offset);
return module.createLoad(typeArguments[0].byteSize, typeArguments[0].is(TypeFlags.SIGNED | TypeFlags.INTEGER), arg0,
typeArguments[0].is(TypeFlags.INTEGER) && contextualType.is(TypeFlags.INTEGER) && contextualType.size >= typeArguments[0].size
? (compiler.currentType = contextualType).toNativeType()
: (compiler.currentType = typeArguments[0]).toNativeType()
, offset);
case "store": // store<T?>(offset: usize, value: T, constantOffset?: usize) -> void
case "store": // store<T!>(offset: usize, value: *, constantOffset?: usize) -> void
compiler.currentType = Type.void;
if (operands.length < 2 || operands.length > 3) {
if (typeArguments && typeArguments.length != 1)
compiler.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, reportNode.range, "1", typeArguments.length.toString(10));
if (!(typeArguments && typeArguments.length == 1))
compiler.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0");
if (operands.length < 2)
compiler.error(DiagnosticCode.Expected_at_least_0_arguments_but_got_1, reportNode.range, "2", operands.length.toString(10));
else
compiler.error(DiagnosticCode.Expected_0_arguments_but_got_1, reportNode.range, "3", operands.length.toString(10));
return module.createUnreachable();
}
if (typeArguments) {
if (typeArguments.length != 1) {
compiler.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, reportNode.range, "1", typeArguments.length.toString(10));
return module.createUnreachable();
}
arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType);
arg1 = compiler.compileExpression(operands[1], typeArguments[0]);
} else {
arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType);
arg1 = compiler.compileExpression(operands[1], Type.i32, ConversionKind.NONE);
if (!(typeArguments && typeArguments.length == 1)) {
compiler.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0");
return module.createUnreachable();
}
type = compiler.currentType;
arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType);
arg1 = compiler.compileExpression(operands[1], typeArguments[0],
typeArguments[0].is(TypeFlags.INTEGER)
? ConversionKind.NONE // wraps a larger integer type to a smaller one, i.e. i32.store8
: ConversionKind.IMPLICIT
);
if (compiler.currentType.is(TypeFlags.INTEGER) && typeArguments[0].is(TypeFlags.INTEGER) && typeArguments[0].size > compiler.currentType.size) {
arg1 = compiler.convertExpression(arg1, compiler.currentType, typeArguments[0], ConversionKind.IMPLICIT, operands[1]);
type = typeArguments[0];
} else
type = compiler.currentType;
offset = operands.length == 3 ? evaluateConstantOffset(compiler, operands[2]) : 0; // reports
if (offset < 0)
return module.createUnreachable();
compiler.currentType = Type.void;
return module.createStore(type.byteSize, arg0, arg1, type.toNativeType(), offset);
return module.createStore(typeArguments[0].byteSize, arg0, arg1, type.toNativeType(), offset);
case "sizeof": // sizeof<T!>() -> usize
compiler.currentType = compiler.options.usizeType;

View File

@ -578,15 +578,15 @@ export class Compiler extends DiagnosticEmitter {
// compile statements
var stmts: ExpressionRef[] | null = null;
if (!instance.is(ElementFlags.DECLARED)) {
declaration = assert(declaration);
declaration = assert(declaration, "declaration expected");
var previousFunction = this.currentFunction;
this.currentFunction = instance;
var statements = assert(declaration.statements);
var statements = assert(declaration.statements, "implementation expected");
stmts = this.compileStatements(statements);
// make sure the top-level branch or all child branches return
var allBranchesReturn = this.currentFunction.flow.finalize();
if (instance.returnType != Type.void && !allBranchesReturn)
this.error(DiagnosticCode.A_function_whose_declared_type_is_not_void_must_return_a_value, assert(declaration.returnType).range);
this.error(DiagnosticCode.A_function_whose_declared_type_is_not_void_must_return_a_value, assert(declaration.returnType, "return type expected").range);
this.currentFunction = previousFunction;
}
@ -895,6 +895,7 @@ export class Compiler extends DiagnosticEmitter {
this.error(DiagnosticCode.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement, statement.range);
return this.module.createUnreachable();
}
this.currentFunction.flow.set(FlowFlags.POSSIBLY_BREAKS);
return this.module.createBreak(breakLabel);
}
@ -909,6 +910,7 @@ export class Compiler extends DiagnosticEmitter {
this.error(DiagnosticCode.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement, statement.range);
return this.module.createUnreachable();
}
this.currentFunction.flow.set(FlowFlags.POSSIBLY_CONTINUES);
return this.module.createBreak(continueLabel);
}
@ -1022,8 +1024,6 @@ export class Compiler extends DiagnosticEmitter {
}
compileReturnStatement(statement: ReturnStatement): ExpressionRef {
assert(this.currentFunction);
var expression: ExpressionRef = 0;
if (statement.value)
expression = this.compileExpression(<Expression>statement.value, this.currentFunction.returnType);
@ -1353,7 +1353,7 @@ export class Compiler extends DiagnosticEmitter {
convertExpression(expr: ExpressionRef, fromType: Type, toType: Type, conversionKind: ConversionKind, reportNode: Node): ExpressionRef {
if (conversionKind == ConversionKind.NONE) {
assert(false);
assert(false, "concrete type expected");
return expr;
}
@ -1437,7 +1437,7 @@ export class Compiler extends DiagnosticEmitter {
// float to void
} else {
assert(toType.flags == TypeFlags.NONE);
assert(toType.flags == TypeFlags.NONE, "void type expected");
expr = this.module.createDrop(expr);
}
@ -2296,11 +2296,10 @@ export class Compiler extends DiagnosticEmitter {
// otherwise make use of the temp. local
else {
assert(tempLocal);
expr = this.module.createIf(
condition,
right,
this.module.createGetLocal((<Local>tempLocal).index, this.currentType.toNativeType())
this.module.createGetLocal(assert(tempLocal, "tempLocal must be set").index, this.currentType.toNativeType())
);
}
break;
@ -2331,10 +2330,9 @@ export class Compiler extends DiagnosticEmitter {
// otherwise make use of the temp. local
else {
assert(tempLocal);
expr = this.module.createIf(
condition,
this.module.createGetLocal((<Local>tempLocal).index, this.currentType.toNativeType()),
this.module.createGetLocal(assert(tempLocal, "tempLocal must be set").index, this.currentType.toNativeType()),
right
);
}
@ -2345,7 +2343,7 @@ export class Compiler extends DiagnosticEmitter {
throw new Error("not implemented");
}
if (possiblyOverflows && wrapSmallIntegers) {
assert(this.currentType.is(TypeFlags.SMALL | TypeFlags.INTEGER));
assert(this.currentType.is(TypeFlags.SMALL | TypeFlags.INTEGER)), "small integer type expected";
expr = makeSmallIntegerWrap(expr, this.currentType, this.module);
}
return compound
@ -2366,7 +2364,7 @@ export class Compiler extends DiagnosticEmitter {
case ElementKind.GLOBAL:
if (!this.compileGlobal(<Global>element)) // reports; not yet compiled if a static field compiled as a global
return this.module.createUnreachable();
assert((<Global>element).type != Type.void);
assert((<Global>element).type != Type.void, "concrete type expected");
// fall-through
case ElementKind.LOCAL:
@ -2429,7 +2427,7 @@ export class Compiler extends DiagnosticEmitter {
case ElementKind.GLOBAL:
if (!this.compileGlobal(<Global>element)) // reports; not yet compiled if a static field compiled as a global
return this.module.createUnreachable();
assert((<Global>element).type != Type.void);
assert((<Global>element).type != Type.void, "concrete type expected");
this.currentType = tee ? (<Global>element).type : Type.void;
if ((<Local>element).is(ElementFlags.CONSTANT)) {
this.error(DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, expression.range, (<Local>element).internalName);
@ -2448,9 +2446,9 @@ export class Compiler extends DiagnosticEmitter {
this.error(DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, expression.range, (<Field>element).internalName);
return this.module.createUnreachable();
}
assert(resolved.targetExpression != null);
assert(resolved.targetExpression != null, "target expression expected");
targetExpr = this.compileExpression(<Expression>resolved.targetExpression, this.options.target == Target.WASM64 ? Type.usize64 : Type.usize32, ConversionKind.NONE);
assert(this.currentType.classType);
assert(this.currentType.classType, "class type expected");
this.currentType = tee ? (<Field>element).type : Type.void;
var elementNativeType = (<Field>element).type.toNativeType();
if (!tee)

View File

@ -240,7 +240,8 @@ export class Module {
ref: ModuleRef;
lit: BinaryenLiteral;
static MAX_MEMORY_WASM32: Index = 0xffff;
static readonly MAX_MEMORY_WASM32: Index = 0xffff;
// TODO: static readonly MAX_MEMORY_WASM64
static create(): Module {
var module = new Module();

View File

@ -2134,6 +2134,10 @@ export const enum FlowFlags {
RETURNS = 1 << 0,
/** This branch possibly throws. */
POSSIBLY_THROWS = 1 << 1,
/** This branch possible breaks. */
POSSIBLY_BREAKS = 1 << 2,
/** This branch possible continues. */
POSSIBLY_CONTINUES = 1 << 3
}
/** A control flow evaluator. */
@ -2185,17 +2189,22 @@ export class Flow {
/** Leaves the current branch or scope and returns the parent flow. */
leaveBranchOrScope(): Flow {
var parent = assert(this.parent);
// Free block-scoped locals
if (this.scopedLocals) {
for (var scopedLocal of this.scopedLocals.values())
this.currentFunction.freeTempLocal(scopedLocal);
this.scopedLocals = null;
}
// Mark parent as THROWS if any child throws
if (this.is(FlowFlags.POSSIBLY_THROWS))
parent.set(FlowFlags.POSSIBLY_THROWS);
this.continueLabel = null;
this.breakLabel = null;
// Propagate flags to parent
if (this.is(FlowFlags.POSSIBLY_THROWS))
parent.set(FlowFlags.POSSIBLY_THROWS);
if (this.is(FlowFlags.POSSIBLY_BREAKS) && parent.breakLabel == this.breakLabel)
parent.set(FlowFlags.POSSIBLY_BREAKS);
if (this.is(FlowFlags.POSSIBLY_CONTINUES) && parent.continueLabel == this.continueLabel)
parent.set(FlowFlags.POSSIBLY_CONTINUES);
return parent;
}

4
std/assembly.d.ts vendored
View File

@ -155,9 +155,9 @@ declare function sqrt<T = f32 | f64>(value: T): T;
/** Rounds to the nearest integer towards zero of a 32-bit or 64-bit float. */
declare function trunc<T = f32 | f64>(value: T): T;
/** Loads a value of the specified type from memory. Equivalent to dereferncing a pointer in other languages. */
declare function load<T>(ptr: usize, constantOffset?: usize): T;
declare function load<T>(ptr: usize, constantOffset?: usize): any;
/** Stores a value of the specified type to memory. Equivalent to dereferencing a pointer in other languages when assigning a value. */
declare function store<T>(ptr: usize, value: T, constantOffset?: usize): void;
declare function store<T>(ptr: usize, value: any, constantOffset?: usize): void;
/** Returns the current memory size in units of pages. One page is 64kb. */
declare function current_memory(): i32;
/** Grows linear memory by a given unsigned delta of pages. One page is 64kb. Returns the previous memory size in units of pages or `-1` on failure. */

View File

@ -5,6 +5,8 @@
(global $builtins/I (mut i64) (i64.const 0))
(global $builtins/f (mut f32) (f32.const 0))
(global $builtins/F (mut f64) (f64.const 0))
(global $builtins/u (mut i32) (i32.const 0))
(global $builtins/U (mut i64) (i64.const 0))
(global $builtins/s (mut i32) (i32.const 0))
(memory $0 1)
(export "test" (func $builtins/test))
@ -414,6 +416,138 @@
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load8_s
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load16_s
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load8_u
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load16_u
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load8_u
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load16_u
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load8_s
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load16_s
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load8_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load16_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load32_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load8_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load16_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load32_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load
(i32.const 8)
)
)
(i32.store8
(i32.const 8)
(i32.const 1)
)
(i32.store16
(i32.const 8)
(i32.const 1)
)
(i32.store
(i32.const 8)
(i32.const 1)
)
(i64.store8
(i32.const 8)
(i64.const 1)
)
(i64.store16
(i32.const 8)
(i64.const 1)
)
(i64.store32
(i32.const 8)
(i64.const 1)
)
(i64.store
(i32.const 8)
(i64.const 1)
)
(i64.store
(i32.const 8)
(i64.const 1)
)
(set_global $builtins/i
(i32.const 1067450368)
)

View File

@ -125,6 +125,47 @@ store<f32>(0, load<f32>(0, constantOffset), constantOffset);
F = load<f64>(0, constantOffset); store<f64>(0, F, constantOffset);
store<f64>(0, load<f64>(0, constantOffset), constantOffset);
// load and store smaller types
i = load<i8>(8);
i = load<i16>(8);
i = load<i32>(8);
i = load<u8>(8);
i = load<u16>(8);
i = load<u32>(8);
var u: u32;
u = load<u8>(8);
u = load<u16>(8);
u = load<u32>(8);
u = load<i8>(8);
u = load<i16>(8);
u = load<i32>(8);
I = load<i8>(8);
I = load<i16>(8);
I = load<i32>(8);
I = load<i64>(8);
var U: u64;
U = load<u8>(8);
U = load<u16>(8);
U = load<u32>(8);
U = load<u64>(8);
store<i8>(8, <i32>1);
store<i16>(8, <i32>1);
store<i32>(8, <i32>1);
store<i8>(8, <i64>1);
store<i16>(8, <i64>1);
store<i32>(8, <i64>1);
store<i64>(8, <i64>1);
store<i64>(8, <i32>1); // must extend
// reinterpretation
reinterpret<i32>(1.25);

View File

@ -7,6 +7,8 @@
(global $builtins/f (mut f32) (f32.const 0))
(global $builtins/F (mut f64) (f64.const 0))
(global $builtins/constantOffset i32 (i32.const 8))
(global $builtins/u (mut i32) (i32.const 0))
(global $builtins/U (mut i64) (i64.const 0))
(global $builtins/s (mut i32) (i32.const 0))
(global $i8.MIN_VALUE i32 (i32.const -128))
(global $i8.MAX_VALUE i32 (i32.const 127))
@ -810,6 +812,140 @@
(i32.const 0)
)
)
(set_global $builtins/i
(i32.load8_s
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load16_s
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load8_u
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load16_u
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load8_u
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load16_u
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load8_s
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load16_s
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load8_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load16_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load32_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load8_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load16_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load32_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load
(i32.const 8)
)
)
(i32.store8
(i32.const 8)
(i32.const 1)
)
(i32.store16
(i32.const 8)
(i32.const 1)
)
(i32.store
(i32.const 8)
(i32.const 1)
)
(i64.store8
(i32.const 8)
(i64.const 1)
)
(i64.store16
(i32.const 8)
(i64.const 1)
)
(i64.store32
(i32.const 8)
(i64.const 1)
)
(i64.store
(i32.const 8)
(i64.const 1)
)
(i64.store
(i32.const 8)
(i64.extend_s/i32
(i32.const 1)
)
)
(drop
(i32.reinterpret/f32
(f32.const 1.25)
@ -1454,6 +1590,8 @@
GLOBAL: builtins/f
GLOBAL: builtins/F
GLOBAL: builtins/constantOffset
GLOBAL: builtins/u
GLOBAL: builtins/U
GLOBAL: builtins/s
FUNCTION_PROTOTYPE: builtins/test
[program.exports]

View File

@ -84,39 +84,28 @@
)
(block
(set_local $2
(i32.and
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
(i32.load8_u
(i32.add
(i32.mul
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(tee_local $2
(select
(i32.sub
(get_local $1)
(i32.const 1)
)
(get_local $6)
(get_local $1)
)
)
(i32.load8_u
(i32.add
(i32.mul
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
)
(i32.load8_u
(i32.add
(i32.mul
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
(tee_local $2
(select
(i32.sub
(get_local $1)
(i32.const 1)
)
(get_local $6)
(get_local $1)
)
(get_local $1)
)
)
)
@ -126,29 +115,29 @@
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(tee_local $7
(select
(i32.const 0)
(i32.add
(get_local $1)
(i32.const 1)
)
(i32.eq
(get_local $1)
(get_local $6)
)
)
)
(get_local $1)
)
)
)
(i32.load8_u
(i32.add
(i32.mul
(get_local $0)
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $2)
(tee_local $7
(select
(i32.const 0)
(i32.add
(get_local $1)
(i32.const 1)
)
(i32.eq
(get_local $1)
(get_local $6)
)
)
)
)
)
)
@ -158,17 +147,17 @@
(get_local $0)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $7)
(get_local $2)
)
)
)
(i32.load8_u
(i32.add
(i32.mul
(get_local $4)
(get_local $0)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $2)
(get_local $7)
)
)
)
@ -178,7 +167,7 @@
(get_local $4)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $1)
(get_local $2)
)
)
)
@ -188,11 +177,19 @@
(get_local $4)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $7)
(get_local $1)
)
)
)
(i32.const 255)
(i32.load8_u
(i32.add
(i32.mul
(get_local $4)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $7)
)
)
)
)
(if
@ -208,15 +205,15 @@
(if
(i32.and
(select
(i32.lt_u
(i32.lt_s
(get_local $2)
(i32.const 2)
)
(i32.gt_u
(i32.gt_s
(get_local $2)
(i32.const 3)
)
(i32.lt_u
(i32.lt_s
(get_local $2)
(i32.const 2)
)

View File

@ -128,31 +128,20 @@
)
)
(set_local $8
(i32.and
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
(i32.load8_u
(i32.add
(i32.mul
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $6)
)
)
(i32.load8_u
(i32.add
(i32.mul
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $5)
(i32.load8_u
(i32.add
(i32.mul
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $6)
)
)
(i32.load8_u
@ -161,17 +150,17 @@
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $7)
(get_local $5)
)
)
)
(i32.load8_u
(i32.add
(i32.mul
(get_local $2)
(get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $6)
(get_local $7)
)
)
)
@ -181,17 +170,17 @@
(get_local $2)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $7)
(get_local $6)
)
)
)
(i32.load8_u
(i32.add
(i32.mul
(get_local $4)
(get_local $2)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $6)
(get_local $7)
)
)
)
@ -201,7 +190,7 @@
(get_local $4)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $5)
(get_local $6)
)
)
)
@ -211,11 +200,19 @@
(get_local $4)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $7)
(get_local $5)
)
)
)
(i32.const 255)
(i32.load8_u
(i32.add
(i32.mul
(get_local $4)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(get_local $7)
)
)
)
)
(if
@ -232,17 +229,17 @@
(i32.and
(if (result i32)
(i32.ne
(i32.lt_u
(i32.lt_s
(get_local $8)
(i32.const 2)
)
(i32.const 0)
)
(i32.lt_u
(i32.lt_s
(get_local $8)
(i32.const 2)
)
(i32.gt_u
(i32.gt_s
(get_local $8)
(i32.const 3)
)

View File

@ -24,6 +24,8 @@
(global $builtins/I (mut i64) (i64.const 0))
(global $builtins/f (mut f32) (f32.const 0))
(global $builtins/F (mut f64) (f64.const 0))
(global $builtins/u (mut i32) (i32.const 0))
(global $builtins/U (mut i64) (i64.const 0))
(global $builtins/s (mut i32) (i32.const 0))
(global $showcase/ANamespace.aNamespacedGlobal (mut i32) (i32.const 42))
(global $showcase/AnEnum.ONE i32 (i32.const 1))
@ -3658,6 +3660,138 @@
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load8_s
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load16_s
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load8_u
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load16_u
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load8_u
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load16_u
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load8_s
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load16_s
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load8_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load16_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load32_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load8_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load16_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load32_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load
(i32.const 8)
)
)
(i32.store8
(i32.const 8)
(i32.const 1)
)
(i32.store16
(i32.const 8)
(i32.const 1)
)
(i32.store
(i32.const 8)
(i32.const 1)
)
(i64.store8
(i32.const 8)
(i64.const 1)
)
(i64.store16
(i32.const 8)
(i64.const 1)
)
(i64.store32
(i32.const 8)
(i64.const 1)
)
(i64.store
(i32.const 8)
(i64.const 1)
)
(i64.store
(i32.const 8)
(i64.const 1)
)
(set_global $builtins/i
(i32.const 1067450368)
)

View File

@ -34,6 +34,8 @@
(global $builtins/f (mut f32) (f32.const 0))
(global $builtins/F (mut f64) (f64.const 0))
(global $builtins/constantOffset i32 (i32.const 8))
(global $builtins/u (mut i32) (i32.const 0))
(global $builtins/U (mut i64) (i64.const 0))
(global $builtins/s (mut i32) (i32.const 0))
(global $i8.MIN_VALUE i32 (i32.const -128))
(global $i8.MAX_VALUE i32 (i32.const 127))
@ -5195,6 +5197,140 @@
(i32.const 0)
)
)
(set_global $builtins/i
(i32.load8_s
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load16_s
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load8_u
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load16_u
(i32.const 8)
)
)
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load8_u
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load16_u
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load8_s
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load16_s
(i32.const 8)
)
)
(set_global $builtins/u
(i32.load
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load8_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load16_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load32_s
(i32.const 8)
)
)
(set_global $builtins/I
(i64.load
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load8_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load16_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load32_u
(i32.const 8)
)
)
(set_global $builtins/U
(i64.load
(i32.const 8)
)
)
(i32.store8
(i32.const 8)
(i32.const 1)
)
(i32.store16
(i32.const 8)
(i32.const 1)
)
(i32.store
(i32.const 8)
(i32.const 1)
)
(i64.store8
(i32.const 8)
(i64.const 1)
)
(i64.store16
(i32.const 8)
(i64.const 1)
)
(i64.store32
(i32.const 8)
(i64.const 1)
)
(i64.store
(i32.const 8)
(i64.const 1)
)
(i64.store
(i32.const 8)
(i64.extend_s/i32
(i32.const 1)
)
)
(drop
(i32.reinterpret/f32
(f32.const 1.25)
@ -6369,6 +6505,8 @@
GLOBAL: builtins/f
GLOBAL: builtins/F
GLOBAL: builtins/constantOffset
GLOBAL: builtins/u
GLOBAL: builtins/U
GLOBAL: builtins/s
FUNCTION_PROTOTYPE: builtins/test
FUNCTION_PROTOTYPE: memcpy/memcpy