Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3825,6 +3825,28 @@ and compile_exp (env : E.t) exp =
sanitize_word_result Type.Word16)
| "shrs" -> compile_kernel_as SR.UnboxedWord32 (G.i (Binary (Wasm.Values.I32 I32Op.ShrS)))
| "shrs64" -> compile_kernel_as SR.UnboxedInt64 (G.i (Binary (Wasm.Values.I64 I64Op.ShrS)))
| "btst8" -> compile_kernel_as SR.Vanilla (
let ty = Type.Word8 in
let (set_b, get_b) = new_local env "b"
in lsb_adjust ty ^^ set_b ^^ lsb_adjust ty ^^
compile_unboxed_one ^^ get_b ^^ clamp_shift_amount ty ^^
G.i (Binary (Wasm.Values.I32 I32Op.Shl)) ^^
G.i (Binary (Wasm.Values.I32 I32Op.And)))
| "btst16" -> compile_kernel_as SR.Vanilla (
let ty = Type.Word16 in
let (set_b, get_b) = new_local env "b"
in lsb_adjust ty ^^ set_b ^^ lsb_adjust ty ^^
compile_unboxed_one ^^ get_b ^^ clamp_shift_amount ty ^^
G.i (Binary (Wasm.Values.I32 I32Op.Shl)) ^^
G.i (Binary (Wasm.Values.I32 I32Op.And)))
| "btst" -> compile_kernel_as SR.UnboxedWord32 (
let (set_b, get_b) = new_local env "b"
in set_b ^^ compile_unboxed_one ^^ get_b ^^ G.i (Binary (Wasm.Values.I32 I32Op.Shl)) ^^
G.i (Binary (Wasm.Values.I32 I32Op.And)))
| "btst64" -> compile_kernel_as SR.UnboxedInt64 (
let (set_b, get_b) = new_local64 env "b"
in set_b ^^ compile_const_64 1L ^^ get_b ^^ G.i (Binary (Wasm.Values.I64 I64Op.Shl)) ^^
G.i (Binary (Wasm.Values.I64 I64Op.And)))

