1fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil/* 2fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * Copyright (c) 2017 Imagination Technologies. 3fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * 4fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * All rights reserved. 5fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * 6fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * Redistribution and use in source and binary forms, with or without 7fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * modification, are permitted provided that the following conditions 8fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * are met: 9fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * 10fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * * Redistributions of source code must retain the above copyright 11fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * notice, this list of conditions and the following disclaimer. 12fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * * Redistributions in binary form must reproduce the above copyright 13fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * notice, this list of conditions and the following disclaimer 14fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * in the documentation and/or other materials provided with 15fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * the distribution. 16fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * * Neither the name of Imagination Technologies nor the names of its 17fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * contributors may be used to endorse or promote products derived 18fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * from this software without specific prior written permission. 19fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * 20fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil */ 32fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 33fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#include <string.h> 34fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 35fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if !defined(UNALIGNED_INSTR_SUPPORT) 36fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil/* does target have unaligned lw/ld/ualw/uald instructions? */ 37fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#define UNALIGNED_INSTR_SUPPORT 0 38fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if __mips_isa_rev < 6 && !__mips1 39fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#undef UNALIGNED_INSTR_SUPPORT 40fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#define UNALIGNED_INSTR_SUPPORT 1 41fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 42fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 43fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 44fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if !defined(HW_UNALIGNED_SUPPORT) 45fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil/* Does target have hardware support for unaligned accesses? */ 46fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#define HW_UNALIGNED_SUPPORT 0 47fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if __mips_isa_rev >= 6 48fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#undef HW_UNALIGNED_SUPPORT 49fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#define HW_UNALIGNED_SUPPORT 1 50fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 51fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 52fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 53fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#define ENABLE_PREFETCH 1 54fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 55fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if ENABLE_PREFETCH 56fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#define PREFETCH(addr) __builtin_prefetch (addr, 0, 1); 57fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#else 58fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#define PREFETCH(addr) 59fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 60fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 61fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if _MIPS_SIM == _ABIO32 62fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patiltypedef unsigned long reg_t; 63fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patiltypedef struct 64fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 65fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t B0:8, B1:8, B2:8, B3:8; 66fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} bits_t; 67fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#else 68fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patiltypedef unsigned long long reg_t; 69fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patiltypedef struct 70fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 71fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t B0:8, B1:8, B2:8, B3:8, B4:8, B5:8, B6:8, B7:8; 72fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} bits_t; 73fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 74fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 75fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patiltypedef union 76fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 77fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t v; 78fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil bits_t b; 79fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} bitfields_t; 80fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 81fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#define DO_BYTE(a, i) \ 82fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[i] = bw.b.B##i; \ 83fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil len--; \ 84fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if(!len) return ret; \ 85fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 86fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil/* This code is called when aligning a pointer, there are remaining bytes 87fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil after doing word compares, or architecture does not have some form 88fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil of unaligned support. */ 89fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilstatic inline void * __attribute__ ((always_inline)) 90fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patildo_bytes (void *a, const void *b, unsigned long len, void *ret) 91fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 92fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned char *x = (unsigned char *) a; 93fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned char *y = (unsigned char *) b; 94fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long i; 95fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 96fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* 'len' might be zero here, so preloading the first two values 97fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil before the loop may access unallocated memory. */ 98fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil for (i = 0; i < len; i++) { 99fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil *x = *y; 100fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x++; 101fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil y++; 102fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 103fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return ret; 104fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} 105fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 106fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil/* This code is called to copy only remaining bytes within word or doubleword */ 107fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilstatic inline void * __attribute__ ((always_inline)) 108fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patildo_bytes_remaining (void *a, const void *b, unsigned long len, void *ret) 109fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 110fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned char *x = (unsigned char *) a; 111fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 112fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if(len > 0) { 113fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil bitfields_t bw; 114fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil bw.v = *((reg_t*) b); 115fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 116fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if __mips64 117fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 0); 118fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 1); 119fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 2); 120fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 3); 121fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 4); 122fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 5); 123fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 6); 124fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 7); 125fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#else 126fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 0); 127fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 1); 128fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 2); 129fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil DO_BYTE(x, 3); 130fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 131fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 132fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 133fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return ret; 134fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} 135fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 136fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if !HW_UNALIGNED_SUPPORT 137fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if UNALIGNED_INSTR_SUPPORT 138fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil/* for MIPS GCC, there are no unaligned builtins - so this struct forces 139fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil the compiler to treat the pointer access as unaligned. */ 140fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilstruct ulw 141fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 142fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t uli; 143fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} __attribute__ ((packed)); 144fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 145fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil/* first pointer is not aligned while second pointer is. */ 146fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilstatic void * 147fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilunaligned_words (struct ulw *a, const reg_t * b, 148fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long words, unsigned long bytes, void *ret) 149fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 150fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if ((_MIPS_SIM == _ABIO32) || _MIPS_TUNE_I6400) 151fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long i, words_by_8, words_by_1; 152fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil words_by_1 = words % 8; 153fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil words_by_8 = words >> 3; 154fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil for (; words_by_8 > 0; words_by_8--) { 155fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if(words_by_8 != 1) 156fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil PREFETCH (b + 8); 157fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t y0 = b[0], y1 = b[1], y2 = b[2], y3 = b[3]; 158fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t y4 = b[4], y5 = b[5], y6 = b[6], y7 = b[7]; 159fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[0].uli = y0; 160fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[1].uli = y1; 161fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[2].uli = y2; 162fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[3].uli = y3; 163fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[4].uli = y4; 164fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[5].uli = y5; 165fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[6].uli = y6; 166fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[7].uli = y7; 167fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a += 8; 168fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil b += 8; 169fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 170fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#else 171fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long i, words_by_4, words_by_1; 172fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil words_by_1 = words % 4; 173fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil words_by_4 = words >> 2; 174fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil for (; words_by_4 > 0; words_by_4--) { 175fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if(words_by_4 != 1) 176fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil PREFETCH (b + 4); 177fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t y0 = b[0], y1 = b[1], y2 = b[2], y3 = b[3]; 178fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[0].uli = y0; 179fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[1].uli = y1; 180fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[2].uli = y2; 181fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[3].uli = y3; 182fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a += 4; 183fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil b += 4; 184fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 185fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 186fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 187fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* do remaining words. */ 188fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil for (i = 0; i < words_by_1; i++) { 189fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a->uli = *b; 190fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a += 1; 191fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil b += 1; 192fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 193fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 194fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* mop up any remaining bytes. */ 195fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return do_bytes_remaining (a, b, bytes, ret); 196fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} 197fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#else 198fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil/* no HW support or unaligned lw/ld/ualw/uald instructions. */ 199fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilstatic void * 200fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilunaligned_words (reg_t * a, const reg_t * b, 201fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long words, unsigned long bytes, void *ret) 202fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 203fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long i; 204fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned char *x = (unsigned char *) a; 205fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 206fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil for (i = 0; i < words; i++) { 207fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil bitfields_t bw; 208fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil bw.v = *((reg_t*) b); 209fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x = (unsigned char *) a; 210fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if __mips64 211fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[0] = bw.b.B0; 212fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[1] = bw.b.B1; 213fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[2] = bw.b.B2; 214fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[3] = bw.b.B3; 215fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[4] = bw.b.B4; 216fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[5] = bw.b.B5; 217fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[6] = bw.b.B6; 218fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[7] = bw.b.B7; 219fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#else 220fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[0] = bw.b.B0; 221fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[1] = bw.b.B1; 222fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[2] = bw.b.B2; 223fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil x[3] = bw.b.B3; 224fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 225fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a += 1; 226fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil b += 1; 227fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 228fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 229fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* mop up any remaining bytes */ 230fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return do_bytes_remaining (a, b, bytes, ret); 231fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} 232fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif /* UNALIGNED_INSTR_SUPPORT */ 233fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif /* HW_UNALIGNED_SUPPORT */ 234fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 235fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil/* both pointers are aligned, or first isn't and HW support for unaligned. */ 236fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilstatic void * 237fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilaligned_words (reg_t * a, const reg_t * b, 238fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long words, unsigned long bytes, void *ret) 239fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 240fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if ((_MIPS_SIM == _ABIO32) || _MIPS_TUNE_I6400) 241fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long i, words_by_8, words_by_1; 242fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil words_by_1 = words % 8; 243fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil words_by_8 = words >> 3; 244fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil for (; words_by_8 > 0; words_by_8--) { 245fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if(words_by_8 != 1) 246fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil PREFETCH (b + 8); 247fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t x0 = b[0], x1 = b[1], x2 = b[2], x3 = b[3]; 248fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t x4 = b[4], x5 = b[5], x6 = b[6], x7 = b[7]; 249fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[0] = x0; 250fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[1] = x1; 251fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[2] = x2; 252fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[3] = x3; 253fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[4] = x4; 254fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[5] = x5; 255fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[6] = x6; 256fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[7] = x7; 257fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a += 8; 258fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil b += 8; 259fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 260fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#else 261fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long i, words_by_4, words_by_1; 262fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil words_by_1 = words % 4; 263fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil words_by_4 = words >> 2; 264fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil for (; words_by_4 > 0; words_by_4--) { 265fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if(words_by_4 != 1) 266fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil PREFETCH (b + 4); 267fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil reg_t x0 = b[0], x1 = b[1], x2 = b[2], x3 = b[3]; 268fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[0] = x0; 269fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[1] = x1; 270fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[2] = x2; 271fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a[3] = x3; 272fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a += 4; 273fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil b += 4; 274fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 275fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 276fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 277fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* do remaining words. */ 278fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil for (i = 0; i < words_by_1; i++) { 279fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil *a = *b; 280fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a += 1; 281fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil b += 1; 282fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 283fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 284fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* mop up any remaining bytes. */ 285fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return do_bytes_remaining (a, b, bytes, ret); 286fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} 287fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 288fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilvoid * 289fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patilmemcpy (void *a, const void *b, size_t len) __overloadable 290fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil{ 291fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil unsigned long bytes, words; 292fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil void *ret = a; 293fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 294fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* shouldn't hit that often. */ 295fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if (len < sizeof (reg_t) * 4) { 296fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return do_bytes (a, b, len, a); 297fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 298fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 299fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* Align the second pointer to word/dword alignment. 300fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil Note that the pointer is only 32-bits for o32/n32 ABIs. For 301fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil n32, loads are done as 64-bit while address remains 32-bit. */ 302fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil bytes = ((unsigned long) b) % sizeof (reg_t); 303fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if (bytes) { 304fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil bytes = sizeof (reg_t) - bytes; 305fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if (bytes > len) 306fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil bytes = len; 307fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil do_bytes (a, b, bytes, ret); 308fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if (len == bytes) 309fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return ret; 310fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil len -= bytes; 311fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil a = (void *) (((unsigned char *) a) + bytes); 312fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil b = (const void *) (((unsigned char *) b) + bytes); 313fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 314fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil 315fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* Second pointer now aligned. */ 316fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil words = len / sizeof (reg_t); 317fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil bytes = len % sizeof (reg_t); 318fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#if HW_UNALIGNED_SUPPORT 319fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* treat possible unaligned first pointer as aligned. */ 320fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return aligned_words (a, b, words, bytes, ret); 321fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#else 322fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil if (((unsigned long) a) % sizeof (reg_t) == 0) { 323fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return aligned_words (a, b, words, bytes, ret); 324fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil } 325fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil /* need to use unaligned instructions on first pointer. */ 326fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil return unaligned_words (a, b, words, bytes, ret); 327fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil#endif 328fcb877ac4b05e65f64b9b3199d71dfeaae299177Prashant Patil} 329