/* memset.S: optimised assembly memset1*2* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.3* Written by David Howells ([email protected])4*5* This program is free software; you can redistribute it and/or6* modify it under the terms of the GNU General Public License7* as published by the Free Software Foundation; either version8* 2 of the License, or (at your option) any later version.9*/101112.text13.p2align 41415###############################################################################16#17# void *memset(void *p, char ch, size_t count)18#19# - NOTE: must not use any stack. exception detection performs function return20# to caller's fixup routine, aborting the remainder of the set21# GR4, GR7, GR8, and GR11 must be managed22#23###############################################################################24.globl memset,__memset_end25.type memset,@function26memset:27orcc.p gr10,gr0,gr5,icc3 ; GR5 = count28andi gr9,#0xff,gr929or.p gr8,gr0,gr4 ; GR4 = address30beqlr icc3,#03132# conditionally write a byte to 2b-align the address33setlos.p #1,gr634andicc gr4,#1,gr0,icc035ckne icc0,cc736cstb.p gr9,@(gr4,gr0) ,cc7,#137csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC338cadd.p gr4,gr6,gr4 ,cc7,#139beqlr icc3,#04041# conditionally write a word to 4b-align the address42andicc.p gr4,#2,gr0,icc043subicc gr5,#2,gr0,icc144setlos.p #2,gr645ckne icc0,cc746slli.p gr9,#8,gr12 ; need to double up the pattern47cknc icc1,cc548or.p gr9,gr12,gr1249andcr cc7,cc5,cc75051csth.p gr12,@(gr4,gr0) ,cc7,#152csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC353cadd.p gr4,gr6,gr4 ,cc7,#154beqlr icc3,#05556# conditionally write a dword to 8b-align the address57andicc.p gr4,#4,gr0,icc058subicc gr5,#4,gr0,icc159setlos.p #4,gr660ckne icc0,cc761slli.p gr12,#16,gr13 ; need to quadruple-up the pattern62cknc icc1,cc563or.p gr13,gr12,gr1264andcr cc7,cc5,cc76566cst.p gr12,@(gr4,gr0) ,cc7,#167csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC368cadd.p gr4,gr6,gr4 ,cc7,#169beqlr icc3,#07071or.p gr12,gr12,gr13 ; need to octuple-up the pattern7273# the address is now 8b-aligned - loop around writing 64b chunks74setlos #8,gr775subi.p gr4,#8,gr4 ; store with update index does weird stuff76setlos #64,gr67778subicc gr5,#64,gr0,icc0790: cknc icc0,cc780cstdu gr12,@(gr4,gr7) ,cc7,#181cstdu gr12,@(gr4,gr7) ,cc7,#182cstdu gr12,@(gr4,gr7) ,cc7,#183cstdu gr12,@(gr4,gr7) ,cc7,#184cstdu gr12,@(gr4,gr7) ,cc7,#185cstdu.p gr12,@(gr4,gr7) ,cc7,#186csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC387cstdu.p gr12,@(gr4,gr7) ,cc7,#188subicc gr5,#64,gr0,icc089cstdu.p gr12,@(gr4,gr7) ,cc7,#190beqlr icc3,#091bnc icc0,#2,0b9293# now do 32-byte remnant94subicc.p gr5,#32,gr0,icc095setlos #32,gr696cknc icc0,cc797cstdu.p gr12,@(gr4,gr7) ,cc7,#198csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC399cstdu.p gr12,@(gr4,gr7) ,cc7,#1100setlos #16,gr6101cstdu.p gr12,@(gr4,gr7) ,cc7,#1102subicc gr5,#16,gr0,icc0103cstdu.p gr12,@(gr4,gr7) ,cc7,#1104beqlr icc3,#0105106# now do 16-byte remnant107cknc icc0,cc7108cstdu.p gr12,@(gr4,gr7) ,cc7,#1109csubcc gr5,gr6,gr5 ,cc7,#1 ; also set ICC3110cstdu.p gr12,@(gr4,gr7) ,cc7,#1111beqlr icc3,#0112113# now do 8-byte remnant114subicc gr5,#8,gr0,icc1115cknc icc1,cc7116cstdu.p gr12,@(gr4,gr7) ,cc7,#1117csubcc gr5,gr7,gr5 ,cc7,#1 ; also set ICC3118setlos.p #4,gr7119beqlr icc3,#0120121# now do 4-byte remnant122subicc gr5,#4,gr0,icc0123addi.p gr4,#4,gr4124cknc icc0,cc7125cstu.p gr12,@(gr4,gr7) ,cc7,#1126csubcc gr5,gr7,gr5 ,cc7,#1 ; also set ICC3127subicc.p gr5,#2,gr0,icc1128beqlr icc3,#0129130# now do 2-byte remnant131setlos #2,gr7132addi.p gr4,#2,gr4133cknc icc1,cc7134csthu.p gr12,@(gr4,gr7) ,cc7,#1135csubcc gr5,gr7,gr5 ,cc7,#1 ; also set ICC3136subicc.p gr5,#1,gr0,icc0137beqlr icc3,#0138139# now do 1-byte remnant140setlos #0,gr7141addi.p gr4,#2,gr4142cknc icc0,cc7143cstb.p gr12,@(gr4,gr0) ,cc7,#1144bralr145__memset_end:146147.size memset, __memset_end-memset148149###############################################################################150#151# clear memory in userspace152# - return the number of bytes that could not be cleared (0 on complete success)153#154# long __memset_user(void *p, size_t count)155#156###############################################################################157.globl __memset_user, __memset_user_error_lr, __memset_user_error_handler158.type __memset_user,@function159__memset_user:160movsg lr,gr11161162# abuse memset to do the dirty work163or.p gr9,gr9,gr10164setlos #0,gr9165call memset166__memset_user_error_lr:167jmpl.p @(gr11,gr0)168setlos #0,gr8169170# deal any exception generated by memset171# GR4 - memset's address tracking pointer172# GR7 - memset's step value (index register for store insns)173# GR8 - memset's original start address174# GR10 - memset's original count175__memset_user_error_handler:176add.p gr4,gr7,gr4177add gr8,gr10,gr8178jmpl.p @(gr11,gr0)179sub gr8,gr4,gr8 ; we return the amount left uncleared180181.size __memset_user, .-__memset_user182183184