14d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe/*
24d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe * Copyright (C) 2014 The Android Open Source Project
34d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe *
44d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License");
54d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe * you may not use this file except in compliance with the License.
64d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe * You may obtain a copy of the License at
74d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe *
84d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe *      http://www.apache.org/licenses/LICENSE-2.0
94d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe *
104d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe * Unless required by applicable law or agreed to in writing, software
114d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS,
124d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe * See the License for the specific language governing permissions and
144d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe * limitations under the License.
154d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe */
164d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe
174d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe#ifndef ART_RUNTIME_ARCH_MEMCMP16_H_
184d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe#define ART_RUNTIME_ARCH_MEMCMP16_H_
194d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe
204d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe#include <cstddef>
214d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe#include <cstdint>
224d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe
234d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe// memcmp16 support.
244d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe//
254d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe// This can either be optimized assembly code, in which case we expect a function __memcmp16,
264d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe// or generic C support.
274d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe//
284d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe// In case of the generic support we declare two versions: one in this header file meant to be
294d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe// inlined, and a static version that assembly stubs can link against.
304d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe//
314d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe// In both cases, MemCmp16 is declared.
324d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe
33df179cbc0739a770b66110f941223d2b951e3cefAndreas Gampe#if defined(__aarch64__) || defined(__arm__) || defined(__mips__) || defined(__i386__) || defined(__x86_64__)
344d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe
354d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampeextern "C" uint32_t __memcmp16(const uint16_t* s0, const uint16_t* s1, size_t count);
364d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe#define MemCmp16 __memcmp16
374d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe
384d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe#else
394d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe
404d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe// This is the generic inlined version.
414d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampestatic inline int32_t MemCmp16(const uint16_t* s0, const uint16_t* s1, size_t count) {
424d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe  for (size_t i = 0; i < count; i++) {
434d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe    if (s0[i] != s1[i]) {
444d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe      return static_cast<int32_t>(s0[i]) - static_cast<int32_t>(s1[i]);
454d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe    }
464d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe  }
474d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe  return 0;
484d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe}
494d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe
504d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampeextern "C" int32_t memcmp16_generic_static(const uint16_t* s0, const uint16_t* s1, size_t count);
514d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe#endif
524d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe
5329b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampenamespace art {
5429b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe
5529b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampenamespace testing {
5629b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe
5729b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe// A version that is exposed and relatively "close to the metal," so that memcmp16_test can do
5829b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe// some reasonable testing. Without this, as __memcmp16 is hidden, the test cannot access the
5929b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe// implementation.
6029b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampeint32_t MemCmp16Testing(const uint16_t* s0, const uint16_t* s1, size_t count);
6129b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe
6229b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe}
6329b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe
6429b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe}  // namespace art
6529b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe
664d0589c90971e19c25894414ae7da579269e1fe2Andreas Gampe#endif  // ART_RUNTIME_ARCH_MEMCMP16_H_
67