diff options
Diffstat (limited to 'src/pkg/runtime/arm/memset.s')
-rw-r--r-- | src/pkg/runtime/arm/memset.s | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/pkg/runtime/arm/memset.s b/src/pkg/runtime/arm/memset.s new file mode 100644 index 000000000..974b8da7a --- /dev/null +++ b/src/pkg/runtime/arm/memset.s @@ -0,0 +1,94 @@ +// Inferno's libkern/memset-arm.s +// http://code.google.com/p/inferno-os/source/browse/libkern/memset-arm.s +// +// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. +// Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved. +// Portions Copyright 2009 The Go Authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +TO = 1 +TOE = 2 +N = 3 +TMP = 3 /* N and TMP don't overlap */ + +// TODO(kaib): memset clobbers R9 and R10 (m and g). This makes the +// registers unpredictable if (when) memset SIGSEGV's. Fix it by +// moving the R4-R11 register bank. +TEXT runtime·memset(SB), $0 + MOVW R0, R(TO) + MOVW data+4(FP), R(4) + MOVW n+8(FP), R(N) + + ADD R(N), R(TO), R(TOE) /* to end pointer */ + + CMP $4, R(N) /* need at least 4 bytes to copy */ + BLT _1tail + + AND $0xFF, R(4) /* it's a byte */ + SLL $8, R(4), R(TMP) /* replicate to a word */ + ORR R(TMP), R(4) + SLL $16, R(4), R(TMP) + ORR R(TMP), R(4) + +_4align: /* align on 4 */ + AND.S $3, R(TO), R(TMP) + BEQ _4aligned + + MOVBU.P R(4), 1(R(TO)) /* implicit write back */ + B _4align + +_4aligned: + SUB $31, R(TOE), R(TMP) /* do 32-byte chunks if possible */ + CMP R(TMP), R(TO) + BHS _4tail + + MOVW R4, R5 /* replicate */ + MOVW R4, R6 + MOVW R4, R7 + MOVW R4, R8 + MOVW R4, R9 + MOVW R4, R10 + MOVW R4, R11 + +_f32loop: + CMP R(TMP), R(TO) + BHS _4tail + + MOVM.IA.W [R4-R11], (R(TO)) + B _f32loop + +_4tail: + SUB $3, R(TOE), R(TMP) /* do remaining words if possible */ +_4loop: + CMP R(TMP), R(TO) + BHS _1tail + + MOVW.P R(4), 4(R(TO)) /* implicit write back */ + B _4loop + +_1tail: + CMP R(TO), R(TOE) + BEQ _return + + MOVBU.P R(4), 1(R(TO)) /* implicit write back */ + B _1tail + +_return: + RET |