Skip to content

Commit 889e579

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[vm, compiler] Use immediate forms for BinaryUint32Op.
dart2js.aot.arm64 28757440 -> 28691320 (-66k) dart2js.aot.x64 28311232 -> 28310536 (-1k) dart2js.aot.rv64 27971912 -> 27955200 (-16k) dart2js.aot.arm32 27793504 -> 27775936 (-17k) TEST=vm/dart/uint32_op_imm_test Change-Id: I25e486ea1ab3b20369c0c5a5fafae5d1ea53b1c7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/388120 Reviewed-by: Alexander Markov <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent 950f08f commit 889e579

File tree

8 files changed

+527
-123
lines changed

8 files changed

+527
-123
lines changed
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import "dart:typed_data";
6+
7+
@pragma("vm:never-inline")
8+
void and1(Uint32List list) {
9+
list[0] &= 1;
10+
}
11+
12+
@pragma("vm:never-inline")
13+
void or1(Uint32List list) {
14+
list[0] |= 1;
15+
}
16+
17+
@pragma("vm:never-inline")
18+
void xor1(Uint32List list) {
19+
list[0] ^= 1;
20+
}
21+
22+
@pragma("vm:never-inline")
23+
void add1(Uint32List list) {
24+
list[0] += 1;
25+
}
26+
27+
@pragma("vm:never-inline")
28+
void sub1(Uint32List list) {
29+
list[0] -= 1;
30+
}
31+
32+
@pragma("vm:never-inline")
33+
void mul1(Uint32List list) {
34+
list[0] *= 1;
35+
}
36+
37+
@pragma("vm:never-inline")
38+
void and2(Uint32List list) {
39+
list[0] &= 2;
40+
}
41+
42+
@pragma("vm:never-inline")
43+
void or2(Uint32List list) {
44+
list[0] |= 2;
45+
}
46+
47+
@pragma("vm:never-inline")
48+
void xor2(Uint32List list) {
49+
list[0] ^= 2;
50+
}
51+
52+
@pragma("vm:never-inline")
53+
void add2(Uint32List list) {
54+
list[0] += 2;
55+
}
56+
57+
@pragma("vm:never-inline")
58+
void sub2(Uint32List list) {
59+
list[0] -= 2;
60+
}
61+
62+
@pragma("vm:never-inline")
63+
void mul2(Uint32List list) {
64+
list[0] *= 2;
65+
}
66+
67+
@pragma("vm:never-inline")
68+
void and7(Uint32List list) {
69+
list[0] &= 7;
70+
}
71+
72+
@pragma("vm:never-inline")
73+
void or7(Uint32List list) {
74+
list[0] |= 7;
75+
}
76+
77+
@pragma("vm:never-inline")
78+
void xor7(Uint32List list) {
79+
list[0] ^= 7;
80+
}
81+
82+
@pragma("vm:never-inline")
83+
void add7(Uint32List list) {
84+
list[0] += 7;
85+
}
86+
87+
@pragma("vm:never-inline")
88+
void sub7(Uint32List list) {
89+
list[0] -= 7;
90+
}
91+
92+
@pragma("vm:never-inline")
93+
void mul7(Uint32List list) {
94+
list[0] *= 7;
95+
}
96+
97+
@pragma("vm:never-inline")
98+
void andH(Uint32List list) {
99+
list[0] &= 0x7FFFFFF;
100+
}
101+
102+
@pragma("vm:never-inline")
103+
void orH(Uint32List list) {
104+
list[0] |= 0x7FFFFFF;
105+
}
106+
107+
@pragma("vm:never-inline")
108+
void xorH(Uint32List list) {
109+
list[0] ^= 0x7FFFFFF;
110+
}
111+
112+
@pragma("vm:never-inline")
113+
void addH(Uint32List list) {
114+
list[0] += 0x7FFFFFF;
115+
}
116+
117+
@pragma("vm:never-inline")
118+
void subH(Uint32List list) {
119+
list[0] -= 0x7FFFFFF;
120+
}
121+
122+
@pragma("vm:never-inline")
123+
void mulH(Uint32List list) {
124+
list[0] *= 0x7FFFFFF;
125+
}
126+
127+
expect(int observed, int expected) {
128+
if (observed != expected) {
129+
throw "0x${observed.toRadixString(16)}";
130+
}
131+
}
132+
133+
main() {
134+
Uint32List u32 = Uint32List(1);
135+
136+
u32[0] = 0x12345678;
137+
and1(u32);
138+
expect(u32[0], 0);
139+
u32[0] = 0x87654321;
140+
and1(u32);
141+
expect(u32[0], 1);
142+
u32[0] = 0x12345678;
143+
or1(u32);
144+
expect(u32[0], 0x12345679);
145+
u32[0] = 0x87654321;
146+
or1(u32);
147+
expect(u32[0], 0x87654321);
148+
u32[0] = 0x12345678;
149+
xor1(u32);
150+
expect(u32[0], 0x12345679);
151+
u32[0] = 0x87654321;
152+
xor1(u32);
153+
expect(u32[0], 0x87654320);
154+
u32[0] = 0x12345678;
155+
add1(u32);
156+
expect(u32[0], 0x12345679);
157+
u32[0] = 0x87654321;
158+
add1(u32);
159+
expect(u32[0], 0x87654322);
160+
u32[0] = 0x12345678;
161+
sub1(u32);
162+
expect(u32[0], 0x12345677);
163+
u32[0] = 0x87654321;
164+
sub1(u32);
165+
expect(u32[0], 0x87654320);
166+
u32[0] = 0x12345678;
167+
mul1(u32);
168+
expect(u32[0], 0x12345678);
169+
u32[0] = 0x87654321;
170+
mul1(u32);
171+
expect(u32[0], 0x87654321);
172+
173+
u32[0] = 0x12345678;
174+
and2(u32);
175+
expect(u32[0], 0);
176+
u32[0] = 0x87654321;
177+
and2(u32);
178+
expect(u32[0], 0);
179+
u32[0] = 0x12345678;
180+
or2(u32);
181+
expect(u32[0], 0x1234567a);
182+
u32[0] = 0x87654321;
183+
or2(u32);
184+
expect(u32[0], 0x87654323);
185+
u32[0] = 0x12345678;
186+
xor2(u32);
187+
expect(u32[0], 0x1234567a);
188+
u32[0] = 0x87654321;
189+
xor2(u32);
190+
expect(u32[0], 0x87654323);
191+
u32[0] = 0x12345678;
192+
add2(u32);
193+
expect(u32[0], 0x1234567a);
194+
u32[0] = 0x87654321;
195+
add2(u32);
196+
expect(u32[0], 0x87654323);
197+
u32[0] = 0x12345678;
198+
sub2(u32);
199+
expect(u32[0], 0x12345676);
200+
u32[0] = 0x87654321;
201+
sub2(u32);
202+
expect(u32[0], 0x8765431f);
203+
u32[0] = 0x12345678;
204+
mul2(u32);
205+
expect(u32[0], 0x2468acf0);
206+
u32[0] = 0x87654321;
207+
mul2(u32);
208+
expect(u32[0], 0x0eca8642);
209+
210+
u32[0] = 0x12345678;
211+
and7(u32);
212+
expect(u32[0], 0);
213+
u32[0] = 0x87654321;
214+
and7(u32);
215+
expect(u32[0], 1);
216+
u32[0] = 0x12345678;
217+
or7(u32);
218+
expect(u32[0], 0x1234567f);
219+
u32[0] = 0x87654321;
220+
or7(u32);
221+
expect(u32[0], 0x87654327);
222+
u32[0] = 0x12345678;
223+
xor7(u32);
224+
expect(u32[0], 0x1234567f);
225+
u32[0] = 0x87654321;
226+
xor7(u32);
227+
expect(u32[0], 0x87654326);
228+
u32[0] = 0x12345678;
229+
add7(u32);
230+
expect(u32[0], 0x1234567f);
231+
u32[0] = 0x87654321;
232+
add7(u32);
233+
expect(u32[0], 0x87654328);
234+
u32[0] = 0x12345678;
235+
sub7(u32);
236+
expect(u32[0], 0x12345671);
237+
u32[0] = 0x87654321;
238+
sub7(u32);
239+
expect(u32[0], 0x8765431a);
240+
u32[0] = 0x12345678;
241+
mul7(u32);
242+
expect(u32[0], 0x7f6e5d48);
243+
u32[0] = 0x87654321;
244+
mul7(u32);
245+
expect(u32[0], 0xb3c4d5e7);
246+
247+
u32[0] = 0x12345678;
248+
andH(u32);
249+
expect(u32[0], 0x02345678);
250+
u32[0] = 0x87654321;
251+
andH(u32);
252+
expect(u32[0], 0x07654321);
253+
u32[0] = 0x12345678;
254+
orH(u32);
255+
expect(u32[0], 0x17ffffff);
256+
u32[0] = 0x87654321;
257+
orH(u32);
258+
expect(u32[0], 0x87ffffff);
259+
u32[0] = 0x12345678;
260+
xorH(u32);
261+
expect(u32[0], 0x15cba987);
262+
u32[0] = 0x87654321;
263+
xorH(u32);
264+
expect(u32[0], 0x809abcde);
265+
u32[0] = 0x12345678;
266+
addH(u32);
267+
expect(u32[0], 0x1a345677);
268+
u32[0] = 0x87654321;
269+
addH(u32);
270+
expect(u32[0], 0x8f654320);
271+
u32[0] = 0x12345678;
272+
subH(u32);
273+
expect(u32[0], 0x0a345679);
274+
u32[0] = 0x87654321;
275+
subH(u32);
276+
expect(u32[0], 0x7f654322);
277+
u32[0] = 0x12345678;
278+
mulH(u32);
279+
expect(u32[0], 0xadcba988);
280+
u32[0] = 0x87654321;
281+
mulH(u32);
282+
expect(u32[0], 0x809abcdf);
283+
}