| _ -> SR.Unreachable, todo "compile_exp" (Arrange_ir.exp pe) (G.i Unreachable)
end
Expand Down
16 changes: 16 additions & 0 deletions src/prelude.ml
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,25 @@ func shrsWord8(w : Word8, amount : Word8) : Word8 = (prim "shrs8" : (Word8, Word
func popcntWord8(w : Word8) : Word8 = (prim "popcnt8" : Word8 -> Word8) w;
func clzWord8(w : Word8) : Word8 = (prim "clz8" : Word8 -> Word8) w;
func ctzWord8(w : Word8) : Word8 = (prim "ctz8" : Word8 -> Word8) w;
func btstWord8(w : Word8, amount : Word8) : Bool = (prim "btst8" : (Word8, Word8) -> Word8) (w, amount) != (0 : Word8);

func shrsWord16(w : Word16, amount : Word16) : Word16 = (prim "shrs16" : (Word16, Word16) -> Word16) (w, amount);
func popcntWord16(w : Word16) : Word16 = (prim "popcnt16" : Word16 -> Word16) w;
func clzWord16(w : Word16) : Word16 = (prim "clz16" : Word16 -> Word16) w;
func ctzWord16(w : Word16) : Word16 = (prim "ctz16" : Word16 -> Word16) w;
func btstWord16(w : Word16, amount : Word16) : Bool = (prim "btst16" : (Word16, Word16) -> Word16) (w, amount) != (0 : Word16);

func shrsWord32(w : Word32, amount : Word32) : Word32 = (prim "shrs" : (Word32, Word32) -> Word32) (w, amount);
func popcntWord32(w : Word32) : Word32 = (prim "popcnt" : Word32 -> Word32) w;
func clzWord32(w : Word32) : Word32 = (prim "clz" : Word32 -> Word32) w;
func ctzWord32(w : Word32) : Word32 = (prim "ctz" : Word32 -> Word32) w;
func btstWord32(w : Word32, amount : Word32) : Bool = (prim "btst" : (Word32, Word32) -> Word32) (w, amount) != (0 : Word32);

func shrsWord64(w : Word64, amount : Word64) : Word64 = (prim "shrs64" : (Word64, Word64) -> Word64) (w, amount);
func popcntWord64(w : Word64) : Word64 = (prim "popcnt64" : Word64 -> Word64) w;
func clzWord64(w : Word64) : Word64 = (prim "clz64" : Word64 -> Word64) w;
func ctzWord64(w : Word64) : Word64 = (prim "ctz64" : Word64 -> Word64) w;
func btstWord64(w : Word64, amount : Word64) : Bool = (prim "btst64" : (Word64, Word64) -> Word64) (w, amount) != (0 : Word64);


// This would be nicer as a objects, but lets do them as functions
Expand Down Expand Up @@ -230,6 +234,18 @@ let prim = function
| Word64 w -> Word64 (Word64.ctz w)
| _ -> failwith "ctz")

| "btst8"
| "btst16"
| "btst"
| "btst64" -> fun v k ->
let w, a = as_pair v
in k (match w with
| Word8 y -> Word8 Word8.(and_ y (shl (of_int_u 1) (as_word8 a)))
| Word16 y -> Word16 Word16.(and_ y (shl (of_int_u 1) (as_word16 a)))
| Word32 y -> Word32 (Word32.and_ y (Word32.shl 1l (as_word32 a)))
| Word64 y -> Word64 (Word64.and_ y (Word64.shl 1L (as_word64 a)))
| _ -> failwith "btst")

| "print" -> fun v k -> Printf.printf "%s%!" (as_text v); k unit
| "printInt" -> fun v k -> Printf.printf "%d%!" (Int.to_int (as_int v)); k unit
| "@serialize" -> fun v k -> k (Serialized v)
Expand Down
16 changes: 8 additions & 8 deletions test/run-dfinity/ok/counter-class.wasm.stderr.ok
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,31 @@ non-closed actor: (ActorE
(FuncE
read
(shared 1 -> 0)
(params $60)
(params $68)
()
(BlockE
(LetD
(TupP (VarP $58))
(TupE (CallE ( 1 -> 1) (PrimE @deserialize) (VarE $60)))
(TupP (VarP $66))
(TupE (CallE ( 1 -> 1) (PrimE @deserialize) (VarE $68)))
)
(CallE
( 1 -> 0)
(FuncE
$lambda
( 1 -> 0)
(params $57)
(params $65)
()
(CallE ( 1 -> 0) (VarE $57) (VarE c))
(CallE ( 1 -> 0) (VarE $65) (VarE c))
)
(FuncE
$lambda
( 1 -> 0)
(params $59)
(params $67)
()
(CallE
(shared 1 -> 0)
(VarE $58)
(CallE ( 1 -> 1) (PrimE @serialize) (VarE $59))
(VarE $66)
(CallE ( 1 -> 1) (PrimE @serialize) (VarE $67))
)
)
)
Expand Down
12 changes: 12 additions & 0 deletions test/run/ok/words.run-ir.ok
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
61 61
49 49
5 5
set
clear
set
8912765 8912765
4286054531 -8912765
4286054530 -8912766
Expand All @@ -40,6 +43,9 @@
29 29
17 17
5 5
set
clear
set
55734 -9802
9802 9802
9801 9801
Expand All @@ -60,6 +66,9 @@
13 13
1 1
5 5
set
clear
set
34 34
222 -34
221 -35
Expand All @@ -80,3 +89,6 @@
5 5
0 0
3 3
set
clear
set
12 changes: 12 additions & 0 deletions test/run/ok/words.run-low.ok
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
61 61
49 49
5 5
set
clear
set
8912765 8912765
4286054531 -8912765
4286054530 -8912766
Expand All @@ -40,6 +43,9 @@
29 29
17 17
5 5
set
clear
set
55734 -9802
9802 9802
9801 9801
Expand All @@ -60,6 +66,9 @@
13 13
1 1
5 5
set
clear
set
34 34
222 -34
221 -35
Expand All @@ -80,3 +89,6 @@
5 5
0 0
3 3
set
clear
set
12 changes: 12 additions & 0 deletions test/run/ok/words.run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
61 61
49 49
5 5
set
clear
set
8912765 8912765
4286054531 -8912765
4286054530 -8912766
Expand All @@ -40,6 +43,9 @@
29 29
17 17
5 5
set
clear
set
55734 -9802
9802 9802
9801 9801
Expand All @@ -60,6 +66,9 @@
13 13
1 1
5 5
set
clear
set
34 34
222 -34
221 -35
Expand All @@ -80,3 +89,6 @@
5 5
0 0
3 3
set
clear
set
15 changes: 15 additions & 0 deletions test/run/words.as
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// CHECK: func $start

func printBit(a : Bool) { print(if a "set" else "clear"); print "\n" };


func checkpointAlpha() {};
func checkpointBravo() {};
func checkpointCharlie() {};
Expand Down Expand Up @@ -53,6 +56,9 @@ func checkpointJuliett() {};
printW64ln(popcntWord64 d); // -15 = 0xfffffffffffffff1 = 0b1111_..._1111_1111_0001 (population = 61)
printW64ln(clzWord64 e); // 20000 = 0x0000000000004e20 (leading zeros = 49)
printW64ln(ctzWord64 e); // 20000 = 0x0000000000004e20 (trailing zeros = 5)
printBit(btstWord64(e, 5 : Word64)); // 20000 = 0x0000000000004e20 (result = true)
printBit(btstWord64(e, 63 : Word64)); // 20000 = 0x0000000000004e20 (result = false)
printBit(btstWord64(e, 69 : Word64)); // 20000 = 0x0000000000004e20 (mod 64, result = true)

assert (3 : Word64 ** (4 : Word64) == (81 : Word64));
assert (3 : Word64 ** (7 : Word64) == (2187 : Word64));
Expand Down Expand Up @@ -105,6 +111,9 @@ func checkpointJuliett() {};
printW32ln(popcntWord32 d); // -15 = 0xfffffff1 = 0b1111_1111_1111_1111_1111_1111_1111_0001 (population = 29)
printW32ln(clzWord32 e); // 20000 = 0x00004e20 (leading zeros = 17)
printW32ln(ctzWord32 e); // 20000 = 0x00004e20 (trailing zeros = 5)
printBit(btstWord32(e, 5 : Word32)); // 20000 = 0x00004e20 (result = true)
printBit(btstWord32(e, 31 : Word32)); // 20000 = 0x00004e20 (result = false)
printBit(btstWord32(e, 37 : Word32)); // 20000 = 0x00004e20 (mod 32, result = true)

assert (3 : Word32 ** (4 : Word32) == (81 : Word32));
assert (3 : Word32 ** (7 : Word32) == (2187 : Word32));
Expand Down Expand Up @@ -180,6 +189,9 @@ func checkpointJuliett() {};
printW16ln(popcntWord16 d); // -15 = 0xfff1 = 0b1111_1111_1111_0001 (population = 13)
printW16ln(clzWord16 e); // 20000 = 0x4e20 (leading zeros = 1)
printW16ln(ctzWord16 e); // 20000 = 0x4e20 (trailing zeros = 5)
printBit(btstWord16(e, 5 : Word16)); // 20000 = 0x4e20 (result = true)
printBit(btstWord16(e, 15 : Word16)); // 20000 = 0x4e20 (result = false)
printBit(btstWord16(e, 21 : Word16)); // 20000 = 0x4e20 (mod 16, result = true)


assert (3 : Word16 ** (0 : Word16) == (1 : Word16));
Expand Down Expand Up @@ -251,6 +263,9 @@ func checkpointJuliett() {};
printW8ln(popcntWord8 d); // -15 = 0xf1 = 0b1111_0001 (population = 5)
printW8ln(clzWord8 e); // 200 = 0xC8 (leading zeros = 0)
printW8ln(ctzWord8 e); // 200 = 0xC8 (trailing zeros = 3)
printBit(btstWord8(e, 3 : Word8)); // 200 = 0xC8 (result = true)
printBit(btstWord8(e, 5 : Word8)); // 200 = 0xC8 (result = false)
printBit(btstWord8(e, 11 : Word8)); // 200 = 0xC8 (mod 8, result = true)

assert (3 : Word8 ** (0 : Word8) == (1 : Word8));
assert (3 : Word8 ** (3 : Word8) == (27 : Word8));
Expand Down