linux/arch/metag/lib/memmove.S
<<
>>
Prefs
   1!   Copyright (C) 2008-2012 Imagination Technologies Ltd.
   2
   3        .text
   4        .global _memmove
   5        .type   _memmove,function
   6! D1Ar1 dst
   7! D0Ar2 src
   8! D1Ar3 cnt
   9! D0Re0 dst
  10_memmove:
  11        CMP     D1Ar3, #0
  12        MOV     D0Re0, D1Ar1
  13        BZ      $LEND2
  14        MSETL   [A0StP], D0.5, D0.6, D0.7
  15        MOV     D1Ar5, D0Ar2
  16        CMP     D1Ar1, D1Ar5
  17        BLT     $Lforwards_copy
  18        SUB     D0Ar4, D1Ar1, D1Ar3
  19        ADD     D0Ar4, D0Ar4, #1
  20        CMP     D0Ar2, D0Ar4
  21        BLT     $Lforwards_copy
  22        ! should copy backwards
  23        MOV     D1Re0, D0Ar2
  24        ! adjust pointer to the end of mem
  25        ADD     D0Ar2, D1Re0, D1Ar3
  26        ADD     D1Ar1, D1Ar1, D1Ar3
  27
  28        MOV     A1.2, D0Ar2
  29        MOV     A0.2, D1Ar1
  30        CMP     D1Ar3, #8
  31        BLT     $Lbbyte_loop
  32
  33        MOV     D0Ar4, D0Ar2
  34        MOV     D1Ar5, D1Ar1
  35
  36        ! test 8 byte alignment
  37        ANDS    D1Ar5, D1Ar5, #7
  38        BNE     $Lbdest_unaligned
  39
  40        ANDS    D0Ar4, D0Ar4, #7
  41        BNE     $Lbsrc_unaligned
  42
  43        LSR     D1Ar5, D1Ar3, #3
  44
  45$Lbaligned_loop:
  46        GETL    D0Re0, D1Re0, [--A1.2]
  47        SETL    [--A0.2], D0Re0, D1Re0
  48        SUBS    D1Ar5, D1Ar5, #1
  49        BNE     $Lbaligned_loop
  50
  51        ANDS    D1Ar3, D1Ar3, #7
  52        BZ      $Lbbyte_loop_exit
  53$Lbbyte_loop:
  54        GETB    D1Re0, [--A1.2]
  55        SETB    [--A0.2], D1Re0
  56        SUBS    D1Ar3, D1Ar3, #1
  57        BNE     $Lbbyte_loop
  58$Lbbyte_loop_exit:
  59        MOV     D0Re0, A0.2
  60$LEND:
  61        SUB     A0.2, A0StP, #24
  62        MGETL   D0.5, D0.6, D0.7, [A0.2]
  63        SUB     A0StP, A0StP, #24
  64$LEND2:
  65        MOV     PC, D1RtP
  66
  67$Lbdest_unaligned:
  68        GETB    D0Re0, [--A1.2]
  69        SETB    [--A0.2], D0Re0
  70        SUBS    D1Ar5, D1Ar5, #1
  71        SUB     D1Ar3, D1Ar3, #1
  72        BNE     $Lbdest_unaligned
  73        CMP     D1Ar3, #8
  74        BLT     $Lbbyte_loop
  75$Lbsrc_unaligned:
  76        LSR     D1Ar5, D1Ar3, #3
  77        ! adjust A1.2
  78        MOV     D0Ar4, A1.2
  79        ! save original address
  80        MOV     D0Ar6, A1.2
  81
  82        ADD     D0Ar4, D0Ar4, #7
  83        ANDMB   D0Ar4, D0Ar4, #0xfff8
  84        ! new address is the 8-byte aligned one above the original
  85        MOV     A1.2, D0Ar4
  86
  87        ! A0.2 dst 64-bit is aligned
  88        ! measure the gap size
  89        SUB     D0Ar6, D0Ar4, D0Ar6
  90        MOVS    D0Ar4, D0Ar6
  91        ! keep this information for the later adjustment
  92        ! both aligned
  93        BZ      $Lbaligned_loop
  94
  95        ! prefetch
  96        GETL    D0Re0, D1Re0, [--A1.2]
  97
  98        CMP     D0Ar6, #4
  99        BLT     $Lbunaligned_1_2_3
 100        ! 32-bit aligned
 101        BZ      $Lbaligned_4
 102
 103        SUB     D0Ar6, D0Ar6, #4
 104        ! D1.6 stores the gap size in bits
 105        MULW    D1.6, D0Ar6, #8
 106        MOV     D0.6, #32
 107        ! D0.6 stores the complement of the gap size
 108        SUB     D0.6, D0.6, D1.6
 109
 110$Lbunaligned_5_6_7:
 111        GETL    D0.7, D1.7, [--A1.2]
 112        ! form 64-bit data in D0Re0, D1Re0
 113        MOV     D1Re0, D0Re0
 114        ! D1Re0 << gap-size
 115        LSL     D1Re0, D1Re0, D1.6
 116        MOV     D0Re0, D1.7
 117        ! D0Re0 >> complement
 118        LSR     D0Re0, D0Re0, D0.6
 119        MOV     D1.5, D0Re0
 120        ! combine the both
 121        ADD     D1Re0, D1Re0, D1.5
 122
 123        MOV     D1.5, D1.7
 124        LSL     D1.5, D1.5, D1.6
 125        MOV     D0Re0, D0.7
 126        LSR     D0Re0, D0Re0, D0.6
 127        MOV     D0.5, D1.5
 128        ADD     D0Re0, D0Re0, D0.5
 129
 130        SETL    [--A0.2], D0Re0, D1Re0
 131        MOV     D0Re0, D0.7
 132        MOV     D1Re0, D1.7
 133        SUBS    D1Ar5, D1Ar5, #1
 134        BNE     $Lbunaligned_5_6_7
 135
 136        ANDS    D1Ar3, D1Ar3, #7
 137        BZ      $Lbbyte_loop_exit
 138        ! Adjust A1.2
 139        ! A1.2 <- A1.2 +8 - gapsize
 140        ADD     A1.2, A1.2, #8
 141        SUB     A1.2, A1.2, D0Ar4
 142        B       $Lbbyte_loop
 143
 144$Lbunaligned_1_2_3:
 145        MULW    D1.6, D0Ar6, #8
 146        MOV     D0.6, #32
 147        SUB     D0.6, D0.6, D1.6
 148
 149$Lbunaligned_1_2_3_loop:
 150        GETL    D0.7, D1.7, [--A1.2]
 151        ! form 64-bit data in D0Re0, D1Re0
 152        LSL     D1Re0, D1Re0, D1.6
 153        ! save D0Re0 for later use
 154        MOV     D0.5, D0Re0
 155        LSR     D0Re0, D0Re0, D0.6
 156        MOV     D1.5, D0Re0
 157        ADD     D1Re0, D1Re0, D1.5
 158
 159        ! orignal data in D0Re0
 160        MOV     D1.5, D0.5
 161        LSL     D1.5, D1.5, D1.6
 162        MOV     D0Re0, D1.7
 163        LSR     D0Re0, D0Re0, D0.6
 164        MOV     D0.5, D1.5
 165        ADD     D0Re0, D0Re0, D0.5
 166
 167        SETL    [--A0.2], D0Re0, D1Re0
 168        MOV     D0Re0, D0.7
 169        MOV     D1Re0, D1.7
 170        SUBS    D1Ar5, D1Ar5, #1
 171        BNE     $Lbunaligned_1_2_3_loop
 172
 173        ANDS    D1Ar3, D1Ar3, #7
 174        BZ      $Lbbyte_loop_exit
 175        ! Adjust A1.2
 176        ADD     A1.2, A1.2, #8
 177        SUB     A1.2, A1.2, D0Ar4
 178        B       $Lbbyte_loop
 179
 180$Lbaligned_4:
 181        GETL    D0.7, D1.7, [--A1.2]
 182        MOV     D1Re0, D0Re0
 183        MOV     D0Re0, D1.7
 184        SETL    [--A0.2], D0Re0, D1Re0
 185        MOV     D0Re0, D0.7
 186        MOV     D1Re0, D1.7
 187        SUBS    D1Ar5, D1Ar5, #1
 188        BNE     $Lbaligned_4
 189        ANDS    D1Ar3, D1Ar3, #7
 190        BZ      $Lbbyte_loop_exit
 191        ! Adjust A1.2
 192        ADD     A1.2, A1.2, #8
 193        SUB     A1.2, A1.2, D0Ar4
 194        B       $Lbbyte_loop
 195
 196$Lforwards_copy:
 197        MOV     A1.2, D0Ar2
 198        MOV     A0.2, D1Ar1
 199        CMP     D1Ar3, #8
 200        BLT     $Lfbyte_loop
 201
 202        MOV     D0Ar4, D0Ar2
 203        MOV     D1Ar5, D1Ar1
 204
 205        ANDS    D1Ar5, D1Ar5, #7
 206        BNE     $Lfdest_unaligned
 207
 208        ANDS    D0Ar4, D0Ar4, #7
 209        BNE     $Lfsrc_unaligned
 210
 211        LSR     D1Ar5, D1Ar3, #3
 212
 213$Lfaligned_loop:
 214        GETL    D0Re0, D1Re0, [A1.2++]
 215        SUBS    D1Ar5, D1Ar5, #1
 216        SETL    [A0.2++], D0Re0, D1Re0
 217        BNE     $Lfaligned_loop
 218
 219        ANDS    D1Ar3, D1Ar3, #7
 220        BZ      $Lfbyte_loop_exit
 221$Lfbyte_loop:
 222        GETB    D1Re0, [A1.2++]
 223        SETB    [A0.2++], D1Re0
 224        SUBS    D1Ar3, D1Ar3, #1
 225        BNE     $Lfbyte_loop
 226$Lfbyte_loop_exit:
 227        MOV     D0Re0, D1Ar1
 228        B       $LEND
 229
 230$Lfdest_unaligned:
 231        GETB    D0Re0, [A1.2++]
 232        ADD     D1Ar5, D1Ar5, #1
 233        SUB     D1Ar3, D1Ar3, #1
 234        SETB    [A0.2++], D0Re0
 235        CMP     D1Ar5, #8
 236        BNE     $Lfdest_unaligned
 237        CMP     D1Ar3, #8
 238        BLT     $Lfbyte_loop
 239$Lfsrc_unaligned:
 240        ! adjust A1.2
 241        LSR     D1Ar5, D1Ar3, #3
 242
 243        MOV     D0Ar4, A1.2
 244        MOV     D0Ar6, A1.2
 245        ANDMB   D0Ar4, D0Ar4, #0xfff8
 246        MOV     A1.2, D0Ar4
 247
 248        ! A0.2 dst 64-bit is aligned
 249        SUB     D0Ar6, D0Ar6, D0Ar4
 250        ! keep the information for the later adjustment
 251        MOVS    D0Ar4, D0Ar6
 252
 253        ! both aligned
 254        BZ      $Lfaligned_loop
 255
 256        ! prefetch
 257        GETL    D0Re0, D1Re0, [A1.2]
 258
 259        CMP     D0Ar6, #4
 260        BLT     $Lfunaligned_1_2_3
 261        BZ      $Lfaligned_4
 262
 263        SUB     D0Ar6, D0Ar6, #4
 264        MULW    D0.6, D0Ar6, #8
 265        MOV     D1.6, #32
 266        SUB     D1.6, D1.6, D0.6
 267
 268$Lfunaligned_5_6_7:
 269        GETL    D0.7, D1.7, [++A1.2]
 270        ! form 64-bit data in D0Re0, D1Re0
 271        MOV     D0Re0, D1Re0
 272        LSR     D0Re0, D0Re0, D0.6
 273        MOV     D1Re0, D0.7
 274        LSL     D1Re0, D1Re0, D1.6
 275        MOV     D0.5, D1Re0
 276        ADD     D0Re0, D0Re0, D0.5
 277
 278        MOV     D0.5, D0.7
 279        LSR     D0.5, D0.5, D0.6
 280        MOV     D1Re0, D1.7
 281        LSL     D1Re0, D1Re0, D1.6
 282        MOV     D1.5, D0.5
 283        ADD     D1Re0, D1Re0, D1.5
 284
 285        SETL    [A0.2++], D0Re0, D1Re0
 286        MOV     D0Re0, D0.7
 287        MOV     D1Re0, D1.7
 288        SUBS    D1Ar5, D1Ar5, #1
 289        BNE     $Lfunaligned_5_6_7
 290
 291        ANDS    D1Ar3, D1Ar3, #7
 292        BZ      $Lfbyte_loop_exit
 293        ! Adjust A1.2
 294        ADD     A1.2, A1.2, D0Ar4
 295        B       $Lfbyte_loop
 296
 297$Lfunaligned_1_2_3:
 298        MULW    D0.6, D0Ar6, #8
 299        MOV     D1.6, #32
 300        SUB     D1.6, D1.6, D0.6
 301
 302$Lfunaligned_1_2_3_loop:
 303        GETL    D0.7, D1.7, [++A1.2]
 304        ! form 64-bit data in D0Re0, D1Re0
 305        LSR     D0Re0, D0Re0, D0.6
 306        MOV     D1.5, D1Re0
 307        LSL     D1Re0, D1Re0, D1.6
 308        MOV     D0.5, D1Re0
 309        ADD     D0Re0, D0Re0, D0.5
 310
 311        MOV     D0.5, D1.5
 312        LSR     D0.5, D0.5, D0.6
 313        MOV     D1Re0, D0.7
 314        LSL     D1Re0, D1Re0, D1.6
 315        MOV     D1.5, D0.5
 316        ADD     D1Re0, D1Re0, D1.5
 317
 318        SETL    [A0.2++], D0Re0, D1Re0
 319        MOV     D0Re0, D0.7
 320        MOV     D1Re0, D1.7
 321        SUBS    D1Ar5, D1Ar5, #1
 322        BNE     $Lfunaligned_1_2_3_loop
 323
 324        ANDS    D1Ar3, D1Ar3, #7
 325        BZ      $Lfbyte_loop_exit
 326        ! Adjust A1.2
 327        ADD     A1.2, A1.2, D0Ar4
 328        B       $Lfbyte_loop
 329
 330$Lfaligned_4:
 331        GETL    D0.7, D1.7, [++A1.2]
 332        MOV     D0Re0, D1Re0
 333        MOV     D1Re0, D0.7
 334        SETL    [A0.2++], D0Re0, D1Re0
 335        MOV     D0Re0, D0.7
 336        MOV     D1Re0, D1.7
 337        SUBS    D1Ar5, D1Ar5, #1
 338        BNE     $Lfaligned_4
 339        ANDS    D1Ar3, D1Ar3, #7
 340        BZ      $Lfbyte_loop_exit
 341        ! Adjust A1.2
 342        ADD     A1.2, A1.2, D0Ar4
 343        B       $Lfbyte_loop
 344
 345        .size _memmove,.-_memmove
 346