Add atomic definitions (#524)

This commit is contained in:
Daniel Wirtz
2019-03-02 10:14:09 +01:00
committed by GitHub
parent f3aa762ccb
commit 8e5b9c734b
11 changed files with 1886 additions and 402 deletions

View File

@ -1350,6 +1350,26 @@ export class CallExpression extends Expression {
typeArguments: CommonTypeNode[] | null;
/** Provided arguments. */
arguments: Expression[];
/** Gets the type arguments range for reporting. */
get typeArgumentsRange(): Range {
var typeArguments = this.typeArguments;
var numTypeArguments: i32;
if (typeArguments && (numTypeArguments = typeArguments.length)) {
return Range.join(typeArguments[0].range, typeArguments[numTypeArguments - 1].range);
}
return this.expression.range;
}
/** Gets the arguments range for reporting. */
get argumentsRange(): Range {
var args = this.arguments;
var numArguments = args.length;
if (numArguments) {
return Range.join(args[0].range, args[numArguments - 1].range);
}
return this.expression.range;
}
}
/** Represents a class expression using the 'class' keyword. */

View File

@ -227,54 +227,54 @@ export namespace BuiltinSymbols {
export const i64_atomic_store16 = "~lib/builtins/i64.atomic.store16";
export const i64_atomic_store32 = "~lib/builtins/i64.atomic.store32";
export const i64_atomic_store = "~lib/builtins/i64.atomic.store";
export const i32_atomic_rmw8_u_add = "~lib/builtins/i32.atomic.rmw8_u.add";
export const i32_atomic_rmw16_u_add = "~lib/builtins/i32.atomic.rmw16_u.add";
export const i32_atomic_rmw8_add_u = "~lib/builtins/i32.atomic.rmw8.add_u";
export const i32_atomic_rmw16_add_u = "~lib/builtins/i32.atomic.rmw16.add_u";
export const i32_atomic_rmw_add = "~lib/builtins/i32.atomic.rmw.add";
export const i64_atomic_rmw8_u_add = "~lib/builtins/i64.atomic.rmw8_u.add";
export const i64_atomic_rmw16_u_add = "~lib/builtins/i64.atomic.rmw16_u.add";
export const i64_atomic_rmw32_u_add = "~lib/builtins/i64.atomic.rmw32_u.add";
export const i64_atomic_rmw8_add_u = "~lib/builtins/i64.atomic.rmw8.add_u";
export const i64_atomic_rmw16_add_u = "~lib/builtins/i64.atomic.rmw16.add_u";
export const i64_atomic_rmw32_add_u = "~lib/builtins/i64.atomic.rmw32.add_u";
export const i64_atomic_rmw_add = "~lib/builtins/i64.atomic.rmw.add";
export const i32_atomic_rmw8_u_sub = "~lib/builtins/i32.atomic.rmw8_u.sub";
export const i32_atomic_rmw16_u_sub = "~lib/builtins/i32.atomic.rmw16_u.sub";
export const i32_atomic_rmw8_sub_u = "~lib/builtins/i32.atomic.rmw8.sub_u";
export const i32_atomic_rmw16_sub_u = "~lib/builtins/i32.atomic.rmw16.sub_u";
export const i32_atomic_rmw_sub = "~lib/builtins/i32.atomic.rmw.sub";
export const i64_atomic_rmw8_u_sub = "~lib/builtins/i64.atomic.rmw8_u.sub";
export const i64_atomic_rmw16_u_sub = "~lib/builtins/i64.atomic.rmw16_u.sub";
export const i64_atomic_rmw32_u_sub = "~lib/builtins/i64.atomic.rmw32_u.sub";
export const i64_atomic_rmw8_sub_u = "~lib/builtins/i64.atomic.rmw8.sub_u";
export const i64_atomic_rmw16_sub_u = "~lib/builtins/i64.atomic.rmw16.sub_u";
export const i64_atomic_rmw32_sub_u = "~lib/builtins/i64.atomic.rmw32.sub_u";
export const i64_atomic_rmw_sub = "~lib/builtins/i64.atomic.rmw.sub";
export const i32_atomic_rmw8_u_and = "~lib/builtins/i32.atomic.rmw8_u.and";
export const i32_atomic_rmw16_u_and = "~lib/builtins/i32.atomic.rmw16_u.and";
export const i32_atomic_rmw8_and_u = "~lib/builtins/i32.atomic.rmw8.and_u";
export const i32_atomic_rmw16_and_u = "~lib/builtins/i32.atomic.rmw16.and_u";
export const i32_atomic_rmw_and = "~lib/builtins/i32.atomic.rmw.and";
export const i64_atomic_rmw8_u_and = "~lib/builtins/i64.atomic.rmw8_u.and";
export const i64_atomic_rmw16_u_and = "~lib/builtins/i64.atomic.rmw16_u.and";
export const i64_atomic_rmw32_u_and = "~lib/builtins/i64.atomic.rmw32_u.and";
export const i64_atomic_rmw8_and_u = "~lib/builtins/i64.atomic.rmw8.and_u";
export const i64_atomic_rmw16_and_u = "~lib/builtins/i64.atomic.rmw16.and_u";
export const i64_atomic_rmw32_and_u = "~lib/builtins/i64.atomic.rmw32.and_u";
export const i64_atomic_rmw_and = "~lib/builtins/i64.atomic.rmw.and";
export const i32_atomic_rmw8_u_or = "~lib/builtins/i32.atomic.rmw8_u.or";
export const i32_atomic_rmw16_u_or = "~lib/builtins/i32.atomic.rmw16_u.or";
export const i32_atomic_rmw8_or_u = "~lib/builtins/i32.atomic.rmw8.or_u";
export const i32_atomic_rmw16_or_u = "~lib/builtins/i32.atomic.rmw16.or_u";
export const i32_atomic_rmw_or = "~lib/builtins/i32.atomic.rmw.or";
export const i64_atomic_rmw8_u_or = "~lib/builtins/i64.atomic.rmw8_u.or";
export const i64_atomic_rmw16_u_or = "~lib/builtins/i64.atomic.rmw16_u.or";
export const i64_atomic_rmw32_u_or = "~lib/builtins/i64.atomic.rmw32_u.or";
export const i64_atomic_rmw8_or_u = "~lib/builtins/i64.atomic.rmw8.or_u";
export const i64_atomic_rmw16_or_u = "~lib/builtins/i64.atomic.rmw16.or_u";
export const i64_atomic_rmw32_or_u = "~lib/builtins/i64.atomic.rmw32.or_u";
export const i64_atomic_rmw_or = "~lib/builtins/i64.atomic.rmw.or";
export const i32_atomic_rmw8_u_xor = "~lib/builtins/i32.atomic.rmw8_u.xor";
export const i32_atomic_rmw16_u_xor = "~lib/builtins/i32.atomic.rmw16_u.xor";
export const i32_atomic_rmw8_u_xor = "~lib/builtins/i32.atomic.rmw8.xor_u";
export const i32_atomic_rmw16_u_xor = "~lib/builtins/i32.atomic.rmw16.xor_u";
export const i32_atomic_rmw_xor = "~lib/builtins/i32.atomic.rmw.xor";
export const i64_atomic_rmw8_u_xor = "~lib/builtins/i64.atomic.rmw8_u.xor";
export const i64_atomic_rmw16_u_xor = "~lib/builtins/i64.atomic.rmw16_u.xor";
export const i64_atomic_rmw32_u_xor = "~lib/builtins/i64.atomic.rmw32_u.xor";
export const i64_atomic_rmw8_xor_u = "~lib/builtins/i64.atomic.rmw8.xor_u";
export const i64_atomic_rmw16_xor_u = "~lib/builtins/i64.atomic.rmw16.xor_u";
export const i64_atomic_rmw32_xor_u = "~lib/builtins/i64.atomic.rmw32.xor_u";
export const i64_atomic_rmw_xor = "~lib/builtins/i64.atomic.rmw.xor";
export const i32_atomic_rmw8_u_xchg = "~lib/builtins/i32.atomic.rmw8_u.xchg";
export const i32_atomic_rmw16_u_xchg = "~lib/builtins/i32.atomic.rmw16_u.xchg";
export const i32_atomic_rmw8_xchg_u = "~lib/builtins/i32.atomic.rmw8.xchg_u";
export const i32_atomic_rmw16_xchg_u = "~lib/builtins/i32.atomic.rmw16.xchg_u";
export const i32_atomic_rmw_xchg = "~lib/builtins/i32.atomic.rmw.xchg";
export const i64_atomic_rmw8_u_xchg = "~lib/builtins/i64.atomic.rmw8_u.xchg";
export const i64_atomic_rmw16_u_xchg = "~lib/builtins/i64.atomic.rmw16_u.xchg";
export const i64_atomic_rmw32_u_xchg = "~lib/builtins/i64.atomic.rmw32_u.xchg";
export const i64_atomic_rmw8_xchg_u = "~lib/builtins/i64.atomic.rmw8.xchg_u";
export const i64_atomic_rmw16_xchg_u = "~lib/builtins/i64.atomic.rmw16.xchg_u";
export const i64_atomic_rmw32_xchg_u = "~lib/builtins/i64.atomic.rmw32.xchg_u";
export const i64_atomic_rmw_xchg = "~lib/builtins/i64.atomic.rmw.xchg";
export const i32_atomic_rmw8_u_cmpxchg = "~lib/builtins/i32.atomic.rmw8_u.cmpxchg";
export const i32_atomic_rmw16_u_cmpxchg = "~lib/builtins/i32.atomic.rmw16_u.cmpxchg";
export const i32_atomic_rmw8_cmpxchg_u = "~lib/builtins/i32.atomic.rmw8.cmpxchg_u";
export const i32_atomic_rmw16_cmpxchg_u = "~lib/builtins/i32.atomic.rmw16.cmpxchg_u";
export const i32_atomic_rmw_cmpxchg = "~lib/builtins/i32.atomic.rmw.cmpxchg";
export const i64_atomic_rmw8_u_cmpxchg = "~lib/builtins/i64.atomic.rmw8_u.cmpxchg";
export const i64_atomic_rmw16_u_cmpxchg = "~lib/builtins/i64.atomic.rmw16_u.cmpxchg";
export const i64_atomic_rmw32_u_cmpxchg = "~lib/builtins/i64.atomic.rmw32_u.cmpxchg";
export const i64_atomic_rmw8_cmpxchg_u = "~lib/builtins/i64.atomic.rmw8.cmpxchg_u";
export const i64_atomic_rmw16_cmpxchg_u = "~lib/builtins/i64.atomic.rmw16.cmpxchg_u";
export const i64_atomic_rmw32_cmpxchg_u = "~lib/builtins/i64.atomic.rmw32.cmpxchg_u";
export const i64_atomic_rmw_cmpxchg = "~lib/builtins/i64.atomic.rmw.cmpxchg";
export const i32_wait = "~lib/builtins/i32.wait";
export const i64_wait = "~lib/builtins/i64.wait";
@ -483,7 +483,8 @@ export function compileCall(
typeArguments: Type[] | null,
operands: Expression[],
contextualType: Type,
reportNode: CallExpression
reportNode: CallExpression,
isAsm: bool = false
): ExpressionRef {
var module = compiler.module;
@ -2151,33 +2152,35 @@ export function compileCall(
compiler.currentType = Type.void;
return module.createStore(typeArguments[0].byteSize, arg0, arg1, type.toNativeType(), offset, align);
}
case BuiltinSymbols.atomic_load: {
case BuiltinSymbols.atomic_load: { // load<T!>(offset: usize, immOffset?) -> T
if (!compiler.options.hasFeature(Feature.THREADS)) break;
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"
);
}
if (operands.length < 1) {
compiler.error(
DiagnosticCode.Expected_at_least_0_arguments_but_got_1,
reportNode.range, "1", operands.length.toString(10)
);
} else {
compiler.error(
DiagnosticCode.Expected_0_arguments_but_got_1,
reportNode.range, "2", operands.length.toString(10)
);
}
return module.createUnreachable();
}
let hasError = false;
if (!(typeArguments && typeArguments.length == 1)) {
if (typeArguments && typeArguments.length) compiler.currentType = typeArguments[0];
compiler.error(
DiagnosticCode.Expected_0_type_arguments_but_got_1,
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
reportNode.typeArgumentsRange, "1", typeArguments ? typeArguments.length.toString() : "0"
);
hasError = true;
}
if (operands.length < 1) {
compiler.error(
DiagnosticCode.Expected_at_least_0_arguments_but_got_1,
reportNode.argumentsRange, "1", operands.length.toString(10)
);
hasError = true;
} else if (operands.length > 2) {
compiler.error(
DiagnosticCode.Expected_0_arguments_but_got_1,
reportNode.argumentsRange, "2", operands.length.toString(10)
);
hasError = true;
}
if (hasError) return module.createUnreachable();
let loadType = typeArguments![0];
if (!loadType.is(TypeFlags.INTEGER)) {
compiler.error(
DiagnosticCode.Operation_not_supported,
reportNode.typeArgumentsRange
);
return module.createUnreachable();
}
@ -2188,48 +2191,49 @@ export function compileCall(
WrapMode.NONE
);
let offset = operands.length == 2 ? evaluateImmediateOffset(compiler, operands[1]) : 0; // reports
if (offset < 0) { // reported in evaluateImmediateOffset
return module.createUnreachable();
}
compiler.currentType = typeArguments[0];
if (offset < 0) return module.createUnreachable();
compiler.currentType = loadType;
return module.createAtomicLoad(
typeArguments[0].byteSize,
loadType.byteSize,
arg0,
typeArguments[0].is(TypeFlags.INTEGER) &&
loadType.is(TypeFlags.INTEGER) &&
contextualType.is(TypeFlags.INTEGER) &&
contextualType.size > typeArguments[0].size
contextualType.size > loadType.size
? (compiler.currentType = contextualType).toNativeType()
: (compiler.currentType = typeArguments[0]).toNativeType(),
: (compiler.currentType = loadType).toNativeType(),
offset
);
}
case BuiltinSymbols.atomic_store: { // store<T!>(offset: usize, value: *, immOffset?, immAlign?) -> void
case BuiltinSymbols.atomic_store: { // store<T!>(offset: usize, value: *, immOffset?) -> void
if (!compiler.options.hasFeature(Feature.THREADS)) break;
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 ? 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();
}
let hasError = false;
if (!(typeArguments && typeArguments.length == 1)) {
compiler.error(
DiagnosticCode.Expected_0_type_arguments_but_got_1,
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
reportNode.typeArgumentsRange, "1", typeArguments ? typeArguments.length.toString(10) : "0"
);
hasError = true;
}
if (operands.length < 2) {
compiler.error(
DiagnosticCode.Expected_at_least_0_arguments_but_got_1,
reportNode.argumentsRange, "2", operands.length.toString(10)
);
hasError = true;
} else if (operands.length > 3) {
compiler.error(
DiagnosticCode.Expected_0_arguments_but_got_1,
reportNode.argumentsRange, "3", operands.length.toString(10)
);
hasError = true;
}
if (hasError) return module.createUnreachable();
let storeType = typeArguments![0];
if (!storeType.is(TypeFlags.INTEGER) || storeType.size < 8) {
compiler.error(
DiagnosticCode.Operation_not_supported,
reportNode.typeArgumentsRange
);
return module.createUnreachable();
}
@ -2241,68 +2245,69 @@ export function compileCall(
);
arg1 = compiler.compileExpression(
operands[1],
typeArguments[0],
typeArguments[0].is(TypeFlags.INTEGER)
storeType,
storeType.is(TypeFlags.INTEGER)
? ConversionKind.NONE // no need to convert to small int (but now might result in a float)
: ConversionKind.IMPLICIT,
WrapMode.NONE
);
let type: Type;
let valueType = storeType;
if (
typeArguments[0].is(TypeFlags.INTEGER) &&
storeType.is(TypeFlags.INTEGER) &&
(
!compiler.currentType.is(TypeFlags.INTEGER) || // float to int
compiler.currentType.size < typeArguments[0].size // int to larger int (clear garbage bits)
!compiler.currentType.is(TypeFlags.INTEGER) || // float to int
compiler.currentType.size < storeType.size // int to larger int (clear garbage bits)
)
) {
arg1 = compiler.convertExpression(
arg1,
compiler.currentType, typeArguments[0],
compiler.currentType, storeType,
ConversionKind.IMPLICIT,
WrapMode.NONE, // still clears garbage bits
operands[1]
);
type = typeArguments[0];
} else {
type = compiler.currentType;
valueType = compiler.currentType;
}
let offset = operands.length == 3 ? evaluateImmediateOffset(compiler, operands[2]) : 0; // reports
if (offset < 0) return module.createUnreachable();
compiler.currentType = Type.void;
return module.createAtomicStore(typeArguments[0].byteSize, arg0, arg1, type.toNativeType(), offset);
return module.createAtomicStore(storeType.byteSize, arg0, arg1, valueType.toNativeType(), offset);
}
case BuiltinSymbols.atomic_add: // add<T!>(ptr, value: T, immOffset?: usize): T;
case BuiltinSymbols.atomic_sub: // sub<T!>(ptr, value: T, immOffset?: usize): T;
case BuiltinSymbols.atomic_and: // and<T!>(ptr, value: T, immOffset?: usize): T;
case BuiltinSymbols.atomic_or: // or<T!>(ptr, value: T, immOffset?: usize): T;
case BuiltinSymbols.atomic_xor: // xor<T!>(ptr, value: T, immOffset?: usize): T;
case BuiltinSymbols.atomic_xchg: // xchg<T!>(ptr, value, immOffset?: usize): T;
{
case BuiltinSymbols.atomic_xchg: { // xchg<T!>(ptr, value, immOffset?: usize): T;
if (!compiler.options.hasFeature(Feature.THREADS)) break;
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 ? 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();
}
let hasError = false;
if (!(typeArguments && typeArguments.length == 1)) {
compiler.error(
DiagnosticCode.Expected_0_type_arguments_but_got_1,
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
reportNode.typeArgumentsRange, "1", typeArguments ? typeArguments.length.toString(10) : "0"
);
hasError = true;
}
if (operands.length < 2) {
compiler.error(
DiagnosticCode.Expected_at_least_0_arguments_but_got_1,
reportNode.argumentsRange, "2", operands.length.toString(10)
);
hasError = true;
} else if (operands.length > 3) {
compiler.error(
DiagnosticCode.Expected_0_arguments_but_got_1,
reportNode.argumentsRange, "3", operands.length.toString(10)
);
hasError = true;
}
if (hasError) return module.createUnreachable();
let resultType = typeArguments![0];
if (!resultType.is(TypeFlags.INTEGER) || resultType.size < 8) {
compiler.error(
DiagnosticCode.Operation_not_supported,
reportNode.typeArgumentsRange
);
return module.createUnreachable();
}
@ -2314,37 +2319,35 @@ export function compileCall(
);
arg1 = compiler.compileExpression(
operands[1],
typeArguments[0],
typeArguments[0].is(TypeFlags.INTEGER)
resultType,
resultType.is(TypeFlags.INTEGER)
? ConversionKind.NONE // no need to convert to small int (but now might result in a float)
: ConversionKind.IMPLICIT,
WrapMode.NONE
);
let type: Type;
let valueType = resultType;
if (
typeArguments[0].is(TypeFlags.INTEGER) &&
resultType.is(TypeFlags.INTEGER) &&
(
!compiler.currentType.is(TypeFlags.INTEGER) || // float to int
compiler.currentType.size < typeArguments[0].size // int to larger int (clear garbage bits)
!compiler.currentType.is(TypeFlags.INTEGER) || // float to int
compiler.currentType.size < resultType.size // int to larger int (clear garbage bits)
)
) {
arg1 = compiler.convertExpression(
arg1,
compiler.currentType, typeArguments[0],
compiler.currentType, resultType,
ConversionKind.IMPLICIT,
WrapMode.NONE, // still clears garbage bits
operands[1]
);
type = typeArguments[0];
} else {
type = compiler.currentType;
valueType = compiler.currentType;
}
let offset = operands.length == 3 ? evaluateImmediateOffset(compiler, operands[2]) : 0; // reports
if (offset < 0) return module.createUnreachable();
let RMWOp: AtomicRMWOp | null = null;
let RMWOp: AtomicRMWOp;
switch (prototype.internalName) {
default: assert(false);
case BuiltinSymbols.atomic_add: { RMWOp = AtomicRMWOp.Add; break; }
case BuiltinSymbols.atomic_sub: { RMWOp = AtomicRMWOp.Sub; break; }
case BuiltinSymbols.atomic_and: { RMWOp = AtomicRMWOp.And; break; }
@ -2352,45 +2355,40 @@ export function compileCall(
case BuiltinSymbols.atomic_xor: { RMWOp = AtomicRMWOp.Xor; break; }
case BuiltinSymbols.atomic_xchg: { RMWOp = AtomicRMWOp.Xchg; break; }
}
compiler.currentType = typeArguments[0];
if (RMWOp !== null) {
return module.createAtomicRMW(
RMWOp, typeArguments[0].byteSize, offset, arg0, arg1, type.toNativeType()
);
} else {
compiler.error(
DiagnosticCode.Operation_not_supported,
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
);
return module.createUnreachable();
}
compiler.currentType = resultType;
return module.createAtomicRMW(
RMWOp, resultType.byteSize, offset, arg0, arg1, valueType.toNativeType()
);
}
case BuiltinSymbols.atomic_cmpxchg: { // cmpxchg<T!>(ptr: usize, expected: T, replacement: T, cOff?: usize): T
if (!compiler.options.hasFeature(Feature.THREADS)) break;
if (operands.length < 3 || operands.length > 4) {
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 < 3) {
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();
}
let hasError = false;
if (!(typeArguments && typeArguments.length == 1)) {
compiler.error(
DiagnosticCode.Expected_0_type_arguments_but_got_1,
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
reportNode.typeArgumentsRange, "1", typeArguments ? typeArguments.length.toString() : "0"
);
hasError = true;
}
if (operands.length < 3) {
compiler.error(
DiagnosticCode.Expected_at_least_0_arguments_but_got_1,
reportNode.argumentsRange, "3", operands.length.toString()
);
hasError = true;
} else if (operands.length > 4) {
compiler.error(
DiagnosticCode.Expected_0_arguments_but_got_1,
reportNode.argumentsRange, "4", operands.length.toString()
);
hasError = true;
}
if (hasError) return module.createUnreachable();
let resultType = typeArguments![0];
if (!resultType.is(TypeFlags.INTEGER) || resultType.size < 8) {
compiler.error(
DiagnosticCode.Operation_not_supported,
reportNode.typeArgumentsRange
);
return module.createUnreachable();
}
@ -2402,77 +2400,76 @@ export function compileCall(
);
arg1 = compiler.compileExpression(
operands[1],
typeArguments[0],
typeArguments[0].is(TypeFlags.INTEGER)
resultType,
resultType.is(TypeFlags.INTEGER)
? ConversionKind.NONE // no need to convert to small int (but now might result in a float)
: ConversionKind.IMPLICIT,
WrapMode.NONE
);
arg2 = compiler.compileExpression(
operands[2],
typeArguments[0],
typeArguments[0].is(TypeFlags.INTEGER)
? ConversionKind.NONE // no need to convert to small int (but now might result in a float)
: ConversionKind.IMPLICIT,
compiler.currentType,
ConversionKind.IMPLICIT,
WrapMode.NONE
);
let type: Type;
let valueType = resultType;
if (
typeArguments[0].is(TypeFlags.INTEGER) &&
resultType.is(TypeFlags.INTEGER) &&
(
!compiler.currentType.is(TypeFlags.INTEGER) || // float to int
compiler.currentType.size < typeArguments[0].size // int to larger int (clear garbage bits)
!compiler.currentType.is(TypeFlags.INTEGER) || // float to int
compiler.currentType.size < resultType.size // int to larger int (clear garbage bits)
)
) {
arg1 = compiler.convertExpression(
arg1,
compiler.currentType, typeArguments[0],
compiler.currentType, resultType,
ConversionKind.IMPLICIT,
WrapMode.NONE, // still clears garbage bits
operands[1]
);
arg2 = compiler.convertExpression(
arg2,
compiler.currentType, typeArguments[0],
compiler.currentType, resultType,
ConversionKind.IMPLICIT,
WrapMode.NONE, // still clears garbage bits
operands[2]
);
type = typeArguments[0];
} else {
type = compiler.currentType;
valueType = compiler.currentType;
}
let offset = operands.length == 4 ? evaluateImmediateOffset(compiler, operands[3]) : 0; // reports
if (offset < 0) return module.createUnreachable();
compiler.currentType = typeArguments[0];
compiler.currentType = resultType;
return module.createAtomicCmpxchg(
typeArguments[0].byteSize, offset, arg0, arg1, arg2, type.toNativeType()
resultType.byteSize, offset, arg0, arg1, arg2, valueType.toNativeType()
);
}
case BuiltinSymbols.atomic_wait: { // wait<T!>(ptr: usize, expected:T, timeout: i64): i32;
if (!compiler.options.hasFeature(Feature.THREADS)) break;
let hasError = typeArguments == null;
if (operands.length != 3) {
compiler.error(
DiagnosticCode.Expected_0_arguments_but_got_1,
reportNode.range, "3", operands.length.toString(10)
);
hasError = true;
}
let hasError = false;
if (!(typeArguments && typeArguments.length == 1)) {
compiler.error(
DiagnosticCode.Expected_0_type_arguments_but_got_1,
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
reportNode.typeArgumentsRange, "1", typeArguments ? typeArguments.length.toString(10) : "0"
);
hasError = true;
}
if (!typeArguments || hasError) {
if (operands.length != 3) {
compiler.error(
DiagnosticCode.Expected_0_arguments_but_got_1,
reportNode.argumentsRange, "3", operands.length.toString(10)
);
hasError = true;
}
if (hasError) return module.createUnreachable();
let valueType = typeArguments![0];
if (!valueType.is(TypeFlags.INTEGER) || valueType.size < 32) {
compiler.error(
DiagnosticCode.Operation_not_supported,
reportNode.typeArgumentsRange
);
return module.createUnreachable();
}
arg0 = compiler.compileExpression(
operands[0],
compiler.options.usizeType,
@ -2481,10 +2478,8 @@ export function compileCall(
);
arg1 = compiler.compileExpression(
operands[1],
typeArguments[0],
typeArguments[0].is(TypeFlags.INTEGER)
? ConversionKind.NONE // no need to convert to small int (but now might result in a float)
: ConversionKind.IMPLICIT,
valueType,
ConversionKind.IMPLICIT,
WrapMode.NONE
);
arg2 = compiler.compileExpression(
@ -2493,57 +2488,35 @@ export function compileCall(
ConversionKind.IMPLICIT,
WrapMode.NONE
);
let type: Type = typeArguments[0];
if (
typeArguments[0].is(TypeFlags.INTEGER) &&
(
!compiler.currentType.is(TypeFlags.INTEGER) || // float to int
compiler.currentType.size < typeArguments[0].size // int to larger int (clear garbage bits)
)
) {
arg1 = compiler.convertExpression(
arg1,
compiler.currentType, typeArguments[0],
ConversionKind.IMPLICIT,
WrapMode.NONE, // still clears garbage bits
operands[1]
);
arg2 = compiler.convertExpression(
arg2,
compiler.currentType, typeArguments[0],
ConversionKind.IMPLICIT,
WrapMode.NONE, // still clears garbage bits
operands[2]
);
}
return module.createAtomicWait(
arg0, arg1, arg2, type.toNativeType()
);
compiler.currentType = Type.i32;
return module.createAtomicWait(arg0, arg1, arg2, valueType.toNativeType());
}
case BuiltinSymbols.atomic_notify: { // notify<T!>(ptr: usize, count: u32): u32;
if (!compiler.options.hasFeature(Feature.THREADS)) break;
let hasError = typeArguments == null;
if (operands.length != 2) {
compiler.error(
DiagnosticCode.Expected_0_arguments_but_got_1,
reportNode.range, "2", operands.length.toString(10)
);
hasError = true;
}
let hasError = false;
if (!(typeArguments && typeArguments.length == 1)) {
compiler.error(
DiagnosticCode.Expected_0_type_arguments_but_got_1,
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
reportNode.typeArgumentsRange, "1", typeArguments ? typeArguments.length.toString(10) : "0"
);
hasError = true;
}
if (!typeArguments || hasError) {
if (operands.length != 2) {
compiler.error(
DiagnosticCode.Expected_0_arguments_but_got_1,
reportNode.argumentsRange, "2", operands.length.toString(10)
);
hasError = true;
}
if (hasError) return module.createUnreachable();
let valueType = typeArguments![0];
if (!valueType.is(TypeFlags.INTEGER) || valueType.size < 32) {
compiler.error(
DiagnosticCode.Operation_not_supported,
reportNode.typeArgumentsRange
);
return module.createUnreachable();
}
arg0 = compiler.compileExpression(
operands[0],
compiler.options.usizeType,
@ -2552,14 +2525,12 @@ export function compileCall(
);
arg1 = compiler.compileExpression(
operands[1],
Type.i32,
valueType,
ConversionKind.IMPLICIT,
WrapMode.NONE
);
return module.createAtomicWake(
arg0, arg1
);
compiler.currentType = Type.i32;
return module.createAtomicWake(arg0, arg1);
}
case BuiltinSymbols.sizeof: { // sizeof<T!>() -> usize
compiler.currentType = compiler.options.usizeType;
@ -5539,16 +5510,16 @@ function tryDeferASM(
case BuiltinSymbols.f32_trunc: return deferASM(BuiltinSymbols.trunc, compiler, Type.f32, operands, Type.f32, reportNode);
case BuiltinSymbols.f64_trunc: return deferASM(BuiltinSymbols.trunc, compiler, Type.f64, operands, Type.f64, reportNode);
case BuiltinSymbols.i32_load8_s: return deferASM(BuiltinSymbols.load, compiler, Type.i8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_load8_u: return deferASM(BuiltinSymbols.load, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_load8_u: return deferASM(BuiltinSymbols.load, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_load16_s: return deferASM(BuiltinSymbols.load, compiler, Type.i16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_load16_u: return deferASM(BuiltinSymbols.load, compiler, Type.u16, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_load16_u: return deferASM(BuiltinSymbols.load, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_load: return deferASM(BuiltinSymbols.load, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_load8_s: return deferASM(BuiltinSymbols.load, compiler, Type.i8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_load8_u: return deferASM(BuiltinSymbols.load, compiler, Type.u8, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_load8_u: return deferASM(BuiltinSymbols.load, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_load16_s: return deferASM(BuiltinSymbols.load, compiler, Type.i16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_load16_u: return deferASM(BuiltinSymbols.load, compiler, Type.u16, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_load16_u: return deferASM(BuiltinSymbols.load, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_load32_s: return deferASM(BuiltinSymbols.load, compiler, Type.i32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_load32_u: return deferASM(BuiltinSymbols.load, compiler, Type.u32, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_load32_u: return deferASM(BuiltinSymbols.load, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_load: return deferASM(BuiltinSymbols.load, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.f32_load: return deferASM(BuiltinSymbols.load, compiler, Type.f32, operands, Type.f32, reportNode);
case BuiltinSymbols.f64_load: return deferASM(BuiltinSymbols.load, compiler, Type.f64, operands, Type.f64, reportNode);
@ -5565,82 +5536,82 @@ function tryDeferASM(
if (compiler.options.hasFeature(Feature.THREADS)) {
switch (prototype.internalName) {
case BuiltinSymbols.i32_atomic_load8_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_load16_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u16, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_load8_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_load16_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_load: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_atomic_load8_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u8, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_load16_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u16, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_load32_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u32, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_load8_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_load16_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_load32_u: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_load: return deferASM(BuiltinSymbols.atomic_load, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_atomic_store8: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.i8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_store16: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.i16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_store8: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_store16: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_store: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_atomic_store8: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.i8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_store16: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.i16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_store32: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.i32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_store8: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_store16: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_store32: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_store: return deferASM(BuiltinSymbols.atomic_store, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_u_add: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_u_add: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u16, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_add: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u32, operands, Type.u32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_u_add: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u8, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_u_add: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u16, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_u_add: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u32, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_add: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u64, operands, Type.u64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_add_u: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_add_u: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_add: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_add_u: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_add_u: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_add_u: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_add: return deferASM(BuiltinSymbols.atomic_add, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_u_sub: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_u_sub: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u16, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_sub: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u32, operands, Type.u32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_u_sub: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u8, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_u_sub: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u16, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_u_sub: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u32, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_sub: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u64, operands, Type.u64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_sub_u: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_sub_u: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_sub: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_sub_u: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_sub_u: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_sub_u: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_sub: return deferASM(BuiltinSymbols.atomic_sub, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_u_and: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_u_and: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u16, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_and: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u32, operands, Type.u32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_u_and: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u8, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_u_and: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u16, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_u_and: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u32, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_and: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u64, operands, Type.u64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_and_u: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_and_u: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_and: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_and_u: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_and_u: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_and_u: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_and: return deferASM(BuiltinSymbols.atomic_and, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_u_or: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_u_or: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u16, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_or: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u32, operands, Type.u32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_u_or: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u8, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_u_or: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u16, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_u_or: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u32, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_or: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u64, operands, Type.u64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_or_u: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_or_u: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_or: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_or_u: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_or_u: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_or_u: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_or: return deferASM(BuiltinSymbols.atomic_or, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_u_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_u_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_u_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u8, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_u_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u16, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_u_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u32, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u64, operands, Type.u64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_u_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_u_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_xor_u: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_xor_u: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_xor_u: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_xor: return deferASM(BuiltinSymbols.atomic_xor, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_u_xchg: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_u_xchg: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_xchg: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_u_xchg: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u8, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_u_xchg: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u16, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_u_xchg: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u32, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_xchg: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u64, operands, Type.u64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_xchg_u: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_xchg_u: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_xchg: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_xchg_u: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_xchg_u: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_xchg_u: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_xchg: return deferASM(BuiltinSymbols.atomic_xchg, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_u_cmpxchg: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_u_cmpxchg: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_cmpxchg: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u8, operands, Type.u32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_u_cmpxchg: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u8, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_u_cmpxchg: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u16, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_u_cmpxchg: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u32, operands, Type.u64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_cmpxchg: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u64, operands, Type.u64, reportNode);
case BuiltinSymbols.i32_atomic_rmw8_cmpxchg_u: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u8, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw16_cmpxchg_u: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u16, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_atomic_rmw_cmpxchg: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_atomic_rmw8_cmpxchg_u: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u8, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw16_cmpxchg_u: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u16, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw32_cmpxchg_u: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.u32, operands, Type.i64, reportNode);
case BuiltinSymbols.i64_atomic_rmw_cmpxchg: return deferASM(BuiltinSymbols.atomic_cmpxchg, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_wait: return deferASM(BuiltinSymbols.atomic_wait, compiler, Type.i32, operands, Type.u32, reportNode);
case BuiltinSymbols.i64_wait: return deferASM(BuiltinSymbols.atomic_wait, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_notify: return deferASM(BuiltinSymbols.atomic_notify, compiler, Type.i32, operands, Type.u32, reportNode);
case BuiltinSymbols.i64_notify: return deferASM(BuiltinSymbols.atomic_notify, compiler, Type.i64, operands, Type.i64, reportNode);
case BuiltinSymbols.i32_wait: return deferASM(BuiltinSymbols.atomic_wait, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_wait: return deferASM(BuiltinSymbols.atomic_wait, compiler, Type.i64, operands, Type.i32, reportNode);
case BuiltinSymbols.i32_notify: return deferASM(BuiltinSymbols.atomic_notify, compiler, Type.i32, operands, Type.i32, reportNode);
case BuiltinSymbols.i64_notify: return deferASM(BuiltinSymbols.atomic_notify, compiler, Type.i64, operands, Type.i32, reportNode);
}
}
if (compiler.options.hasFeature(Feature.SIMD)) {
@ -5799,13 +5770,21 @@ function deferASM(
compiler: Compiler,
typeArgument: Type,
operands: Expression[],
valueType: Type,
contextualType: Type,
reportNode: CallExpression
): ExpressionRef {
assert(compiler.program.elementsByName.has(name));
var prototype = compiler.program.elementsByName.get(name)!;
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
return compileCall(compiler, <FunctionPrototype>prototype, [ typeArgument ], operands, valueType, reportNode);
return compileCall(
compiler,
<FunctionPrototype>prototype,
[ typeArgument ],
operands,
contextualType,
reportNode,
/* isAsm */ true
);
}
/** Evaluates the constant type of a type argument *or* expression. */

View File

@ -411,7 +411,8 @@ export class Compiler extends DiagnosticEmitter {
isSharedMemory ? options.sharedMemory : Module.UNLIMITED_MEMORY,
this.memorySegments,
options.target,
"memory"
"memory",
isSharedMemory
);
// import memory if requested (default memory is named '0' by Binaryen)