Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/Makefile.core
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/Makefile.core	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/Makefile.core	(revision 374)
@@ -55,3 +55,3 @@
 	$(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
 
-LDFLAGS := -nostdlib $(LDFLAGS)
+LDFLAGS := -nodefaultlibs $(LDFLAGS)
Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/arm.h
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/arm.h	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/arm.h	(revision 374)
@@ -5,5 +5,5 @@
  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
  *                              Toyohashi Univ. of Technology, JAPAN
- *  Copyright (C) 2006-2016 by Embedded and Real-Time Systems Laboratory
+ *  Copyright (C) 2006-2018 by Embedded and Real-Time Systems Laboratory
  *              Graduate School of Information Science, Nagoya Univ., JAPAN
  * 
@@ -119,4 +119,12 @@
 
 /*
+ *  CP15のコプロセッサアクセス制御レジスタ（CPACR）の設定値
+ */
+#define CP15_CPACR_ASEDIS			UINT_C(0x80000000)
+#define CP15_CPACR_D32DIS			UINT_C(0x40000000)
+#define CP15_CPACR_CP11_FULLACCESS	UINT_C(0x00c00000)
+#define CP15_CPACR_CP10_FULLACCESS	UINT_C(0x00300000)
+
+/*
  *  CP15のフォールト状態レジスタの参照値
  */
@@ -444,3 +452,9 @@
 
 #endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  浮動小数点例外制御レジスタ（FPEXC）の設定値
+ */
+#define FPEXC_ENABLE		UINT_C(0x40000000)
+
 #endif /* TOPPERS_ARM_H */
Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/arm_insn.h
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/arm_insn.h	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/arm_insn.h	(revision 374)
@@ -5,5 +5,5 @@
  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
  *                              Toyohashi Univ. of Technology, JAPAN
- *  Copyright (C) 2006-2017 by Embedded and Real-Time Systems Laboratory
+ *  Copyright (C) 2006-2018 by Embedded and Real-Time Systems Laboratory
  *              Graduate School of Information Science, Nagoya Univ., JAPAN
  * 
@@ -227,4 +227,8 @@
 #define CP15_WRITE_ACTLR(reg)	Asm("mcr p15, 0, %0, c1, c0, 1"::"r"(reg))
 
+/* コプロセッサアクセス制御レジスタ */
+#define CP15_READ_CPACR(reg)	Asm("mrc p15, 0, %0, c1, c0, 2":"=r"(reg))
+#define CP15_WRITE_CPACR(reg)	Asm("mcr p15, 0, %0, c1, c0, 2"::"r"(reg))
+
 /*
  *  CP15によるキャッシュ操作マクロ
@@ -421,3 +425,25 @@
 
 #endif /* __TARGET_ARCH_ARM == 7 */
+
+/*
+ *  浮動小数点例外制御レジスタ（FPEXC）の現在値の読出し
+ */
+Inline uint32_t
+current_fpexc(void)
+{
+	uint32_t	fpexc;
+
+	Asm("vmrs %0, fpexc" : "=r"(fpexc));
+	return(fpexc);
+}
+
+/*
+ *  浮動小数点例外制御レジスタ（FPEXC）の現在値の変更
+ */
+Inline void
+set_fpexc(uint32_t fpexc)
+{
+	Asm("vmsr fpexc, %0" : : "r"(fpexc));
+}
+
 #endif /* TOPPERS_ARM_INSN_H */
Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_check.trb
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_check.trb	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_check.trb	(revision 374)
@@ -19,6 +19,7 @@
 #
 inhTable = SYMBOL("_kernel_inh_table")
+offset = SYMBOL("__etext") - SYMBOL("__data_start__")
 $cfgData[:DEF_INH].each do |key, params|
-  inthdr = PEEK(inhTable + params[:inhno] * $sizeof_FP, $sizeof_FP)
+  inthdr = PEEK(inhTable + offset + params[:inhno] * $sizeof_FP, $sizeof_FP)
 
   #	割込みハンドラの先頭番地のチェック［NGKI3056］
Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel.h
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel.h	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel.h	(revision 374)
@@ -6,5 +6,5 @@
  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
  *                              Toyohashi Univ. of Technology, JAPAN
- *  Copyright (C) 2004-2016 by Embedded and Real-Time Systems Laboratory
+ *  Copyright (C) 2004-2018 by Embedded and Real-Time Systems Laboratory
  *              Graduate School of Information Science, Nagoya Univ., JAPAN
  * 
@@ -51,4 +51,9 @@
 #ifndef TOPPERS_CORE_KERNEL_H
 #define TOPPERS_CORE_KERNEL_H
+
+/*
+ *  ターゲット定義のタスク属性
+ */
+#define TA_FPU		UINT_C(0x08)	/* FPUレジスタをコンテキストに含める */
 
 /*
Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel.trb
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel.trb	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel.trb	(revision 374)
@@ -65,5 +65,5 @@
 $kernelCfgC.comment_header("Interrupt Handler Table")
 
-$kernelCfgC.add("const FP _kernel_inh_table[TNUM_INHNO] = {")
+$kernelCfgC.add("FP _kernel_inh_table[TNUM_INHNO] = {")
 $INHNO_VALID.each_with_index do |inhnoVal, index|
   $kernelCfgC.add(",") if index > 0
Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel_impl.c
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel_impl.c	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel_impl.c	(revision 374)
@@ -170,4 +170,29 @@
 
 /*
+ *  FPUの初期化
+ */
+#ifdef USE_ARM_FPU
+
+void
+arm_fpu_initialize(void)
+{
+	uint32_t	reg;
+
+	/*
+	 *  CP10とCP11をアクセス可能に設定する．
+	 */
+	CP15_READ_CPACR(reg);
+	reg |= (CP15_CPACR_CP10_FULLACCESS | CP15_CPACR_CP11_FULLACCESS);
+	CP15_WRITE_CPACR(reg);
+
+	/*
+	 *  FPUをディスエーブルする．
+	 */
+	set_fpexc(current_fpexc() & ~FPEXC_ENABLE);
+}
+
+#endif /* USE_ARM_FPU */
+
+/*
  *  コア依存の初期化
  */
@@ -187,4 +212,11 @@
 	arm_mmu_initialize();
 #endif /* USE_ARM_MMU */
+
+	/*
+	 *  FPUの初期化
+	 */
+#ifdef USE_ARM_FPU
+	arm_fpu_initialize();
+#endif /* USE_ARM_FPU */
 
 	/*
Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel_impl.h
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel_impl.h	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_kernel_impl.h	(revision 374)
@@ -55,4 +55,11 @@
 
 /*
+ *  ターゲット依存のタスク属性（エラーチェック用）
+ */
+#ifdef USE_ARM_FPU
+#define TARGET_TSKATR		(TA_FPU)
+#endif /* USE_ARM_FPU */
+
+/*
  *  エラーチェック方法の指定
  */
@@ -324,5 +331,5 @@
  *  割込みハンドラテーブル（kernel_cfg.c）
  */
-extern const FP inh_table[TNUM_INHNO];
+extern FP inh_table[TNUM_INHNO];
 
 /*
Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_offset.trb
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_offset.trb	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_offset.trb	(revision 374)
@@ -17,4 +17,5 @@
 GenerateDefine("TCB_sp", $offsetof_TCB_sp)
 GenerateDefine("TCB_pc", $offsetof_TCB_pc)
+GenerateDefine("TINIB_tskatr", $offsetof_TINIB_tskatr)
 GenerateDefine("TINIB_exinf", $offsetof_TINIB_exinf)
 GenerateDefine("TINIB_task", $offsetof_TINIB_task)
Index: asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_support.S
===================================================================
--- asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_support.S	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/asp3_dcre/arch/arm_gcc/common/core_support.S	(revision 374)
@@ -6,8 +6,8 @@
  *  Copyright (C) 2000-2004 by Embedded and Real-Time Systems Laboratory
  *                              Toyohashi Univ. of Technology, JAPAN
- *  Copyright (C) 2006-2017 by Embedded and Real-Time Systems Laboratory
+ *  Copyright (C) 2006-2018 by Embedded and Real-Time Systems Laboratory
  *              Graduate School of Information Science, Nagoya Univ., JAPAN
  * 
- *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  上記著作権者は，以下の(1)〜(4)の条件を満たす場合に限り，本ソフトウェ
  *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
  *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
@@ -55,4 +55,11 @@
 
 /*
+ *  使用する命令セットの定義
+ */
+#ifdef USE_ARM_FPU
+	.fpu	vfpv3
+#endif /* USE_ARM_FPU */
+
+/*
  *  例外ベクタ
  */
@@ -101,11 +108,20 @@
 	 *  マスク全解除状態・ディスパッチ許可状態で呼び出される．
 	 */
-	push	{r12,lr}				/* 戻り番地を保存，r12はダミー */
+	push	{r12,lr}				/* 戻り番地（lr）を保存 */
+									/* r12はアラインメントのため */
 #ifdef TOPPERS_SUPPORT_OVRHDR
 	bl		ovrtimer_stop
 #endif /* TOPPERS_SUPPORT_OVRHDR */
-	stmfd	sp!, {r4-r11}			/* 非スクラッチレジスタの保存 */
+	push	{r4-r11}				/* 非スクラッチレジスタの保存 */
 	ldr		r0, =p_runtsk			/* p_runtsk → r0 */
 	ldr		r0, [r0]
+#ifdef USE_ARM_FPU
+	ldr		r2, [r0,#TCB_p_tinib]	/* p_runtsk->p_tinib → r2 */
+	ldr		r1, [r2,#TINIB_tskatr]	/* p_runtsk->p_tinib->tskatr → r1 */
+	tst		r1, #TA_FPU
+	beq		1f
+	vpush	{d8-d15}				/* 非スクラッチFPUレジスタの保存 */
+1:
+#endif /* USE_ARM_FPU */
 	str		sp, [r0,#TCB_sp]		/* スタックポインタを保存 */
 	adr		r1, dispatch_r
@@ -114,5 +130,21 @@
 
 ALABEL(dispatch_r)
-	ldmfd	sp!, {r4-r11}			/* 非スクラッチレジスタの復帰 */
+	/*
+	 * 【この時点のレジスタ状態】
+	 *  r4：p_runtsk（タスク切換え後）
+	 */
+#ifdef USE_ARM_FPU
+	ldr		r2, [r4,#TCB_p_tinib]	/* p_runtsk->p_tinib → r2 */
+	ldr		r1, [r2,#TINIB_tskatr]	/* p_runtsk->p_tinib->tskatr → r1 */
+	tst		r1, #TA_FPU
+	vmrs	r0, fpexc
+	biceq	r0, r0, #FPEXC_ENABLE
+	orrne	r0, r0, #FPEXC_ENABLE
+	vmsr	fpexc, r0				/* FPEXCを設定 */
+	beq		1f
+	vpop	{d8-d15}				/* 非スクラッチFPUレジスタの復帰 */
+1:
+#endif /* USE_ARM_FPU */
+	pop		{r4-r11}				/* 非スクラッチレジスタの復帰 */
 #ifdef TOPPERS_SUPPORT_OVRHDR
 	bl		ovrtimer_start
@@ -136,4 +168,9 @@
 	 */
 
+	/*
+	 *  各種のデバイス（特に割込みコントローラ）の設定が完了するのを待つ．
+	 */
+	asm_data_sync_barrier r0
+	
 	/*
 	 *	タスクコンテキストに切り換える．
@@ -232,6 +269,9 @@
 ALABEL(call_exit_kernel)
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_INTLOCK)
-	ldr		r0, =istkpt				/* 非タスクコンテキストのスタックへ */
+	ldr		r0, =istkpt				/* 非タスクコンテキスト用のスタックに */
 	ldr		sp, [r0]
+	ldr		r0, =excpt_nest_count	/* 例外ネストカウントを1に */
+	mov		r1, #1
+	str		r1, [r0]
 	b		exit_kernel
 
@@ -243,5 +283,6 @@
 	AGLOBAL(start_r)
 	/*
-	 *  ディスパッチャ本体から呼び出されるため，p_runtskはr4に入っている．
+	 * 【この時点のレジスタ状態】
+	 *  r4：p_runtsk（タスク切換え後）
 	 */
 ALABEL(start_r)
@@ -253,4 +294,12 @@
 	ldr		lr, =ext_tsk			/* タスク本体からの戻り番地を設定 */
 	ldr		r2, [r4,#TCB_p_tinib]	/* p_runtsk->p_tinib → r2 */
+#ifdef USE_ARM_FPU
+	ldr		r1, [r2,#TINIB_tskatr]	/* p_runtsk->p_tinib->tskatr → r1 */
+	tst		r1, #TA_FPU
+	vmrs	r0, fpexc
+	biceq	r0, r0, #FPEXC_ENABLE
+	orrne	r0, r0, #FPEXC_ENABLE
+	vmsr	fpexc, r0				/* FPEXCを設定 */
+#endif /* USE_ARM_FPU */
 	ldr		r0, [r2,#TINIB_exinf]	/* exinfをパラメータに */
 	ldr		r1, [r2,#TINIB_task]	/* タスク起動番地にジャンプ */
@@ -270,11 +319,12 @@
 #if __TARGET_ARCH_ARM < 6
 	/*
-	 *  スーパバイザモードに切り換え，スクラッチレジスタを保存する．
+	 *  スーパバイザモードに切り換え，スクラッチレジスタ＋αを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_IRQ_BIT)
-	stmfd	sp!, {r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
-
-	/*
-	 *  IRQモードに戻して，戻り番地とspsr（戻り先のcpsr）を取得する．
+	push	{r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
+
+	/*
+	 *  IRQモードに戻して，戻り番地（lr−4）と戻り先のcpsr（spsr）を取
+	 *  得する．
 	 */
 	msr		cpsr_c, #(CPSR_IRQ_MODE AOR CPSR_IRQ_BIT)
@@ -283,13 +333,13 @@
 
 	/*
-	 *  スーパバイザモードに切り換え，戻り番地とspsrを保存する．
+	 *  スーパバイザモードに切り換え，戻り番地と戻り先のcpsrを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_IRQ_BIT)
-	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存 */
-	push	{r1}					/* spsrをスタックに保存 */
+	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存（pcの場所）*/
+	push	{r1}					/* 戻り先のcpsrをスタックに保存 */
 #else /* __TARGET_ARCH_ARM < 6 */
 	/*
-	 *  戻り先（lr）とspsr（cpsr_svc）をスーパバイザモードのスタックに
-	 *  保存する．
+	 *  戻り番地（lr）と戻り先のcpsr（spsr）をスーパバイザモードのスタッ
+	 *  クに保存する．
 	 */
 	sub		lr, lr, #4				/* 戻り番地の算出 */
@@ -297,8 +347,8 @@
 
 	/*
-	 *  スーパバイザモードに切り換え，スクラッチレジスタを保存する．
+	 *  スーパバイザモードに切り換え，スクラッチレジスタ＋αを保存する．
 	 */
 	cps		#CPSR_SVC_MODE
-	stmfd	sp!, {r0-r5,r12,lr}
+	push	{r0-r5,r12,lr}
 #endif /* __TARGET_ARCH_ARM < 6 */
 
@@ -308,6 +358,6 @@
 	and		r1, sp, #4
 	sub		sp, sp, r1
-	push	{r0,r1}					/* r0はスペース確保のため */
-
+	push	{r0,r1}					/* スタックポインタの調整値を保存 */
+									/* r0はスペース確保のため */
 	/*
 	 *  例外ネストカウントをインクリメントする．割込みが非タスクコンテキ
@@ -328,4 +378,14 @@
 #endif /* TOPPERS_SUPPORT_OVRHDR */
 
+#ifdef USE_ARM_FPU
+	/*
+	 *  FPUをディスエーブルする．
+	 */
+	vmrs	r0, fpexc
+	str		r0, [sp]				/* FPEXCを保存（r0の場所）*/
+	bic		r0, r0, #FPEXC_ENABLE
+	vmsr	fpexc, r0				/* FPEXCを設定 */
+#endif /* USE_ARM_FPU */
+	
 	/*
 	 *  非タスクコンテキスト用のスタックに切り換える．
@@ -339,4 +399,7 @@
 	/*
 	 *  割込みコントローラを操作し，割込み番号を取得する．
+	 *
+	 *  irc_begin_intは，スタックトップ（r0の場所）に，irc_end_intで用
+	 *  いる情報を保存する．
 	 */
 	bl		irc_begin_int
@@ -420,4 +483,12 @@
 	mov   	sp, r3
 
+#ifdef USE_ARM_FPU
+	/*
+	 *  FPUを元に戻す．
+	 */
+	ldr		r0, [sp]				/* FPEXCを復帰 */
+	vmsr	fpexc, r0
+#endif /* USE_ARM_FPU */
+	
 	/*
 	 *  p_runtskがNULLか判定する．
@@ -433,5 +504,5 @@
 	pop		{r0,r1}					/* スタックポインタの調整を元に戻す */
 	add		sp, sp, r1
-	add		sp, sp, #40				/* スクラッチレジスタを捨てる */
+	add		sp, sp, #40				/* スクラッチレジスタ等を捨てる */
 	b		dispatcher_0
 
@@ -440,4 +511,8 @@
 	 */
 ALABEL(irq_handler_3)
+	/*
+	 * 【この時点のレジスタ状態】
+	 *  r0：p_runtsk
+	 */
 	ldr		r1, =p_schedtsk			/* p_schedtsk → r1 */
 	ldr		r1, [r1]
@@ -448,5 +523,18 @@
 	 *  コンテキストを保存する．
 	 */
-	stmfd	sp!, {r6-r11}			/* 非スクラッチレジスタの保存 */
+	push	{r6-r11}				/* 残りのレジスタの保存 */
+#ifdef USE_ARM_FPU
+	ldr		r2, [r0,#TCB_p_tinib]	/* p_runtsk->p_tinib → r2 */
+	ldr		r1, [r2,#TINIB_tskatr]	/* p_runtsk->p_tinib->tskatr → r1 */
+	tst		r1, #TA_FPU
+	beq		1f						/* TA_FPU属性でない場合は分岐 */
+#ifdef USE_ARM_FPU_D32
+	vpush	{d16-d31}
+#endif /* USE_ARM_FPU_D32 */
+	vpush	{d0-d15}				/* 全FPUレジスタの保存 */
+	vmrs	r1, fpscr
+	push	{r1,r2}					/* FPSCRの保存 */
+1:									/* r2はアラインメントのため */
+#endif /* USE_ARM_FPU */
 	str		sp, [r0,#TCB_sp]		/* スタックポインタを保存 */
 	adr		r1, ret_int_r			/* 実行再開番地を保存 */
@@ -457,6 +545,26 @@
 	/*
 	 *  コンテキストを復帰する．
-	 */
-	ldmfd	sp!, {r6-r11}			/* 非スクラッチレジスタの復帰 */
+	 *
+	 * 【この時点のレジスタ状態】
+	 *  r4：p_runtsk（タスク切換え後）
+	 */
+#ifdef USE_ARM_FPU
+	ldr		r2, [r4,#TCB_p_tinib]	/* p_runtsk->p_tinib → r2 */
+	ldr		r1, [r2,#TINIB_tskatr]	/* p_runtsk->p_tinib->tskatr → r1 */
+	tst		r1, #TA_FPU
+	vmrs	r0, fpexc
+	biceq	r0, r0, #FPEXC_ENABLE
+	orrne	r0, r0, #FPEXC_ENABLE
+	vmsr	fpexc, r0				/* FPEXCを設定 */
+	beq		1f						/* TA_FPU属性でない場合は分岐 */
+	pop		{r1,r2}					/* FPSCRの復帰 */
+	vmsr	fpscr, r1
+	vpop	{d0-d15}				/* 全FPUレジスタの復帰 */
+#ifdef USE_ARM_FPU_D32
+	vpop	{d16-d31}
+#endif /* USE_ARM_FPU_D32 */
+1:
+#endif /* USE_ARM_FPU */
+	pop		{r6-r11}				/* 残りのレジスタの復帰 */
 
 ALABEL(irq_handler_4)
@@ -469,9 +577,9 @@
 
 	/*
-	 *  割込み／CPU例外処理からのリターン
+	 *  割込み処理からのリターン
 	 *
-	 *  割込み／CPU例外処理からのリターンにより，CPUロック解除状態に遷
-	 *  移するようにする必要があるが，ARMはCPSRのビットによってCPUロッ
-	 *  ク状態を表しているため，CPSRを元に戻してリターンすればよい．
+	 *  割込み処理からのリターンにより，CPUロック解除状態に遷移するよ
+	 *  うにする必要があるが，ARMはCPSRのビットによってCPUロック状態を
+	 *  表しているため，CPSRを元に戻してリターンすればよい．
 	 */
 ALABEL(irq_handler_5)
@@ -480,10 +588,10 @@
 
 #if __TARGET_ARCH_ARM < 6
-	ldmfd	sp!, {r0}				/* 戻り先のcpsrをspsrに設定 */
+	pop		{r0}					/* 戻り先のcpsrをspsrに設定 */
 	msr		spsr_cxsf, r0
 	ldmfd	sp!, {r0-r5,r12,lr,pc}^	/* コンテキストの復帰 */
 									/* ^付きなので，spsr → cpsr */
 #else /* __TARGET_ARCH_ARM < 6 */
-	ldmfd	sp!, {r0-r5,r12,lr}
+	pop		{r0-r5,r12,lr}			/* スクラッチレジスタ＋αの復帰 */
 	rfefd	sp!
 #endif /* __TARGET_ARCH_ARM < 6 */
@@ -509,11 +617,12 @@
 	/*
 	 *  IビットとFビットをセットし，スーパバイザモードに切り換え，スク
-	 *  ラッチレジスタを保存する．
+	 *  ラッチレジスタ＋αを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	stmfd	sp!, {r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
-
-	/*
-	 *  未定義モードに戻して，戻り番地とspsrを取得する．
+	push	{r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
+
+	/*
+	 *  未定義モードに戻して，戻り番地（lr）と戻り先のcpsr（spsr）を取
+	 *  得する．
 	 */
 	msr		cpsr_c, #(CPSR_UND_MODE AOR CPSR_FIQ_IRQ_BIT)
@@ -522,21 +631,21 @@
 
 	/*
-	 *  スーパバイザモードに切り換え，戻り番地とspsrを保存する．
+	 *  スーパバイザモードに切り換え，戻り番地と戻り先のcpsrを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存 */
-	push	{r1}					/* spsrをスタックに保存 */
+	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存（pcの場所）*/
+	push	{r1}					/* 戻り先のcpsrをスタックに保存 */
 #else /* __TARGET_ARCH_ARM < 6 */
 	/*
-	 *  戻り先（lr）とspsr（cpsr_svc）をスーパバイザモードのスタックに
-	 *  保存する．
+	 *  戻り番地（lr）と戻り先のcpsr（spsr）をスーパバイザモードのスタッ
+	 *  クに保存する．
 	 */
 	srsfd	#CPSR_SVC_MODE!
 
 	/*
-	 *  スーパバイザモードに切り換え，スクラッチレジスタを保存する．
+	 *  スーパバイザモードに切り換え，スクラッチレジスタ＋αを保存する．
 	 */
 	cps		#CPSR_SVC_MODE
-	stmfd	sp!, {r0-r5,r12,lr}
+	push	{r0-r5,r12,lr}
 #endif /* __TARGET_ARCH_ARM < 6 */
 	mov		r4, #EXCNO_UNDEF
@@ -550,5 +659,4 @@
 	ATEXT
 	AALIGN(2)
-	AWEAK(svc_handler)
 	AGLOBAL(svc_handler)
 ALABEL(svc_handler)
@@ -558,32 +666,23 @@
 #if __TARGET_ARCH_ARM < 6
 	/*
-	 *  IビットとFビットをセットし，スクラッチレジスタを保存する．
+	 *  IビットとFビットをセットし，戻り番地（lr），スクラッチレジスタ
+	 *  ＋α，戻り先のcpsr（spsr）を保存する（lrは二重に保存される）．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	stmfd	sp!, {r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
-
-	/*
-	 *  戻り番地とspsrを取得する．
-	 */
-	mov		r2, lr
+	push	{lr}
+	push	{r0-r5,r12,lr}
 	mrs		r1, spsr
-
-	/*
-	 *  戻り番地とspsrを保存する．
-	 */
-	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存 */
-	push	{r1}					/* spsrをスタックに保存 */
+	push	{r1}
 #else /* __TARGET_ARCH_ARM < 6 */
 	/*
-	 *  戻り先（lr）とspsr（cpsr_svc）をスーパバイザモードのスタックに
-	 *  保存する．
+	 *  戻り番地（lr）と戻り先のcpsr（spsr）をスーパバイザモードのスタッ
+	 *  クに保存する．
 	 */
 	srsfd	#CPSR_SVC_MODE!
 
 	/*
-	 *  スーパバイザモードで，スクラッチレジスタを保存する．
-	 */
-	cps		#CPSR_SVC_MODE			/* 不要と思われる */
-	stmfd	sp!, {r0-r5,r12,lr}
+	 *  スーパバイザモードで，スクラッチレジスタ＋αを保存する．
+	 */
+	push	{r0-r5,r12,lr}
 #endif /* __TARGET_ARCH_ARM < 6 */
 	mov		r4, #EXCNO_SVC
@@ -605,11 +704,12 @@
 	/*
 	 *  IビットとFビットをセットし，スーパバイザモードに切り換え，スク
-	 *  ラッチレジスタを保存する．
+	 *  ラッチレジスタ＋αを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	stmfd	sp!, {r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
-
-	/*
-	 *  アボートモードに戻して，戻り番地とspsrを取得する．
+	push	{r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
+
+	/*
+	 *  アボートモードに戻して，戻り番地（lr）と戻り先のcpsr（spsr）を
+	 *  取得する．
 	 */
 	msr		cpsr_c, #(CPSR_ABT_MODE AOR CPSR_FIQ_IRQ_BIT)
@@ -618,21 +718,21 @@
 
 	/*
-	 *  スーパバイザモードに切り換え，戻り番地とspsrを保存する．
+	 *  スーパバイザモードに切り換え，戻り番地と戻り先のcpsrを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存 */
-	push	{r1}					/* spsrをスタックに保存 */
+	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存（pcの場所）*/
+	push	{r1}					/* 戻り先のcpsrをスタックに保存 */
 #else /* __TARGET_ARCH_ARM < 6 */
 	/*
-	 *  戻り先（lr）とspsr（cpsr_svc）をスーパバイザモードのスタックに
-	 *  保存する．
+	 *  戻り番地（lr）と戻り先のcpsr（spsr）をスーパバイザモードのスタッ
+	 *  クに保存する．
 	 */
 	srsfd	#CPSR_SVC_MODE!
 
 	/*
-	 *  スーパバイザモードに切り換え，スクラッチレジスタを保存する．
+	 *  スーパバイザモードに切り換え，スクラッチレジスタ＋αを保存する．
 	 */
 	cps		#CPSR_SVC_MODE
-	stmfd	sp!, {r0-r5,r12,lr}
+	push	{r0-r5,r12,lr}
 #endif /* __TARGET_ARCH_ARM < 6 */
 	mov		r4, #EXCNO_PABORT
@@ -666,11 +766,12 @@
 	/*
 	 *  IビットとFビットをセットし，スーパバイザモードに切り換え，スク
-	 *  ラッチレジスタを保存する．
+	 *  ラッチレジスタ＋αを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	stmfd	sp!, {r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
-
-	/*
-	 *  アボートモードに戻して，戻り番地とspsrを取得する．
+	push	{r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
+
+	/*
+	 *  アボートモードに戻して，戻り番地（lr）と戻り先のcpsr（spsr）を
+	 *  取得する．
 	 */
 	msr		cpsr_c, #(CPSR_ABT_MODE AOR CPSR_FIQ_IRQ_BIT)
@@ -679,21 +780,21 @@
 
 	/*
-	 *  スーパバイザモードに切り換え，戻り番地とspsrを保存する．
+	 *  スーパバイザモードに切り換え，戻り番地と戻り先のcpsrを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存 */
-	push	{r1}					/* spsrをスタックに保存 */
+	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存（pcの場所）*/
+	push	{r1}					/* 戻り先のcpsrをスタックに保存 */
 #else /* __TARGET_ARCH_ARM < 6 */
 	/*
-	 *  戻り先（lr）とspsr（cpsr_svc）をスーパバイザモードのスタックに
-	 *  保存する．
+	 *  戻り番地（lr）と戻り先のcpsr（spsr）をスーパバイザモードのスタッ
+	 *  クに保存する．
 	 */
 	srsfd	#CPSR_SVC_MODE!
 
 	/*
-	 *  スーパバイザモードに切り換え，スクラッチレジスタを保存する．
+	 *  スーパバイザモードに切り換え，スクラッチレジスタ＋αを保存する．
 	 */
 	cps		#CPSR_SVC_MODE
-	stmfd	sp!, {r0-r5,r12,lr}
+	push	{r0-r5,r12,lr}
 #endif /* __TARGET_ARCH_ARM < 6 */
 	mov		r4, #EXCNO_DABORT
@@ -708,13 +809,14 @@
 	/*
 	 *  IビットとFビットをセットし，スーパバイザモードに切り換え，スタッ
-	 *  クポインタを初期化し，スクラッチレジスタを保存する．
+	 *  クポインタを初期化し，スクラッチレジスタ＋αを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
 	ldr		sp, =istkpt
 	ldr		sp, [sp]
-	stmfd	sp!, {r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
-
-	/*
-	 *  アボートモードに戻して，戻り番地とspsrを取得する．
+	push	{r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
+
+	/*
+	 *  アボートモードに戻して，戻り番地（lr）と戻り先のcpsr（spsr）を
+	 *  取得する．
 	 */
 	msr		cpsr_c, #(CPSR_ABT_MODE AOR CPSR_FIQ_IRQ_BIT)
@@ -723,9 +825,9 @@
 
 	/*
-	 *  スーパバイザモードに切り換え，戻り番地とspsrを保存する．
+	 *  スーパバイザモードに切り換え，戻り番地と戻り先のcpsrを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存 */
-	push	{r1}					/* spsrをスタックに保存 */
+	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存（pcの場所）*/
+	push	{r1}					/* 戻り先のcpsrをスタックに保存 */
 #else /* __TARGET_ARCH_ARM < 6 */
 	/*
@@ -738,6 +840,6 @@
 
 	/*
-	 *  アボートモードに戻して，戻り先（lr）とspsr（cpsr_svc）をスーパ
-	 *  バイザモードのスタックに保存する．
+	 *  アボートモードに戻して，戻り番地（lr）と戻り先のcpsr（spsr）を
+	 *  スーパバイザモードのスタックに保存する．
 	 */
 	cps		#CPSR_ABT_MODE
@@ -745,8 +847,8 @@
 
 	/*
-	 *  スーパバイザモードに切り換え，スクラッチレジスタを保存する．
+	 *  スーパバイザモードに切り換え，スクラッチレジスタ＋αを保存する．
 	 */
 	cps		#CPSR_SVC_MODE
-	stmfd	sp!, {r0-r5,r12,lr}
+	push	{r0-r5,r12,lr}
 #endif /* __TARGET_ARCH_ARM < 6 */
 
@@ -776,11 +878,12 @@
 	/*
 	 *  IビットとFビットをセットし，スーパバイザモードに切り換え，スク
-	 *  ラッチレジスタを保存する．
+	 *  ラッチレジスタ＋αを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	stmfd	sp!, {r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
-
-	/*
-	 *  FIQモードに戻して，戻り番地とspsrを取得する．
+	push	{r0-r5,r12,lr,pc}		/* pcはスペース確保のため */
+
+	/*
+	 *  FIQモードに戻して，戻り番地（lr）と戻り先のcpsr（spsr）を取得
+	 *  する．
 	 */
 	msr		cpsr_c, #(CPSR_FIQ_MODE AOR CPSR_FIQ_IRQ_BIT)
@@ -789,21 +892,21 @@
 
 	/*
-	 *  スーパバイザモードに切り換え，戻り番地とspsrを保存する．
+	 *  スーパバイザモードに切り換え，戻り番地と戻り先のcpsrを保存する．
 	 */
 	msr		cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
-	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存 */
-	push	{r1}					/* spsrをスタックに保存 */
+	str		r2, [sp,#0x20]			/* 戻り番地をスタックに保存（pcの場所）*/
+	push	{r1}					/* 戻り先のcpsrをスタックに保存 */
 #else /* __TARGET_ARCH_ARM < 6 */
 	/*
-	 *  戻り先（lr）とspsr（cpsr_svc）をスーパバイザモードのスタックに
-	 *  保存する．
+	 *  戻り番地（lr）と戻り先のcpsr（spsr）をスーパバイザモードのスタッ
+	 *  クに保存する．
 	 */
 	srsfd	#CPSR_SVC_MODE!
 
 	/*
-	 *  スーパバイザモードに切り換え，スクラッチレジスタを保存する．
+	 *  スーパバイザモードに切り換え，スクラッチレジスタ＋αを保存する．
 	 */
 	cps		#CPSR_SVC_MODE
-	stmfd	sp!, {r0-r5,r12,lr}
+	push	{r0-r5,r12,lr}
 #endif /* __TARGET_ARCH_ARM < 6 */
 	mov		r4, #EXCNO_FIQ
@@ -815,10 +918,10 @@
 /*
  *  CPU例外ハンドラ出入口処理の共通部分
- *
- * 【この時点のレジスタ状態】
- *  r4：CPU例外ハンドラ番号
  */
 ALABEL(exc_handler_1)
 	/*
+	 * 【この時点のレジスタ状態】
+	 *  r4：CPU例外ハンドラ番号
+	 *
 	 *  CPU例外が発生した状況の判断に用いるために，CPU例外発生前の割
 	 *  込み優先度マスクと例外ネストカウントをスタックに保存する．
@@ -836,6 +939,6 @@
 	and		r1, sp, #4
 	sub		sp, sp, r1
-	push	{r0,r1}					/* r0はスペース確保のため */
-
+	push	{r0,r1}					/* スタックポインタの調整値を保存 */
+									/* r0はスペース確保のため */
 	/*
 	 *  カーネル管理外のCPU例外か判定する
@@ -873,4 +976,14 @@
 #endif /* TOPPERS_SUPPORT_OVRHDR */
 
+#ifdef USE_ARM_FPU
+	/*
+	 *  FPUをディスエーブルする．
+	 */
+	vmrs	r0, fpexc
+	str		r0, [sp]				/* FPEXCを保存（r0の場所）*/
+	bic		r0, r0, #FPEXC_ENABLE
+	vmsr	fpexc, r0				/* FPEXCを設定 */
+#endif /* USE_ARM_FPU */
+	
 	/*
 	 *  非タスクコンテキスト用のスタックに切り換える．
@@ -890,4 +1003,7 @@
 	/*
 	 *  （必要なら）割込みコントローラを操作する．
+	 *
+	 *  irc_begin_excは，スタックトップ（r0の場所）に，irc_end_excで用
+	 *  いる情報を保存する．
 	 */
 	bl		irc_begin_exc
@@ -970,4 +1086,12 @@
 	mov		sp, r3
 
+#ifdef USE_ARM_FPU
+	/*
+	 *  FPUを元に戻す．
+	 */
+	ldr		r0, [sp]				/* FPEXCを復帰 */
+	vmsr	fpexc, r0
+#endif /* USE_ARM_FPU */
+	
 	/*
 	 *  p_runtskがNULLか判定する．
@@ -990,4 +1114,8 @@
 	 */
 ALABEL(exc_handler_3)
+	/*
+	 * 【この時点のレジスタ状態】
+	 *  r0：p_runtsk
+	 */
 	ldr		r1, =p_schedtsk			/* p_schedtsk → r1 */
 	ldr		r1, [r1]
@@ -998,5 +1126,18 @@
 	 *  コンテキストを保存する．
 	 */
-	stmfd	sp!, {r6-r11}			/* 非スクラッチレジスタの保存 */
+	push	{r6-r11}				/* 残りのレジスタの保存 */
+#ifdef USE_ARM_FPU
+	ldr		r2, [r0,#TCB_p_tinib]	/* p_runtsk->p_tinib → r2 */
+	ldr		r1, [r2,#TINIB_tskatr]	/* p_runtsk->p_tinib->tskatr → r1 */
+	tst		r1, #TA_FPU
+	beq		1f						/* TA_FPU属性でない場合は分岐 */
+#ifdef USE_ARM_FPU_D32
+	vpush	{d16-d31}
+#endif /* USE_ARM_FPU_D32 */
+	vpush	{d0-d15}				/* 全FPUレジスタの保存 */
+	vmrs	r1, fpscr
+	push	{r1,r2}					/* FPSCRの保存 */
+1:									/* r2はアラインメントのため */
+#endif /* USE_ARM_FPU */
 	str		sp, [r0,#TCB_sp]		/* スタックポインタを保存 */
 	adr		r1, ret_exc_r			/* 実行再開番地を保存 */
@@ -1007,6 +1148,26 @@
 	/*
 	 *  コンテキストを復帰する．
-	 */
-	ldmfd	sp!, {r6-r11}			/* 非スクラッチレジスタの復帰 */
+	 *
+	 * 【この時点のレジスタ状態】
+	 *  r4：p_runtsk（タスク切換え後）
+	 */
+#ifdef USE_ARM_FPU
+	ldr		r2, [r4,#TCB_p_tinib]	/* p_runtsk->p_tinib → r2 */
+	ldr		r1, [r2,#TINIB_tskatr]	/* p_runtsk->p_tinib->tskatr → r1 */
+	tst		r1, #TA_FPU
+	vmrs	r0, fpexc
+	biceq	r0, r0, #FPEXC_ENABLE
+	orrne	r0, r0, #FPEXC_ENABLE
+	vmsr	fpexc, r0				/* FPEXCを設定 */
+	beq		1f						/* TA_FPU属性でない場合は分岐 */
+	pop		{r1,r2}					/* FPSCRの復帰 */
+	vmsr	fpscr, r1
+	vpop	{d0-d15}				/* 全FPUレジスタの復帰 */
+#ifdef USE_ARM_FPU_D32
+	vpop	{d16-d31}
+#endif /* USE_ARM_FPU_D32 */
+1:
+#endif /* USE_ARM_FPU */
+	pop		{r6-r11}				/* 残りのレジスタの復帰 */
 
 ALABEL(exc_handler_4)
@@ -1031,10 +1192,10 @@
 
 #if __TARGET_ARCH_ARM < 6
-	ldmfd	sp!, {r0}				/* 戻り先のcpsrをspsrに設定 */
+	pop		{r0}					/* 戻り先のcpsrをspsrに設定 */
 	msr		spsr_cxsf, r0
 	ldmfd	sp!, {r0-r5,r12,lr,pc}^	/* コンテキストの復帰 */
 									/* ^付きなので，spsr → cpsr */
 #else /* __TARGET_ARCH_ARM < 6 */
-	ldmfd	sp!, {r0-r5,r12,lr}
+	pop		{r0-r5,r12,lr}			/* スクラッチレジスタ＋αの復帰 */
 	rfefd	sp!
 #endif /* __TARGET_ARCH_ARM < 6 */
@@ -1061,4 +1222,14 @@
 	bne		nk_exc_handler_2		/*		 	ならnk_exc_handler_2に分岐 */
 
+#ifdef USE_ARM_FPU
+	/*
+	 *  FPUをディスエーブルする．
+	 */
+	vmrs	r0, fpexc
+	str		r0, [sp]				/* FPEXCを保存（r0の場所）*/
+	bic		r0, r0, #FPEXC_ENABLE
+	vmsr	fpexc, r0				/* FPEXCを設定 */
+#endif /* USE_ARM_FPU */
+	
 	/*
 	 *  非タスクコンテキスト用のスタックに切り換える．
@@ -1068,5 +1239,5 @@
 	ldr		sp, [r2]
 	push	{r0,r3}					/* 切換え前のスタックポインタを保存 */
-									/* r0はスペース確保のため */
+									/* r0はアラインメントのため */
 ALABEL(nk_exc_handler_2)
 	/*
@@ -1101,6 +1272,14 @@
 	pop		{r0,r3}
 	mov		sp, r3
+
+#ifdef USE_ARM_FPU
+	/*
+	 *  FPUを元に戻す．
+	 */
+	ldr		r0, [sp]				/* FPEXCを復帰 */
+	vmsr	fpexc, r0
+#endif /* USE_ARM_FPU */
 	b		exc_handler_5
-
+	
 /*
  *  ステータスレジスタの操作関数
