Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 1996, 98, 99, 2000, 01 Ralf Baechle
0007  *
0008  * Multi-arch abstraction and asm macros for easier reading:
0009  * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
0010  *
0011  * Carsten Langgaard, carstenl@mips.com
0012  * Copyright (C) 2000 MIPS Technologies, Inc.
0013  * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
0014  */
0015 #include <asm/asm.h>
0016 #include <asm/asmmacro.h>
0017 #include <asm/errno.h>
0018 #include <asm/export.h>
0019 #include <asm/fpregdef.h>
0020 #include <asm/mipsregs.h>
0021 #include <asm/asm-offsets.h>
0022 #include <asm/regdef.h>
0023 
0024 /* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
0025 #undef fp
0026 
0027     .macro  EX insn, reg, src
0028     .set    push
0029     SET_HARDFLOAT
0030     .set    nomacro
0031 .ex\@:  \insn   \reg, \src
0032     .set    pop
0033     .section __ex_table,"a"
0034     PTR_WD  .ex\@, fault
0035     .previous
0036     .endm
0037 
0038 /*
0039  * Save a thread's fp context.
0040  */
0041 LEAF(_save_fp)
0042 EXPORT_SYMBOL(_save_fp)
0043 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
0044     defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
0045     mfc0    t0, CP0_STATUS
0046 #endif
0047     fpu_save_double a0 t0 t1        # clobbers t1
0048     jr  ra
0049     END(_save_fp)
0050 
0051 /*
0052  * Restore a thread's fp context.
0053  */
0054 LEAF(_restore_fp)
0055 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
0056     defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
0057     mfc0    t0, CP0_STATUS
0058 #endif
0059     fpu_restore_double a0 t0 t1     # clobbers t1
0060     jr  ra
0061     END(_restore_fp)
0062 
0063 #ifdef CONFIG_CPU_HAS_MSA
0064 
0065 /*
0066  * Save a thread's MSA vector context.
0067  */
0068 LEAF(_save_msa)
0069 EXPORT_SYMBOL(_save_msa)
0070     msa_save_all    a0
0071     jr  ra
0072     END(_save_msa)
0073 
0074 /*
0075  * Restore a thread's MSA vector context.
0076  */
0077 LEAF(_restore_msa)
0078     msa_restore_all a0
0079     jr  ra
0080     END(_restore_msa)
0081 
0082 LEAF(_init_msa_upper)
0083     msa_init_all_upper
0084     jr  ra
0085     END(_init_msa_upper)
0086 
0087 #endif
0088 
0089     .set    noreorder
0090 
0091 /**
0092  * _save_fp_context() - save FP context from the FPU
0093  * @a0 - pointer to fpregs field of sigcontext
0094  * @a1 - pointer to fpc_csr field of sigcontext
0095  *
0096  * Save FP context, including the 32 FP data registers and the FP
0097  * control & status register, from the FPU to signal context.
0098  */
0099 LEAF(_save_fp_context)
0100     .set    push
0101     SET_HARDFLOAT
0102     cfc1    t1, fcr31
0103     .set    pop
0104 
0105 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
0106     defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
0107     .set    push
0108     SET_HARDFLOAT
0109 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5)
0110     .set    mips32r2
0111     .set    fp=64
0112     mfc0    t0, CP0_STATUS
0113     sll t0, t0, 5
0114     bgez    t0, 1f          # skip storing odd if FR=0
0115      nop
0116 #endif
0117     /* Store the 16 odd double precision registers */
0118     EX  sdc1 $f1, 8(a0)
0119     EX  sdc1 $f3, 24(a0)
0120     EX  sdc1 $f5, 40(a0)
0121     EX  sdc1 $f7, 56(a0)
0122     EX  sdc1 $f9, 72(a0)
0123     EX  sdc1 $f11, 88(a0)
0124     EX  sdc1 $f13, 104(a0)
0125     EX  sdc1 $f15, 120(a0)
0126     EX  sdc1 $f17, 136(a0)
0127     EX  sdc1 $f19, 152(a0)
0128     EX  sdc1 $f21, 168(a0)
0129     EX  sdc1 $f23, 184(a0)
0130     EX  sdc1 $f25, 200(a0)
0131     EX  sdc1 $f27, 216(a0)
0132     EX  sdc1 $f29, 232(a0)
0133     EX  sdc1 $f31, 248(a0)
0134 1:  .set    pop
0135 #endif
0136 
0137     .set push
0138     SET_HARDFLOAT
0139     /* Store the 16 even double precision registers */
0140     EX  sdc1 $f0, 0(a0)
0141     EX  sdc1 $f2, 16(a0)
0142     EX  sdc1 $f4, 32(a0)
0143     EX  sdc1 $f6, 48(a0)
0144     EX  sdc1 $f8, 64(a0)
0145     EX  sdc1 $f10, 80(a0)
0146     EX  sdc1 $f12, 96(a0)
0147     EX  sdc1 $f14, 112(a0)
0148     EX  sdc1 $f16, 128(a0)
0149     EX  sdc1 $f18, 144(a0)
0150     EX  sdc1 $f20, 160(a0)
0151     EX  sdc1 $f22, 176(a0)
0152     EX  sdc1 $f24, 192(a0)
0153     EX  sdc1 $f26, 208(a0)
0154     EX  sdc1 $f28, 224(a0)
0155     EX  sdc1 $f30, 240(a0)
0156     EX  sw t1, 0(a1)
0157     jr  ra
0158      li v0, 0                   # success
0159     .set pop
0160     END(_save_fp_context)
0161 
0162 /**
0163  * _restore_fp_context() - restore FP context to the FPU
0164  * @a0 - pointer to fpregs field of sigcontext
0165  * @a1 - pointer to fpc_csr field of sigcontext
0166  *
0167  * Restore FP context, including the 32 FP data registers and the FP
0168  * control & status register, from signal context to the FPU.
0169  */
0170 LEAF(_restore_fp_context)
0171     EX  lw t1, 0(a1)
0172 
0173 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
0174     defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
0175     .set    push
0176     SET_HARDFLOAT
0177 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5)
0178     .set    mips32r2
0179     .set    fp=64
0180     mfc0    t0, CP0_STATUS
0181     sll t0, t0, 5
0182     bgez    t0, 1f          # skip loading odd if FR=0
0183      nop
0184 #endif
0185     EX  ldc1 $f1, 8(a0)
0186     EX  ldc1 $f3, 24(a0)
0187     EX  ldc1 $f5, 40(a0)
0188     EX  ldc1 $f7, 56(a0)
0189     EX  ldc1 $f9, 72(a0)
0190     EX  ldc1 $f11, 88(a0)
0191     EX  ldc1 $f13, 104(a0)
0192     EX  ldc1 $f15, 120(a0)
0193     EX  ldc1 $f17, 136(a0)
0194     EX  ldc1 $f19, 152(a0)
0195     EX  ldc1 $f21, 168(a0)
0196     EX  ldc1 $f23, 184(a0)
0197     EX  ldc1 $f25, 200(a0)
0198     EX  ldc1 $f27, 216(a0)
0199     EX  ldc1 $f29, 232(a0)
0200     EX  ldc1 $f31, 248(a0)
0201 1:  .set pop
0202 #endif
0203     .set push
0204     SET_HARDFLOAT
0205     EX  ldc1 $f0, 0(a0)
0206     EX  ldc1 $f2, 16(a0)
0207     EX  ldc1 $f4, 32(a0)
0208     EX  ldc1 $f6, 48(a0)
0209     EX  ldc1 $f8, 64(a0)
0210     EX  ldc1 $f10, 80(a0)
0211     EX  ldc1 $f12, 96(a0)
0212     EX  ldc1 $f14, 112(a0)
0213     EX  ldc1 $f16, 128(a0)
0214     EX  ldc1 $f18, 144(a0)
0215     EX  ldc1 $f20, 160(a0)
0216     EX  ldc1 $f22, 176(a0)
0217     EX  ldc1 $f24, 192(a0)
0218     EX  ldc1 $f26, 208(a0)
0219     EX  ldc1 $f28, 224(a0)
0220     EX  ldc1 $f30, 240(a0)
0221     ctc1    t1, fcr31
0222     .set pop
0223     jr  ra
0224      li v0, 0                   # success
0225     END(_restore_fp_context)
0226 
0227 #ifdef CONFIG_CPU_HAS_MSA
0228 
0229     .macro  op_one_wr   op, idx, base
0230     .align  4
0231 \idx:   \op \idx, 0, \base
0232     jr  ra
0233      nop
0234     .endm
0235 
0236     .macro  op_msa_wr   name, op
0237 LEAF(\name)
0238     .set        push
0239     .set        noreorder
0240     sll     t0, a0, 4
0241     PTR_LA      t1, 0f
0242     PTR_ADDU    t0, t0, t1
0243     jr      t0
0244       nop
0245     op_one_wr   \op, 0, a1
0246     op_one_wr   \op, 1, a1
0247     op_one_wr   \op, 2, a1
0248     op_one_wr   \op, 3, a1
0249     op_one_wr   \op, 4, a1
0250     op_one_wr   \op, 5, a1
0251     op_one_wr   \op, 6, a1
0252     op_one_wr   \op, 7, a1
0253     op_one_wr   \op, 8, a1
0254     op_one_wr   \op, 9, a1
0255     op_one_wr   \op, 10, a1
0256     op_one_wr   \op, 11, a1
0257     op_one_wr   \op, 12, a1
0258     op_one_wr   \op, 13, a1
0259     op_one_wr   \op, 14, a1
0260     op_one_wr   \op, 15, a1
0261     op_one_wr   \op, 16, a1
0262     op_one_wr   \op, 17, a1
0263     op_one_wr   \op, 18, a1
0264     op_one_wr   \op, 19, a1
0265     op_one_wr   \op, 20, a1
0266     op_one_wr   \op, 21, a1
0267     op_one_wr   \op, 22, a1
0268     op_one_wr   \op, 23, a1
0269     op_one_wr   \op, 24, a1
0270     op_one_wr   \op, 25, a1
0271     op_one_wr   \op, 26, a1
0272     op_one_wr   \op, 27, a1
0273     op_one_wr   \op, 28, a1
0274     op_one_wr   \op, 29, a1
0275     op_one_wr   \op, 30, a1
0276     op_one_wr   \op, 31, a1
0277     .set        pop
0278     END(\name)
0279     .endm
0280 
0281     op_msa_wr   read_msa_wr_b, st_b
0282     op_msa_wr   read_msa_wr_h, st_h
0283     op_msa_wr   read_msa_wr_w, st_w
0284     op_msa_wr   read_msa_wr_d, st_d
0285 
0286     op_msa_wr   write_msa_wr_b, ld_b
0287     op_msa_wr   write_msa_wr_h, ld_h
0288     op_msa_wr   write_msa_wr_w, ld_w
0289     op_msa_wr   write_msa_wr_d, ld_d
0290 
0291 #endif /* CONFIG_CPU_HAS_MSA */
0292 
0293 #ifdef CONFIG_CPU_HAS_MSA
0294 
0295     .macro  save_msa_upper  wr, off, base
0296     .set    push
0297     .set    noat
0298 #ifdef CONFIG_64BIT
0299     copy_s_d \wr, 1
0300     EX sd   $1, \off(\base)
0301 #elif defined(CONFIG_CPU_LITTLE_ENDIAN)
0302     copy_s_w \wr, 2
0303     EX sw   $1, \off(\base)
0304     copy_s_w \wr, 3
0305     EX sw   $1, (\off+4)(\base)
0306 #else /* CONFIG_CPU_BIG_ENDIAN */
0307     copy_s_w \wr, 2
0308     EX sw   $1, (\off+4)(\base)
0309     copy_s_w \wr, 3
0310     EX sw   $1, \off(\base)
0311 #endif
0312     .set    pop
0313     .endm
0314 
0315 LEAF(_save_msa_all_upper)
0316     save_msa_upper  0, 0x00, a0
0317     save_msa_upper  1, 0x08, a0
0318     save_msa_upper  2, 0x10, a0
0319     save_msa_upper  3, 0x18, a0
0320     save_msa_upper  4, 0x20, a0
0321     save_msa_upper  5, 0x28, a0
0322     save_msa_upper  6, 0x30, a0
0323     save_msa_upper  7, 0x38, a0
0324     save_msa_upper  8, 0x40, a0
0325     save_msa_upper  9, 0x48, a0
0326     save_msa_upper  10, 0x50, a0
0327     save_msa_upper  11, 0x58, a0
0328     save_msa_upper  12, 0x60, a0
0329     save_msa_upper  13, 0x68, a0
0330     save_msa_upper  14, 0x70, a0
0331     save_msa_upper  15, 0x78, a0
0332     save_msa_upper  16, 0x80, a0
0333     save_msa_upper  17, 0x88, a0
0334     save_msa_upper  18, 0x90, a0
0335     save_msa_upper  19, 0x98, a0
0336     save_msa_upper  20, 0xa0, a0
0337     save_msa_upper  21, 0xa8, a0
0338     save_msa_upper  22, 0xb0, a0
0339     save_msa_upper  23, 0xb8, a0
0340     save_msa_upper  24, 0xc0, a0
0341     save_msa_upper  25, 0xc8, a0
0342     save_msa_upper  26, 0xd0, a0
0343     save_msa_upper  27, 0xd8, a0
0344     save_msa_upper  28, 0xe0, a0
0345     save_msa_upper  29, 0xe8, a0
0346     save_msa_upper  30, 0xf0, a0
0347     save_msa_upper  31, 0xf8, a0
0348     jr  ra
0349      li v0, 0
0350     END(_save_msa_all_upper)
0351 
0352     .macro  restore_msa_upper   wr, off, base
0353     .set    push
0354     .set    noat
0355 #ifdef CONFIG_64BIT
0356     EX ld   $1, \off(\base)
0357     insert_d \wr, 1
0358 #elif defined(CONFIG_CPU_LITTLE_ENDIAN)
0359     EX lw   $1, \off(\base)
0360     insert_w \wr, 2
0361     EX lw   $1, (\off+4)(\base)
0362     insert_w \wr, 3
0363 #else /* CONFIG_CPU_BIG_ENDIAN */
0364     EX lw   $1, (\off+4)(\base)
0365     insert_w \wr, 2
0366     EX lw   $1, \off(\base)
0367     insert_w \wr, 3
0368 #endif
0369     .set    pop
0370     .endm
0371 
0372 LEAF(_restore_msa_all_upper)
0373     restore_msa_upper   0, 0x00, a0
0374     restore_msa_upper   1, 0x08, a0
0375     restore_msa_upper   2, 0x10, a0
0376     restore_msa_upper   3, 0x18, a0
0377     restore_msa_upper   4, 0x20, a0
0378     restore_msa_upper   5, 0x28, a0
0379     restore_msa_upper   6, 0x30, a0
0380     restore_msa_upper   7, 0x38, a0
0381     restore_msa_upper   8, 0x40, a0
0382     restore_msa_upper   9, 0x48, a0
0383     restore_msa_upper   10, 0x50, a0
0384     restore_msa_upper   11, 0x58, a0
0385     restore_msa_upper   12, 0x60, a0
0386     restore_msa_upper   13, 0x68, a0
0387     restore_msa_upper   14, 0x70, a0
0388     restore_msa_upper   15, 0x78, a0
0389     restore_msa_upper   16, 0x80, a0
0390     restore_msa_upper   17, 0x88, a0
0391     restore_msa_upper   18, 0x90, a0
0392     restore_msa_upper   19, 0x98, a0
0393     restore_msa_upper   20, 0xa0, a0
0394     restore_msa_upper   21, 0xa8, a0
0395     restore_msa_upper   22, 0xb0, a0
0396     restore_msa_upper   23, 0xb8, a0
0397     restore_msa_upper   24, 0xc0, a0
0398     restore_msa_upper   25, 0xc8, a0
0399     restore_msa_upper   26, 0xd0, a0
0400     restore_msa_upper   27, 0xd8, a0
0401     restore_msa_upper   28, 0xe0, a0
0402     restore_msa_upper   29, 0xe8, a0
0403     restore_msa_upper   30, 0xf0, a0
0404     restore_msa_upper   31, 0xf8, a0
0405     jr  ra
0406      li v0, 0
0407     END(_restore_msa_all_upper)
0408 
0409 #endif /* CONFIG_CPU_HAS_MSA */
0410 
0411     .set    reorder
0412 
0413     .type   fault, @function
0414     .ent    fault
0415 fault:  li  v0, -EFAULT             # failure
0416     jr  ra
0417     .end    fault