reinterpret and select builtins

This commit is contained in:
dcodeIO
2017-12-04 22:47:08 +01:00
parent df3e34f2aa
commit b7030d4dea
19 changed files with 374 additions and 140 deletions

View File

@ -1466,7 +1466,7 @@ export class Compiler extends DiagnosticEmitter {
functionInstance = <Function | null>functionPrototype.instances.get(sb.join(","));
if (!functionInstance) {
let arg0: ExpressionRef, arg1: ExpressionRef;
let arg0: ExpressionRef, arg1: ExpressionRef, arg2: ExpressionRef;
if (functionPrototype.internalName == "sizeof") { // no parameters
this.currentType = this.options.target == Target.WASM64 ? Type.usize64 : Type.usize32;
@ -1483,11 +1483,11 @@ export class Compiler extends DiagnosticEmitter {
: this.module.createI32(resolvedTypeArguments[0].byteSize);
} else if (functionPrototype.internalName == "load") {
this.currentType = resolvedTypeArguments[0];
if (k != 1) {
this.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, expression.range, "1", k.toString());
return this.module.createUnreachable();
}
this.currentType = resolvedTypeArguments[0];
if (expression.arguments.length != 1) {
this.error(DiagnosticCode.Expected_0_arguments_but_got_1, expression.range, "1", expression.arguments.length.toString());
return this.module.createUnreachable();
@ -1517,6 +1517,60 @@ export class Compiler extends DiagnosticEmitter {
if (!arg1)
return this.module.createUnreachable();
return this.module.createStore(resolvedTypeArguments[0].byteSize, arg0, arg1, typeToNativeType(resolvedTypeArguments[0]));
} else if (functionPrototype.internalName == "reinterpret") {
if (k != 2) {
this.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, expression.range, "2", k.toString());
return this.module.createUnreachable();
}
this.currentType = resolvedTypeArguments[1];
if (expression.arguments.length != 1) {
this.error(DiagnosticCode.Expected_0_arguments_but_got_1, expression.range, "1", expression.arguments.length.toString());
return this.module.createUnreachable();
}
if (this.currentType == Type.f64) {
arg0 = this.compileExpression(expression.arguments[0], Type.i64); // reports
this.currentType = Type.f64;
return this.module.createUnary(UnaryOp.ReinterpretI64, arg0);
}
if (this.currentType == Type.f32) {
arg0 = this.compileExpression(expression.arguments[0], Type.i32); // reports
this.currentType = Type.f32;
return this.module.createUnary(UnaryOp.ReinterpretI32, arg0);
}
if (this.currentType.isLongInteger) {
arg0 = this.compileExpression(expression.arguments[0], Type.f64); // reports
this.currentType = Type.i64;
return this.module.createUnary(UnaryOp.ReinterpretF64, arg0);
}
if (this.currentType.isAnyInteger) {
arg0 = this.compileExpression(expression.arguments[0], Type.f32); // reports
this.currentType = Type.i32;
return this.module.createUnary(UnaryOp.ReinterpretF32, arg0);
}
} else if (functionPrototype.internalName == "select") {
if (k != 1) {
this.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, expression.range, "1", k.toString());
return this.module.createUnreachable();
}
this.currentType = resolvedTypeArguments[0];
if (expression.arguments.length != 3) {
this.error(DiagnosticCode.Expected_0_arguments_but_got_1, expression.range, "3", expression.arguments.length.toString());
return this.module.createUnreachable();
}
arg0 = this.compileExpression(expression.arguments[0], this.currentType); // reports
if (!arg0)
return this.module.createUnreachable();
arg1 = this.compileExpression(expression.arguments[1], this.currentType); // reports
if (!arg1)
return this.module.createUnreachable();
arg2 = this.compileExpression(expression.arguments[2], Type.i32); // reports
this.currentType = resolvedTypeArguments[0];
if (!arg2)
return this.module.createUnreachable();
return this.module.createSelect(arg0, arg1, arg2);
}
this.error(DiagnosticCode.Operation_not_supported, expression.range);
return this.module.createUnreachable();

View File

@ -1111,6 +1111,9 @@ export class Interface extends Class {
}
}
const builtinIntTypes: Type[] = [ Type.i32, Type.i64 ];
const builtinFloatTypes: Type[] = [ Type.f32, Type.f64 ];
function initializeBuiltins(program: Program): void {
// types
@ -1134,37 +1137,37 @@ function initializeBuiltins(program: Program): void {
// functions
const genericInt: Type[] = [ Type.i32, Type.i64 ];
const genericFloat: Type[] = [ Type.f32, Type.f64 ];
const usize: Type = program.target == Target.WASM64 ? Type.usize64 : Type.usize32;
addGenericUnaryBuiltin(program, "clz", genericInt);
addGenericUnaryBuiltin(program, "ctz", genericInt);
addGenericUnaryBuiltin(program, "popcnt", genericInt);
addGenericBinaryBuiltin(program, "rotl", genericInt);
addGenericBinaryBuiltin(program, "rotr", genericInt);
addGenericUnaryBuiltin(program, "clz", builtinIntTypes);
addGenericUnaryBuiltin(program, "ctz", builtinIntTypes);
addGenericUnaryBuiltin(program, "popcnt", builtinIntTypes);
addGenericBinaryBuiltin(program, "rotl", builtinIntTypes);
addGenericBinaryBuiltin(program, "rotr", builtinIntTypes);
addGenericUnaryBuiltin(program, "abs", genericFloat);
addGenericUnaryBuiltin(program, "ceil", genericFloat);
addGenericBinaryBuiltin(program, "copysign", genericFloat);
addGenericUnaryBuiltin(program, "floor", genericFloat);
addGenericBinaryBuiltin(program, "max", genericFloat);
addGenericBinaryBuiltin(program, "min", genericFloat);
addGenericUnaryBuiltin(program, "nearest", genericFloat);
addGenericUnaryBuiltin(program, "sqrt", genericFloat);
addGenericUnaryBuiltin(program, "trunc", genericFloat);
addGenericUnaryBuiltin(program, "abs", builtinFloatTypes);
addGenericUnaryBuiltin(program, "ceil", builtinFloatTypes);
addGenericBinaryBuiltin(program, "copysign", builtinFloatTypes);
addGenericUnaryBuiltin(program, "floor", builtinFloatTypes);
addGenericBinaryBuiltin(program, "max", builtinFloatTypes);
addGenericBinaryBuiltin(program, "min", builtinFloatTypes);
addGenericUnaryBuiltin(program, "nearest", builtinFloatTypes);
addGenericUnaryBuiltin(program, "sqrt", builtinFloatTypes);
addGenericUnaryBuiltin(program, "trunc", builtinFloatTypes);
addSimpleBuiltin(program, "current_memory", [], usize);
addSimpleBuiltin(program, "grow_memory", [ usize ], usize);
addSimpleBuiltin(program, "unreachable", [], Type.void);
addGenericUnaryTestBuiltin(program, "isNaN", genericFloat);
addGenericUnaryTestBuiltin(program, "isFinite", genericFloat);
addSimpleBuiltin(program, "assert", [ Type.bool ], Type.void);
addGenericAnyBuiltin(program, "sizeof");
addGenericAnyBuiltin(program, "load");
addGenericAnyBuiltin(program, "store");
addGenericAnyBuiltin(program, "reinterpret");
addGenericAnyBuiltin(program, "select");
addGenericAnyBuiltin(program, "sizeof");
addGenericUnaryTestBuiltin(program, "isNaN", builtinFloatTypes);
addGenericUnaryTestBuiltin(program, "isFinite", builtinFloatTypes);
addSimpleBuiltin(program, "assert", [ Type.bool ], Type.void);
}
/** Adds a simple (non-generic) builtin. */