1ae2c6ca6SDavid S. Miller/* NG4memcpy.S: Niagara-4 optimized memcpy. 2ae2c6ca6SDavid S. Miller * 3ae2c6ca6SDavid S. Miller * Copyright (C) 2012 David S. Miller (davem@davemloft.net) 4ae2c6ca6SDavid S. Miller */ 5ae2c6ca6SDavid S. Miller 6ae2c6ca6SDavid S. Miller#ifdef __KERNEL__ 795707704SDavid S. Miller#include <linux/linkage.h> 8ae2c6ca6SDavid S. Miller#include <asm/visasm.h> 9ae2c6ca6SDavid S. Miller#include <asm/asi.h> 10ae2c6ca6SDavid S. Miller#define GLOBAL_SPARE %g7 11ae2c6ca6SDavid S. Miller#else 12ae2c6ca6SDavid S. Miller#define ASI_BLK_INIT_QUAD_LDD_P 0xe2 13ae2c6ca6SDavid S. Miller#define FPRS_FEF 0x04 14ae2c6ca6SDavid S. Miller 15ae2c6ca6SDavid S. Miller/* On T4 it is very expensive to access ASRs like %fprs and 16ae2c6ca6SDavid S. Miller * %asi, avoiding a read or a write can save ~50 cycles. 17ae2c6ca6SDavid S. Miller */ 18ae2c6ca6SDavid S. Miller#define FPU_ENTER \ 19ae2c6ca6SDavid S. Miller rd %fprs, %o5; \ 20ae2c6ca6SDavid S. Miller andcc %o5, FPRS_FEF, %g0; \ 21ae2c6ca6SDavid S. Miller be,a,pn %icc, 999f; \ 22ae2c6ca6SDavid S. Miller wr %g0, FPRS_FEF, %fprs; \ 23ae2c6ca6SDavid S. Miller 999: 24ae2c6ca6SDavid S. Miller 25ae2c6ca6SDavid S. Miller#ifdef MEMCPY_DEBUG 26ae2c6ca6SDavid S. Miller#define VISEntryHalf FPU_ENTER; \ 27ae2c6ca6SDavid S. Miller clr %g1; clr %g2; clr %g3; clr %g5; subcc %g0, %g0, %g0; 28ae2c6ca6SDavid S. Miller#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs 29ae2c6ca6SDavid S. Miller#else 30ae2c6ca6SDavid S. Miller#define VISEntryHalf FPU_ENTER 31ae2c6ca6SDavid S. Miller#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs 32ae2c6ca6SDavid S. Miller#endif 33ae2c6ca6SDavid S. Miller 34ae2c6ca6SDavid S. Miller#define GLOBAL_SPARE %g5 35ae2c6ca6SDavid S. Miller#endif 36ae2c6ca6SDavid S. Miller 37ae2c6ca6SDavid S. Miller#ifndef STORE_ASI 38ae2c6ca6SDavid S. Miller#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA 39ae2c6ca6SDavid S. Miller#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P 40ae2c6ca6SDavid S. Miller#else 41ae2c6ca6SDavid S. Miller#define STORE_ASI 0x80 /* ASI_P */ 42ae2c6ca6SDavid S. Miller#endif 43ae2c6ca6SDavid S. Miller#endif 44ae2c6ca6SDavid S. Miller 45f4da3628SDavid S. Miller#if !defined(EX_LD) && !defined(EX_ST) 46f4da3628SDavid S. Miller#define NON_USER_COPY 47f4da3628SDavid S. Miller#endif 48f4da3628SDavid S. Miller 49ae2c6ca6SDavid S. Miller#ifndef EX_LD 5095707704SDavid S. Miller#define EX_LD(x,y) x 51ae2c6ca6SDavid S. Miller#endif 52a7c5724bSRob Gardner#ifndef EX_LD_FP 5395707704SDavid S. Miller#define EX_LD_FP(x,y) x 54a7c5724bSRob Gardner#endif 55ae2c6ca6SDavid S. Miller 56ae2c6ca6SDavid S. Miller#ifndef EX_ST 5795707704SDavid S. Miller#define EX_ST(x,y) x 58ae2c6ca6SDavid S. Miller#endif 59a7c5724bSRob Gardner#ifndef EX_ST_FP 6095707704SDavid S. Miller#define EX_ST_FP(x,y) x 61a7c5724bSRob Gardner#endif 62ae2c6ca6SDavid S. Miller 63ae2c6ca6SDavid S. Miller 64ae2c6ca6SDavid S. Miller#ifndef LOAD 65ae2c6ca6SDavid S. Miller#define LOAD(type,addr,dest) type [addr], dest 66ae2c6ca6SDavid S. Miller#endif 67ae2c6ca6SDavid S. Miller 68ae2c6ca6SDavid S. Miller#ifndef STORE 69ae2c6ca6SDavid S. Miller#ifndef MEMCPY_DEBUG 70ae2c6ca6SDavid S. Miller#define STORE(type,src,addr) type src, [addr] 71ae2c6ca6SDavid S. Miller#else 72ae2c6ca6SDavid S. Miller#define STORE(type,src,addr) type##a src, [addr] %asi 73ae2c6ca6SDavid S. Miller#endif 74ae2c6ca6SDavid S. Miller#endif 75ae2c6ca6SDavid S. Miller 76ae2c6ca6SDavid S. Miller#ifndef STORE_INIT 77ae2c6ca6SDavid S. Miller#define STORE_INIT(src,addr) stxa src, [addr] STORE_ASI 78ae2c6ca6SDavid S. Miller#endif 79ae2c6ca6SDavid S. Miller 80ae2c6ca6SDavid S. Miller#ifndef FUNC_NAME 81ae2c6ca6SDavid S. Miller#define FUNC_NAME NG4memcpy 82ae2c6ca6SDavid S. Miller#endif 83ae2c6ca6SDavid S. Miller#ifndef PREAMBLE 84ae2c6ca6SDavid S. Miller#define PREAMBLE 85ae2c6ca6SDavid S. Miller#endif 86ae2c6ca6SDavid S. Miller 87ae2c6ca6SDavid S. Miller#ifndef XCC 88ae2c6ca6SDavid S. Miller#define XCC xcc 89ae2c6ca6SDavid S. Miller#endif 90ae2c6ca6SDavid S. Miller 91ae2c6ca6SDavid S. Miller .register %g2,#scratch 92ae2c6ca6SDavid S. Miller .register %g3,#scratch 93ae2c6ca6SDavid S. Miller 94ae2c6ca6SDavid S. Miller .text 9595707704SDavid S. Miller#ifndef EX_RETVAL 9695707704SDavid S. Miller#define EX_RETVAL(x) x 9795707704SDavid S. Miller__restore_asi_fp: 9895707704SDavid S. Miller VISExitHalf 9995707704SDavid S. Miller__restore_asi: 10095707704SDavid S. Miller retl 10195707704SDavid S. Miller wr %g0, ASI_AIUS, %asi 10295707704SDavid S. Miller 10395707704SDavid S. MillerENTRY(NG4_retl_o2) 10495707704SDavid S. Miller ba,pt %xcc, __restore_asi 10595707704SDavid S. Miller mov %o2, %o0 10695707704SDavid S. MillerENDPROC(NG4_retl_o2) 10795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_1) 10895707704SDavid S. Miller ba,pt %xcc, __restore_asi 10995707704SDavid S. Miller add %o2, 1, %o0 11095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_1) 11195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_4) 11295707704SDavid S. Miller ba,pt %xcc, __restore_asi 11395707704SDavid S. Miller add %o2, 4, %o0 11495707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_4) 11595707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5) 11695707704SDavid S. Miller ba,pt %xcc, __restore_asi 11795707704SDavid S. Miller add %o2, %o5, %o0 11895707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5) 11995707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_4) 12095707704SDavid S. Miller add %o5, 4, %o5 12195707704SDavid S. Miller ba,pt %xcc, __restore_asi 12295707704SDavid S. Miller add %o2, %o5, %o0 12395707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_4) 12495707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_8) 12595707704SDavid S. Miller add %o5, 8, %o5 12695707704SDavid S. Miller ba,pt %xcc, __restore_asi 12795707704SDavid S. Miller add %o2, %o5, %o0 12895707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_8) 12995707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_16) 13095707704SDavid S. Miller add %o5, 16, %o5 13195707704SDavid S. Miller ba,pt %xcc, __restore_asi 13295707704SDavid S. Miller add %o2, %o5, %o0 13395707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_16) 13495707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_24) 13595707704SDavid S. Miller add %o5, 24, %o5 13695707704SDavid S. Miller ba,pt %xcc, __restore_asi 13795707704SDavid S. Miller add %o2, %o5, %o0 13895707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_24) 13995707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_32) 14095707704SDavid S. Miller add %o5, 32, %o5 14195707704SDavid S. Miller ba,pt %xcc, __restore_asi 14295707704SDavid S. Miller add %o2, %o5, %o0 14395707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_32) 14495707704SDavid S. MillerENTRY(NG4_retl_o2_plus_g1) 14595707704SDavid S. Miller ba,pt %xcc, __restore_asi 14695707704SDavid S. Miller add %o2, %g1, %o0 14795707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_g1) 14895707704SDavid S. MillerENTRY(NG4_retl_o2_plus_g1_plus_1) 14995707704SDavid S. Miller add %g1, 1, %g1 15095707704SDavid S. Miller ba,pt %xcc, __restore_asi 15195707704SDavid S. Miller add %o2, %g1, %o0 15295707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_g1_plus_1) 15395707704SDavid S. MillerENTRY(NG4_retl_o2_plus_g1_plus_8) 15495707704SDavid S. Miller add %g1, 8, %g1 15595707704SDavid S. Miller ba,pt %xcc, __restore_asi 15695707704SDavid S. Miller add %o2, %g1, %o0 15795707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_g1_plus_8) 15895707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4) 15995707704SDavid S. Miller ba,pt %xcc, __restore_asi 16095707704SDavid S. Miller add %o2, %o4, %o0 16195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4) 16295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_8) 16395707704SDavid S. Miller add %o4, 8, %o4 16495707704SDavid S. Miller ba,pt %xcc, __restore_asi 16595707704SDavid S. Miller add %o2, %o4, %o0 16695707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_8) 16795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_16) 16895707704SDavid S. Miller add %o4, 16, %o4 16995707704SDavid S. Miller ba,pt %xcc, __restore_asi 17095707704SDavid S. Miller add %o2, %o4, %o0 17195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_16) 17295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_24) 17395707704SDavid S. Miller add %o4, 24, %o4 17495707704SDavid S. Miller ba,pt %xcc, __restore_asi 17595707704SDavid S. Miller add %o2, %o4, %o0 17695707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_24) 17795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_32) 17895707704SDavid S. Miller add %o4, 32, %o4 17995707704SDavid S. Miller ba,pt %xcc, __restore_asi 18095707704SDavid S. Miller add %o2, %o4, %o0 18195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_32) 18295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_40) 18395707704SDavid S. Miller add %o4, 40, %o4 18495707704SDavid S. Miller ba,pt %xcc, __restore_asi 18595707704SDavid S. Miller add %o2, %o4, %o0 18695707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_40) 18795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_48) 18895707704SDavid S. Miller add %o4, 48, %o4 18995707704SDavid S. Miller ba,pt %xcc, __restore_asi 19095707704SDavid S. Miller add %o2, %o4, %o0 19195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_48) 19295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_56) 19395707704SDavid S. Miller add %o4, 56, %o4 19495707704SDavid S. Miller ba,pt %xcc, __restore_asi 19595707704SDavid S. Miller add %o2, %o4, %o0 19695707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_56) 19795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_64) 19895707704SDavid S. Miller add %o4, 64, %o4 19995707704SDavid S. Miller ba,pt %xcc, __restore_asi 20095707704SDavid S. Miller add %o2, %o4, %o0 20195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_64) 20295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_fp) 20395707704SDavid S. Miller ba,pt %xcc, __restore_asi_fp 20495707704SDavid S. Miller add %o2, %o4, %o0 20595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_fp) 20695707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_8_fp) 20795707704SDavid S. Miller add %o4, 8, %o4 20895707704SDavid S. Miller ba,pt %xcc, __restore_asi_fp 20995707704SDavid S. Miller add %o2, %o4, %o0 21095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_8_fp) 21195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_16_fp) 21295707704SDavid S. Miller add %o4, 16, %o4 21395707704SDavid S. Miller ba,pt %xcc, __restore_asi_fp 21495707704SDavid S. Miller add %o2, %o4, %o0 21595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_16_fp) 21695707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_24_fp) 21795707704SDavid S. Miller add %o4, 24, %o4 21895707704SDavid S. Miller ba,pt %xcc, __restore_asi_fp 21995707704SDavid S. Miller add %o2, %o4, %o0 22095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_24_fp) 22195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_32_fp) 22295707704SDavid S. Miller add %o4, 32, %o4 22395707704SDavid S. Miller ba,pt %xcc, __restore_asi_fp 22495707704SDavid S. Miller add %o2, %o4, %o0 22595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_32_fp) 22695707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_40_fp) 22795707704SDavid S. Miller add %o4, 40, %o4 22895707704SDavid S. Miller ba,pt %xcc, __restore_asi_fp 22995707704SDavid S. Miller add %o2, %o4, %o0 23095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_40_fp) 23195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_48_fp) 23295707704SDavid S. Miller add %o4, 48, %o4 23395707704SDavid S. Miller ba,pt %xcc, __restore_asi_fp 23495707704SDavid S. Miller add %o2, %o4, %o0 23595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_48_fp) 23695707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_56_fp) 23795707704SDavid S. Miller add %o4, 56, %o4 23895707704SDavid S. Miller ba,pt %xcc, __restore_asi_fp 23995707704SDavid S. Miller add %o2, %o4, %o0 24095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_56_fp) 24195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_64_fp) 24295707704SDavid S. Miller add %o4, 64, %o4 24395707704SDavid S. Miller ba,pt %xcc, __restore_asi_fp 24495707704SDavid S. Miller add %o2, %o4, %o0 24595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_64_fp) 24695707704SDavid S. Miller#endif 247ae2c6ca6SDavid S. Miller .align 64 248ae2c6ca6SDavid S. Miller 249ae2c6ca6SDavid S. Miller .globl FUNC_NAME 250ae2c6ca6SDavid S. Miller .type FUNC_NAME,#function 251ae2c6ca6SDavid S. MillerFUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ 252ae2c6ca6SDavid S. Miller#ifdef MEMCPY_DEBUG 253ae2c6ca6SDavid S. Miller wr %g0, 0x80, %asi 254ae2c6ca6SDavid S. Miller#endif 255ae2c6ca6SDavid S. Miller srlx %o2, 31, %g2 256ae2c6ca6SDavid S. Miller cmp %g2, 0 257ae2c6ca6SDavid S. Miller tne %XCC, 5 258ae2c6ca6SDavid S. Miller PREAMBLE 259ae2c6ca6SDavid S. Miller mov %o0, %o3 260ae2c6ca6SDavid S. Miller brz,pn %o2, .Lexit 261ae2c6ca6SDavid S. Miller cmp %o2, 3 262ae2c6ca6SDavid S. Miller ble,pn %icc, .Ltiny 263ae2c6ca6SDavid S. Miller cmp %o2, 19 264ae2c6ca6SDavid S. Miller ble,pn %icc, .Lsmall 265ae2c6ca6SDavid S. Miller or %o0, %o1, %g2 266ae2c6ca6SDavid S. Miller cmp %o2, 128 267ae2c6ca6SDavid S. Miller bl,pn %icc, .Lmedium 268ae2c6ca6SDavid S. Miller nop 269ae2c6ca6SDavid S. Miller 270ae2c6ca6SDavid S. Miller.Llarge:/* len >= 0x80 */ 271ae2c6ca6SDavid S. Miller /* First get dest 8 byte aligned. */ 272ae2c6ca6SDavid S. Miller sub %g0, %o0, %g1 273ae2c6ca6SDavid S. Miller and %g1, 0x7, %g1 274ae2c6ca6SDavid S. Miller brz,pt %g1, 51f 275ae2c6ca6SDavid S. Miller sub %o2, %g1, %o2 276ae2c6ca6SDavid S. Miller 27795707704SDavid S. Miller 27895707704SDavid S. Miller1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1) 279ae2c6ca6SDavid S. Miller add %o1, 1, %o1 280ae2c6ca6SDavid S. Miller subcc %g1, 1, %g1 281ae2c6ca6SDavid S. Miller add %o0, 1, %o0 282ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 28395707704SDavid S. Miller EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1) 284ae2c6ca6SDavid S. Miller 285ae2c6ca6SDavid S. Miller51: LOAD(prefetch, %o1 + 0x040, #n_reads_strong) 286ae2c6ca6SDavid S. Miller LOAD(prefetch, %o1 + 0x080, #n_reads_strong) 287ae2c6ca6SDavid S. Miller LOAD(prefetch, %o1 + 0x0c0, #n_reads_strong) 288ae2c6ca6SDavid S. Miller LOAD(prefetch, %o1 + 0x100, #n_reads_strong) 289ae2c6ca6SDavid S. Miller LOAD(prefetch, %o1 + 0x140, #n_reads_strong) 290ae2c6ca6SDavid S. Miller LOAD(prefetch, %o1 + 0x180, #n_reads_strong) 291ae2c6ca6SDavid S. Miller LOAD(prefetch, %o1 + 0x1c0, #n_reads_strong) 292ae2c6ca6SDavid S. Miller LOAD(prefetch, %o1 + 0x200, #n_reads_strong) 293ae2c6ca6SDavid S. Miller 294ae2c6ca6SDavid S. Miller /* Check if we can use the straight fully aligned 295ae2c6ca6SDavid S. Miller * loop, or we require the alignaddr/faligndata variant. 296ae2c6ca6SDavid S. Miller */ 297ae2c6ca6SDavid S. Miller andcc %o1, 0x7, %o5 298ae2c6ca6SDavid S. Miller bne,pn %icc, .Llarge_src_unaligned 299ae2c6ca6SDavid S. Miller sub %g0, %o0, %g1 300ae2c6ca6SDavid S. Miller 301ae2c6ca6SDavid S. Miller /* Legitimize the use of initializing stores by getting dest 302ae2c6ca6SDavid S. Miller * to be 64-byte aligned. 303ae2c6ca6SDavid S. Miller */ 304ae2c6ca6SDavid S. Miller and %g1, 0x3f, %g1 305ae2c6ca6SDavid S. Miller brz,pt %g1, .Llarge_aligned 306ae2c6ca6SDavid S. Miller sub %o2, %g1, %o2 307ae2c6ca6SDavid S. Miller 30895707704SDavid S. Miller1: EX_LD(LOAD(ldx, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1) 309ae2c6ca6SDavid S. Miller add %o1, 8, %o1 310ae2c6ca6SDavid S. Miller subcc %g1, 8, %g1 311ae2c6ca6SDavid S. Miller add %o0, 8, %o0 312ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 31395707704SDavid S. Miller EX_ST(STORE(stx, %g2, %o0 - 0x08), NG4_retl_o2_plus_g1_plus_8) 314ae2c6ca6SDavid S. Miller 315ae2c6ca6SDavid S. Miller.Llarge_aligned: 316ae2c6ca6SDavid S. Miller /* len >= 0x80 && src 8-byte aligned && dest 8-byte aligned */ 317ae2c6ca6SDavid S. Miller andn %o2, 0x3f, %o4 318ae2c6ca6SDavid S. Miller sub %o2, %o4, %o2 319ae2c6ca6SDavid S. Miller 32095707704SDavid S. Miller1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o4) 321ae2c6ca6SDavid S. Miller add %o1, 0x40, %o1 32295707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 - 0x38, %g2), NG4_retl_o2_plus_o4) 323ae2c6ca6SDavid S. Miller subcc %o4, 0x40, %o4 32495707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 - 0x30, %g3), NG4_retl_o2_plus_o4_plus_64) 32595707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_64) 32695707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 - 0x20, %o5), NG4_retl_o2_plus_o4_plus_64) 32795707704SDavid S. Miller EX_ST(STORE_INIT(%g1, %o0), NG4_retl_o2_plus_o4_plus_64) 328ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 32995707704SDavid S. Miller EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_56) 330ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 33195707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 - 0x18, %g2), NG4_retl_o2_plus_o4_plus_48) 33295707704SDavid S. Miller EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_48) 333ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 33495707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 - 0x10, %g3), NG4_retl_o2_plus_o4_plus_40) 33595707704SDavid S. Miller EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_40) 336ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 33795707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_32) 33895707704SDavid S. Miller EX_ST(STORE_INIT(%o5, %o0), NG4_retl_o2_plus_o4_plus_32) 339ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 34095707704SDavid S. Miller EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_24) 341ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 34295707704SDavid S. Miller EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_16) 343ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 34495707704SDavid S. Miller EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_8) 345ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 346ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 347ae2c6ca6SDavid S. Miller LOAD(prefetch, %o1 + 0x200, #n_reads_strong) 348ae2c6ca6SDavid S. Miller 349ae2c6ca6SDavid S. Miller membar #StoreLoad | #StoreStore 350ae2c6ca6SDavid S. Miller 351ae2c6ca6SDavid S. Miller brz,pn %o2, .Lexit 352ae2c6ca6SDavid S. Miller cmp %o2, 19 353ae2c6ca6SDavid S. Miller ble,pn %icc, .Lsmall_unaligned 354ae2c6ca6SDavid S. Miller nop 355ae2c6ca6SDavid S. Miller ba,a,pt %icc, .Lmedium_noprefetch 356ae2c6ca6SDavid S. Miller 357ae2c6ca6SDavid S. Miller.Lexit: retl 358ae2c6ca6SDavid S. Miller mov EX_RETVAL(%o3), %o0 359ae2c6ca6SDavid S. Miller 360ae2c6ca6SDavid S. Miller.Llarge_src_unaligned: 361f4da3628SDavid S. Miller#ifdef NON_USER_COPY 362f4da3628SDavid S. Miller VISEntryHalfFast(.Lmedium_vis_entry_fail) 363f4da3628SDavid S. Miller#else 364f4da3628SDavid S. Miller VISEntryHalf 365f4da3628SDavid S. Miller#endif 366ae2c6ca6SDavid S. Miller andn %o2, 0x3f, %o4 367ae2c6ca6SDavid S. Miller sub %o2, %o4, %o2 368ae2c6ca6SDavid S. Miller alignaddr %o1, %g0, %g1 369ae2c6ca6SDavid S. Miller add %o1, %o4, %o1 37095707704SDavid S. Miller EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0), NG4_retl_o2_plus_o4) 37195707704SDavid S. Miller1: EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2), NG4_retl_o2_plus_o4) 372ae2c6ca6SDavid S. Miller subcc %o4, 0x40, %o4 37395707704SDavid S. Miller EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4), NG4_retl_o2_plus_o4_plus_64) 37495707704SDavid S. Miller EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6), NG4_retl_o2_plus_o4_plus_64) 37595707704SDavid S. Miller EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8), NG4_retl_o2_plus_o4_plus_64) 37695707704SDavid S. Miller EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10), NG4_retl_o2_plus_o4_plus_64) 37795707704SDavid S. Miller EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12), NG4_retl_o2_plus_o4_plus_64) 37895707704SDavid S. Miller EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14), NG4_retl_o2_plus_o4_plus_64) 379ae2c6ca6SDavid S. Miller faligndata %f0, %f2, %f16 38095707704SDavid S. Miller EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0), NG4_retl_o2_plus_o4_plus_64) 381ae2c6ca6SDavid S. Miller faligndata %f2, %f4, %f18 382ae2c6ca6SDavid S. Miller add %g1, 0x40, %g1 383ae2c6ca6SDavid S. Miller faligndata %f4, %f6, %f20 384ae2c6ca6SDavid S. Miller faligndata %f6, %f8, %f22 385ae2c6ca6SDavid S. Miller faligndata %f8, %f10, %f24 386ae2c6ca6SDavid S. Miller faligndata %f10, %f12, %f26 387ae2c6ca6SDavid S. Miller faligndata %f12, %f14, %f28 388ae2c6ca6SDavid S. Miller faligndata %f14, %f0, %f30 38995707704SDavid S. Miller EX_ST_FP(STORE(std, %f16, %o0 + 0x00), NG4_retl_o2_plus_o4_plus_64) 39095707704SDavid S. Miller EX_ST_FP(STORE(std, %f18, %o0 + 0x08), NG4_retl_o2_plus_o4_plus_56) 39195707704SDavid S. Miller EX_ST_FP(STORE(std, %f20, %o0 + 0x10), NG4_retl_o2_plus_o4_plus_48) 39295707704SDavid S. Miller EX_ST_FP(STORE(std, %f22, %o0 + 0x18), NG4_retl_o2_plus_o4_plus_40) 39395707704SDavid S. Miller EX_ST_FP(STORE(std, %f24, %o0 + 0x20), NG4_retl_o2_plus_o4_plus_32) 39495707704SDavid S. Miller EX_ST_FP(STORE(std, %f26, %o0 + 0x28), NG4_retl_o2_plus_o4_plus_24) 39595707704SDavid S. Miller EX_ST_FP(STORE(std, %f28, %o0 + 0x30), NG4_retl_o2_plus_o4_plus_16) 39695707704SDavid S. Miller EX_ST_FP(STORE(std, %f30, %o0 + 0x38), NG4_retl_o2_plus_o4_plus_8) 397ae2c6ca6SDavid S. Miller add %o0, 0x40, %o0 398ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 399ae2c6ca6SDavid S. Miller LOAD(prefetch, %g1 + 0x200, #n_reads_strong) 40044922150SDavid S. Miller#ifdef NON_USER_COPY 40144922150SDavid S. Miller VISExitHalfFast 40244922150SDavid S. Miller#else 403ae2c6ca6SDavid S. Miller VISExitHalf 40444922150SDavid S. Miller#endif 405ae2c6ca6SDavid S. Miller brz,pn %o2, .Lexit 406ae2c6ca6SDavid S. Miller cmp %o2, 19 407ae2c6ca6SDavid S. Miller ble,pn %icc, .Lsmall_unaligned 408ae2c6ca6SDavid S. Miller nop 409ae2c6ca6SDavid S. Miller ba,a,pt %icc, .Lmedium_unaligned 410ae2c6ca6SDavid S. Miller 411f4da3628SDavid S. Miller#ifdef NON_USER_COPY 412f4da3628SDavid S. Miller.Lmedium_vis_entry_fail: 413f4da3628SDavid S. Miller or %o0, %o1, %g2 414f4da3628SDavid S. Miller#endif 415ae2c6ca6SDavid S. Miller.Lmedium: 416ae2c6ca6SDavid S. Miller LOAD(prefetch, %o1 + 0x40, #n_reads_strong) 417ae2c6ca6SDavid S. Miller andcc %g2, 0x7, %g0 418ae2c6ca6SDavid S. Miller bne,pn %icc, .Lmedium_unaligned 419ae2c6ca6SDavid S. Miller nop 420ae2c6ca6SDavid S. Miller.Lmedium_noprefetch: 421ae2c6ca6SDavid S. Miller andncc %o2, 0x20 - 1, %o5 422ae2c6ca6SDavid S. Miller be,pn %icc, 2f 423ae2c6ca6SDavid S. Miller sub %o2, %o5, %o2 42495707704SDavid S. Miller1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5) 42595707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 + 0x08, %g2), NG4_retl_o2_plus_o5) 42695707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE), NG4_retl_o2_plus_o5) 42795707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 + 0x18, %o4), NG4_retl_o2_plus_o5) 428ae2c6ca6SDavid S. Miller add %o1, 0x20, %o1 429ae2c6ca6SDavid S. Miller subcc %o5, 0x20, %o5 43095707704SDavid S. Miller EX_ST(STORE(stx, %g1, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_32) 43195707704SDavid S. Miller EX_ST(STORE(stx, %g2, %o0 + 0x08), NG4_retl_o2_plus_o5_plus_24) 43295707704SDavid S. Miller EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), NG4_retl_o2_plus_o5_plus_24) 43395707704SDavid S. Miller EX_ST(STORE(stx, %o4, %o0 + 0x18), NG4_retl_o2_plus_o5_plus_8) 434ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 435ae2c6ca6SDavid S. Miller add %o0, 0x20, %o0 436ae2c6ca6SDavid S. Miller2: andcc %o2, 0x18, %o5 437ae2c6ca6SDavid S. Miller be,pt %icc, 3f 438ae2c6ca6SDavid S. Miller sub %o2, %o5, %o2 43995707704SDavid S. Miller 44095707704SDavid S. Miller1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5) 441ae2c6ca6SDavid S. Miller add %o1, 0x08, %o1 442ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 443ae2c6ca6SDavid S. Miller subcc %o5, 0x08, %o5 444ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 44595707704SDavid S. Miller EX_ST(STORE(stx, %g1, %o0 - 0x08), NG4_retl_o2_plus_o5_plus_8) 446ae2c6ca6SDavid S. Miller3: brz,pt %o2, .Lexit 447ae2c6ca6SDavid S. Miller cmp %o2, 0x04 448ae2c6ca6SDavid S. Miller bl,pn %icc, .Ltiny 449ae2c6ca6SDavid S. Miller nop 45095707704SDavid S. Miller EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2) 451ae2c6ca6SDavid S. Miller add %o1, 0x04, %o1 452ae2c6ca6SDavid S. Miller add %o0, 0x04, %o0 453ae2c6ca6SDavid S. Miller subcc %o2, 0x04, %o2 454ae2c6ca6SDavid S. Miller bne,pn %icc, .Ltiny 45595707704SDavid S. Miller EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_4) 456ae2c6ca6SDavid S. Miller ba,a,pt %icc, .Lexit 457ae2c6ca6SDavid S. Miller.Lmedium_unaligned: 458ae2c6ca6SDavid S. Miller /* First get dest 8 byte aligned. */ 459ae2c6ca6SDavid S. Miller sub %g0, %o0, %g1 460ae2c6ca6SDavid S. Miller and %g1, 0x7, %g1 461ae2c6ca6SDavid S. Miller brz,pt %g1, 2f 462ae2c6ca6SDavid S. Miller sub %o2, %g1, %o2 463ae2c6ca6SDavid S. Miller 46495707704SDavid S. Miller1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1) 465ae2c6ca6SDavid S. Miller add %o1, 1, %o1 466ae2c6ca6SDavid S. Miller subcc %g1, 1, %g1 467ae2c6ca6SDavid S. Miller add %o0, 1, %o0 468ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 46995707704SDavid S. Miller EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1) 470ae2c6ca6SDavid S. Miller2: 471ae2c6ca6SDavid S. Miller and %o1, 0x7, %g1 472ae2c6ca6SDavid S. Miller brz,pn %g1, .Lmedium_noprefetch 473ae2c6ca6SDavid S. Miller sll %g1, 3, %g1 474ae2c6ca6SDavid S. Miller mov 64, %g2 475ae2c6ca6SDavid S. Miller sub %g2, %g1, %g2 476ae2c6ca6SDavid S. Miller andn %o1, 0x7, %o1 47795707704SDavid S. Miller EX_LD(LOAD(ldx, %o1 + 0x00, %o4), NG4_retl_o2) 478ae2c6ca6SDavid S. Miller sllx %o4, %g1, %o4 479ae2c6ca6SDavid S. Miller andn %o2, 0x08 - 1, %o5 480ae2c6ca6SDavid S. Miller sub %o2, %o5, %o2 48195707704SDavid S. Miller1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3), NG4_retl_o2_plus_o5) 482ae2c6ca6SDavid S. Miller add %o1, 0x08, %o1 483ae2c6ca6SDavid S. Miller subcc %o5, 0x08, %o5 484ae2c6ca6SDavid S. Miller srlx %g3, %g2, GLOBAL_SPARE 485ae2c6ca6SDavid S. Miller or GLOBAL_SPARE, %o4, GLOBAL_SPARE 48695707704SDavid S. Miller EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_8) 487ae2c6ca6SDavid S. Miller add %o0, 0x08, %o0 488ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 489ae2c6ca6SDavid S. Miller sllx %g3, %g1, %o4 490ae2c6ca6SDavid S. Miller srl %g1, 3, %g1 491ae2c6ca6SDavid S. Miller add %o1, %g1, %o1 492ae2c6ca6SDavid S. Miller brz,pn %o2, .Lexit 493ae2c6ca6SDavid S. Miller nop 494ae2c6ca6SDavid S. Miller ba,pt %icc, .Lsmall_unaligned 495ae2c6ca6SDavid S. Miller 496ae2c6ca6SDavid S. Miller.Ltiny: 49795707704SDavid S. Miller EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2) 498ae2c6ca6SDavid S. Miller subcc %o2, 1, %o2 499ae2c6ca6SDavid S. Miller be,pn %icc, .Lexit 50095707704SDavid S. Miller EX_ST(STORE(stb, %g1, %o0 + 0x00), NG4_retl_o2_plus_1) 50195707704SDavid S. Miller EX_LD(LOAD(ldub, %o1 + 0x01, %g1), NG4_retl_o2) 502ae2c6ca6SDavid S. Miller subcc %o2, 1, %o2 503ae2c6ca6SDavid S. Miller be,pn %icc, .Lexit 50495707704SDavid S. Miller EX_ST(STORE(stb, %g1, %o0 + 0x01), NG4_retl_o2_plus_1) 50595707704SDavid S. Miller EX_LD(LOAD(ldub, %o1 + 0x02, %g1), NG4_retl_o2) 506ae2c6ca6SDavid S. Miller ba,pt %icc, .Lexit 50795707704SDavid S. Miller EX_ST(STORE(stb, %g1, %o0 + 0x02), NG4_retl_o2) 508ae2c6ca6SDavid S. Miller 509ae2c6ca6SDavid S. Miller.Lsmall: 510ae2c6ca6SDavid S. Miller andcc %g2, 0x3, %g0 511ae2c6ca6SDavid S. Miller bne,pn %icc, .Lsmall_unaligned 512ae2c6ca6SDavid S. Miller andn %o2, 0x4 - 1, %o5 513ae2c6ca6SDavid S. Miller sub %o2, %o5, %o2 514ae2c6ca6SDavid S. Miller1: 51595707704SDavid S. Miller EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5) 516ae2c6ca6SDavid S. Miller add %o1, 0x04, %o1 517ae2c6ca6SDavid S. Miller subcc %o5, 0x04, %o5 518ae2c6ca6SDavid S. Miller add %o0, 0x04, %o0 519ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 52095707704SDavid S. Miller EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_o5_plus_4) 521ae2c6ca6SDavid S. Miller brz,pt %o2, .Lexit 522ae2c6ca6SDavid S. Miller nop 523ae2c6ca6SDavid S. Miller ba,a,pt %icc, .Ltiny 524ae2c6ca6SDavid S. Miller 525ae2c6ca6SDavid S. Miller.Lsmall_unaligned: 52695707704SDavid S. Miller1: EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2) 527ae2c6ca6SDavid S. Miller add %o1, 1, %o1 528ae2c6ca6SDavid S. Miller add %o0, 1, %o0 529ae2c6ca6SDavid S. Miller subcc %o2, 1, %o2 530ae2c6ca6SDavid S. Miller bne,pt %icc, 1b 53195707704SDavid S. Miller EX_ST(STORE(stb, %g1, %o0 - 0x01), NG4_retl_o2_plus_1) 532ae2c6ca6SDavid S. Miller ba,a,pt %icc, .Lexit 533*0ae2d26fSBabu Moger nop 534ae2c6ca6SDavid S. Miller .size FUNC_NAME, .-FUNC_NAME 535