linux/arch/powerpc/lib/ldstfp.S
<<
>>
Prefs
   1/*
   2 * Floating-point, VMX/Altivec and VSX loads and stores
   3 * for use in instruction emulation.
   4 *
   5 * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
   6 *
   7 *  This program is free software; you can redistribute it and/or
   8 *  modify it under the terms of the GNU General Public License
   9 *  as published by the Free Software Foundation; either version
  10 *  2 of the License, or (at your option) any later version.
  11 */
  12
  13#include <asm/processor.h>
  14#include <asm/ppc_asm.h>
  15#include <asm/ppc-opcode.h>
  16#include <asm/reg.h>
  17#include <asm/asm-offsets.h>
  18#include <linux/errno.h>
  19
  20#ifdef CONFIG_PPC_FPU
  21
  22#define STKFRM  (PPC_MIN_STKFRM + 16)
  23
  24        .macro  extab   instr,handler
  25        .section __ex_table,"a"
  26        PPC_LONG \instr,\handler
  27        .previous
  28        .endm
  29
  30        .macro  inst32  op
  31reg = 0
  32        .rept   32
  3320:     \op     reg,0,r4
  34        b       3f
  35        extab   20b,99f
  36reg = reg + 1
  37        .endr
  38        .endm
  39
  40/* Get the contents of frN into fr0; N is in r3. */
  41_GLOBAL(get_fpr)
  42        mflr    r0
  43        rlwinm  r3,r3,3,0xf8
  44        bcl     20,31,1f
  45        blr                     /* fr0 is already in fr0 */
  46        nop
  47reg = 1
  48        .rept   31
  49        fmr     fr0,reg
  50        blr
  51reg = reg + 1
  52        .endr
  531:      mflr    r5
  54        add     r5,r3,r5
  55        mtctr   r5
  56        mtlr    r0
  57        bctr
  58
  59/* Put the contents of fr0 into frN; N is in r3. */
  60_GLOBAL(put_fpr)
  61        mflr    r0
  62        rlwinm  r3,r3,3,0xf8
  63        bcl     20,31,1f
  64        blr                     /* fr0 is already in fr0 */
  65        nop
  66reg = 1
  67        .rept   31
  68        fmr     reg,fr0
  69        blr
  70reg = reg + 1
  71        .endr
  721:      mflr    r5
  73        add     r5,r3,r5
  74        mtctr   r5
  75        mtlr    r0
  76        bctr
  77
  78/* Load FP reg N from float at *p.  N is in r3, p in r4. */
  79_GLOBAL(do_lfs)
  80        PPC_STLU r1,-STKFRM(r1)
  81        mflr    r0
  82        PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
  83        mfmsr   r6
  84        ori     r7,r6,MSR_FP
  85        cmpwi   cr7,r3,0
  86        MTMSRD(r7)
  87        isync
  88        beq     cr7,1f
  89        stfd    fr0,STKFRM-16(r1)
  901:      li      r9,-EFAULT
  912:      lfs     fr0,0(r4)
  92        li      r9,0
  933:      bl      put_fpr
  94        beq     cr7,4f
  95        lfd     fr0,STKFRM-16(r1)
  964:      PPC_LL  r0,STKFRM+PPC_LR_STKOFF(r1)
  97        mtlr    r0
  98        MTMSRD(r6)
  99        isync
 100        mr      r3,r9
 101        addi    r1,r1,STKFRM
 102        blr
 103        extab   2b,3b
 104
 105/* Load FP reg N from double at *p.  N is in r3, p in r4. */
 106_GLOBAL(do_lfd)
 107        PPC_STLU r1,-STKFRM(r1)
 108        mflr    r0
 109        PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
 110        mfmsr   r6
 111        ori     r7,r6,MSR_FP
 112        cmpwi   cr7,r3,0
 113        MTMSRD(r7)
 114        isync
 115        beq     cr7,1f
 116        stfd    fr0,STKFRM-16(r1)
 1171:      li      r9,-EFAULT
 1182:      lfd     fr0,0(r4)
 119        li      r9,0
 1203:      beq     cr7,4f
 121        bl      put_fpr
 122        lfd     fr0,STKFRM-16(r1)
 1234:      PPC_LL  r0,STKFRM+PPC_LR_STKOFF(r1)
 124        mtlr    r0
 125        MTMSRD(r6)
 126        isync
 127        mr      r3,r9
 128        addi    r1,r1,STKFRM
 129        blr
 130        extab   2b,3b
 131
 132/* Store FP reg N to float at *p.  N is in r3, p in r4. */
 133_GLOBAL(do_stfs)
 134        PPC_STLU r1,-STKFRM(r1)
 135        mflr    r0
 136        PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
 137        mfmsr   r6
 138        ori     r7,r6,MSR_FP
 139        cmpwi   cr7,r3,0
 140        MTMSRD(r7)
 141        isync
 142        beq     cr7,1f
 143        stfd    fr0,STKFRM-16(r1)
 144        bl      get_fpr
 1451:      li      r9,-EFAULT
 1462:      stfs    fr0,0(r4)
 147        li      r9,0
 1483:      beq     cr7,4f
 149        lfd     fr0,STKFRM-16(r1)
 1504:      PPC_LL  r0,STKFRM+PPC_LR_STKOFF(r1)
 151        mtlr    r0
 152        MTMSRD(r6)
 153        isync
 154        mr      r3,r9
 155        addi    r1,r1,STKFRM
 156        blr
 157        extab   2b,3b
 158
 159/* Store FP reg N to double at *p.  N is in r3, p in r4. */
 160_GLOBAL(do_stfd)
 161        PPC_STLU r1,-STKFRM(r1)
 162        mflr    r0
 163        PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
 164        mfmsr   r6
 165        ori     r7,r6,MSR_FP
 166        cmpwi   cr7,r3,0
 167        MTMSRD(r7)
 168        isync
 169        beq     cr7,1f
 170        stfd    fr0,STKFRM-16(r1)
 171        bl      get_fpr
 1721:      li      r9,-EFAULT
 1732:      stfd    fr0,0(r4)
 174        li      r9,0
 1753:      beq     cr7,4f
 176        lfd     fr0,STKFRM-16(r1)
 1774:      PPC_LL  r0,STKFRM+PPC_LR_STKOFF(r1)
 178        mtlr    r0
 179        MTMSRD(r6)
 180        isync
 181        mr      r3,r9
 182        addi    r1,r1,STKFRM
 183        blr
 184        extab   2b,3b
 185
 186#ifdef CONFIG_ALTIVEC
 187/* Get the contents of vrN into vr0; N is in r3. */
 188_GLOBAL(get_vr)
 189        mflr    r0
 190        rlwinm  r3,r3,3,0xf8
 191        bcl     20,31,1f
 192        blr                     /* vr0 is already in vr0 */
 193        nop
 194reg = 1
 195        .rept   31
 196        vor     vr0,reg,reg     /* assembler doesn't know vmr? */
 197        blr
 198reg = reg + 1
 199        .endr
 2001:      mflr    r5
 201        add     r5,r3,r5
 202        mtctr   r5
 203        mtlr    r0
 204        bctr
 205
 206/* Put the contents of vr0 into vrN; N is in r3. */
 207_GLOBAL(put_vr)
 208        mflr    r0
 209        rlwinm  r3,r3,3,0xf8
 210        bcl     20,31,1f
 211        blr                     /* vr0 is already in vr0 */
 212        nop
 213reg = 1
 214        .rept   31
 215        vor     reg,vr0,vr0
 216        blr
 217reg = reg + 1
 218        .endr
 2191:      mflr    r5
 220        add     r5,r3,r5
 221        mtctr   r5
 222        mtlr    r0
 223        bctr
 224
 225/* Load vector reg N from *p.  N is in r3, p in r4. */
 226_GLOBAL(do_lvx)
 227        PPC_STLU r1,-STKFRM(r1)
 228        mflr    r0
 229        PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
 230        mfmsr   r6
 231        oris    r7,r6,MSR_VEC@h
 232        cmpwi   cr7,r3,0
 233        li      r8,STKFRM-16
 234        MTMSRD(r7)
 235        isync
 236        beq     cr7,1f
 237        stvx    vr0,r1,r8
 2381:      li      r9,-EFAULT
 2392:      lvx     vr0,0,r4
 240        li      r9,0
 2413:      beq     cr7,4f
 242        bl      put_vr
 243        lvx     vr0,r1,r8
 2444:      PPC_LL  r0,STKFRM+PPC_LR_STKOFF(r1)
 245        mtlr    r0
 246        MTMSRD(r6)
 247        isync
 248        mr      r3,r9
 249        addi    r1,r1,STKFRM
 250        blr
 251        extab   2b,3b
 252
 253/* Store vector reg N to *p.  N is in r3, p in r4. */
 254_GLOBAL(do_stvx)
 255        PPC_STLU r1,-STKFRM(r1)
 256        mflr    r0
 257        PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
 258        mfmsr   r6
 259        oris    r7,r6,MSR_VEC@h
 260        cmpwi   cr7,r3,0
 261        li      r8,STKFRM-16
 262        MTMSRD(r7)
 263        isync
 264        beq     cr7,1f
 265        stvx    vr0,r1,r8
 266        bl      get_vr
 2671:      li      r9,-EFAULT
 2682:      stvx    vr0,0,r4
 269        li      r9,0
 2703:      beq     cr7,4f
 271        lvx     vr0,r1,r8
 2724:      PPC_LL  r0,STKFRM+PPC_LR_STKOFF(r1)
 273        mtlr    r0
 274        MTMSRD(r6)
 275        isync
 276        mr      r3,r9
 277        addi    r1,r1,STKFRM
 278        blr
 279        extab   2b,3b
 280#endif /* CONFIG_ALTIVEC */
 281
 282#ifdef CONFIG_VSX
 283/* Get the contents of vsrN into vsr0; N is in r3. */
 284_GLOBAL(get_vsr)
 285        mflr    r0
 286        rlwinm  r3,r3,3,0x1f8
 287        bcl     20,31,1f
 288        blr                     /* vsr0 is already in vsr0 */
 289        nop
 290reg = 1
 291        .rept   63
 292        XXLOR(0,reg,reg)
 293        blr
 294reg = reg + 1
 295        .endr
 2961:      mflr    r5
 297        add     r5,r3,r5
 298        mtctr   r5
 299        mtlr    r0
 300        bctr
 301
 302/* Put the contents of vsr0 into vsrN; N is in r3. */
 303_GLOBAL(put_vsr)
 304        mflr    r0
 305        rlwinm  r3,r3,3,0x1f8
 306        bcl     20,31,1f
 307        blr                     /* vr0 is already in vr0 */
 308        nop
 309reg = 1
 310        .rept   63
 311        XXLOR(reg,0,0)
 312        blr
 313reg = reg + 1
 314        .endr
 3151:      mflr    r5
 316        add     r5,r3,r5
 317        mtctr   r5
 318        mtlr    r0
 319        bctr
 320
 321/* Load VSX reg N from vector doubleword *p.  N is in r3, p in r4. */
 322_GLOBAL(do_lxvd2x)
 323        PPC_STLU r1,-STKFRM(r1)
 324        mflr    r0
 325        PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
 326        mfmsr   r6
 327        oris    r7,r6,MSR_VSX@h
 328        cmpwi   cr7,r3,0
 329        li      r8,STKFRM-16
 330        MTMSRD(r7)
 331        isync
 332        beq     cr7,1f
 333        STXVD2X(0,r1,r8)
 3341:      li      r9,-EFAULT
 3352:      LXVD2X(0,0,r4)
 336        li      r9,0
 3373:      beq     cr7,4f
 338        bl      put_vsr
 339        LXVD2X(0,r1,r8)
 3404:      PPC_LL  r0,STKFRM+PPC_LR_STKOFF(r1)
 341        mtlr    r0
 342        MTMSRD(r6)
 343        isync
 344        mr      r3,r9
 345        addi    r1,r1,STKFRM
 346        blr
 347        extab   2b,3b
 348
 349/* Store VSX reg N to vector doubleword *p.  N is in r3, p in r4. */
 350_GLOBAL(do_stxvd2x)
 351        PPC_STLU r1,-STKFRM(r1)
 352        mflr    r0
 353        PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
 354        mfmsr   r6
 355        oris    r7,r6,MSR_VSX@h
 356        cmpwi   cr7,r3,0
 357        li      r8,STKFRM-16
 358        MTMSRD(r7)
 359        isync
 360        beq     cr7,1f
 361        STXVD2X(0,r1,r8)
 362        bl      get_vsr
 3631:      li      r9,-EFAULT
 3642:      STXVD2X(0,0,r4)
 365        li      r9,0
 3663:      beq     cr7,4f
 367        LXVD2X(0,r1,r8)
 3684:      PPC_LL  r0,STKFRM+PPC_LR_STKOFF(r1)
 369        mtlr    r0
 370        MTMSRD(r6)
 371        isync
 372        mr      r3,r9
 373        addi    r1,r1,STKFRM
 374        blr
 375        extab   2b,3b
 376
 377#endif /* CONFIG_VSX */
 378
 379#endif  /* CONFIG_PPC_FPU */
 380