• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 /**
18  * Tests for SAD (sum of absolute differences).
19  */
20 public class SimdSadByte {
21 
22   // TODO: lower precision still coming, b/64091002
23 
sadByte2Byte(byte[] b1, byte[] b2)24   private static byte sadByte2Byte(byte[] b1, byte[] b2) {
25     int min_length = Math.min(b1.length, b2.length);
26     byte sad = 0;
27     for (int i = 0; i < min_length; i++) {
28       sad += Math.abs(b1[i] - b2[i]);
29     }
30     return sad;
31   }
32 
sadByte2ByteAlt(byte[] b1, byte[] b2)33   private static byte sadByte2ByteAlt(byte[] b1, byte[] b2) {
34     int min_length = Math.min(b1.length, b2.length);
35     byte sad = 0;
36     for (int i = 0; i < min_length; i++) {
37       byte s = b1[i];
38       byte p = b2[i];
39       sad += s >= p ? s - p : p - s;
40     }
41     return sad;
42   }
43 
sadByte2ByteAlt2(byte[] b1, byte[] b2)44   private static byte sadByte2ByteAlt2(byte[] b1, byte[] b2) {
45     int min_length = Math.min(b1.length, b2.length);
46     byte sad = 0;
47     for (int i = 0; i < min_length; i++) {
48       byte s = b1[i];
49       byte p = b2[i];
50       int x = s - p;
51       if (x < 0) x = -x;
52       sad += x;
53     }
54     return sad;
55   }
56 
sadByte2Short(byte[] b1, byte[] b2)57   private static short sadByte2Short(byte[] b1, byte[] b2) {
58     int min_length = Math.min(b1.length, b2.length);
59     short sad = 0;
60     for (int i = 0; i < min_length; i++) {
61       sad += Math.abs(b1[i] - b2[i]);
62     }
63     return sad;
64   }
65 
sadByte2ShortAlt(byte[] b1, byte[] b2)66   private static short sadByte2ShortAlt(byte[] b1, byte[] b2) {
67     int min_length = Math.min(b1.length, b2.length);
68     short sad = 0;
69     for (int i = 0; i < min_length; i++) {
70       byte s = b1[i];
71       byte p = b2[i];
72       sad += s >= p ? s - p : p - s;
73     }
74     return sad;
75   }
76 
sadByte2ShortAlt2(byte[] b1, byte[] b2)77   private static short sadByte2ShortAlt2(byte[] b1, byte[] b2) {
78     int min_length = Math.min(b1.length, b2.length);
79     short sad = 0;
80     for (int i = 0; i < min_length; i++) {
81       byte s = b1[i];
82       byte p = b2[i];
83       int x = s - p;
84       if (x < 0) x = -x;
85       sad += x;
86     }
87     return sad;
88   }
89 
90   /// CHECK-START: int SimdSadByte.sadByte2Int(byte[], byte[]) loop_optimization (before)
91   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
92   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
93   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
94   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
95   /// CHECK-DAG: <<Get1:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
96   /// CHECK-DAG: <<Get2:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
97   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Get1>>,<<Get2>>]        loop:<<Loop>>      outer_loop:none
98   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
99   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
100   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
101   //
102   /// CHECK-START-ARM64: int SimdSadByte.sadByte2Int(byte[], byte[]) loop_optimization (after)
103   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
104   /// CHECK-IF:     hasIsaFeature("sve")
105   //
106   //      SAD idiom is not supported for SVE.
107   ///     CHECK-NOT: VecSADAccumulate
108   //
109   /// CHECK-ELSE:
110   //
111   ///     CHECK-DAG: <<Cons16:i\d+>> IntConstant 16                 loop:none
112   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
113   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
114   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
115   ///     CHECK-DAG: <<Load1:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
116   ///     CHECK-DAG: <<Load2:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
117   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load1>>,<<Load2>>] loop:<<Loop>> outer_loop:none
118   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons16>>]      loop:<<Loop>>      outer_loop:none
119   //
120   /// CHECK-FI:
sadByte2Int(byte[] b1, byte[] b2)121   private static int sadByte2Int(byte[] b1, byte[] b2) {
122     int min_length = Math.min(b1.length, b2.length);
123     int sad = 0;
124     for (int i = 0; i < min_length; i++) {
125       sad += Math.abs(b1[i] - b2[i]);
126     }
127     return sad;
128   }
129 
130   /// CHECK-START: int SimdSadByte.sadByte2IntAlt(byte[], byte[]) loop_optimization (before)
131   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
132   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
133   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
134   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
135   /// CHECK-DAG: <<Get1:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
136   /// CHECK-DAG: <<Get2:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
137   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Get2>>,<<Get1>>]        loop:<<Loop>>      outer_loop:none
138   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
139   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
140   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
141   //
142   /// CHECK-START-ARM64: int SimdSadByte.sadByte2IntAlt(byte[], byte[]) loop_optimization (after)
143   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
144   /// CHECK-IF:     hasIsaFeature("sve")
145   //
146   //      SAD idiom is not supported for SVE.
147   ///     CHECK-NOT: VecSADAccumulate
148   //
149   /// CHECK-ELSE:
150   //
151   ///     CHECK-DAG: <<Cons16:i\d+>> IntConstant 16                 loop:none
152   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
153   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
154   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
155   ///     CHECK-DAG: <<Load1:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
156   ///     CHECK-DAG: <<Load2:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
157   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load2>>,<<Load1>>] loop:<<Loop>> outer_loop:none
158   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons16>>]      loop:<<Loop>>      outer_loop:none
159   //
160   /// CHECK-FI:
sadByte2IntAlt(byte[] b1, byte[] b2)161   private static int sadByte2IntAlt(byte[] b1, byte[] b2) {
162     int min_length = Math.min(b1.length, b2.length);
163     int sad = 0;
164     for (int i = 0; i < min_length; i++) {
165       byte s = b1[i];
166       byte p = b2[i];
167       sad += s >= p ? s - p : p - s;
168     }
169     return sad;
170   }
171 
172   /// CHECK-START: int SimdSadByte.sadByte2IntAlt2(byte[], byte[]) loop_optimization (before)
173   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
174   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
175   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
176   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
177   /// CHECK-DAG: <<Get1:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
178   /// CHECK-DAG: <<Get2:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
179   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Get1>>,<<Get2>>]        loop:<<Loop>>      outer_loop:none
180   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
181   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
182   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
183   //
184   /// CHECK-START-ARM64: int SimdSadByte.sadByte2IntAlt2(byte[], byte[]) loop_optimization (after)
185   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
186   /// CHECK-IF:     hasIsaFeature("sve")
187   //
188   //      SAD idiom is not supported for SVE.
189   ///     CHECK-NOT: VecSADAccumulate
190   //
191   /// CHECK-ELSE:
192   //
193   ///     CHECK-DAG: <<Cons16:i\d+>> IntConstant 16                 loop:none
194   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
195   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
196   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
197   ///     CHECK-DAG: <<Load1:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
198   ///     CHECK-DAG: <<Load2:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
199   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load1>>,<<Load2>>] loop:<<Loop>> outer_loop:none
200   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons16>>]      loop:<<Loop>>      outer_loop:none
201   //
202   /// CHECK-FI:
sadByte2IntAlt2(byte[] b1, byte[] b2)203   private static int sadByte2IntAlt2(byte[] b1, byte[] b2) {
204     int min_length = Math.min(b1.length, b2.length);
205     int sad = 0;
206     for (int i = 0; i < min_length; i++) {
207       byte s = b1[i];
208       byte p = b2[i];
209       int x = s - p;
210       if (x < 0) x = -x;
211       sad += x;
212     }
213     return sad;
214   }
215 
216   /// CHECK-START: long SimdSadByte.sadByte2Long(byte[], byte[]) loop_optimization (before)
217   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
218   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
219   /// CHECK-DAG: <<ConsL:j\d+>>  LongConstant 0                 loop:none
220 
221   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
222   /// CHECK-DAG: <<Phi2:j\d+>>   Phi [<<ConsL>>,{{j\d+}}]       loop:<<Loop>>      outer_loop:none
223   /// CHECK-DAG: <<Get1:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
224   /// CHECK-DAG: <<Get2:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
225   /// CHECK-DAG: <<Cnv1:j\d+>>   TypeConversion [<<Get1>>]      loop:<<Loop>>      outer_loop:none
226   /// CHECK-DAG: <<Cnv2:j\d+>>   TypeConversion [<<Get2>>]      loop:<<Loop>>      outer_loop:none
227   /// CHECK-DAG: <<Sub:j\d+>>    Sub [<<Cnv1>>,<<Cnv2>>]        loop:<<Loop>>      outer_loop:none
228   /// CHECK-DAG: <<Intrin:j\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
229   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
230   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
231   //
232   /// CHECK-START-ARM64: long SimdSadByte.sadByte2Long(byte[], byte[]) loop_optimization (after)
233   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
234   /// CHECK-DAG: <<ConsL:j\d+>>  LongConstant 0                 loop:none
235   /// CHECK-IF:     hasIsaFeature("sve")
236   //
237   //      SAD idiom is not supported for SVE.
238   ///     CHECK-NOT: VecSADAccumulate
239   //
240   /// CHECK-ELSE:
241   //
242   ///     CHECK-DAG: <<Cons16:i\d+>> IntConstant 16                 loop:none
243   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<ConsL>>]      loop:none
244   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
245   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
246   ///     CHECK-DAG: <<Load1:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
247   ///     CHECK-DAG: <<Load2:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
248   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load1>>,<<Load2>>] loop:<<Loop>> outer_loop:none
249   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons16>>]      loop:<<Loop>>      outer_loop:none
250   //
251   /// CHECK-FI:
sadByte2Long(byte[] b1, byte[] b2)252   private static long sadByte2Long(byte[] b1, byte[] b2) {
253     int min_length = Math.min(b1.length, b2.length);
254     long sad = 0;
255     for (int i = 0; i < min_length; i++) {
256       long x = b1[i];
257       long y = b2[i];
258       sad += Math.abs(x - y);
259     }
260     return sad;
261   }
262 
263   /// CHECK-START: long SimdSadByte.sadByte2LongAt1(byte[], byte[]) loop_optimization (before)
264   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
265   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
266   /// CHECK-DAG: <<ConsL:j\d+>>  LongConstant 1                 loop:none
267   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
268   /// CHECK-DAG: <<Phi2:j\d+>>   Phi [<<ConsL>>,{{j\d+}}]       loop:<<Loop>>      outer_loop:none
269   /// CHECK-DAG: <<Get1:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
270   /// CHECK-DAG: <<Get2:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
271   /// CHECK-DAG: <<Cnv1:j\d+>>   TypeConversion [<<Get1>>]      loop:<<Loop>>      outer_loop:none
272   /// CHECK-DAG: <<Cnv2:j\d+>>   TypeConversion [<<Get2>>]      loop:<<Loop>>      outer_loop:none
273   /// CHECK-DAG: <<Sub:j\d+>>    Sub [<<Cnv1>>,<<Cnv2>>]        loop:<<Loop>>      outer_loop:none
274   /// CHECK-DAG: <<Intrin:j\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
275   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
276   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
277   //
278   /// CHECK-START-ARM64: long SimdSadByte.sadByte2LongAt1(byte[], byte[]) loop_optimization (after)
279   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
280   /// CHECK-DAG: <<ConsL:j\d+>>  LongConstant 1                 loop:none
281   /// CHECK-IF:     hasIsaFeature("sve")
282   //
283   //      SAD idiom is not supported for SVE.
284   ///     CHECK-NOT: VecSADAccumulate
285   //
286   /// CHECK-ELSE:
287   //
288   ///     CHECK-DAG: <<Cons16:i\d+>> IntConstant 16                 loop:none
289   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<ConsL>>]      loop:none
290   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
291   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
292   ///     CHECK-DAG: <<Load1:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
293   ///     CHECK-DAG: <<Load2:d\d+>>  VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
294   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load1>>,<<Load2>>] loop:<<Loop>> outer_loop:none
295   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons16>>]      loop:<<Loop>>      outer_loop:none
296   //
297   /// CHECK-FI:
sadByte2LongAt1(byte[] b1, byte[] b2)298   private static long sadByte2LongAt1(byte[] b1, byte[] b2) {
299     int min_length = Math.min(b1.length, b2.length);
300     long sad = 1;  // starts at 1
301     for (int i = 0; i < min_length; i++) {
302       long x = b1[i];
303       long y = b2[i];
304       sad += Math.abs(x - y);
305     }
306     return sad;
307   }
308 
main()309   public static void main() {
310     // Cross-test the two most extreme values individually.
311     byte[] b1 = { 0, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
312     byte[] b2 = { 0,  127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
313     expectEquals(-1, sadByte2Byte(b1, b2));
314     expectEquals(-1, sadByte2Byte(b2, b1));
315     expectEquals(-1, sadByte2ByteAlt(b1, b2));
316     expectEquals(-1, sadByte2ByteAlt(b2, b1));
317     expectEquals(-1, sadByte2ByteAlt2(b1, b2));
318     expectEquals(-1, sadByte2ByteAlt2(b2, b1));
319     expectEquals(255, sadByte2Short(b1, b2));
320     expectEquals(255, sadByte2Short(b2, b1));
321     expectEquals(255, sadByte2ShortAlt(b1, b2));
322     expectEquals(255, sadByte2ShortAlt(b2, b1));
323     expectEquals(255, sadByte2ShortAlt2(b1, b2));
324     expectEquals(255, sadByte2ShortAlt2(b2, b1));
325     expectEquals(255, sadByte2Int(b1, b2));
326     expectEquals(255, sadByte2Int(b2, b1));
327     expectEquals(255, sadByte2IntAlt(b1, b2));
328     expectEquals(255, sadByte2IntAlt(b2, b1));
329     expectEquals(255, sadByte2IntAlt2(b1, b2));
330     expectEquals(255, sadByte2IntAlt2(b2, b1));
331     expectEquals(255, sadByte2Long(b1, b2));
332     expectEquals(255L, sadByte2Long(b2, b1));
333     expectEquals(256L, sadByte2LongAt1(b1, b2));
334     expectEquals(256L, sadByte2LongAt1(b2, b1));
335 
336     // Use cross-values to test all cases.
337     // One for scalar cleanup.
338     int n = 256;
339     int m = n * n + 1;
340     int k = 0;
341     b1 = new byte[m];
342     b2 = new byte[m];
343     for (int i = 0; i < n; i++) {
344       for (int j = 0; j < n; j++) {
345         b1[k] = (byte) i;
346         b2[k] = (byte) j;
347         k++;
348       }
349     }
350     b1[k] = 10;
351     b2[k] = 2;
352     expectEquals(8, sadByte2Byte(b1, b2));
353     expectEquals(8, sadByte2ByteAlt(b1, b2));
354     expectEquals(8, sadByte2ByteAlt2(b1, b2));
355     expectEquals(21768, sadByte2Short(b1, b2));
356     expectEquals(21768, sadByte2ShortAlt(b1, b2));
357     expectEquals(21768, sadByte2ShortAlt2(b1, b2));
358     expectEquals(5592328, sadByte2Int(b1, b2));
359     expectEquals(5592328, sadByte2IntAlt(b1, b2));
360     expectEquals(5592328, sadByte2IntAlt2(b1, b2));
361     expectEquals(5592328L, sadByte2Long(b1, b2));
362     expectEquals(5592329L, sadByte2LongAt1(b1, b2));
363 
364     System.out.println("SimdSadByte passed");
365   }
366 
expectEquals(int expected, int result)367   private static void expectEquals(int expected, int result) {
368     if (expected != result) {
369       throw new Error("Expected: " + expected + ", found: " + result);
370     }
371   }
372 
expectEquals(long expected, long result)373   private static void expectEquals(long expected, long result) {
374     if (expected != result) {
375       throw new Error("Expected: " + expected + ", found: " + result);
376     }
377   }
378 }
379