Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9417d7e

Browse files
authored
Merge pull request #1482 from Shaikh-Ubaid/wasm_shift_opts
WASM, WASM_X64: Support shift operations
2 parents 0331203 + 177a12d commit 9417d7e

File tree

5 files changed

+117
-0
lines changed

5 files changed

+117
-0
lines changed

integration_tests/bit_operations_i32.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,38 @@ def test_bitxor():
8787
assert(r == -1)
8888
assert(s == -2147483643)
8989

90+
def test_left_shift():
91+
a: i32 = 4
92+
shift_amount: i32 = 2
93+
b: i32 = a << shift_amount
94+
print(b)
95+
assert b == 16
96+
97+
a = -16
98+
shift_amount = 2
99+
b = a << shift_amount
100+
print(b)
101+
assert b == -64
102+
103+
def test_right_shift():
104+
a: i32 = 16
105+
shift_amount: i32 = 2
106+
b: i32 = a >> shift_amount
107+
print(b)
108+
assert b == 4
109+
110+
a = -16
111+
shift_amount = 2
112+
b = a >> shift_amount
113+
print(b)
114+
assert b == -4
115+
90116
def main0():
91117
test_bitnot()
92118
test_bitand()
93119
test_bitor()
94120
test_bitxor()
121+
test_left_shift()
122+
test_right_shift()
95123

96124
main0()

integration_tests/bit_operations_i64.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,38 @@ def test_bitxor():
8484
assert(r == i64(-1))
8585
assert(s == i64(-115292150461418))
8686

87+
def test_left_shift():
88+
a: i64 = i64(4294967296)
89+
shift_amount: i64 = i64(2)
90+
b: i64 = a << shift_amount
91+
print(b)
92+
assert b == i64(17179869184)
93+
94+
a = i64(-4294967296)
95+
shift_amount = i64(2)
96+
b = a << shift_amount
97+
print(b)
98+
assert b == i64(-17179869184)
99+
100+
def test_right_shift():
101+
a: i64 = i64(4294967296)
102+
shift_amount: i64 = i64(2)
103+
b: i64 = a >> shift_amount
104+
print(b)
105+
assert b == i64(1073741824)
106+
107+
a = i64(-4294967296)
108+
shift_amount = i64(2)
109+
b = a >> shift_amount
110+
print(b)
111+
assert b == i64(-1073741824)
112+
87113
def main0():
88114
test_bitnot()
89115
test_bitand()
90116
test_bitor()
91117
test_bitxor()
118+
test_left_shift()
119+
test_right_shift()
92120

93121
main0()

src/libasr/codegen/asr_to_wasm.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,14 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
890890
wasm::emit_i32_xor(m_code_section, m_al);
891891
break;
892892
};
893+
case ASR::binopType::BitLShift: {
894+
wasm::emit_i32_shl(m_code_section, m_al);
895+
break;
896+
};
897+
case ASR::binopType::BitRShift: {
898+
wasm::emit_i32_shr_s(m_code_section, m_al);
899+
break;
900+
};
893901
default: {
894902
throw CodeGenError(
895903
"ICE IntegerBinop kind 4: unknown operation");
@@ -947,6 +955,14 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
947955
wasm::emit_i64_xor(m_code_section, m_al);
948956
break;
949957
};
958+
case ASR::binopType::BitLShift: {
959+
wasm::emit_i64_shl(m_code_section, m_al);
960+
break;
961+
};
962+
case ASR::binopType::BitRShift: {
963+
wasm::emit_i64_shr_s(m_code_section, m_al);
964+
break;
965+
};
950966
default: {
951967
throw CodeGenError(
952968
"ICE IntegerBinop kind 8: unknown operation");

src/libasr/codegen/wasm_to_x64.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,19 @@ class X64Visitor : public WASMDecoder<X64Visitor>,
309309
handleI32Opt([&](){ m_a.asm_xor_r64_r64(X64Reg::rax, X64Reg::rbx);});
310310
}
311311

312+
void visit_I32Shl() {
313+
m_a.asm_pop_r64(X64Reg::rcx);
314+
m_a.asm_pop_r64(X64Reg::rax);
315+
m_a.asm_shl_r64_cl(X64Reg::rax);
316+
m_a.asm_push_r64(X64Reg::rax);
317+
}
318+
void visit_I32ShrS() {
319+
m_a.asm_pop_r64(X64Reg::rcx);
320+
m_a.asm_pop_r64(X64Reg::rax);
321+
m_a.asm_sar_r64_cl(X64Reg::rax);
322+
m_a.asm_push_r64(X64Reg::rax);
323+
}
324+
312325
void visit_I32Eqz() {
313326
m_a.asm_mov_r64_imm64(X64Reg::rax, 0);
314327
m_a.asm_push_r64(X64Reg::rax);

src/libasr/codegen/x86_assembler.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,38 @@ class X86Assembler {
12541254
EMIT("syscall");
12551255
}
12561256

1257+
// SHL - Shift Logical/Unsigned Left
1258+
void asm_shl_r64_cl(X64Reg r64) {
1259+
X86Reg r32 = X86Reg(r64 & 7);
1260+
m_code.push_back(m_al, rex(1, 0, 0, r64 >> 3));
1261+
m_code.push_back(m_al, 0xD3);
1262+
modrm_sib_disp(m_code, m_al, X86Reg::esp, &r32, nullptr, 1, 0, false);
1263+
EMIT("shl " + r2s(r64) + ", cl");
1264+
}
1265+
1266+
// SHL - Shift Logical/Unsigned Left
1267+
void asm_shl_r32_cl(X86Reg r32) {
1268+
m_code.push_back(m_al, 0xD3);
1269+
modrm_sib_disp(m_code, m_al, X86Reg::esp, &r32, nullptr, 1, 0, false);
1270+
EMIT("shl " + r2s(r32) + ", cl");
1271+
}
1272+
1273+
// SAR - Shift Arithmetic/Signed Right
1274+
void asm_sar_r64_cl(X64Reg r64) {
1275+
X86Reg r32 = X86Reg(r64 & 7);
1276+
m_code.push_back(m_al, rex(1, 0, 0, r64 >> 3));
1277+
m_code.push_back(m_al, 0xD3);
1278+
modrm_sib_disp(m_code, m_al, X86Reg::edi, &r32, nullptr, 1, 0, false);
1279+
EMIT("sar " + r2s(r64) + ", cl");
1280+
}
1281+
1282+
// SAR - Shift Arithmetic/Signed Right
1283+
void asm_sar_r32_cl(X86Reg r32) {
1284+
m_code.push_back(m_al, 0xD3);
1285+
modrm_sib_disp(m_code, m_al, X86Reg::edi, &r32, nullptr, 1, 0, false);
1286+
EMIT("sar " + r2s(r32) + ", cl");
1287+
}
1288+
12571289
void asm_fld_m32(X86Reg *base, X86Reg *index,
12581290
uint8_t scale, int32_t disp) {
12591291
m_code.push_back(m_al, 0xd9);

0 commit comments

Comments
 (0)