Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cb7c9de

Browse files
authored
fix: Move bswap back to stdlib (#2701)
1 parent 9480469 commit cb7c9de

File tree

13 files changed

+1162
-1090
lines changed

13 files changed

+1162
-1090
lines changed

‎src/builtins.ts‎

Lines changed: 0 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ export namespace BuiltinNames {
143143
export const isManaged = "~lib/builtins/isManaged";
144144
export const isVoid = "~lib/builtins/isVoid";
145145

146-
export const bswap = "~lib/builtins/bswap";
147-
148146
export const add = "~lib/builtins/add";
149147
export const sub = "~lib/builtins/sub";
150148
export const mul = "~lib/builtins/mul";
@@ -1193,181 +1191,6 @@ function builtin_idof(ctx: BuiltinFunctionContext): ExpressionRef {
11931191
}
11941192
builtinFunctions.set(BuiltinNames.idof, builtin_idof);
11951193

1196-
// bswap<T?>(value: T) -> T
1197-
function builtin_bswap(ctx: BuiltinFunctionContext): ExpressionRef {
1198-
let compiler = ctx.compiler;
1199-
let module = compiler.module;
1200-
if (
1201-
checkTypeOptional(ctx, true) |
1202-
checkArgsRequired(ctx, 1)
1203-
) return module.unreachable();
1204-
1205-
let typeArguments = ctx.typeArguments;
1206-
let arg0 = typeArguments
1207-
? compiler.compileExpression(
1208-
ctx.operands[0],
1209-
typeArguments[0].toUnsigned(),
1210-
Constraints.ConvImplicit | Constraints.MustWrap
1211-
)
1212-
: compiler.compileExpression(
1213-
ctx.operands[0],
1214-
Type.u32,
1215-
Constraints.MustWrap
1216-
);
1217-
1218-
let type = compiler.currentType;
1219-
if (type.isValue) {
1220-
switch (type.kind) {
1221-
case TypeKind.Bool:
1222-
case TypeKind.I8:
1223-
case TypeKind.U8: return arg0;
1224-
case TypeKind.I16:
1225-
case TypeKind.U16: {
1226-
// <T>(x << 8 | x >> 8)
1227-
let flow = compiler.currentFlow;
1228-
let temp = flow.getTempLocal(type);
1229-
flow.setLocalFlag(temp.index, LocalFlags.Wrapped);
1230-
1231-
let res = module.binary(
1232-
BinaryOp.OrI32,
1233-
module.binary(
1234-
BinaryOp.ShlI32,
1235-
module.local_tee(temp.index, arg0, false),
1236-
module.i32(8)
1237-
),
1238-
module.binary(
1239-
BinaryOp.ShrU32,
1240-
module.local_get(temp.index, TypeRef.I32),
1241-
module.i32(8)
1242-
)
1243-
);
1244-
// avoid wrapping for u16 due to it's already done for input arg
1245-
if (type.kind == TypeKind.I16) {
1246-
res = compiler.ensureSmallIntegerWrap(res, Type.i16);
1247-
}
1248-
return res;
1249-
}
1250-
case TypeKind.I32:
1251-
case TypeKind.U32:
1252-
case TypeKind.Isize:
1253-
case TypeKind.Usize: {
1254-
if (type.size == 32) {
1255-
// rotl(x & 0xFF00FF00, 8) | rotr(x & 0x00FF00FF, 8)
1256-
let flow = compiler.currentFlow;
1257-
let temp = flow.getTempLocal(type);
1258-
flow.setLocalFlag(temp.index, LocalFlags.Wrapped);
1259-
1260-
let res = module.binary(
1261-
BinaryOp.OrI32,
1262-
module.binary(
1263-
BinaryOp.RotlI32,
1264-
module.binary(
1265-
BinaryOp.AndI32,
1266-
module.local_tee(temp.index, arg0, false),
1267-
module.i32(0xFF00FF00)
1268-
),
1269-
module.i32(8)
1270-
),
1271-
module.binary(
1272-
BinaryOp.RotrI32,
1273-
module.binary(
1274-
BinaryOp.AndI32,
1275-
module.local_get(temp.index, TypeRef.I32),
1276-
module.i32(0x00FF00FF)
1277-
),
1278-
module.i32(8)
1279-
),
1280-
);
1281-
return res;
1282-
}
1283-
// fall-through
1284-
}
1285-
case TypeKind.I64:
1286-
case TypeKind.U64: {
1287-
// let t =
1288-
// ((x >>> 8) & 0x00FF00FF00FF00FF) |
1289-
// ((x & 0x00FF00FF00FF00FF) << 8)
1290-
//
1291-
// let res =
1292-
// ((t >>> 16) & 0x0000FFFF0000FFFF) |
1293-
// ((t & 0x0000FFFF0000FFFF) << 16)
1294-
//
1295-
// rotr(res, 32)
1296-
1297-
let flow = compiler.currentFlow;
1298-
let temp1 = flow.getTempLocal(type);
1299-
flow.setLocalFlag(temp1.index, LocalFlags.Wrapped);
1300-
let temp2 = flow.getTempLocal(type);
1301-
flow.setLocalFlag(temp2.index, LocalFlags.Wrapped);
1302-
1303-
// t = ((x >>> 8) & 0x00FF00FF00FF00FF) | ((x & 0x00FF00FF00FF00FF) << 8)
1304-
let expr = module.local_tee(
1305-
temp2.index,
1306-
module.binary(
1307-
BinaryOp.OrI64,
1308-
module.binary(
1309-
BinaryOp.AndI64,
1310-
module.binary(
1311-
BinaryOp.ShrU64,
1312-
module.local_tee(temp1.index, arg0, false),
1313-
module.i64(8)
1314-
),
1315-
module.i64(0x00FF00FF, 0x00FF00FF)
1316-
),
1317-
module.binary(
1318-
BinaryOp.ShlI64,
1319-
module.binary(
1320-
BinaryOp.AndI64,
1321-
module.local_get(temp1.index, TypeRef.I64),
1322-
module.i64(0x00FF00FF, 0x00FF00FF)
1323-
),
1324-
module.i64(8)
1325-
),
1326-
),
1327-
false
1328-
);
1329-
1330-
// ((t >>> 16) & 0x0000FFFF0000FFFF) | ((t & 0x0000FFFF0000FFFF) << 16)
1331-
let res = module.binary(
1332-
BinaryOp.OrI64,
1333-
module.binary(
1334-
BinaryOp.AndI64,
1335-
module.binary(
1336-
BinaryOp.ShrU64,
1337-
expr,
1338-
module.i64(16)
1339-
),
1340-
module.i64(0x0000FFFF, 0x0000FFFF)
1341-
),
1342-
module.binary(
1343-
BinaryOp.ShlI64,
1344-
module.binary(
1345-
BinaryOp.AndI64,
1346-
module.local_get(temp2.index, TypeRef.I64),
1347-
module.i64(0x0000FFFF, 0x0000FFFF)
1348-
),
1349-
module.i64(16)
1350-
),
1351-
);
1352-
1353-
// rotr(res, 32)
1354-
res = module.binary(
1355-
BinaryOp.RotrI64,
1356-
res,
1357-
module.i64(32)
1358-
);
1359-
return res;
1360-
}
1361-
}
1362-
}
1363-
compiler.error(
1364-
DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,
1365-
ctx.reportNode.typeArgumentsRange, "bswap", type.toString()
1366-
);
1367-
return module.unreachable();
1368-
}
1369-
builtinFunctions.set(BuiltinNames.bswap, builtin_bswap);
1370-
13711194
// === Math ===================================================================================
13721195

13731196
// NaN

‎std/assembly/builtins.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@ export declare function isVoid<T>(): bool;
6666
@builtin
6767
export declare function lengthof<T>(func?: T): i32;
6868

69-
// @ts-ignore
70-
@builtin
71-
export declare function bswap<T>(value: T): T;
72-
7369
// @ts-ignore: decorator
7470
@builtin
7571
export declare function clz<T>(value: T): T;

‎std/assembly/polyfills.ts‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export function bswap<T extends number>(value: T): T {
2+
if (isInteger<T>()) {
3+
if (sizeof<T>() == 1) {
4+
return value;
5+
}
6+
if (sizeof<T>() == 2) {
7+
return <T>(<u16>value << 8 | (<u16>value >> 8));
8+
}
9+
if (sizeof<T>() == 4) {
10+
return <T>(
11+
rotl(<u32>value & 0xFF00FF00, 8) |
12+
rotr(<u32>value & 0x00FF00FF, 8)
13+
);
14+
}
15+
if (sizeof<T>() == 8) {
16+
let a = (<u64>value >> 8) & 0x00FF00FF00FF00FF;
17+
let b = (<u64>value & 0x00FF00FF00FF00FF) << 8;
18+
let v = a | b;
19+
20+
a = (v >>> 16) & 0x0000FFFF0000FFFF;
21+
b = (v & 0x0000FFFF0000FFFF) << 16;
22+
23+
return <T>rotr(a | b, 32);
24+
}
25+
}
26+
ERROR("Unsupported generic type");
27+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /