From 7129d77bee6e1016f849290dbd5aa33874548486 Mon Sep 17 00:00:00 2001 From: 勤为本 <1207280597@qq.com> Date: Thu, 10 Aug 2017 15:35:03 +0800 Subject: 增加龙芯1c硬浮点的支æŒ�(å�¯ä»¥ä½¿ç”¨ç¡¬æµ®ç‚¹äº†ï¼‰ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/mips/common/mipsregs.h | 90 ++++++++++++++++++++++++++++++ libcpu/mips/loongson_1c/context_gcc.S | 6 ++ libcpu/mips/loongson_1c/stackframe_fpu.h | 94 ++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 libcpu/mips/loongson_1c/stackframe_fpu.h (limited to 'libcpu') diff --git a/libcpu/mips/common/mipsregs.h b/libcpu/mips/common/mipsregs.h index 888d4b13b5..22e5754b8b 100644 --- a/libcpu/mips/common/mipsregs.h +++ b/libcpu/mips/common/mipsregs.h @@ -116,6 +116,70 @@ #define CP1_REVISION $0 #define CP1_STATUS $31 +/* + * FPU Status Register Values + */ +/* + * Status Register Values + */ + +#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */ +#define FPU_CSR_COND 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND0 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND1 0x02000000 /* $fcc1 */ +#define FPU_CSR_COND2 0x04000000 /* $fcc2 */ +#define FPU_CSR_COND3 0x08000000 /* $fcc3 */ +#define FPU_CSR_COND4 0x10000000 /* $fcc4 */ +#define FPU_CSR_COND5 0x20000000 /* $fcc5 */ +#define FPU_CSR_COND6 0x40000000 /* $fcc6 */ +#define FPU_CSR_COND7 0x80000000 /* $fcc7 */ + + +/* FS/FO/FN */ +#define FPU_CSR_FS 0x01000000 +#define FPU_CSR_FO 0x00400000 +#define FPU_CSR_FN 0x00200000 + +/* + * Bits 18 - 20 of the FPU Status Register will be read as 0, + * and should be written as zero. + */ +#define FPU_CSR_RSVD 0x001c0000 + +/* + * X the exception cause indicator + * E the exception enable + * S the sticky/flag bit +*/ +#define FPU_CSR_ALL_X 0x0003f000 +#define FPU_CSR_UNI_X 0x00020000 +#define FPU_CSR_INV_X 0x00010000 +#define FPU_CSR_DIV_X 0x00008000 +#define FPU_CSR_OVF_X 0x00004000 +#define FPU_CSR_UDF_X 0x00002000 +#define FPU_CSR_INE_X 0x00001000 + +#define FPU_CSR_ALL_E 0x00000f80 +#define FPU_CSR_INV_E 0x00000800 +#define FPU_CSR_DIV_E 0x00000400 +#define FPU_CSR_OVF_E 0x00000200 +#define FPU_CSR_UDF_E 0x00000100 +#define FPU_CSR_INE_E 0x00000080 + +#define FPU_CSR_ALL_S 0x0000007c +#define FPU_CSR_INV_S 0x00000040 +#define FPU_CSR_DIV_S 0x00000020 +#define FPU_CSR_OVF_S 0x00000010 +#define FPU_CSR_UDF_S 0x00000008 +#define FPU_CSR_INE_S 0x00000004 + +/* Bits 0 and 1 of FPU Status Register specify the rounding mode */ +#define FPU_CSR_RM 0x00000003 +#define FPU_CSR_RN 0x0 /* nearest */ +#define FPU_CSR_RZ 0x1 /* towards zero */ +#define FPU_CSR_RU 0x2 /* towards +Infinity */ +#define FPU_CSR_RD 0x3 /* towards -Infinity */ + /* * R4x00 interrupt enable / cause bits @@ -610,6 +674,32 @@ do { \ #define write_c0_config3(val) __write_32bit_c0_register($16, 3, val) +/* + * Macros to access the floating point coprocessor control registers + */ +#define read_32bit_cp1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + /* gas fails to assemble cfc1 for some archs (octeon).*/ \ + ".set\tmips1\n\t" \ + "cfc1\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) +#define write_32bit_cp1_register(register, value) \ +do { \ + __asm__ __volatile__( \ + "ctc1\t%z0, "STR(register)"\n\t" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +#define read_c1_status() read_32bit_cp1_register(CP1_STATUS) +#define read_c1_revision() read_32bit_cp1_register(CP1_REVISION); +#define write_c1_status(val) write_32bit_cp1_register(CP1_STATUS, val) + + #endif /* end of __ASSEMBLY__ */ #endif /* end of __MIPSREGS_H__ */ diff --git a/libcpu/mips/loongson_1c/context_gcc.S b/libcpu/mips/loongson_1c/context_gcc.S index 1ac2747747..fbffd34866 100644 --- a/libcpu/mips/loongson_1c/context_gcc.S +++ b/libcpu/mips/loongson_1c/context_gcc.S @@ -16,6 +16,7 @@ #include "../common/mips.inc" #include "../common/stackframe.h" +#include "stackframe_fpu.h" .section ".text", "ax" .set noreorder @@ -56,10 +57,12 @@ rt_hw_interrupt_enable: rt_hw_context_switch: mtc0 ra, CP0_EPC SAVE_ALL + SAVE_FPU sw sp, 0(a0) /* store sp in preempted tasks TCB */ lw sp, 0(a1) /* get new task stack pointer */ + RESTORE_FPU RESTORE_ALL_AND_RET /* @@ -70,6 +73,7 @@ rt_hw_context_switch: rt_hw_context_switch_to: lw sp, 0(a0) /* get new task stack pointer */ + RESTORE_FPU RESTORE_ALL_AND_RET /* @@ -103,6 +107,7 @@ _reswitch: .globl mips_irq_handle mips_irq_handle: SAVE_ALL + SAVE_FPU mfc0 t0, CP0_CAUSE and t1, t0, 0xff @@ -151,6 +156,7 @@ mips_irq_handle: nop spurious_interrupt: + RESTORE_FPU RESTORE_ALL_AND_RET .set reorder diff --git a/libcpu/mips/loongson_1c/stackframe_fpu.h b/libcpu/mips/loongson_1c/stackframe_fpu.h new file mode 100644 index 0000000000..58e9271833 --- /dev/null +++ b/libcpu/mips/loongson_1c/stackframe_fpu.h @@ -0,0 +1,94 @@ +/* + * ls1c FPU's stackframe + * ×ʼ±¾Ï룬½«´úÂë¼ÓÈëµ½stackframe.hÖеÄSAVE_ALL, RESTORE_ALLºÍRESTORE_ALL_AND_RETÖУ¬ + * µ«¿¼Âǵ½Ô´Îļþ"stackframe.h"λÓÚĿ¼"libcpu\mips\common"ÄÚ£¬ÅÂÓ°Ïìµ½ÆäËümips cpu + * ËùÒÔ£¬ÁíÍâн¨±¾Ô´Îļþ + */ +#ifndef __OPENLOONGSON_STACKFRAME_FPU_H +#define __OPENLOONGSON_STACKFRAME_FPU_H + + +#include "../common/asm.h" +#include "../common/mipsregs.h" +#include "../common/stackframe.h" + + + +#define PT_FPU_R0 (0) +#define PT_FPU_R2 ((PT_FPU_R0) + 2*LONGSIZE) +#define PT_FPU_R4 ((PT_FPU_R2) + 2*LONGSIZE) +#define PT_FPU_R6 ((PT_FPU_R4) + 2*LONGSIZE) +#define PT_FPU_R8 ((PT_FPU_R6) + 2*LONGSIZE) +#define PT_FPU_R10 ((PT_FPU_R8) + 2*LONGSIZE) +#define PT_FPU_R12 ((PT_FPU_R10) + 2*LONGSIZE) +#define PT_FPU_R14 ((PT_FPU_R12) + 2*LONGSIZE) +#define PT_FPU_R16 ((PT_FPU_R14) + 2*LONGSIZE) +#define PT_FPU_R18 ((PT_FPU_R16) + 2*LONGSIZE) +#define PT_FPU_R20 ((PT_FPU_R18) + 2*LONGSIZE) +#define PT_FPU_R22 ((PT_FPU_R20) + 2*LONGSIZE) +#define PT_FPU_R24 ((PT_FPU_R22) + 2*LONGSIZE) +#define PT_FPU_R26 ((PT_FPU_R24) + 2*LONGSIZE) +#define PT_FPU_R28 ((PT_FPU_R26) + 2*LONGSIZE) +#define PT_FPU_R30 ((PT_FPU_R28) + 2*LONGSIZE) + +#define PT_FPU_SIZE ((((PT_FPU_R30) + 2*LONGSIZE) + (2*PTRSIZE-1)) & ~(2*PTRSIZE-1)) + + + .macro SAVE_FPU + .set push + .set noreorder + move k1, sp /* ±£´æÏÖ³¡ */ + and k0, k1, 0xFFFFFFF8 /* 8×Ö½Ú¶ÔÆë */ + PTR_SUBU sp, k0, PT_FPU_SIZE /* ¼ÆËãÕ»µ× */ + s.d $f0, PT_FPU_R0(sp) + s.d $f2, PT_FPU_R2(sp) + s.d $f4, PT_FPU_R4(sp) + s.d $f6, PT_FPU_R6(sp) + s.d $f8, PT_FPU_R8(sp) + s.d $f10, PT_FPU_R10(sp) + s.d $f12, PT_FPU_R12(sp) + s.d $f14, PT_FPU_R14(sp) + s.d $f16, PT_FPU_R16(sp) + s.d $f18, PT_FPU_R18(sp) + s.d $f20, PT_FPU_R20(sp) + s.d $f22, PT_FPU_R22(sp) + s.d $f24, PT_FPU_R24(sp) + s.d $f26, PT_FPU_R26(sp) + s.d $f28, PT_FPU_R28(sp) + s.d $f30, PT_FPU_R30(sp) + move sp, k1 /* »Ö¸´ÏÖ³¡ */ + .set reorder + .set pop + .endm + + + .macro RESTORE_FPU + .set push + .set noreorder + move k1, sp /* ±£´æÏÖ³¡ */ + and k0, k1, 0xFFFFFFF8 /* 8×Ö½Ú¶ÔÆë */ + PTR_SUBU sp, k0, PT_FPU_SIZE /* ¼ÆËãÕ»µ×*/ + l.d $f0, PT_FPU_R0(sp) + l.d $f2, PT_FPU_R2(sp) + l.d $f4, PT_FPU_R4(sp) + l.d $f6, PT_FPU_R6(sp) + l.d $f8, PT_FPU_R8(sp) + l.d $f10, PT_FPU_R10(sp) + l.d $f12, PT_FPU_R12(sp) + l.d $f14, PT_FPU_R14(sp) + l.d $f16, PT_FPU_R16(sp) + l.d $f18, PT_FPU_R18(sp) + l.d $f20, PT_FPU_R20(sp) + l.d $f22, PT_FPU_R22(sp) + l.d $f24, PT_FPU_R24(sp) + l.d $f26, PT_FPU_R26(sp) + l.d $f28, PT_FPU_R28(sp) + l.d $f30, PT_FPU_R30(sp) + move sp, k1 /* »Ö¸´ÏÖ³¡ */ + .set reorder + .set pop + .endm + + +#endif + -- cgit v1.3.1