runtime/vm/compiler/assembler/assembler_arm.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3107,6 +3107,19 @@ void Assembler::OrImmediate(Register rd,
31073107
}
31083108
}
31093109

3110+
void Assembler::XorImmediate(Register rd,
3111+
Register rs,
3112+
int32_t imm,
3113+
Condition cond) {
3114+
Operand o;
3115+
if (Operand::CanHold(imm, &o)) {
3116+
eor(rd, rs, Operand(o), cond);
3117+
} else {
3118+
LoadImmediate(TMP, imm, cond);
3119+
eor(rd, rs, Operand(TMP), cond);
3120+
}
3121+
}
3122+
31103123
void Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) {
31113124
Operand o;
31123125
if (Operand::CanHold(value, &o)) {

runtime/vm/compiler/assembler/assembler_arm.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,12 +863,18 @@ class Assembler : public AssemblerBase {
863863
void MulImmediate(Register reg,
864864
int32_t imm,
865865
OperandSize width = kFourBytes) override {
866+
MulImmediate(reg, reg, imm, width);
867+
}
868+
void MulImmediate(Register rd,
869+
Register rn,
870+
int32_t imm,
871+
OperandSize width = kFourBytes) {
866872
ASSERT(width == kFourBytes);
867873
if (Utils::IsPowerOfTwo(imm)) {
868-
LslImmediate(reg, Utils::ShiftForPowerOfTwo(imm));
874+
LslImmediate(rd, rn, Utils::ShiftForPowerOfTwo(imm));
869875
} else {
870876
LoadImmediate(TMP, imm);
871-
mul(reg, reg, TMP);
877+
mul(rd, rn, TMP);
872878
}
873879
}
874880
void AndImmediate(Register rd,
@@ -913,6 +919,7 @@ class Assembler : public AssemblerBase {
913919
void OrImmediate(Register rd, int32_t imm, Condition cond = AL) {
914920
OrImmediate(rd, rd, imm, cond);
915921
}
922+
void XorImmediate(Register rd, Register rn, int32_t imm, Condition cond = AL);
916923
void LslImmediate(Register rd,
917924
Register rn,
918925
int32_t shift,

runtime/vm/compiler/assembler/assembler_arm64.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,15 +1805,21 @@ class Assembler : public AssemblerBase {
18051805
void MulImmediate(Register reg,
18061806
int64_t imm,
18071807
OperandSize width = kEightBytes) override {
1808+
MulImmediate(reg, reg, imm, width);
1809+
}
1810+
void MulImmediate(Register dest,
1811+
Register rn,
1812+
int64_t imm,
1813+
OperandSize width = kEightBytes) {
18081814
ASSERT(width == kFourBytes || width == kEightBytes);
18091815
if (Utils::IsPowerOfTwo(imm)) {
1810-
LslImmediate(reg, Utils::ShiftForPowerOfTwo(imm), width);
1816+
LslImmediate(dest, rn, Utils::ShiftForPowerOfTwo(imm), width);
18111817
} else {
18121818
LoadImmediate(TMP, imm);
18131819
if (width == kFourBytes) {
1814-
mulw(reg, reg, TMP);
1820+
mulw(dest, rn, TMP);
18151821
} else {
1816-
mul(reg, reg, TMP);
1822+
mul(dest, rn, TMP);
18171823
}
18181824
}
18191825
}

0 commit comments

Comments
 (0)