root/arch/mips/kernel/r4k_fpu.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /*
   2  * This file is subject to the terms and conditions of the GNU General Public
   3  * License.  See the file "COPYING" in the main directory of this archive
   4  * for more details.
   5  *
   6  * Copyright (C) 1996, 98, 99, 2000, 01 Ralf Baechle
   7  *
   8  * Multi-arch abstraction and asm macros for easier reading:
   9  * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  10  *
  11  * Carsten Langgaard, carstenl@mips.com
  12  * Copyright (C) 2000 MIPS Technologies, Inc.
  13  * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
  14  */
  15 #include <asm/asm.h>
  16 #include <asm/asmmacro.h>
  17 #include <asm/errno.h>
  18 #include <asm/export.h>
  19 #include <asm/fpregdef.h>
  20 #include <asm/mipsregs.h>
  21 #include <asm/asm-offsets.h>
  22 #include <asm/regdef.h>
  23 
  24 /* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
  25 #undef fp
  26 
  27         .macro  EX insn, reg, src
  28         .set    push
  29         SET_HARDFLOAT
  30         .set    nomacro
  31 .ex\@:  \insn   \reg, \src
  32         .set    pop
  33         .section __ex_table,"a"
  34         PTR     .ex\@, fault
  35         .previous
  36         .endm
  37 
  38 /*
  39  * Save a thread's fp context.
  40  */
  41 LEAF(_save_fp)
  42 EXPORT_SYMBOL(_save_fp)
  43 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
  44                 defined(CONFIG_CPU_MIPSR6)
  45         mfc0    t0, CP0_STATUS
  46 #endif
  47         fpu_save_double a0 t0 t1                # clobbers t1
  48         jr      ra
  49         END(_save_fp)
  50 
  51 /*
  52  * Restore a thread's fp context.
  53  */
  54 LEAF(_restore_fp)
  55 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
  56                 defined(CONFIG_CPU_MIPSR6)
  57         mfc0    t0, CP0_STATUS
  58 #endif
  59         fpu_restore_double a0 t0 t1             # clobbers t1
  60         jr      ra
  61         END(_restore_fp)
  62 
  63 #ifdef CONFIG_CPU_HAS_MSA
  64 
  65 /*
  66  * Save a thread's MSA vector context.
  67  */
  68 LEAF(_save_msa)
  69 EXPORT_SYMBOL(_save_msa)
  70         msa_save_all    a0
  71         jr      ra
  72         END(_save_msa)
  73 
  74 /*
  75  * Restore a thread's MSA vector context.
  76  */
  77 LEAF(_restore_msa)
  78         msa_restore_all a0
  79         jr      ra
  80         END(_restore_msa)
  81 
  82 LEAF(_init_msa_upper)
  83         msa_init_all_upper
  84         jr      ra
  85         END(_init_msa_upper)
  86 
  87 #endif
  88 
  89         .set    noreorder
  90 
  91 /**
  92  * _save_fp_context() - save FP context from the FPU
  93  * @a0 - pointer to fpregs field of sigcontext
  94  * @a1 - pointer to fpc_csr field of sigcontext
  95  *
  96  * Save FP context, including the 32 FP data registers and the FP
  97  * control & status register, from the FPU to signal context.
  98  */
  99 LEAF(_save_fp_context)
 100         .set    push
 101         SET_HARDFLOAT
 102         cfc1    t1, fcr31
 103         .set    pop
 104 
 105 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
 106                 defined(CONFIG_CPU_MIPSR6)
 107         .set    push
 108         SET_HARDFLOAT
 109 #ifdef CONFIG_CPU_MIPSR2
 110         .set    mips32r2
 111         .set    fp=64
 112         mfc0    t0, CP0_STATUS
 113         sll     t0, t0, 5
 114         bgez    t0, 1f                  # skip storing odd if FR=0
 115          nop
 116 #endif
 117         /* Store the 16 odd double precision registers */
 118         EX      sdc1 $f1, 8(a0)
 119         EX      sdc1 $f3, 24(a0)
 120         EX      sdc1 $f5, 40(a0)
 121         EX      sdc1 $f7, 56(a0)
 122         EX      sdc1 $f9, 72(a0)
 123         EX      sdc1 $f11, 88(a0)
 124         EX      sdc1 $f13, 104(a0)
 125         EX      sdc1 $f15, 120(a0)
 126         EX      sdc1 $f17, 136(a0)
 127         EX      sdc1 $f19, 152(a0)
 128         EX      sdc1 $f21, 168(a0)
 129         EX      sdc1 $f23, 184(a0)
 130         EX      sdc1 $f25, 200(a0)
 131         EX      sdc1 $f27, 216(a0)
 132         EX      sdc1 $f29, 232(a0)
 133         EX      sdc1 $f31, 248(a0)
 134 1:      .set    pop
 135 #endif
 136 
 137         .set push
 138         SET_HARDFLOAT
 139         /* Store the 16 even double precision registers */
 140         EX      sdc1 $f0, 0(a0)
 141         EX      sdc1 $f2, 16(a0)
 142         EX      sdc1 $f4, 32(a0)
 143         EX      sdc1 $f6, 48(a0)
 144         EX      sdc1 $f8, 64(a0)
 145         EX      sdc1 $f10, 80(a0)
 146         EX      sdc1 $f12, 96(a0)
 147         EX      sdc1 $f14, 112(a0)
 148         EX      sdc1 $f16, 128(a0)
 149         EX      sdc1 $f18, 144(a0)
 150         EX      sdc1 $f20, 160(a0)
 151         EX      sdc1 $f22, 176(a0)
 152         EX      sdc1 $f24, 192(a0)
 153         EX      sdc1 $f26, 208(a0)
 154         EX      sdc1 $f28, 224(a0)
 155         EX      sdc1 $f30, 240(a0)
 156         EX      sw t1, 0(a1)
 157         jr      ra
 158          li     v0, 0                                   # success
 159         .set pop
 160         END(_save_fp_context)
 161 
 162 /**
 163  * _restore_fp_context() - restore FP context to the FPU
 164  * @a0 - pointer to fpregs field of sigcontext
 165  * @a1 - pointer to fpc_csr field of sigcontext
 166  *
 167  * Restore FP context, including the 32 FP data registers and the FP
 168  * control & status register, from signal context to the FPU.
 169  */
 170 LEAF(_restore_fp_context)
 171         EX      lw t1, 0(a1)
 172 
 173 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2)  || \
 174                 defined(CONFIG_CPU_MIPSR6)
 175         .set    push
 176         SET_HARDFLOAT
 177 #ifdef CONFIG_CPU_MIPSR2
 178         .set    mips32r2
 179         .set    fp=64
 180         mfc0    t0, CP0_STATUS
 181         sll     t0, t0, 5
 182         bgez    t0, 1f                  # skip loading odd if FR=0
 183          nop
 184 #endif
 185         EX      ldc1 $f1, 8(a0)
 186         EX      ldc1 $f3, 24(a0)
 187         EX      ldc1 $f5, 40(a0)
 188         EX      ldc1 $f7, 56(a0)
 189         EX      ldc1 $f9, 72(a0)
 190         EX      ldc1 $f11, 88(a0)
 191         EX      ldc1 $f13, 104(a0)
 192         EX      ldc1 $f15, 120(a0)
 193         EX      ldc1 $f17, 136(a0)
 194         EX      ldc1 $f19, 152(a0)
 195         EX      ldc1 $f21, 168(a0)
 196         EX      ldc1 $f23, 184(a0)
 197         EX      ldc1 $f25, 200(a0)
 198         EX      ldc1 $f27, 216(a0)
 199         EX      ldc1 $f29, 232(a0)
 200         EX      ldc1 $f31, 248(a0)
 201 1:      .set pop
 202 #endif
 203         .set push
 204         SET_HARDFLOAT
 205         EX      ldc1 $f0, 0(a0)
 206         EX      ldc1 $f2, 16(a0)
 207         EX      ldc1 $f4, 32(a0)
 208         EX      ldc1 $f6, 48(a0)
 209         EX      ldc1 $f8, 64(a0)
 210         EX      ldc1 $f10, 80(a0)
 211         EX      ldc1 $f12, 96(a0)
 212         EX      ldc1 $f14, 112(a0)
 213         EX      ldc1 $f16, 128(a0)
 214         EX      ldc1 $f18, 144(a0)
 215         EX      ldc1 $f20, 160(a0)
 216         EX      ldc1 $f22, 176(a0)
 217         EX      ldc1 $f24, 192(a0)
 218         EX      ldc1 $f26, 208(a0)
 219         EX      ldc1 $f28, 224(a0)
 220         EX      ldc1 $f30, 240(a0)
 221         ctc1    t1, fcr31
 222         .set pop
 223         jr      ra
 224          li     v0, 0                                   # success
 225         END(_restore_fp_context)
 226 
 227 #ifdef CONFIG_CPU_HAS_MSA
 228 
 229         .macro  op_one_wr       op, idx, base
 230         .align  4
 231 \idx:   \op     \idx, 0, \base
 232         jr      ra
 233          nop
 234         .endm
 235 
 236         .macro  op_msa_wr       name, op
 237 LEAF(\name)
 238         .set            push
 239         .set            noreorder
 240         sll             t0, a0, 4
 241         PTR_LA          t1, 0f
 242         PTR_ADDU        t0, t0, t1
 243         jr              t0
 244           nop
 245         op_one_wr       \op, 0, a1
 246         op_one_wr       \op, 1, a1
 247         op_one_wr       \op, 2, a1
 248         op_one_wr       \op, 3, a1
 249         op_one_wr       \op, 4, a1
 250         op_one_wr       \op, 5, a1
 251         op_one_wr       \op, 6, a1
 252         op_one_wr       \op, 7, a1
 253         op_one_wr       \op, 8, a1
 254         op_one_wr       \op, 9, a1
 255         op_one_wr       \op, 10, a1
 256         op_one_wr       \op, 11, a1
 257         op_one_wr       \op, 12, a1
 258         op_one_wr       \op, 13, a1
 259         op_one_wr       \op, 14, a1
 260         op_one_wr       \op, 15, a1
 261         op_one_wr       \op, 16, a1
 262         op_one_wr       \op, 17, a1
 263         op_one_wr       \op, 18, a1
 264         op_one_wr       \op, 19, a1
 265         op_one_wr       \op, 20, a1
 266         op_one_wr       \op, 21, a1
 267         op_one_wr       \op, 22, a1
 268         op_one_wr       \op, 23, a1
 269         op_one_wr       \op, 24, a1
 270         op_one_wr       \op, 25, a1
 271         op_one_wr       \op, 26, a1
 272         op_one_wr       \op, 27, a1
 273         op_one_wr       \op, 28, a1
 274         op_one_wr       \op, 29, a1
 275         op_one_wr       \op, 30, a1
 276         op_one_wr       \op, 31, a1
 277         .set            pop
 278         END(\name)
 279         .endm
 280 
 281         op_msa_wr       read_msa_wr_b, st_b
 282         op_msa_wr       read_msa_wr_h, st_h
 283         op_msa_wr       read_msa_wr_w, st_w
 284         op_msa_wr       read_msa_wr_d, st_d
 285 
 286         op_msa_wr       write_msa_wr_b, ld_b
 287         op_msa_wr       write_msa_wr_h, ld_h
 288         op_msa_wr       write_msa_wr_w, ld_w
 289         op_msa_wr       write_msa_wr_d, ld_d
 290 
 291 #endif /* CONFIG_CPU_HAS_MSA */
 292 
 293 #ifdef CONFIG_CPU_HAS_MSA
 294 
 295         .macro  save_msa_upper  wr, off, base
 296         .set    push
 297         .set    noat
 298 #ifdef CONFIG_64BIT
 299         copy_s_d \wr, 1
 300         EX sd   $1, \off(\base)
 301 #elif defined(CONFIG_CPU_LITTLE_ENDIAN)
 302         copy_s_w \wr, 2
 303         EX sw   $1, \off(\base)
 304         copy_s_w \wr, 3
 305         EX sw   $1, (\off+4)(\base)
 306 #else /* CONFIG_CPU_BIG_ENDIAN */
 307         copy_s_w \wr, 2
 308         EX sw   $1, (\off+4)(\base)
 309         copy_s_w \wr, 3
 310         EX sw   $1, \off(\base)
 311 #endif
 312         .set    pop
 313         .endm
 314 
 315 LEAF(_save_msa_all_upper)
 316         save_msa_upper  0, 0x00, a0
 317         save_msa_upper  1, 0x08, a0
 318         save_msa_upper  2, 0x10, a0
 319         save_msa_upper  3, 0x18, a0
 320         save_msa_upper  4, 0x20, a0
 321         save_msa_upper  5, 0x28, a0
 322         save_msa_upper  6, 0x30, a0
 323         save_msa_upper  7, 0x38, a0
 324         save_msa_upper  8, 0x40, a0
 325         save_msa_upper  9, 0x48, a0
 326         save_msa_upper  10, 0x50, a0
 327         save_msa_upper  11, 0x58, a0
 328         save_msa_upper  12, 0x60, a0
 329         save_msa_upper  13, 0x68, a0
 330         save_msa_upper  14, 0x70, a0
 331         save_msa_upper  15, 0x78, a0
 332         save_msa_upper  16, 0x80, a0
 333         save_msa_upper  17, 0x88, a0
 334         save_msa_upper  18, 0x90, a0
 335         save_msa_upper  19, 0x98, a0
 336         save_msa_upper  20, 0xa0, a0
 337         save_msa_upper  21, 0xa8, a0
 338         save_msa_upper  22, 0xb0, a0
 339         save_msa_upper  23, 0xb8, a0
 340         save_msa_upper  24, 0xc0, a0
 341         save_msa_upper  25, 0xc8, a0
 342         save_msa_upper  26, 0xd0, a0
 343         save_msa_upper  27, 0xd8, a0
 344         save_msa_upper  28, 0xe0, a0
 345         save_msa_upper  29, 0xe8, a0
 346         save_msa_upper  30, 0xf0, a0
 347         save_msa_upper  31, 0xf8, a0
 348         jr      ra
 349          li     v0, 0
 350         END(_save_msa_all_upper)
 351 
 352         .macro  restore_msa_upper       wr, off, base
 353         .set    push
 354         .set    noat
 355 #ifdef CONFIG_64BIT
 356         EX ld   $1, \off(\base)
 357         insert_d \wr, 1
 358 #elif defined(CONFIG_CPU_LITTLE_ENDIAN)
 359         EX lw   $1, \off(\base)
 360         insert_w \wr, 2
 361         EX lw   $1, (\off+4)(\base)
 362         insert_w \wr, 3
 363 #else /* CONFIG_CPU_BIG_ENDIAN */
 364         EX lw   $1, (\off+4)(\base)
 365         insert_w \wr, 2
 366         EX lw   $1, \off(\base)
 367         insert_w \wr, 3
 368 #endif
 369         .set    pop
 370         .endm
 371 
 372 LEAF(_restore_msa_all_upper)
 373         restore_msa_upper       0, 0x00, a0
 374         restore_msa_upper       1, 0x08, a0
 375         restore_msa_upper       2, 0x10, a0
 376         restore_msa_upper       3, 0x18, a0
 377         restore_msa_upper       4, 0x20, a0
 378         restore_msa_upper       5, 0x28, a0
 379         restore_msa_upper       6, 0x30, a0
 380         restore_msa_upper       7, 0x38, a0
 381         restore_msa_upper       8, 0x40, a0
 382         restore_msa_upper       9, 0x48, a0
 383         restore_msa_upper       10, 0x50, a0
 384         restore_msa_upper       11, 0x58, a0
 385         restore_msa_upper       12, 0x60, a0
 386         restore_msa_upper       13, 0x68, a0
 387         restore_msa_upper       14, 0x70, a0
 388         restore_msa_upper       15, 0x78, a0
 389         restore_msa_upper       16, 0x80, a0
 390         restore_msa_upper       17, 0x88, a0
 391         restore_msa_upper       18, 0x90, a0
 392         restore_msa_upper       19, 0x98, a0
 393         restore_msa_upper       20, 0xa0, a0
 394         restore_msa_upper       21, 0xa8, a0
 395         restore_msa_upper       22, 0xb0, a0
 396         restore_msa_upper       23, 0xb8, a0
 397         restore_msa_upper       24, 0xc0, a0
 398         restore_msa_upper       25, 0xc8, a0
 399         restore_msa_upper       26, 0xd0, a0
 400         restore_msa_upper       27, 0xd8, a0
 401         restore_msa_upper       28, 0xe0, a0
 402         restore_msa_upper       29, 0xe8, a0
 403         restore_msa_upper       30, 0xf0, a0
 404         restore_msa_upper       31, 0xf8, a0
 405         jr      ra
 406          li     v0, 0
 407         END(_restore_msa_all_upper)
 408 
 409 #endif /* CONFIG_CPU_HAS_MSA */
 410 
 411         .set    reorder
 412 
 413         .type   fault, @function
 414         .ent    fault
 415 fault:  li      v0, -EFAULT                             # failure
 416         jr      ra
 417         .end    fault

/* [<][>][^][v][top][bottom][index][help] */