Skip to content

Commit 7c5e50e

Browse files
MaxGraeydcodeIO
authored andcommitted
Add simd avgr_u instruction (#1033)
1 parent 6d41e58 commit 7c5e50e

File tree

6 files changed

+174
-111
lines changed

6 files changed

+174
-111
lines changed

src/builtins.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ export namespace BuiltinSymbols {
323323
export const v128_min = "~lib/builtins/v128.min";
324324
export const v128_max = "~lib/builtins/v128.max";
325325
export const v128_dot = "~lib/builtins/v128.dot";
326+
export const v128_avgr = "~lib/builtins/v128.avgr";
326327
export const v128_abs = "~lib/builtins/v128.abs";
327328
export const v128_sqrt = "~lib/builtins/v128.sqrt";
328329
export const v128_eq = "~lib/builtins/v128.eq";
@@ -357,6 +358,7 @@ export namespace BuiltinSymbols {
357358
export const i8x16_min_u = "~lib/builtins/i8x16.min_u";
358359
export const i8x16_max_s = "~lib/builtins/i8x16.max_s";
359360
export const i8x16_max_u = "~lib/builtins/i8x16.max_u";
361+
export const i8x16_avgr_u = "~lib/builtins/i8x16.avgr_u";
360362
export const i8x16_neg = "~lib/builtins/i8x16.neg";
361363
export const i8x16_add_saturate_s = "~lib/builtins/i8x16.add_saturate_s";
362364
export const i8x16_add_saturate_u = "~lib/builtins/i8x16.add_saturate_u";
@@ -391,6 +393,7 @@ export namespace BuiltinSymbols {
391393
export const i16x8_min_u = "~lib/builtins/i16x8.min_u";
392394
export const i16x8_max_s = "~lib/builtins/i16x8.max_s";
393395
export const i16x8_max_u = "~lib/builtins/i16x8.max_u";
396+
export const i16x8_avgr_u = "~lib/builtins/i16x8.avgr_u";
394397
export const i16x8_neg = "~lib/builtins/i16x8.neg";
395398
export const i16x8_add_saturate_s = "~lib/builtins/i16x8.add_saturate_s";
396399
export const i16x8_add_saturate_u = "~lib/builtins/i16x8.add_saturate_u";
@@ -3377,6 +3380,30 @@ export function compileCall(
33773380
);
33783381
return module.unreachable();
33793382
}
3383+
case BuiltinSymbols.v128_avgr: { // avgr<T!>(a: v128, b: v128) -> v128
3384+
if (
3385+
checkFeatureEnabled(Feature.SIMD, reportNode, compiler) |
3386+
checkTypeRequired(typeArguments, reportNode, compiler) |
3387+
checkArgsRequired(operands, 2, reportNode, compiler)
3388+
) {
3389+
compiler.currentType = Type.v128;
3390+
return module.unreachable();
3391+
}
3392+
let type = typeArguments![0];
3393+
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
3394+
let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.CONV_IMPLICIT);
3395+
if (!type.is(TypeFlags.REFERENCE)) {
3396+
switch (type.kind) {
3397+
case TypeKind.U8: return module.binary(BinaryOp.AvgrU8x16, arg0, arg1);
3398+
case TypeKind.U16: return module.binary(BinaryOp.AvgrU16x8, arg0, arg1);
3399+
}
3400+
}
3401+
compiler.error(
3402+
DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,
3403+
reportNode.typeArgumentsRange, "v128.avgr", type.toString()
3404+
);
3405+
return module.unreachable();
3406+
}
33803407
case BuiltinSymbols.v128_eq: { // eq<T!>(a: v128, b: v128) -> v128
33813408
if (
33823409
checkFeatureEnabled(Feature.SIMD, reportNode, compiler) |
@@ -4516,6 +4543,7 @@ function tryDeferASM(
45164543
case BuiltinSymbols.i8x16_min_u: return deferASM(BuiltinSymbols.v128_min, compiler, Type.u8, operands, Type.v128, reportNode);
45174544
case BuiltinSymbols.i8x16_max_s: return deferASM(BuiltinSymbols.v128_max, compiler, Type.i8, operands, Type.v128, reportNode);
45184545
case BuiltinSymbols.i8x16_max_u: return deferASM(BuiltinSymbols.v128_max, compiler, Type.u8, operands, Type.v128, reportNode);
4546+
case BuiltinSymbols.i8x16_avgr_u: return deferASM(BuiltinSymbols.v128_avgr, compiler, Type.u8, operands, Type.v128, reportNode);
45194547
case BuiltinSymbols.i8x16_neg: return deferASM(BuiltinSymbols.v128_neg, compiler, Type.i8, operands, Type.v128, reportNode);
45204548
case BuiltinSymbols.i8x16_add_saturate_s: return deferASM(BuiltinSymbols.v128_add_saturate, compiler, Type.i8, operands, Type.v128, reportNode);
45214549
case BuiltinSymbols.i8x16_add_saturate_u: return deferASM(BuiltinSymbols.v128_add_saturate, compiler, Type.u8, operands, Type.v128, reportNode);
@@ -4550,6 +4578,7 @@ function tryDeferASM(
45504578
case BuiltinSymbols.i16x8_min_u: return deferASM(BuiltinSymbols.v128_min, compiler, Type.u16, operands, Type.v128, reportNode);
45514579
case BuiltinSymbols.i16x8_max_s: return deferASM(BuiltinSymbols.v128_max, compiler, Type.i16, operands, Type.v128, reportNode);
45524580
case BuiltinSymbols.i16x8_max_u: return deferASM(BuiltinSymbols.v128_max, compiler, Type.u16, operands, Type.v128, reportNode);
4581+
case BuiltinSymbols.i16x8_avgr_u: return deferASM(BuiltinSymbols.v128_avgr, compiler, Type.u16, operands, Type.v128, reportNode);
45534582
case BuiltinSymbols.i16x8_neg: return deferASM(BuiltinSymbols.v128_neg, compiler, Type.i16, operands, Type.v128, reportNode);
45544583
case BuiltinSymbols.i16x8_add_saturate_s: return deferASM(BuiltinSymbols.v128_add_saturate, compiler, Type.i16, operands, Type.v128, reportNode);
45554584
case BuiltinSymbols.i16x8_add_saturate_u: return deferASM(BuiltinSymbols.v128_add_saturate, compiler, Type.u16, operands, Type.v128, reportNode);

std/assembly/builtins.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,10 @@ export namespace v128 {
10931093
@builtin
10941094
export declare function dot<T>(a: v128, b: v128): v128; // i16 only
10951095

1096+
// @ts-ignore: decorator
1097+
@builtin
1098+
export declare function avgr<T>(a: v128, b: v128): v128; // u8, u16 only
1099+
10961100
// @ts-ignore: decorator
10971101
@builtin
10981102
export declare function abs<T>(a: v128): v128; // f32, f64 only
@@ -1207,6 +1211,10 @@ export namespace i8x16 {
12071211
@builtin
12081212
export declare function max_u(a: v128, b: v128): v128;
12091213

1214+
// @ts-ignore: decorator
1215+
@builtin
1216+
export declare function avgr_u(a: v128, b: v128): v128;
1217+
12101218
// @ts-ignore: decorator
12111219
@builtin
12121220
export declare function neg(a: v128): v128;
@@ -1346,6 +1354,10 @@ export namespace i16x8 {
13461354
@builtin
13471355
export declare function max_u(a: v128, b: v128): v128;
13481356

1357+
// @ts-ignore: decorator
1358+
@builtin
1359+
export declare function avgr_u(a: v128, b: v128): v128;
1360+
13491361
// @ts-ignore: decorator
13501362
@builtin
13511363
export declare function neg(a: v128): v128;

std/assembly/index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,8 @@ declare namespace v128 {
591591
export function max<T>(a: v128, b: v128): v128;
592592
/** Computes the dot product of two lanes each, yielding lanes one size wider than the input. */
593593
export function dot<T = i16>(a: v128, b: v128): v128;
594+
/** Computes the average of each lane. */
595+
export function avgr<T = u8 | u16>(a: v128, b: v128): v128;
594596
/** Computes the absolute value of each lane. */
595597
export function abs<T = f32 | f64>(a: v128): v128;
596598
/** Computes the square root of each lane. */
@@ -647,6 +649,8 @@ declare namespace i8x16 {
647649
export function max_s(a: v128, b: v128): v128;
648650
/** Computes the unsigned maximum of each 8-bit integer lane. */
649651
export function max_u(a: v128, b: v128): v128;
652+
/** Computes the unsigned average of each 8-bit integer lane. */
653+
export function avgr_u(a: v128, b: v128): v128;
650654
/** Negates each 8-bit integer lane. */
651655
export function neg(a: v128): v128;
652656
/** Adds each 8-bit integer lane using signed saturation. */
@@ -717,6 +721,8 @@ declare namespace i16x8 {
717721
export function max_s(a: v128, b: v128): v128;
718722
/** Computes the unsigned maximum of each 16-bit integer lane. */
719723
export function max_u(a: v128, b: v128): v128;
724+
/** Computes the unsigned average of each 16-bit integer lane. */
725+
export function avgr_u(a: v128, b: v128): v128;
720726
/** Negates each 16-bit integer lane. */
721727
export function neg(a: v128): v128;
722728
/** Adds each 16-bit integer lane using signed saturation. */

tests/compiler/features/simd.optimized.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@
114114
unreachable
115115
end
116116
global.get $~lib/rt/stub/offset
117+
local.get $0
117118
local.get $1
118119
i32.load
119-
local.get $0
120120
i32.add
121121
i32.eq
122122
if

tests/compiler/features/simd.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ function test_i8x16(): void {
9797
==
9898
i8x16(-128, 127, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
9999
);
100+
assert(
101+
i8x16.avgr_u(
102+
i8x16(1, 2, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, <u8>0x80, <u8>0xFF),
103+
i8x16(1, 4, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, <u8>0x80, <u8>0xFF)
104+
)
105+
==
106+
i8x16(1, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, <u8>0x80, <u8>0xFF)
107+
);
100108
assert(
101109
i8x16.neg(a)
102110
==
@@ -203,6 +211,14 @@ function test_i16x8(): void {
203211
==
204212
i16x8(-32768, 32767, -32768, 0, 0, 0, 0, 0)
205213
);
214+
assert(
215+
i16x8.avgr_u(
216+
i16x8(1, 2, 4, 4, 5, 6, <u16>0x8000, <u16>0xFFFF),
217+
i16x8(1, 4, 2, 4, 5, 6, <u16>0x8000, <u16>0xFFFF)
218+
)
219+
==
220+
i16x8(1, 3, 3, 4, 5, 6, <u16>0x8000, <u16>0xFFFF)
221+
);
206222
assert(
207223
i16x8.neg(a)
208224
==

0 commit comments

Comments
 (0)