]>
git.proxmox.com Git - rustc.git/blob - src/binaryen/src/ir/bits.h
2 * Copyright 2017 WebAssembly Community Group participants
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef wasm_ir_bits_h
18 #define wasm_ir_bits_h
20 #include "support/bits.h"
21 #include "wasm-builder.h"
22 #include "ir/literal-utils.h"
27 // get a mask to keep only the low # of bits
28 static int32_t lowBitMask(int32_t bits
) {
30 if (bits
>= 32) return ret
;
31 return ret
>> (32 - bits
);
34 // checks if the input is a mask of lower bits, i.e., all 1s up to some high bit, and all zeros
35 // from there. returns the number of masked bits, or 0 if this is not such a mask
36 static uint32_t getMaskedBits(uint32_t mask
) {
37 if (mask
== uint32_t(-1)) return 32; // all the bits
38 if (mask
== 0) return 0; // trivially not a mask
39 // otherwise, see if adding one turns this into a 1-bit thing, 00011111 + 1 => 00100000
40 if (PopCount(mask
+ 1) != 1) return 0;
41 // this is indeed a mask
42 return 32 - CountLeadingZeroes(mask
);
45 // gets the number of effective shifts a shift operation does. In
46 // wasm, only 5 bits matter for 32-bit shifts, and 6 for 64.
47 static Index
getEffectiveShifts(Index amount
, WasmType type
) {
50 } else if (type
== i64
) {
56 static Index
getEffectiveShifts(Expression
* expr
) {
57 auto* amount
= expr
->cast
<Const
>();
58 if (amount
->type
== i32
) {
59 return getEffectiveShifts(amount
->value
.geti32(), i32
);
60 } else if (amount
->type
== i64
) {
61 return getEffectiveShifts(amount
->value
.geti64(), i64
);
66 static Expression
* makeSignExt(Expression
* value
, Index bytes
, Module
& wasm
) {
67 if (value
->type
== i32
) {
68 if (bytes
== 1 || bytes
== 2) {
69 auto shifts
= bytes
== 1 ? 24 : 16;
70 Builder
builder(wasm
);
71 return builder
.makeBinary(
76 LiteralUtils::makeFromInt32(shifts
, i32
, wasm
)
78 LiteralUtils::makeFromInt32(shifts
, i32
, wasm
)
82 return value
; // nothing to do
84 assert(value
->type
== i64
);
85 if (bytes
== 1 || bytes
== 2 || bytes
== 4) {
86 auto shifts
= bytes
== 1 ? 56 : (bytes
== 2 ? 48 : 32);
87 Builder
builder(wasm
);
88 return builder
.makeBinary(
93 LiteralUtils::makeFromInt32(shifts
, i64
, wasm
)
95 LiteralUtils::makeFromInt32(shifts
, i64
, wasm
)
99 return value
; // nothing to do
106 #endif // wasm_ir_bits_h