Home | History | Annotate | Download | only in opts
      1 /*
      2  **
      3  ** Copyright 2009, The Android Open Source Project
      4  **
      5  ** Licensed under the Apache License, Version 2.0 (the "License");
      6  ** you may not use this file except in compliance with the License.
      7  ** You may obtain a copy of the License at
      8  **
      9  **     http://www.apache.org/licenses/LICENSE-2.0
     10  **
     11  ** Unless required by applicable law or agreed to in writing, software
     12  ** distributed under the License is distributed on an "AS IS" BASIS,
     13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  ** See the License for the specific language governing permissions and
     15  ** limitations under the License.
     16  */
     17 
     18 #include <emmintrin.h>
     19 #include "SkUtils_opts_SSE2.h"
     20 
     21 void sk_memset16_SSE2(uint16_t *dst, uint16_t value, int count)
     22 {
     23     SkASSERT(dst != NULL && count >= 0);
     24 
     25     // dst must be 2-byte aligned.
     26     SkASSERT((((size_t) dst) & 0x01) == 0);
     27 
     28     if (count >= 32) {
     29         while (((size_t)dst) & 0x0F) {
     30             *dst++ = value;
     31             --count;
     32         }
     33         __m128i *d = reinterpret_cast<__m128i*>(dst);
     34         __m128i value_wide = _mm_set1_epi16(value);
     35         while (count >= 32) {
     36             _mm_store_si128(d++, value_wide);
     37             _mm_store_si128(d++, value_wide);
     38             _mm_store_si128(d++, value_wide);
     39             _mm_store_si128(d++, value_wide);
     40             count -= 32;
     41         }
     42         dst = reinterpret_cast<uint16_t*>(d);
     43     }
     44     while (count > 0) {
     45         *dst++ = value;
     46         --count;
     47     }
     48 }
     49 
     50 void sk_memset32_SSE2(uint32_t *dst, uint32_t value, int count)
     51 {
     52     SkASSERT(dst != NULL && count >= 0);
     53 
     54     // dst must be 4-byte aligned.
     55     SkASSERT((((size_t) dst) & 0x03) == 0);
     56 
     57     if (count >= 16) {
     58         while (((size_t)dst) & 0x0F) {
     59             *dst++ = value;
     60             --count;
     61         }
     62         __m128i *d = reinterpret_cast<__m128i*>(dst);
     63         __m128i value_wide = _mm_set1_epi32(value);
     64         while (count >= 16) {
     65             _mm_store_si128(d++, value_wide);
     66             _mm_store_si128(d++, value_wide);
     67             _mm_store_si128(d++, value_wide);
     68             _mm_store_si128(d++, value_wide);
     69             count -= 16;
     70         }
     71         dst = reinterpret_cast<uint32_t*>(d);
     72     }
     73     while (count > 0) {
     74         *dst++ = value;
     75         --count;
     76     }
     77 }
     78