📄 memory_asm_cpu.s
字号:
/* * @(#)memory_asm_cpu.S 1.13 06/10/10 * * Portions Copyright 2000-2008 Sun Microsystems, Inc. All Rights * Reserved. Use is subject to license terms. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. *//* * Copyright 2005 Intel Corporation. All rights reserved. */#include "javavm/include/asmmacros_cpu.h"#include "javavm/include/porting/endianness.h"#include "javavm/include/iai_opt_config.h"/* * NOTE: Some linker such as the ARM RVCT (v2.2) linker sorts * sections by attributes and section name. To make sure * the CCM copied code in the same order as they are included * in ccmcodecachecopy_cpu.S, we need to name the sections * in alphabetical order. */ SET_SECTION_EXEC(s6_memory_asm_cpu) ENTRY (CVMARMmemmove8Bit)ENTRY1(CVMARMmemmove8Bit) /* r0 = a1 = dest r1 = a2 = src r2 = a3 = length */#define DEST r0#define SRC r1#define LENGTH r2 /* Check to see if the length is 0. Also check to see if which direction we need to do the copying in: */ cmp LENGTH, #0 cmpne DEST, SRC BRCOND_REG(lr,eq) /* Nothing to copy. Return to caller. */ /* If (dest >= src + length) or (dest < src), then we can do forward copying: */ addhi r12, SRC, LENGTH cmphi r12, DEST bhi memmove8Bit_inverseLABEL(memmove8Bit_copyForward) /* Do forward copying: *//* IAI-01 */#ifdef IAI_MEMMOVE#ifdef IAI_MEMMOVE_PLD pld [SRC] pld [SRC, #32] pld [SRC, #64] pld [DEST] pld [DEST, #32] pld [DEST, #64]#endif cmp LENGTH, #64 blt memmove8Bit_smallLength /* Check if the DEST and SRC pointers are similarly aligned: */ eor r3, SRC, DEST /* Equal bits will become 0. */ tst r3, #0x7 /* Check if low 3 bits are equal. */ bne memmove8Bit_Doubleunaligned /* Do aligned copying: */ tst SRC, #0x7 /* Check if already double word aligned. */ bne memmove8Bit_alignedDoubleWordsLeadingByte LABEL(memmove8Bit_alignedDoubleWords) wldrd wR0, [SRC], #8 and r12, LENGTH, #7 wldrd wR1, [SRC], #8 sub LENGTH, LENGTH, #24 wldrd wR2, [SRC], #8 L10: #ifdef IAI_MEMMOVE_PLD2 pld [SRC, #64] pld [DEST, #64]#endif wstrd wR0, [DEST], #8 wldrd wR0, [SRC], #8 wstrd wR1, [DEST], #8 wldrd wR1, [SRC], #8 wstrd wR2, [DEST], #8 wldrd wR2, [SRC], #8 subs LENGTH, LENGTH, #24 bge L10 LABEL(memmove8Bit_alignedDoubleWordsTrailingTripleword) adds LENGTH, LENGTH, #8 blt memmove8Bit_alignedDoubleWordsTrailingDoubleword wstrd wR0, [DEST], #8 wmov wR0, wR1 wmov wR1, wR2 LABEL(memmove8Bit_alignedDoubleWordsTrailingDoubleword) adds LENGTH, LENGTH, #8 blt memmove8Bit_alignedDoubleWordsTrailingword wstrd wR0, [DEST], #8 wmov wR0, wR1 LABEL(memmove8Bit_alignedDoubleWordsTrailingword) /* Copy the trailing word if necessary: */ tst r12, #0x4 beq memmove8Bit_alignedDoubleWordsTrailingHalfword wstrw wR0, [DEST], #4 waligni wR0, wR0, wR0, #4 LABEL(memmove8Bit_alignedDoubleWordsTrailingHalfword) /* Copy the trailing half word if necessary: */ tst r12, #0x2 beq memmove8Bit_alignedDoubleWordsTrailingByte wstrh wR0, [DEST], #2 waligni wR0, wR0, wR0, #2LABEL(memmove8Bit_alignedDoubleWordsTrailingByte) /* Copy the trailing byte if necessary: */ tst r12, #0x1 wstrbne wR0, [DEST]LABEL(memmove8Bit_alignedDoubleWordsDone) BR_REG(lr) /* Return to caller. */LABEL(memmove8Bit_alignedDoubleWordsLeadingByte) /* Copy leading byte if necessary: */ tst SRC, #0x1 beq memmove8Bit_alignedDoubleWordsLeadingHalfWord ldrb r3, [SRC], #1 sub LENGTH, LENGTH, #1 strb r3, [DEST], #1LABEL(memmove8Bit_alignedDoubleWordsLeadingHalfWord) /* Copy the leading halfword if necessary: */ tst SRC, #0x2 beq memmove8Bit_alignedDoubleWordsLeadingWord ldrh r3, [SRC], #2 sub LENGTH, LENGTH, #2 strh r3, [DEST], #2 LABEL(memmove8Bit_alignedDoubleWordsLeadingWord) /* Copy the leading word if necessary: */ tst SRC, #0x4 beq memmove8Bit_alignedDoubleWords ldr r3, [SRC], #4 sub LENGTH, LENGTH, #4 str r3, [DEST], #4 b memmove8Bit_alignedDoubleWordsLABEL(memmove8Bit_alignedWordCheck) tst SRC, #0x7 /* Check if already double word aligned. */ bne memmove8Bit_alignedWordLeadingByte LABEL(memmove8Bit_alignedWord) wldrd wR0, [SRC], #8 sub LENGTH, LENGTH, #28 wldrd wR1, [SRC], #8 and r12, LENGTH, #7 wldrd wR2, [SRC], #8 wstrw wR0, [DEST], #4 LABEL(L11)#ifdef IAI_MEMMOVE_PLD2 pld [SRC, #64] pld [DEST, #64]#endif waligni wR3, wR0, wR1, #4 wldrd wR0, [SRC], #8 wstrd wR3, [DEST], #8 waligni wR4, wR1, wR2, #4 wldrd wR1, [SRC], #8 wstrd wR4, [DEST], #8 waligni wR5, wR2, wR0, #4 wldrd wR2, [SRC], #8 wstrd wR5, [DEST], #8 subs LENGTH, LENGTH, #24 bge L11 LABEL(memmove8Bit_alignedWordTrailingTripleword) adds LENGTH, LENGTH, #8 blt memmove8Bit_alignedWordTrailingDoubleword waligni wR3, wR0, wR1, #4 wmov wR0, wR1 wmov wR1, wR2 wldrd wR2, [SRC], #8 wstrd wR3, [DEST], #8LABEL(memmove8Bit_alignedWordTrailingDoubleword) adds LENGTH, LENGTH, #8 blt memmove8Bit_alignedWordTrailingword waligni wR3, wR0, wR1, #4 wstrd wR3, [DEST], #8 wmov wR0, wR1 wmov wR1, wR2 LABEL(memmove8Bit_alignedWordTrailingword) /* Copy the trailing word if necessary: */ waligni wR2, wR0, wR1, #4 tst r12, #0x4 beq memmove8Bit_alignedWordTrailingHalfword wstrw wR2, [DEST], #4 waligni wR2, wR2, wR2, #4 LABEL(memmove8Bit_alignedWordTrailingHalfword) /* Copy the trailing half word if necessary: */ tst r12, #0x2 beq memmove8Bit_alignedWordTrailingByte wstrh wR2, [DEST], #2 waligni wR2, wR2, wR2, #2LABEL(memmove8Bit_alignedWordTrailingByte) /* Copy the trailing byte if necessary: */ tst r12, #0x1 wstrbne wR2, [DEST]LABEL(memmove8Bit_alignedWordDone) BR_REG(lr) /* Return to caller. */LABEL(memmove8Bit_alignedWordLeadingByte) /* Copy leading byte if necessary: */ tst SRC, #0x1 beq memmove8Bit_alignedWordLeadingHalfWord ldrb r3, [SRC], #1 sub LENGTH, LENGTH, #1 strb r3, [DEST], #1LABEL(memmove8Bit_alignedWordLeadingHalfWord) /* Copy the leading halfword if necessary: */ tst SRC, #0x2 beq memmove8Bit_alignedWordLeadingWord ldrh r3, [SRC], #2 sub LENGTH, LENGTH, #2 strh r3, [DEST], #2 LABEL(memmove8Bit_alignedWordLeadingWord) /* Copy the leading word if necessary: */ tst SRC, #0x4 beq memmove8Bit_alignedWord bic SRC, SRC, #7 wldrd wR0, [SRC], #8 sub LENGTH, LENGTH, #24 wldrd wR1, [SRC], #8 and r12, LENGTH, #7 wldrd wR2, [SRC], #8 b L11 LABEL(memmove8Bit_Doubleunaligned) tst r3, #0x3 /* Check if low 2 bits are equal. */ beq memmove8Bit_alignedWordCheck stmfd sp!, {r4-r7,lr} and r3, SRC, #7 /*r3 = number of src unaligned */ and r5, DEST, #7 /*r5 = number of DEST unaligned */ subs r7, r3, r5 blt LM2 /* Do alignment for the starting part. If the unaligned byte number of src is bigger than that of dest, |<-src wR1:wR0 -> s12 s11 s10 s9 s8 s7 s6 s5 : s4 s3 s2 s1 s0 x2 x1 x0 wR3 -> y7 y6 y5 y4 y3 y2 y1 y0 |<-dest Result -> s6 s5 s4 s3 s2 s1 s0 y0 Step 1 -> s6 s5 s4 s3 s2 s1 s0 x2 Step 2 -> y0 s6 s5 s4 s3 s2 s1 s0 Step 3 -> s6 s5 s4 s3 s2 s1 s0 y0 */ bic r6, DEST, #7 /*r6 = address 8-byte aligned */ wldrd wR3, [r6] bic r4, SRC, #7 /*r4 = address 8-byte aligned */ wldrd wR0, [r4], #8 tmcr wCGR0, r7 /*wCGR0 = number of bytes to be aligned */ wldrd wR1, [r4], #8 tmcr wCGR1, r5 /*wCGR1 = number of bytes to be aligned */ rsb r12, r5, #8 sub LENGTH, LENGTH, r12 mov r12, r12, LSL #3 tmcr wCGR2, r12 /*wCGR2 = number of bits to be rotated */ walignr0 wR2, wR0, wR1 /* Step 1 */ wmov wR0, wR1 wldrd wR1, [r4], #8 sub LENGTH, LENGTH, #24 walignr1 wR4, wR2, wR3 /* Step 2 */ wldrd wR2, [r4], #8 wrordg wR4, wR4, wCGR2 /* Step 3 */ wstrd wR4, [r6], #8 /* The first unaligned 8-byte has been done. Begin mainloop * of 8-byte memmove. */LABEL(LM1) #ifdef IAI_MEMMOVE_PLD2 pld [r4, #64] pld [r6, #64]#endif walignr0 wR3, wR0, wR1 wldrd wR0, [r4], #8 wstrd wR3, [r6], #8 walignr0 wR4, wR1, wR2 wldrd wR1, [r4], #8 wstrd wR4, [r6], #8 walignr0 wR5, wR2, wR0 wldrd wR2, [r4], #8 wstrd wR5, [r6], #8 subs LENGTH, LENGTH, #24 bge LM1 /* * Do the end unaligned part */LABEL(L101) adds LENGTH, LENGTH, #8 blt L102 walignr0 wR3, wR0, wR1 wmov wR0, wR1 wmov wR1, wR2 wldrd wR2, [r4], #8 wstrd wR3, [r6], #8LABEL(L102) adds LENGTH, LENGTH, #8 blt L103 walignr0 wR3, wR0, wR1 wstrd wR3, [r6], #8 wmov wR0, wR1 wmov wR1, wR2 LABEL(L103) walignr0 wR3, wR0, wR1 tst LENGTH, #4 beq L104 wstrw wR3, [r6], #4 waligni wR3, wR3, wR3, #4 LABEL(L104) tst LENGTH, #2 beq L105 wstrh wR3, [r6], #2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -