zoukankan      html  css  js  c++  java
  • gas_marco_advance

    在查阅unicore的memcpy函数时,感觉学到了不少东西,今天把一周的东西整理下,留下了这个文档,方便以后查阅

    文件 asm/hwcap.h
    /*
    * linux/arch/unicore/include/asm/hwcap.h
    *
    * Code specific to PKUnity SoC and UniCore ISA
    * Fragments that appear the same as the files in arm or x86
    *
    * Copyright (C) 2001-2008 GUAN Xue-tao
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as
    * published by the Free Software Foundation.
    */
    #ifndef __UNICORE_HWCAP_H__
    #define __UNICORE_HWCAP_H__
    /*
    * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
    */
    #define HWCAP_MSP   1
    #define HWCAP_UNICORE16   2
    #define HWCAP_CMOV  4
    #define HWCAP_UNICORE_F64  8
    #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
    /*
    * This yields a mask that user programs can use to figure out what
    * instruction set this cpu supports.
    */
    #define ELF_HWCAP (elf_hwcap)
    extern unsigned int elf_hwcap;
    #endif
    #endif


    文件 asm/ptrace.h
    /*
    * linux/arch/unicore/include/asm/ptrace.h
    *
    * Code specific to PKUnity SoC and UniCore ISA
    * Fragments that appear the same as the files in arm or x86
    *
    * Copyright (C) 2001-2008 GUAN Xue-tao
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as
    * published by the Free Software Foundation.
    */
    #ifndef __UNICORE_PTRACE_H__
    #define __UNICORE_PTRACE_H__
    #include <asm/hwcap.h>
    #define PTRACE_GETREGS  12
    #define PTRACE_SETREGS  13
    #define PTRACE_GETFPREGS  14
    #define PTRACE_SETFPREGS  15
    /* PTRACE_ATTACH is   16 */
    /* PTRACE_DETACH is   17 */
    /* 18~20 is unused */
    #define PTRACE_OLDSETOPTIONS   21
    #define PTRACE_GET_THREAD_AREA  22
    #define PTRACE_SET_SYSCALL   23
    /* PTRACE_SYSCALL is   24 */
    #define PTRACE_GETVFPREGS   27
    #define PTRACE_SETVFPREGS   28
    /*
    * PSR bits
    */
    #define USER_MODE 0x00000010
    #define REAL_MODE 0x00000011
    #define INTR_MODE 0x00000012
    #define PRIV_MODE  0x00000013
    #define ABRT_MODE 0x00000017
    #define EXTN_MODE 0x0000001b
    #define SUSR_MODE 0x0000001f
    #define MODE_MASK 0x0000001f
    #define PSR_R_BIT 0x00000040
    #define PSR_I_BIT 0x00000080
    #define PSR_V_BIT0x10000000
    #define PSR_C_BIT 0x20000000
    #define PSR_Z_BIT 0x40000000
    #define PSR_S_BIT 0x80000000
    /*
    * Groups of PSR bits
    */
    #define PSR_f  0xff000000  /* Flags*/
    #define PSR_s  0x00ff0000  /* Status*/
    #define PSR_x  0x0000ff00  /* Extension*/ 
    #define PSR_c  0x000000ff  /* Control*/

    /*
    * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
    * process is located in memory.
    */
    #define PT_TEXT_ADDR  0x10000
    #define PT_DATA_ADDR  0x10004
    #define PT_TEXT_END_ADDR   0x10008
    #ifndef __ASSEMBLY__
    /*
    * This struct defines the way the registers are stored on the
    * stack during a system call. Note that sizeof(struct pt_regs)
    * has to be a multiple of 8.
    */
    struct pt_regs {
    long uregs[34];
    };
    #define UCreg_csr  uregs[32]
    #define UCreg_pc  uregs[31]
    #define UCreg_lr  uregs[30]
    #define UCreg_sp  uregs[29]
    #define UCreg_ip  uregs[28]
    #define UCreg_fp  uregs[27]
    #define UCreg_26  uregs[26]
    #define UCreg_25  uregs[25]
    #define UCreg_24  uregs[24]
    #define UCreg_23  uregs[23]
    #define UCreg_22  uregs[22]
    #define UCreg_21  uregs[21]
    #define UCreg_20  uregs[20]
    #define UCreg_19  uregs[19]
    #define UCreg_18  uregs[18]

    #define UCreg_17  uregs[17]
    #define UCreg_16  uregs[16]
    #define UCreg_15  uregs[15]
    #define UCreg_14  uregs[14]
    #define UCreg_13  uregs[13]
    #define UCreg_12  uregs[12]
    #define UCreg_11  uregs[11]
    #define UCreg_10  uregs[10]
    #define UCreg_09  uregs[9]
    #define UCreg_08  uregs[8]
    #define UCreg_07  uregs[7]
    #define UCreg_06  uregs[6]
    #define UCreg_05  uregs[5]
    #define UCreg_04  uregs[4]
    #define UCreg_03  uregs[3]
    #define UCreg_02  uregs[2]
    #define UCreg_01  uregs[1]
    #define UCreg_00  uregs[0]
    #define UCreg_ORIG_00  uregs[33]
    #ifdef __KERNEL__
    #define user_mode(regs) \
      (processor_mode(regs) == USER_MODE)
    #define isa_mode(regs)
      0
    #define processor_mode(regs) \
      ((regs)->UCreg_csr & MODE_MASK)
    #define interrupts_enabled(regs) \
      (!((regs)->UCreg_csr & PSR_I_BIT))
    #define fast_interrupts_enabled(regs) \
      (!((regs)->UCreg_csr & PSR_R_BIT))
    /* Are the current registers suitable for user mode?
    * (used to maintain security in signal handlers)
    */
    static inline int valid_user_regs(struct pt_regs *regs)
    {
      if (user_mode(regs) && (regs->UCreg_csr & PSR_I_BIT) == 0) {
        regs->UCreg_csr &= ~(PSR_R_BIT);
        return 1;
      }
    /*
    * Force CSR to something logical...
    */
      regs->UCreg_csr &= PSR_f | PSR_s | PSR_x | USER_MODE;
      return 0;
    }
    #define instruction_pointer(regs)  (regs)->UCreg_pc
    #define profile_pc(regs) instruction_pointer(regs)
    #define predicate(x)  ((x) & 0xf0000000)
    #define PREDICATE_ALWAYS  0xe0000000
    #endif /* __KERNEL__ */
    #endif /* __ASSEMBLY__ */
    #endif


    文件 asm/assember.h
    /*
    * linux/arch/unicore/include/asm/assembler.h
    *
    * Code specific to PKUnity SoC and UniCore ISA
    * Fragments that appear the same as the files in arm or x86
    *
    * Copyright (C) 2001-2008 GUAN Xue-tao
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as
    * published by the Free Software Foundation.
    *
    * Do not include any C declarations in this file - it is included by
    * assembler source.
    */
    #ifndef __ASSEMBLY__
    #error "Only include this from assembly code"
    #endif
    #include <asm/ptrace.h>
    /*
    * Little Endian independent macros for shifting bytes within registers.
    */
    #define pull  >>
    #define push  <<
    #define get_byte_0  << #0
    #define get_byte_1   >> #8
    #define get_byte_2   >> #16
    #define get_byte_3   >> #24
    #define put_byte_0  << #0
    #define put_byte_1   << #8
    #define put_byte_2   << #16
    #define put_byte_3   << #24
    /*
    * Enable and disable interrupts
    */
    .macro disable_irq_notrace, temp
      mov \temp, asr
      andn \temp, \temp, #0xFF
      or \temp, \temp, #PSR_I_BIT | PRIV_MODE
      mov.a
      asr, \temp
    .endm


    .macro enable_irq_notrace, temp
      mov \temp, asr
      andn \temp, \temp, #0xFF
      or \temp, \temp, #PRIV_MODE
      mov.a
      asr, \temp
    .endm


    .macro asm_trace_hardirqs_off
      #if defined(CONFIG_TRACE_IRQFLAGS)
      stm.w (ip, lr), [sp-]
      stm.w (r0-r3), [sp-]
      b.l trace_hardirqs_off
      ldm.w
      (r0-r3), [sp]+
      ldm.w
      (ip, lr), [sp]+
      #endif
    .endm


    .macro asm_trace_hardirqs_on_cond, cond
      #if defined(CONFIG_TRACE_IRQFLAGS)
    /*
    * actually the registers should be pushed and pop'd conditionally, but
    * after bl the flags are certainly clobbered
    */
      stm.w (ip, lr), [sp-]
      stm.w (r0-r3), [sp-]
      bl\cond trace_hardirqs_on
      ldm.w
      (r0-r3), [sp]+
      ldm.w
      (ip, lr), [sp]+
      #endif
    .endm


    .macro asm_trace_hardirqs_on
      asm_trace_hardirqs_on_cond al
    .endm


    .macro disable_irq, temp
      disable_irq_notrace \temp
      asm_trace_hardirqs_off
    .endm


    .macro enable_irq, temp
      asm_trace_hardirqs_on
      enable_irq_notrace \temp
    .endm
    /*
    * Save the current IRQ state and disable IRQs. Note that this macro
    * assumes FIQs are enabled, and that the processor is in SVC mode.
    */
    .macro save_and_disable_irqs, oldcpsr, temp
      mov \oldcpsr, asr
      disable_irq \temp
    .endm


    /*
    * Restore interrupt state previously stored in a register. We don't
    * guarantee that this will preserve the flags.
    */


    .macro restore_irqs_notrace, oldcpsr, temp
      mov \temp, asr
      mov.a
      asr, \oldcpsr
      mov.f
      asr, \temp
    .endm


    .macro restore_irqs, oldcpsr, temp
      cmpand.a \oldcpsr, #PSR_I_BIT
      asm_trace_hardirqs_on_cond eq
      restore_irqs_notrace \oldcpsr, \temp
    .endm


    #define USER(x...) \ 

    9999:  \

      .section __ex_table,"ax";  \
      .align  3;  \
      .long9999b,9001f;  \
      .previous  \

    .macro notcond, cond, nexti=.+8
      .ifc \cond, eq
        bne \nexti
      .else;.ifc \cond, ne
        beq \nexti
      .else;.ifc \cond, ea
        bub \nexti
      .else;.ifc \cond, ub
        bea \nexti
      .else;.ifc \cond, fs
        bns \nexti
      .else;.ifc \cond, ns
        bfs \nexti
      .else;.ifc \cond, fv
        bnv \nexti
      .else;.ifc \cond, nv
        bfv \nexti
      .else;.ifc \cond, ua
        beb \nexti
      .else;.ifc \cond, eb
        bua \nexti
      .else;.ifc \cond, eg
        bsl \nexti
      .else;.ifc \cond, sl
        beg \nexti
      .else;.ifc \cond, sg
        bel \nexti
      .else;.ifc \cond, el
        bsg \nexti
      .else;.ifnc \cond, al
      .error "Unknown cond in notcond macro argument"
     .endif;.endif;.endif;.endif;.endif;.endif;.endif;.endif;.endif;.endif;.endif;.endif;.endif
    .endm

    .endif
    .endif


    .macro usracc, instr, reg, ptr, inc, cond, rept, abort
      .rept \rept
      notcond \cond, .+8
    9999:
      .if \inc == 1
        \instr\()b.u \reg, [\ptr], #\inc
      .elseif  \inc == 4
        \instr\()w.u \reg, [\ptr], #\inc
      .else
      .error  "Unsupported inc macro argument"
      .endif
      .section __ex_table,"a"
      .align
      3
      .long9999b, \abort
      .previous
      .endr
    .endm


    .macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
      usracc st, \reg, \ptr, \inc, \cond, \rept, \abort
    .endm


    .macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
      usracc ld, \reg, \ptr, \inc, \cond, \rept, \abort
    .endm


    文件 asm/linkage.h
    /
    *
    * linux/arch/unicore/include/asm/linkage.h
    *
    * Code specific to PKUnity SoC and UniCore ISA
    * Fragments that appear the same as the files in arm or x86
    *
    * Copyright (C) 2001-2008 GUAN Xue-tao
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as
    * published by the Free Software Foundation.
    */
    #ifndef __UNICORE_LINKAGE_H__
    #define __UNICORE_LINKAGE_H__
    #define __ALIGN .align 0
    #define __ALIGN_STR ".align 0"
    #define ENDPROC(name) \
    .type name, %function; \
    END(name)
    #endif


    文件 linux/linkage.h
    #ifndef _LINUX_LINKAGE_H
    #define _LINUX_LINKAGE_H
    #include <linux/compiler.h>
    #include <asm/linkage.h>
    #ifdef __cplusplus
    #define CPP_ASMLINKAGE extern "C"
    #else
    #define CPP_ASMLINKAGE
    #endif
    #ifndef asmlinkage
    #define asmlinkage CPP_ASMLINKAGE
    #endif
    #ifndef asmregparm
    # define asmregparm
    #endif
    #define __page_aligned_data __section(.data.page_aligned) __aligned(PAGE_SIZE)
    #define __page_aligned_bss __section(.bss.page_aligned) __aligned(PAGE_SIZE)
    /*
    * For assembly routines.
    *
    * Note when using these that you must specify the appropriate
    * alignment directives yourself
    */
    #define __PAGE_ALIGNED_DATA
    .section ".data.page_aligned", "aw"
    #define __PAGE_ALIGNED_BSS .section ".bss.page_aligned", "aw"
    /*
    * This is used by architectures to keep arguments on the stack
    * untouched by the compiler by keeping them live until the end.
    * The argument stack may be owned by the assembly-language
    * caller, not the callee, and gcc doesn't always understand
    * that.
    *
    * We have the return value, and a maximum of six arguments.
    *
    * This should always be followed by a "return ret" for the
    * protection to work (ie no more work that the compiler might
    * end up needing stack temporaries for).
    */
    /* Assembly files may be compiled with -traditional .. */
    #ifndef __ASSEMBLY__
    #ifndef asmlinkage_protect
    # define asmlinkage_protect(n, ret, args...)
    do { } while (0)
    #endif
    #endif
    #ifndef __ALIGN
    #define __ALIGN
    .align 4,0x90
    #define __ALIGN_STR ".align 4,0x90"
    #endif
    #ifdef __ASSEMBLY__


    #ifndef LINKER_SCRIPT
    #define ALIGN __ALIGN
    #define ALIGN_STR __ALIGN_STR


    #ifndef ENTRY
    #define ENTRY(name) \
    .globl name; \
    ALIGN; \
    name:
    #endif
    #endif /* LINKER_SCRIPT */
    #ifndef WEAK
    #define WEAK(name)  \
      .weak name;  \
      name:
    #endif
    #ifndef END
    #define END(name) \
    .size name, .-name
    #endif
    /* If symbol 'name' is treated as a subroutine (gets called, and returns)
    * then please use ENDPROC to mark 'name' as STT_FUNC for the benefit of
    * static analysis tools such as stack depth analyzer.
    */
    #ifndef ENDPROC
    #define ENDPROC(name) \
    .type name, @function; \
    END(name)
    #endif
    #endif
    #define NORET_TYPE /**/
    #define ATTRIB_NORET __attribute__((noreturn))
    #define NORET_AND noreturn,
    #endif


    文件 lib/copy_from_user.S
    /*
    * linux/arch/unicore/lib/copy_from_user.S
    *
    * Code specific to PKUnity SoC and UniCore ISA
    * Fragments that appear the same as the files in arm or x86
    *
    * Copyright (C) 2001-2008 GUAN Xue-tao
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as
    * published by the Free Software Foundation.
    */
    #include <linux/linkage.h>
    #include <asm/assembler.h>
    /*
    * Prototype:
    *
    * size_t __copy_from_user(void *to, const void *from, size_t n)
    *
    * Purpose:
    *
    * copy a block to kernel memory from user memory
    *
    * Params:
    *
    * to = kernel memory
    * from = user memory
    * n = number of bytes to copy
    *
    * Return value:
    *
    * Number of bytes NOT copied.
    */
    .macro ldr1w ptr reg abort
      ldrusr  \reg, \ptr, 4, abort=\abort
    .endm


    .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
    100: ldm.w  (\reg1, \reg2, \reg3, \reg4), [\ptr]+
      .section __ex_table, "a"
      .align  3
      .long 100b, \abort
      .previous
    .endm


    .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
    100:

       ldm.w  (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
      .section __ex_table, "a"
      .align  3
      .long 100b, \abort
      .previous
    .endm


    .macro ldr1b ptr reg cond=al abort
      ldrusr  \reg, \ptr, 1, \cond, abort=\abort
    .endm


    .macro str1w ptr reg abort
      stw.w \reg, [\ptr]+, #4
    .endm


    .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
      stm.w  (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
    .endm

    .macro str1b ptr reg cond=al abort
      .ifnc \cond, al
      b\cond 201f
      b  202f
      .endif
    201:

      stb.w \reg, [\ptr]+, #1
    202:
    .endm


    .macro enter
      mov r3, #0
      stm.w  (r0, r2, r3), [sp-]
    .endm


    .macro exit
      add sp, sp, #8
      ldm.w  (r0), [sp]+
      mov pc, lr
    .endm


    .text
    ENTRY(__copy_from_user)
    #include "copy_template.S"
    ENDPROC(__copy_from_user)
      .section .fixup,"ax"
      .align 0
      copy_abort_preamble
      ldm.w  (r1, r2), [sp]+
      sub r3, r0, r1
      rsub r1, r3, r2
      stw r1, [sp]
      b.l __memzero
      ldw.w  r0, [sp]+, #4
      copy_abort_end
      .previous


    文件 lib/copy_to_user.S
    /*
    * linux/arch/unicore/lib/copy_to_user.S
    *
    * Code specific to PKUnity SoC and UniCore ISA
    * Fragments that appear the same as the files in arm or x86
    *
    * Copyright (C) 2001-2008 GUAN Xue-tao
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as
    * published by the Free Software Foundation.
    */
    #include <linux/linkage.h>
    #include <asm/assembler.h>
    /*
    * Prototype:
    *
    * size_t __copy_to_user(void *to, const void *from, size_t n)
    *
    * Purpose:
    *
    * copy a block to user memory from kernel memory
    *
    * Params:
    *
    * to = user memory
    * from = kernel memory
    * n = number of bytes to copy
    *
    * Return value:
    *
    * Number of bytes NOT copied.
    */
    .macro ldr1w ptr reg abort
    ldw.w \reg, [\ptr]+, #4
    .endm


    .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
    ldm.w  (\reg1, \reg2, \reg3, \reg4), [\ptr]+
    .endm


    .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
    ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
    .endm


    .macro ldr1b ptr reg cond=al abort
      notcond \cond, .+8
      ldb.w \reg, [\ptr]+, #1
    .endm


    .macro str1w ptr reg abort
      strusr  \reg, \ptr, 4, abort=\abort
    .endm


    .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
    100:

      stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
      .section __ex_table, "a"
      .long 100b, \abort
      .previous
    .endm


    .macro str1b ptr reg cond=al abort
      strusr  \reg, \ptr, 1, \cond, abort=\abort
    .endm


    .macro enter
      mov r3, #0
      stm.w  (r0, r2, r3), [sp-]
    .endm
      .macro exit
      add sp, sp, #8
      ldm.w  (r0), [sp]+
      mov pc, lr
    .endm


    .text
    ENTRY(__copy_to_user_std)
    WEAK(__copy_to_user)
    #include "copy_template.S"
    ENDPROC(__copy_to_user)
      .section .fixup,"ax"
      .align 0
      copy_abort_preamble
      ldm.w  (r1, r2, r3), [sp]+
      sub r0, r0, r1
      rsub r0, r0, r2
      copy_abort_end
      .previous


    文件 lib/copy_template.S
    /*
    * linux/arch/unicore/lib/copy_template.S
    *
    * Code specific to PKUnity SoC and UniCore ISA
    * Fragments that appear the same as the files in arm or x86
    *
    * Copyright (C) 2001-2008 GUAN Xue-tao
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as
    * published by the Free Software Foundation.
    */
    /*
    * Theory of operation
    * -------------------
    *
    * This file provides the core code for a forward memory copy used in
    * the implementation of memcopy(), copy_to_user() and copy_from_user().
    *
    * The including file must define the following accessor macros
    * according to the need of the given function:
    *
    * ldr1w ptr reg abort
    *
    * This loads one word from 'ptr', stores it in 'reg' and increments
    * 'ptr' to the next word. The 'abort' argument is used for fixup tables.
    *
    * ldr4w ptr reg1 reg2 reg3 reg4 abort
    * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
    *
    * This loads four or eight words starting from 'ptr', stores them
    * in provided registers and increments 'ptr' past those words.
    * The'abort' argument is used for fixup tables.
    *
    * ldr1b ptr reg cond abort
    *
    * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
    * It also must apply the condition code if provided, otherwise the
    * "al" condition is assumed by default.
    *
    * str1w ptr reg abort
    * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
    * str1b ptr reg cond abort
    *
    * Same as their ldr* counterparts, but data is stored to 'ptr' location
    * rather than being loaded.
    *
    * enter
    *
    * Preserve the provided registers on the stack plus any additional
    * data as needed by the implementation including this code. Called
    * upon code entry.
    *
    * exit
    *
    * Restore registers with the values previously saved with the
    * 'preserv' macro. Called upon code termination.
    */
    enter
      sub.ar2, r2, #4
      bsl 8f
      and.a
      ip, r0, #3
      bne 9f
      and.a
      ip, r1, #3
      bne 10f
      1:sub.ar2, r2, #(28)
      stm.w  (r5 - r8), [sp-]
      bsl 5f

    3:

    4:

      ldr8w  r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
      sub.ar2, r2, #32
      str8w  r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
      beg 3b

    5:
      and.a
      ip, r2, #28
      rsub ip, ip, #32
      beq 7f
      add pc, pc, ip  @ C is always clear here
      nop
      ldr1w  r1, r3, abort=20f
      ldr1w  r1, r4, abort=20f
      ldr1w  r1, r5, abort=20f
      ldr1w  r1, r6, abort=20f
      ldr1w  r1, r7, abort=20f
      ldr1w  r1, r8, abort=20f
      ldr1w  r1, r11, abort=20f
      add pc, pc, ip
      nop
      str1w  r0, r3, abort=20f
      str1w  r0, r4, abort=20f
      str1w  r0, r5, abort=20f
      str1w  r0, r6, abort=20f
      str1w  r0, r7, abort=20f
      str1w  r0, r8, abort=20f
      str1w  r0, r11, abort=20f
    7:

      ldm.w  (r5 - r8), [sp]+
    8:

      mov.a  r2, r2 << #31
       ldr1b  r1, r3, ne, abort=21f
      ldr1b  r1, r4, ea, abort=21f
      ldr1b  r1, r10, ea, abort=21f
      str1b r0, r3, ne, abort=21f
      str1b r0, r4, ea, abort=21f
      str1b r0, r10, ea, abort=21f
      exit
    9:

      rsub ip, ip, #4
       cmpsub.a ip, #2
       ldr1b  r1, r3, sg, abort=21f
      ldr1b  r1, r4, eg, abort=21f
      ldr1b  r1, r11, abort=21f
      str1b r0, r3, sg, abort=21f
      str1b r0, r4, eg, abort=21f
      sub.ar2, r2, ip
      str1b r0, r11, abort=21f
      bsl 8b
      and.a  ip, r1, #3
      beq 1b
    10:

      andn r1, r1, #3

      cmpsub.a ip, #2
        ldr1w   r1, r11, abort=21f
      beq 17f
      bsg 18f
    .macro
      forward_copy_shift a b
      sub.ar2, r2, #28
      bsl 14f
    11:
      stm.w  (r5 - r9), [sp-]
    12:
      ldr4w  r1, r4, r5, r6, r7, abort=19f
      mov r3, r11 pull #\a
      sub.ar2, r2, #32
      ldr4w  r1, r8, r9, r10, r11, abort=19f
      or r3, r3, r4 push #\b
      mov r4, r4 pull #\a
      or r4, r4, r5 push #\b
      mov r5, r5 pull #\a
      or r5, r5, r6 push #\b
      mov r6, r6 pull #\a
      or r6, r6, r7 push #\b
      mov r7, r7 pull #\a
      or r7, r7, r8 push #\b
      mov r8, r8 pull #\a
      or r8, r8, r9 push #\b
      mov r9, r9 pull #\a
      or r9, r9, r10 push #\b
      mov r10, r10 pull #\a
      or r10, r10, r11 push #\b
      str8w  r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f
      beg 12b  

      ldm.w  (r5 - r9), [sp]+
    14:

      and.a   ip, r2, #28
        beq 16f
    15:

      mov r3, r11 pull #\a
      ldr1w  r1, r11, abort=21f
          sub.aip, ip, #4
      or r3, r3, r11 push #\b
      str1w  r0, r3, abort=21f
      bsg 15b
    16:

      sub r1, r1, #(\b / 8)
          b  8b
    .endm
      forward_copy_shift a=8 b=24
    17: forward_copy_shift a=16b=16
    18: forward_copy_shift a=24b=8
    /*
    * Abort preamble and completion macros.
    * If a fixup handler is required then those macros must surround it.
    * It is assumed that the fixup code will handle the private part of
    * the exit macro.
    */
    .macro copy_abort_preamble
    19:

      ldm.w  (r5 - r9), [sp]+
      b  21f
    299:

      .word  0  @ store lr, to avoid function call in fixup
    20:

      ldm.w  (r5 - r8), [sp]+
    21:
      adr r1, 299b
      stw lr, [r1]
    .endm


    .macro copy_abort_end
      adr lr, 299b
      ldw pc, [lr]
    .endm


    文件 lib/memcpy.S
    /*
    * linux/arch/unicore/lib/memcpy.S
    *
    * Code specific to PKUnity SoC and UniCore ISA
    * Fragments that appear the same as the files in arm or x86
    *
    * Copyright (C) 2001-2008 GUAN Xue-tao
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as
    * published by the Free Software Foundation.
    */
    #include <linux/linkage.h>
    #include <asm/assembler.h>
    .macro ldr1w ptr reg abort
      ldw.w \reg, [\ptr]+, #4
    .endm


    .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
      ldm.w (\reg1, \reg2, \reg3, \reg4), [\ptr]+
    .endm


    .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
      ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
    .endm


    .macro ldr1b ptr reg cond=al abort
      .ifnc \cond, al
      b\cond 201f
      b  202f
      .endif
    201:

      ldb.w \reg, [\ptr]+, #1
    202:
    .endm


    .macro str1w ptr reg abort
      stw.w \reg, [\ptr]+, #4
    .endm


    .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
      stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
    .endm


    .macro str1b ptr reg cond=al abort
      .ifnc \cond, al
      b\cond 201f
      b  202f
    .endif


    201:

      stb.w \reg, [\ptr]+, #1
    202:
    .endm


    .macro enter
      stm.w (r0), [sp-]
    .endm


    .macro exit
      ldm.w (r0), [sp]+
      mov pc, lr
    .endm


    .text
    /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
    ENTRY(memcpy)
      #include "copy_template.S"
    ENDPROC(memcpy)

  • 相关阅读:
    final,finally和finalize三者的区别和联系
    Java程序开发中的简单内存分析
    Java堆、栈和常量池以及相关String的详细讲解(经典中的经典)
    java中的基本数据类型一定存储在栈中吗?
    CDN加速-内容分发网络
    大型Java web项目分布式架构演进-分布式部署
    阿里面试-2019
    jvm调优-从eclipse开始
    eclipse中导入maven项目:org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.Maven
    图解 CMS 垃圾回收机制原理,-阿里面试题
  • 原文地址:https://www.cnblogs.com/openix/p/2531323.html
Copyright © 2011-2022 走看看