source: anotherchoice/tags/jsp-1.4.4-full-UTF8/config/sh2/cpu_support.S@ 26

Last change on this file since 26 was 26, checked in by ykominami, 10 years ago

initial

File size: 38.0 KB
Line 
1/*
2 * TOPPERS/JSP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2004 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2001-2004 by Industrial Technology Institute,
9 * Miyagi Prefectural Government, JAPAN
10 * Copyright (C) 2002-2004 by Hokkaido Industrial Research Institute, JAPAN
11 *
12 * 上記著作権者
13は,以下の (1)〜(4) の条件か,Free Software Foundation
14 * によってå…
15¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
16 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
17 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
18å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
19 * 利用と呼ぶ)することを無償で許諾する.
20 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
21 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
22 * スコード中に含まれていること.
23 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
24 * 用できる形で再é…
25å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
26å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
27 * 者
28マニュアルなど)に,上記の著作権表示,この利用条件および下記
29 * の無保証規定を掲載すること.
30 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
31 * 用できない形で再é…
32å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
33 * と.
34 * (a) 再é…
35å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
36マニュアルなど)に,上記の著
37 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
38 * (b) 再é…
39å¸ƒã®å½¢æ…
40‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
41 * 報告すること.
42 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
43 * 害からも,上記著作権者
44およびTOPPERSプロジェクトをå…
45è²¬ã™ã‚‹ã“と.
46 *
47 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
48お
49 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
50 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
51 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
52 *
53 * @(#) $Id: cpu_support.S,v 1.6 2005/09/09 02:35:37 honda Exp $
54 */
55
56/*
57 * プロセッサ依存モジュール アセンブリ言語部(SH1/2用)
58 *     カーネル内
59部で使用する定義
60 */
61
62#define _MACRO_ONLY
63#include "jsp_kernel.h"
64#include "offset.h"
65
66/*
67 * タスクコントロールブロックTCB中のsp,pcがå…
68ˆé ­ã‹ã‚‰60バイトの
69 * 範囲内
70にあり、アラインメントが4バイト境界になっていれば、
71 * イミディエイト相対アドレッシングでアクセスできる
72 * TCB_pc,TCB_spはoffset.hで定義されている
73 * (make時に生成される)
74 */
75
76/* イミディエイト相対アドレッシングが可能かチェック */
77#define CHECK_IMMEDIATE_ADDRESSING(dst) \
78 ((dst <= 60) && ((dst % 4) == 0))
79
80#if CHECK_IMMEDIATE_ADDRESSING(TCB_pc) && \
81 CHECK_IMMEDIATE_ADDRESSING(TCB_sp)
82#define TCB_SHORT
83#endif
84
85/*
86 * タスクコントロールブロックTCB中のsp,pcがå…
87ˆé ­ã‹ã‚‰128バイト
88 * 以降にé…
89ç½®ã•ã‚Œã¦ã„ると
90 * mov #TCB_sp,r9
91 * 等の符号拡張を含む命令は期待
92通りに動作しない
93 */
94#if (TCB_pc > 127) || (TCB_sp > 127)
95#error "TCB_pc <= 127 ?"
96// ここでアセンブルエラー
97#endif
98
99#if !CHECK_IMMEDIATE_ADDRESSING(TCB_texptn)
100#error "TCB_texptn ?"
101// ここでアセンブルエラー
102#endif
103
104/*
105 * その他のオフセット値について
106 *
107 * (1) TCB_enatex
108 * mov.b @(#TCB_enatex,rx),r0命令の即値はゼロ拡張されるので
109 * TCB_enatexに関してはチェックする必
110要がない
111 * (アクセスできる範囲15バイトを超
112えると、アセンブルエラーになる)
113 *
114 * (2) TCB_enatex_mask
115 * and #TCB_enatex_mask,r0命令の即値はゼロ拡張されるので
116 * TCB_enatex_maskに関してはチェックする必
117要がない
118 */
119
120
121/*
122 * タスクディスパッチャ
123 *
124 *  dispatch は、割込み/CPU例外ネストカウンタ = 0,割込み禁止状æ…
125‹
126 * で呼び出さなければならない.exit_and_dispatch も,割込みネスト
127 * カウンタ = 0・割込み禁止状æ…
128‹ã§å‘¼ã³å‡ºã™ã®ãŒåŽŸå‰‡ã§ã‚るが,カーネル
129 * 起動時に対応するため,割込みネストカウンタ = 1で呼び出した場合に
130 * も対応している.
131 */
132
133 .text
134 .align 2
135 .global _dispatch
136_dispatch:
137 /* pr,r8〜r15 をスタックに保存 */
138 mov.l r8, @-r15 /* r0〜r7は呼び出しå…
139ƒã§ä¿å­˜ã—ているため */
140 mov.l r9, @-r15 /* 保存する必
141要が無い */
142 mov.l r10,@-r15
143 mov.l r11,@-r15
144 mov.l r12,@-r15
145 mov.l r13,@-r15
146 mov.l r14,@-r15
147 sts.l pr,@-r15
148 mov.l _runtsk_dis,r2 /* r0 <- runtsk */
149 mov.l @r2,r0
150 /*
151 * タスクコントロールブロックTCB中のsp,pcがå…
152ˆé ­ã‹ã‚‰60バイトの
153 * 範囲内
154にあり、アラインメントが4バイト境界になっていれば、
155 * イミディエイト相対アドレッシングでアクセスできる
156 */
157#ifdef TCB_SHORT
158 /* タスクスタックポインタを保存 */
159 mov.l r15,@(TCB_sp, r0)
160 mov.l dispatch_r_k,r1 /* 実行再開番地 */
161 bra dispatcher
162 mov.l r1,@(TCB_pc, r0) /* 遅
163延スロット */
164#else /* TCB_SHORT */
165 mov #TCB_sp,r9
166 mov.l r15,@(r0,r9) /* タスクスタックを保存 */
167 mov #TCB_pc,r8
168 mov.l dispatch_r_k,r1 /* 実行再開番地を保存 */
169 bra dispatcher
170 mov.l r1,@(r0,r8) /* 遅
171延スロット */
172#endif /* TCB_SHORT */
173
174 /*
175 * dispatch_r:
176 *  タスクコントコンテキストでディスパッチャ呼び出しをした場合の
177 *  実行再開番地
178 *  dispatcherから呼ばれるので、r7にruntskが代å…
179¥ã•ã‚Œã¦ã„ã‚‹
180 *
181 *   レジスタ割り当て
182 *    r7 :runtsk
183 *    r0 :runtsk->enatex
184 *     mov.b @(imm, r),r0命令はオペランドがr0に
185 *     固定されている
186 *    r1 :runtsk->texptn
187 *    r2 :call_texrtn()のå…
188ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
189 *
190 */
191dispatch_r:
192 lds.l @r15+,pr /* レジスタを復帰 */
193 mov.l @r15+,r14
194 mov.l @r15+,r13
195 mov.l @r15+,r12
196 mov.l @r15+,r11
197 mov.l @r15+,r10
198 mov.l @r15+,r9
199 mov.l @r15+,r8
200 mov.b @(TCB_enatex,r7),r0 /* オペランドがr0に固定 (c) */
201 mov.l @(TCB_texptn,r7),r1
202 and #TCB_enatex_mask,r0
203 tst r0,r0 /* runtsk->enatexのチェック */
204 bt _dispatch_r_1
205 /* 遅
206延スロットなし */
207 tst r1,r1 /* runtsk->texptnのチェック */
208 bt _dispatch_r_1
209 /* 遅
210延スロットなし */
211 mov.l _call_texrtn_dis,r2 /* タスク例外処理ルーチン起動 */
212 jmp @r2 /*(dispatch()呼び出しå…
213ƒã«ãƒªã‚¿ãƒ¼ãƒ³ã™ã‚‹ï¼‰*/
214 nop /* 遅
215延スロット  */
216_dispatch_r_1:
217 rts /* dispatch()呼び出しå…
218ƒã¸ã®ãƒªã‚¿ãƒ¼ãƒ³ */
219 nop /* 遅
220延スロット  */
221
222
223 .global _exit_and_dispatch
224_exit_and_dispatch:
225 /* 割込みネストカウンタをクリア */
226 mov.l _intnest_dis, r1
227 mov #0,r0
228 mov.l r0,@r1
229
230/*
231 * ディスパッチャ本体
232 *
233 */
234dispatcher:
235 /*
236 * ここには割り込み禁止で来ること
237 */
238 mov.l _schedtsk_dis,r1
239 mov.l _runtsk_dis,r2
240 mov.l @r1,r7 /* r7 <- schedtsk */
241 mov #0, r0 /* (b)       */
242
243 /*
244 * ここでruntskにschedtskを代å…
245¥ã™ã‚‹ã®ã¯ï¼’つの意味がある。
246 *  (1) schedtsk != NULLの場合
247 *     通常のタスク切り替えを行う。
248 *  (2) schedtsk == NULLの場合
249 *     runtskにNULLを代å…
250¥ã—ておく。
251 *     (dispatcher_1以降の割込み待
252ちで割込みがå…
253¥ã‚Šã€ãã®ä¸­ã§
254 *      iget_tid()がコールされたときに正しくTSK_NONEを返すため
255 *      には、実行状æ…
256‹ã®ã‚¿ã‚¹ã‚¯ãŒãªã„時に、runtskをNULLにして
257 *      おる必
258要がある。)
259 */
260 mov.l r7,@r2 /* runtsk←schedtsk  */
261
262 cmp/eq r7,r0 /* schedtsk があるか? (a) 末尾参ç…
263§ */
264 bt dispatcher_1 /* 無ければジャンプ */
265 /* 遅
266延スロットなし */
267
268 /*
269 * タスクコントロールブロックTCBから実行再開番地を取り出して
270 * 分岐する。
271 * 分岐å…
272ˆã¯ä»¥ä¸‹ã®3つ
273 *  dispatch_r:タスクコンテキストからのディスパッチ呼び出し
274 *  ret_int_r :割込みの出口処理
275 *  activate_r:起動直後
276 *
277 *  分岐å…
278ˆã§ã¯r7にruntsk(=schedtsk)がロードされているとして
279 *  使用して良い
280 */
281#ifdef TCB_SHORT
282 /*
283 * タスクコントロールブロックTCB中のsp,pcがå…
284ˆé ­ã‹ã‚‰60バイトの
285 * 範囲内
286にあり、アラインメントが4バイト境界になっていれば、
287 * イミディエイト相対アドレッシングでアクセスできる
288 */
289 /* 実行再開番地を復帰 */
290 mov.l @(TCB_pc, r7),r1
291 jmp @r1
292 mov.l @(TCB_sp, r7),r15 /* 遅
293延スロット */
294 /* タスクスタックポインタを復å…
295ƒ */
296#else /* TCB_SHORT */
297 mov #TCB_pc,r8
298 mov.l @(r7,r8),r1 /* 実行再開番地を復帰 */
299 mov #TCB_sp,r9
300 jmp @r1
301 mov.l @(r7,r9),r15 /* 遅
302延スロット */
303 /* タスクスタックポインタを復å…
304ƒ */
305#endif /* TCB_SHORT */
306
307
308dispatcher_1:
309 /*
310 * ここで割込みモードに切り換えるのは,ここで発生する割込み処理
311 * にどのスタックを使うかという問題の解決と,割込みハンドラ内
312で
313 * のタスクディスパッチの防止という二つの意味がある.
314 */
315
316
317 /* イミディエイト値を毎回読み込むのは効率が悪いので事前に用意する
318 * r0 : 0x00
319 * r1 : 0x01
320 * r8 : 割り込み禁止中のSRの値
321 * r9 : 割り込み許可中のSRの値
322 * r10 : reqflgの番地
323 * r11 : 割込みネストカウンタintnestの番地
324 */
325 mov #0,r0
326 mov #1,r1
327 mov.l _mask_ipm_dis,r8
328
329#ifdef SUPPORT_CHG_IPM
330 mov.l _task_intmask_dis,r2 /* タスクコンテキストのIPM */
331 mov.l @r2,r9
332#else /* SUPPORT_CHG_IPM */
333 mov #0,r9
334#endif /* SUPPORT_CHG_IPM */
335
336 mov.l _reqflg_dis,r10
337 mov.l _intnest_dis,r11
338
339 mov.l _stacktop_dis,r15 /* スタックを割込みスタックに切替え */
340 mov.l r1,@r11 /* 割込みネストカウンタを1にする */
341dispatcher_2:
342 ldc r9,sr /* 割り込み許可 */
343
344 /*
345 * Relase1.4.1で解決された制限事項
346
347 * 
348 * ディスパッチャの出口で実行すべきタスクがない(schedtsk==
349 * NULL)場合は、sleep命令によってプロセッサを省電力モードに切
350 * り替えて割込み待
351ちをしている。
352 * 
353 * 割込み許可後にsleep命令を実行しているため、割込み許可命令の
354 * 実行前に割込み要求がå…
355¥ã£ã¦ã„る場合(あるいは割込み許可直後、
356 * sleep命令実行前に割込み要求がå…
357¥ã£ãŸå ´åˆï¼‰ã€å‰²è¾¼ã¿è¨±å¯å‘½ä»¤ã®
358 * 実行とå…
359±ã«å‰²è¾¼ã¿ãŒå—け付けられ、その復帰後にsleepしたままに
360 * なり、reqflgのチェックに進まない。
361 * (1msec以内
362にタイマ割込みがå…
363¥ã‚‹ãŸã‚ã€å®Ÿéš›ã«ã¯sleepしたままと
364 * いうことはない。)
365 * 
366 * この問題は、割込みの許可とsleep状æ…
367‹ã¸ã®ç§»è¡ŒãŒã‚¢ãƒˆãƒŸãƒƒã‚¯ã«å®Ÿ
368 * 行できないことに起因する。SH3以降ではIPMとは別にSRのBLビット
369 * を使って割込みの禁止/許可を制御することにより、この問題を回
370 * 避できるが、SH1/2ではIPMを設定する以外に割込みを禁止/許可す
371 * る方法がなく、割込み許可(割込み待
372ちのIPM設定)とsleepをアト
373 * ミックに行う方法がない。
374 * そこでSH1依存部では、割込み受付時にスタックに積まれた戻り番
375 * 地を多重割込みの出口処理でチェックし、戻り番地が上記のsleep
376 * 命令に該当する場合は戻り番地を1命令分(2バイト)進めることに
377 * よりこの問題を回避している。
378 * ただし、この方法では多重割込みの出口処理に数命令のオーバー
379 * ヘッドが生じる。
380 * OMIT_POWER_CONTROLマクロを定義することでsleep命令の代わりに
381 * nop命令が挿å…
382¥ã•ã‚Œã€å¤šé‡å‰²è¾¼ã¿ã®å‡ºå£å‡¦ç†ã§ã®ãƒã‚§ãƒƒã‚¯ãƒ«ãƒ¼ãƒãƒ³
383 * は省略される。(この場合は消費電力の点で不利になる。)
384 */
385#ifndef OMIT_POWER_CONTROL
386_waiting_interrupt:
387 sleep /* 割込み待
388ち */
389#else /* OMIT_POWER_CONTROL */
390 nop
391#endif /* OMIT_POWER_CONTROL */
392 ldc r8,sr /* 割り込み禁止 */
393 mov.l @r10,r2 /* reqflgのチェック */
394 tst r2,r2 /* FALSEならば、もう1度割り込み待
395ち */
396 bt dispatcher_2
397 /* 遅
398延スロットなし */
399 mov.l r0,@r10 /* reqflgのクリア */
400 bra dispatcher
401 mov.l r0,@r11 /* 遅
402延スロット */
403 /* 割込みネストカウンタをクリア */
404
405 /*
406 * 割込み待
407ちの直前に行ったスタック切替の戻しを行っていないが、
408 * ディスパッチャの出口でTCBから取り出した値をスタックポイン
409 * タに設定するので問題ない。
410 */
411
412
413 .align 4
414_runtsk_dis:
415 .long _runtsk
416_schedtsk_dis:
417 .long _schedtsk
418_call_texrtn_dis:
419 .long _call_texrtn
420_mask_ipm_dis:
421 .long MAX_IPM << 4 /* 割込み禁止時のSRの値 */
422dispatch_r_k:
423 .long dispatch_r
424_stacktop_dis:
425 .long STACKTOP /* タスク独立部のスタックの初期値 */
426
427_intnest_dis: /* 割込み/CPU例外ネストカウンタ */
428 .long _intnest
429_reqflg_dis:
430 .long _reqflg
431
432#ifdef SUPPORT_CHG_IPM
433_task_intmask_dis: /* タスクコンテキストの割込みマスク */
434 .long _task_intmask
435#endif /* SUPPORT_CHG_IPM */
436
437
438/*
439 * 割込み/CPU例外のå…
440¥å£å‡¦ç†
441 */
442
443/*
444 * 割込み/CPU例外の際のスタックポインタが指し示す位置から
445 * SR,PCのコピーがある場所までのオフセット
446 *    
447 *   ここでいうスタックポインタとは割込み/CPU例外のå…
448¥å£å‡¦ç†ã§
449 *   プロシージャレジスタPRの退避が終わった直後の値を意味する。
450 *   SRはスタックå…
451ˆé ­ã‹ã‚‰40バイト下に、PCは36バイト下に積まれて
452 *   いる。  (ret_int_3を参ç…
453§ï¼‰
454 */
455#define SP_SR_OFFSET 40
456#define SP_PC_OFFSET 36
457
458/*
459 * CPU例外のå…
460¥å£å‡¦ç†ã®ç¶šã
461 *
462 * CPU例外ハンドラは,非タスクコンテキストで実行する.そのため,CPU例
463 * 外ハンドラを呼び出す前に割込みモードに移行し,リターンしてきた後に
464 * å…
465ƒã®ãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã™ï¼Žå…
466ƒã®ãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã™ãŸã‚ã«ï¼Œå‰²è¾¼ã¿ãƒ¢ãƒ¼ãƒ‰ã«ç§»è¡Œã™ã‚‹å‰
467 * の SR を割込みスタック上に保存する.CPU例外がタスクコンテキストで
468 * 発生し,reqflg が TRUE になった時に,ret_exc へ分岐する.
469 * reqflg をチェックする前に割込みを禁止しないと,reqflg をチェック後
470 * に起動された割込みハンドラ内
471でディスパッチが要求された場合に,ディ
472 * スパッチされない.
473 *  
474 * 一般不当命令の場合は戻り番地を2バイト進める必
475要があるが
476 * 対応していない
477 * (GDB stubがブレークポイントとして使用する。)
478 *  
479 *   CPU例外要因毎に展開されるルーチンでr0,r1を保存し、
480 *   割込み禁止にした後、
481 *    r1:割込み受付直後のSRのコピー
482 *    r2:C言語ルーチンのå…
483ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
484 *   の状æ…
485‹ã§ã“こに来る。
486 *   
487 *   レジスタ割当
488 *    r4:C言語ルーチンの引数
489 *      スタック上に積まれたSRのアドレス
490 *    r7:タスクスタックポインタ
491 */
492 .text
493 .align 2
494 .globl _cpu_exception_entry
495_cpu_exception_entry:
496 /* 残りのスクラッチレジスタをスタックに積む  */
497 mov.l r3,@-r15
498 mov.l r4,@-r15
499 mov.l r5,@-r15
500 mov.l r6,@-r15
501 mov.l r7,@-r15
502 sts.l pr,@-r15
503 mov r15,r4 /* C言語ルーチンの引数設定 */
504 add #SP_SR_OFFSET, r4
505 /* 割込み/CPU例外ネストカウンタのチェック */
506 mov.l _intnest_int, r5
507 mov.l @r5,r6
508 tst r6,r6 /* CPU例外発生時のコンテキストを判定 */
509 add #0x1,r6 /* 割込みネストカウンタをインクリメント */
510 /* add命令ではsrのTビットは変化しない */
511 mov.l r6,@r5
512 /* 多重例外ならジャンプ */
513 bf _exc_from_int
514 /* 遅
515延スロットなし */
516
517/* 初段のCPU例外の場合 */
518 /* スタックå…
519¥ã‚Œæ›¿ãˆå‰ã® */
520 /* タスクスタックポインタを保存 */
521 mov r15,r7
522 /* 割込みスタックに切り替え */
523 mov.l _stacktop_int,r15
524 ldc r1,sr /* 割込み許可 */
525 jsr @r2 /* C言語ルーチン呼び出し */
526 mov.l r7,@-r15 /* 遅
527延スロット  */
528 /* タスクスタックポインタを */
529 /* 割込みスタックに積む */
530
531 /* 割込み禁止 */
532 mov.l _mask_ipm_int,r0
533 ldc r0,sr
534 /* 割込み/CPU例外ネストカウンタをクリア */
535 mov.l _intnest_int,r0
536 mov #0x0,r1
537 mov.l r1,@r0
538 mov.l @r15,r15 /* スタック切替え */
539 /* reqflgのチェック */
540 mov.l _reqflg_int,r4
541 mov.l @r4,r5
542 tst r5,r5
543 bt 1f /* reqflg=FALSEの場合はret_to_task_excへ */
544 /* 遅
545延スロットなし */
546 bra ret_exc /* reqflg=TRUEの場合はret_excへ */
547 nop /* 遅
548延スロット */
549
550 /*
551 * bt命令ではret_to_task_excに届かないので、bra命令を1クッション
552 * å…
553¥ã‚Œã‚‹ã€‚
554 */
5551:
556 bra ret_to_task_exc /* reqflg=FALSEの場合 */
557 nop /* 遅
558延スロット */
559
560
561/* 多重CPU例外の場合 */
562/* CPU例外発生時のコンテキストを判別後、 */
563/* 割込み禁止 */
564/* r1:割込み受付時のsrのコピー */
565/* r2:C言語ルーチンのå…
566ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ */
567/* r4:C言語ルーチンの引数 */
568/* の状æ…
569‹ã§ã“こに飛んでくる */
570/* C言語ルーチンの引数設定と割込みネストカウンタの */
571/* インクリメントは済んでいる */
572
573_exc_from_int:
574 jsr @r2 /* C言語ルーチン呼び出し */
575 ldc r1,sr /* 割込み許可(遅
576延スロット) */
577
578 mov.l _mask_ipm_int,r0 /* 割込み禁止 */
579 ldc r0,sr
580 /* 割込み/CPU例外ネストカウンタをディクリメント */
581 mov.l _intnest_int,r3
582 mov.l @r3,r4
583 add #-1,r4
584 bra _ret_to_exc
585 mov.l r4,@r3 /* 遅
586延スロット */
587
588
589/*
590 * 割込みの口処理の続き
591 *
592 *   割込み要因毎に展開されるルーチンでr0,r1を保存し、
593 *   割込み禁止にした後、
594 *    r1:割込み受付直後のSRのコピー
595 *    r2:C言語ルーチンのå…
596ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
597 *   の状æ…
598‹ã§ã“こに来る。
599 *   
600 *   レジスタ割当
601 *    r7:タスクスタックポインタ
602 */
603 .text
604 .align 2
605 .globl _interrupt_entry
606_interrupt_entry:
607 /* 残りのスクラッチレジスタをスタックに積む  */
608 mov.l r3,@-r15
609 mov.l r4,@-r15
610 mov.l r5,@-r15
611 mov.l r6,@-r15
612 mov.l r7,@-r15
613 sts.l pr,@-r15
614 /* 割込み/CPU例外ネストカウンタのチェック */
615 mov.l _intnest_int, r5
616 mov.l @r5,r6
617 tst r6,r6 /* 割込み発生時のコンテキストを判定 */
618 add #0x1,r6 /* 割込みネストカウンタをインクリメント */
619 /* add命令ではsrのTビットは変化しない */
620 mov.l r6,@r5
621 /* 多重割込みならジャンプ */
622 bf _interrupt_from_int
623 /* 遅
624延スロットなし */
625
626/* 初段の割込みの場合 */
627 /* スタックå…
628¥ã‚Œæ›¿ãˆå‰ã® */
629 /* タスクスタックポインタを保存 */
630 mov r15,r7
631 /* 割込みスタックに切り替え */
632 mov.l _stacktop_int,r15
633 ldc r1,sr /* 割込み許可 */
634 jsr @r2 /* C言語ルーチン呼び出し */
635 mov.l r7,@-r15 /* 遅
636延スロット  */
637 /* タスクスタックポインタを */
638 /* 割込みスタックに積む */
639
640 /* 割込み禁止 */
641 mov.l _mask_ipm_int,r0
642 ldc r0,sr
643 /* 割込み/CPU例外ネストカウンタをクリア*/
644 mov.l _intnest_int,r0
645 mov #0x0,r1
646 mov.l r1,@r0
647 mov.l @r15,r15 /* スタック切替え */
648 /* reqflgのチェック */
649 mov.l _reqflg_int,r4
650 mov.l @r4,r5
651 tst r5,r5
652 bt ret_to_task_int /* reqflg=FALSEの場合 */
653 /* 遅
654延スロットなし */
655 bra ret_int /* reqflg=TRUEの場合 */
656 nop /* 遅
657延スロット */
658
659
660/* 多重割込みの場合 */
661/* 割込み発生時のコンテキストを判別後、 */
662/* 割込み禁止 */
663/* r1:割込み受付時のsrのコピー */
664/* r2:C言語ルーチンのå…
665ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ */
666/* の状æ…
667‹ã§ã“こに飛んでくる */
668/* (割込みネストカウンタのインクリメントは済んでいる) */
669
670_interrupt_from_int:
671 jsr @r2 /* C言語ルーチン呼び出し */
672 ldc r1,sr /* 割込み許可(遅
673延スロット) */
674
675 mov.l _mask_ipm_int,r0 /* 割込み禁止 */
676 ldc r0,sr
677 /* 割込み/CPU例外ネストカウンタをディクリメント */
678 mov.l _intnest_int,r3
679 mov.l @r3,r4
680 add #-1,r4
681 mov.l r4,@r3
682
683
684/* 多重割込み/CPU例外からの復帰処理
685 *
686 * ・ディスパッチもタスク例外処理も必
687要ない
688 * ・chg_ipm()の処理は必
689要ない
690 *  (非タスクコンテキストでは、chg_ipm()は使用不可)
691 *
692 *
693 * ディスパッチャの出口で実行すべきタスクがない(schedtsk==NULL)場合
694 * は、sleep命令によってプロセッサを省電力モードに切り替えて割込み待
695
696 * ちをしている。(dispatcher_2付近を参ç…
697§ï¼‰
698 *
699 * 割込み許可後にsleep命令を実行しているため、割込み許可命令の実行前
700 * に割込み要求がå…
701¥ã£ã¦ã„る場合(あるいは割込み許可直後、sleep命令実
702 * 行前に割込み要求がå…
703¥ã£ãŸå ´åˆï¼‰ã€å‰²è¾¼ã¿è¨±å¯å‘½ä»¤ã®å®Ÿè¡Œã¨å…
704±ã«å‰²è¾¼ã¿ãŒ
705 * 受け付けられ、その復帰後にsleepしたままになってしまう。
706 * (reqflgのチェックに進まない。)この問題は、割込みの許可とsleep 状
707 * æ…
708‹ã¸ã®ç§»è¡ŒãŒã‚¢ãƒˆãƒŸãƒƒã‚¯ã«å®Ÿè¡Œã§ããªã„ことに起因する。
709 * これを防ぐため、割込みの出口で戻りå…
710ˆã‚¢ãƒ‰ãƒ¬ã‚¹ãŒå•é¡Œã®sleep命令であ
711 * る場合、戻り番地を1命令分進める処理をしている。(実行すべきタスク
712 * がなく、ディスパッテャ内
713で割込み待
714ち中に割込みを受け付けた場合は、
715 * ディスパッチャの二重呼び出しを避けるため、多重割込みとして処理して
716 * いるため、下記の_ret_to_intを通過する。
717 */
718_ret_to_int:
719_ret_to_exc:
720
721#ifndef OMIT_POWER_CONTROL
722 /* r4←スタック上に積まれた戻り番地 */
723 mov.l @(SP_PC_OFFSET, r15), r4
724 mov.l _waiting_interrupt_int, r5
725 cmp/eq r4, r5
726 bf _ret_to_int_1
727 add #2, r4
728 mov.l r4, @(SP_PC_OFFSET, r15)
729#endif /* OMIT_POWER_CONTROL */
730
731_ret_to_int_1:
732 lds.l @r15+,pr /* レジスタ復å…
733ƒ */
734 mov.l @r15+,r7
735 mov.l @r15+,r6
736 mov.l @r15+,r5
737 mov.l @r15+,r4
738 mov.l @r15+,r3
739 mov.l @r15+,r2
740 mov.l @r15+,r1
741 mov.l @r15+,r0
742 rte /* 割込みå…
743ƒã«æˆ»ã‚‹ */
744 nop
745
746 .align 4
747_stacktop_int: /* タスク独立部のスタックの初期値 */
748 .long STACKTOP
749_intnest_int: /* 割込み/CPU例外ネストカウンタ */
750 .long _intnest
751_reqflg_int:
752 .long _reqflg
753_mask_ipm_int: /* 割込み禁止用マスク */
754 .long MAX_IPM << 4 /* ipm以外のビットはゼロで良い */
755
756#ifndef OMIT_POWER_CONTROL
757_waiting_interrupt_int:
758 .long _waiting_interrupt
759#endif /* OMIT_POWER_CONTROL */
760
761/*
762 * 割込みハンドラ/CPU例外ハンドラ出口処理
763 *
764 * 戻りå…
765ˆãŒã‚¿ã‚¹ã‚¯ã§reqflgがセットされている場合のみここにくる。
766 * 割込みネストカウンタ = 0,割込み禁止状æ…
767‹,スクラッチレジスタを
768 * 保存した状æ…
769‹ã§å‘¼ã³å‡ºã™ã“と。
770 *
771 * r4には変数reqflgのアドレスが代å…
772¥ã•ã‚ŒãŸçŠ¶æ…
773‹ã§ã“こに来る。
774 *
775 */
776 .text
777 .align 2
778ret_int:
779ret_exc:
780 /*
781 * 戻りå…
782ˆãŒå‰²è¾¼ã¿ã®å…
783¥å£å‡¦ç†ã‹å¦ã‹ã®åˆ¤åˆ¥
784 * 
785 * SH1では割込み受付直後に割込み禁止になっていないため、割込みA
786 * のå…
787¥å£å‡¦ç†ä¸­ã«åˆ¥ã®å‰²è¾¼ã¿Bがå…
788¥ã‚‹å¯èƒ½æ€§ãŒã‚る。(これはハード
789 * ウェアのアーキテクチャ上避けようがない。)割込みハンドラB内
790
791 * でタスク切り替えを起こすようなサービスコールを呼ぶと割込みB
792 * の出口処理で別のタスクにディスパッチしてしまい、タスク2から
793 * å…
794ƒã®ã‚¿ã‚¹ã‚¯ã«æˆ»ã£ã¦ãã‚‹ã¾ã§ã€å‰²è¾¼ã¿Aの処理が遅
795れてしまう。
796 * また、割込みAがレベルトリガだと2回検出されてしまう問題もある。
797 * これを防ぐため、スタックに積んである戻りå…
798ˆã®IPMとtask_intmask
799 * の値を比較して、å…
800¥å£å‡¦ç†ä¸­ã«å‰²è¾¼ã¿ãŒå…
801¥ã‚‰ãªã‹ã£ãŸã‹ãƒã‚§ãƒƒã‚¯ã—
802 * ている。ディスパッチする前のタイミングで判別しているので、
803 * chg_ipm()でtask_intmaskが書き換えられている心é…
804ã¯ãªã„。
805 */
806 /* r0←スタックに積まれたsr */
807 mov.l @(SP_SR_OFFSET,r15),r0
808#ifdef SUPPORT_CHG_IPM
809 mov.l _task_intmask_ret,r2 /* r2←&task_intmask */
810 and #0xf0, r0 /* IPM取り出し */
811 mov.l @r2,r3 /* r3←task_intmask */
812 cmp/eq r0, r3 /* 戻りå…
813ˆãŒå‰²è¾¼ã¿ã®å…
814¥å£å‡¦ç†ã‹ï¼Ÿ */
815#else /* SUPPORT_CHG_IPM */
816 /*
817 * chg_ipmをサポートしない場合は、タスクコンテキストのIPMは
818 * 常に0x0
819 */
820 and #0xf0, r0 /* IPM取り出し */
821 cmp/eq #0x00, r0 /* 戻りå…
822ˆãŒå‰²è¾¼ã¿ã®å…
823¥å£å‡¦ç†ã‹ï¼Ÿ */
824#endif /* SUPPORT_CHG_IPM */
825 bf ret_to_task_int /* ディスパッチしないで割込みå…
826ƒã« */
827 /* 戻る処理へ */
828 /* 遅
829延スロットなし */
830
831#ifdef SUPPORT_CPU_EXC_ENTRY_CHECK
832 /*
833 * 戻りå…
834ˆãŒCPU例外のå…
835¥å£å‡¦ç†ã‹å¦ã‹ã®åˆ¤åˆ¥
836 * 
837 * SH1ではCPU例外も割込みとほぼ同じ出å…
838¥å£å‡¦ç†ã‚’行っているが、
839 * CPU例外を受け付けても割込みマスクは変化しない。CPU例外のå…
840¥
841 * 口処理中に割込みがå…
842¥ã£ãŸå ´åˆã«å‚™ãˆã¦ã€ã‚¹ã‚¿ãƒƒã‚¯ä¸Šã«ç©ã¾ã‚ŒãŸ
843 * 戻り番地を使って判別を行う。
844 * 
845 * 
846 *  check_exc_entry()のAPI
847 *   引数r4:スタック上に積まれた戻り番地
848 *   戻り値r0:
849 *     1:戻りå…
850ˆãŒCPU例外のå…
851¥å£å‡¦ç†
852 *     0:それ以外
853 */
854 mov.l _check_exc_entry_ret, r1
855 jsr @r1 /* C言語ルーチン呼び出し */
856 mov.l @(SP_PC_OFFSET, r15), r4 /* 引数設定(遅
857延スロット) */
858
859 tst r0, r0 /* 戻り値の判定 */
860 bf ret_to_task_int /* 戻りå…
861ˆãŒCPU例外のå…
862¥å£å‡¦ç†ã§ã‚れば */
863 /*  ディスパッチしないで割込みå…
864ƒã«æˆ»ã‚‹ */
865 /* 遅
866延スロットなし */
867
868#endif /* SUPPORT_CPU_EXC_ENTRY_CHECK */
869
870 /*
871 * reqflgのクリア
872 * 
873 * ここに到達する前にreqflgをクリアしてしまうと、上記の割込みA
874 * の出口処理でディスパッチャ呼び出しが必
875要なケースでもディス
876 * パッチャが呼び出されない。
877 * (割込みBでreqflgをセットして、割込みAでreqflgに変化がない場
878 *  合)
879 */
880 mov #0x0, r0
881 mov.l _reqflg_ret,r1
882 mov.l r0, @r1 /* reqflg <- 0 */
883
884 mov.l _runtsk_ret,r1 /* r7 <- runtsk */
885 mov.l @r1,r7
886 mov.l _enadsp_ret,r2 /* enadspのチェック */
887 mov.l @r2,r3
888 tst r3,r3 /* ディスパッチ禁止ならret_int_1へ */
889 bt ret_int_1
890 /* 遅
891延スロットなし */
892
893 mov.l _schedtsk_ret,r4 /* r5 <- schedtsk */
894 mov.l @r4,r5
895 cmp/eq r7,r5 /* runtsk と schedtsk を比較 */
896 bt ret_int_1 /* 同じならret_int_1へ */
897 /* 遅
898延スロットなし */
899
900 mov.l r8,@-r15 /* 残りのレジスタを保存 */
901 mov.l r9,@-r15
902 mov.l r10,@-r15
903 mov.l r11,@-r15
904 mov.l r12,@-r15
905 mov.l r13,@-r15
906 mov.l r14,@-r15
907 sts.l mach,@-r15
908 sts.l macl,@-r15
909 stc.l gbr,@-r15
910 /*
911 * タスクコントロールブロックTCB中のsp,pcがå…
912ˆé ­ã‹ã‚‰60バイトの
913 * 範囲内
914にあり、アラインメントが4バイト境界になっていれば、
915 * イミディエイト相対アドレッシングでアクセスできる
916 */
917#ifdef TCB_SHORT
918 /* タスクスタックポインタを保存 */
919 mov.l r15,@(TCB_sp, r7)
920 mov.l ret_int_r_ret,r1 /* 実行再開番地 */
921 bra dispatcher
922 mov.l r1,@(TCB_pc, r7) /* 遅
923延スロット */
924
925#else /* TCB_SHORT */
926 mov #TCB_sp,r1 /* タスクスタックを保存 */
927 mov.l r15,@(r7,r1)
928 mov.l ret_int_r_ret,r1 /* 実行再開番地を保存 */
929 mov #TCB_pc,r2 /* ディスパッチャからの戻りå…
930ˆã‚’ */
931 /* ret_int_rに設定  */
932 bra dispatcher
933 mov.l r1,@(r7,r2) /* 遅
934延スロット */
935#endif /* TCB_SHORT */
936
937/*
938 * 割込みの出口でディスパッチャからここに戻ってくる
939 * r7にruntskが代å…
940¥ã•ã‚ŒãŸçŠ¶æ…
941‹ã§ã“こに来る
942 */
943ret_int_r:
944 ldc.l @r15+,gbr /* レジスタを復帰 */
945 lds.l @r15+,macl
946 lds.l @r15+,mach
947 mov.l @r15+,r14
948 mov.l @r15+,r13
949 mov.l @r15+,r12
950 mov.l @r15+,r11
951 mov.l @r15+,r10
952 mov.l @r15+,r9
953 mov.l @r15+,r8
954
955 /*
956 * ディスパッチャからret_int_rに分岐した場合、
957 * ret_intから直接ここに分岐した場合、
958 * いずれの場合も、r7にruntskが代å…
959¥ã•ã‚Œã¦ã„ã‚‹
960 *
961 *  レジスタ割り当て
962 * r7 : runtsk
963 * r0 : runtsk->enatex
964 *     mov.b @(imm, r),r0命令はオペランドがr0に
965 *     固定されている
966 * r2 : runtsk->texptn
967 * r3 : call_texrtn()のå…
968ˆé ­ç•ªåœ°
969 */
970ret_int_1:
971 mov.b @(TCB_enatex,r7),r0 /* オペランドがr0に固定 (d) */
972 and #TCB_enatex_mask,r0
973 tst r0,r0 /* runtsk->enatexのチェック */
974 bt ret_int_2
975 /* 遅
976延スロットなし */
977 mov.l @(TCB_texptn,r7),r2 /* runtsk->texptnのチェック */
978 tst r2,r2
979 bt ret_int_2
980 /* 遅
981延スロットなし */
982 mov.l _call_texrtn_ret,r3 /* タスク例外処理ルーチン起動 */
983 jsr @r3
984 nop /* 遅
985延スロット */
986
987ret_int_2:
988#ifdef SUPPORT_CHG_IPM
989 /*
990 * SH1では割込みからのリターン命令でハードウェアがスタック上
991 * のデータを読み出してSRを復å…
992ƒã™ã‚‹ã€‚
993 * 割込みによって別のタスクに切り替わった場合は、タスクコンテ
994 * キストのIPMが変更されている可能性があるのでスタック上のSR
995 * のコピーに含まれるIPMを更新しておく必
996要がある。
997 */
998 /* r0←スタックに積まれたsr */
999 mov.l @(SP_SR_OFFSET,r15),r0
1000 mov.l _unmask_ipm_ret,r1
1001 mov.l _task_intmask_ret,r2 /* r2←&task_intmask */
1002 and r1,r0 /* IPMビットをクリア */
1003 mov.l @r2,r3 /* r3←task_intmask */
1004 or r3,r0 /* IPMビットをセット */
1005 /* スタックに積んであるsrに上書き */
1006 mov.l r0,@(SP_SR_OFFSET,r15)
1007#endif /* SUPPORT_CHG_IPM */
1008
1009 /*
1010 * タスクへの復帰処理
1011 *  ディスパッチャ呼び出しが要らない場合はここから合流する。
1012 *  å…
1013¥å£å‡¦ç†ã®é€”中で割込みがå…
1014¥ã£ãŸå ´åˆã¯ã€å…
1015¥å£å‡¦ç†ãŒæˆ»ã‚Šå…
1016ˆã«
1017 *  なる。
1018 */
1019ret_to_task_int:
1020ret_to_task_exc:
1021 /* pr,スクラッチレジスタを復帰 */
1022 /* スタックのå…
1023ˆé ­ã‹ã‚‰ã®ã‚ªãƒ•ã‚»ãƒƒãƒˆ */
1024 lds.l @r15+,pr /* +0:PR */
1025 mov.l @r15+,r7 /* +4:r7 */
1026 mov.l @r15+,r6 /* +8:r6 */
1027 mov.l @r15+,r5 /* +12:r5 */
1028 mov.l @r15+,r4 /* +16:r4 */
1029 mov.l @r15+,r3 /* +20:r3 */
1030 mov.l @r15+,r2 /* +24:r2 */
1031 mov.l @r15+,r1 /* +28:r1 */
1032 mov.l @r15+,r0 /* +32:r0 */
1033 /* +36:PC */
1034 /* +40:SR */
1035 rte
1036 nop /* 遅
1037延スロット */
1038 .align 4
1039_reqflg_ret:
1040 .long _reqflg
1041_call_texrtn_ret:
1042 .long _call_texrtn
1043_runtsk_ret:
1044 .long _runtsk
1045_schedtsk_ret:
1046 .long _schedtsk
1047_enadsp_ret:
1048 .long _enadsp
1049ret_int_r_ret:
1050 .long ret_int_r
1051
1052#ifdef SUPPORT_CHG_IPM /* chg_ipm()をサポートする場合 */
1053_unmask_ipm_ret:
1054 .long ~0xf0 /* ipmビット以外すべて1 */
1055_task_intmask_ret:
1056 .long _task_intmask
1057#endif /* SUPPORT_CHG_IPM */
1058
1059#ifdef SUPPORT_CPU_EXC_ENTRY_CHECK
1060_check_exc_entry_ret:
1061 .long _check_cpu_exc_entry
1062#endif /* SUPPORT_CPU_EXC_ENTRY_CHECK */
1063
1064
1065/*
1066 * no_reg_exception()
1067 * CPU例外として登録されていない例外が発生すると呼び出される
1068 * 例外が発生した時点のpc,sr,pr,r0〜15を出力してカーネル
1069 * を停止する。
1070 */
1071 .text
1072 .align 2
1073 .globl _no_reg_exception
1074_no_reg_exception:
1075 /* pr,r0〜15を保存 */
1076 sts.l pr, @-r15
1077 mov.l r15,@-r15
1078 mov.l r14,@-r15
1079 mov.l r13,@-r15
1080 mov.l r12,@-r15
1081 mov.l r11,@-r15
1082 mov.l r10,@-r15
1083 mov.l r9, @-r15
1084 mov.l r8, @-r15
1085 mov.l r7, @-r15
1086 mov.l r6, @-r15
1087 mov.l r5, @-r15
1088 mov.l r4, @-r15
1089 mov.l r3, @-r15
1090 mov.l r2, @-r15
1091 mov.l r1, @-r15
1092 mov.l r0, @-r15
1093
1094 /* cpu_experr()の呼び出し */
1095 mov.l _cpu_experr_k,r1 /* (cpu_config.c) */
1096 jsr @r1
1097 mov r15, r4 /* 引数設定(遅
1098延スロット) */
1099
1100 .align 4
1101_cpu_experr_k:
1102 .long _cpu_experr
1103
1104
1105
1106/* イミディエイト相対アドレッシングが可能かチェック */
1107#if !(CHECK_IMMEDIATE_ADDRESSING(TCB_tinib) \
1108 && CHECK_IMMEDIATE_ADDRESSING(TINIB_task) \
1109 && CHECK_IMMEDIATE_ADDRESSING(TINIB_exinf) )
1110
1111ここでアセンブル・エラー
1112#endif
1113
1114
1115/*
1116 * タスク起動処理
1117 *   dispatcherから呼ばれるので、r7にruntskが代å…
1118¥ã•ã‚Œã¦ã„ã‚‹
1119 *
1120 */
1121 .text
1122 .align 2
1123 .globl _activate_r
1124_activate_r:
1125 /* 割り込み許可の準備 */
1126#ifndef SUPPORT_CHG_IPM /* (t_unlock_cpu相当の処理) */
1127 mov #0,r1 /* IPM以外のビットも破壊される */
1128#else /* SUPPORT_CHG_IPM */
1129 mov.l _task_intmask_act,r2
1130 mov.l @r2,r1
1131#endif /* SUPPORT_CHG_IPM */
1132 ldc r1,sr /* 割込み許可 */
1133 mov.l _ext_tsk_act,r3
1134 lds r3,pr /* タスクからの戻り番地を設定 */
1135
1136 /*
1137 * ここで割込みがå…
1138¥ã£ã¦runtskが書き換わっても、
1139 * このタスクに戻ってくるときにはruntskの値も
1140 * 当然、å…
1141ƒã«æˆ»ã£ã¦ã„ã‚‹
1142 *
1143 * レジスタ割り当て
1144 *   r7:runtsk
1145 *   r1:&(runtsk->tinib)
1146 *   r2:runtsk->tinib->task
1147 *   r4:タスクの拡張情
1148報(引数)
1149 */
1150 mov.l @(TCB_tinib,r7),r1
1151 mov.l @(TINIB_task,r1),r2 /* タスク起動番地 */
1152 jmp @r2 /* jsr命令ではprを破壊してしまう*/
1153 mov.l @(TINIB_exinf,r1),r4 /* 遅
1154延スロット */
1155 /* 拡張情
1156報(タスクへの引数) */
1157 .align 4
1158_ext_tsk_act:
1159 .long _ext_tsk
1160
1161#ifdef SUPPORT_CHG_IPM
1162_task_intmask_act:
1163 .long _task_intmask
1164#endif /* SUPPORT_CHG_IPM */
1165
1166/*
1167 * 微少時間待
1168ち
1169 */
1170 .globl _sil_dly_nse
1171_sil_dly_nse:
1172
1173 mov.l _sil_dly_tim1, r1 /* r4から SIL_DLY_TIM1 を引く */
1174 add r1, r4
1175 cmp/pl r4 /* 結果が 0 以下ならリターン */
1176 bt _sil_dly_nse1
1177 /* 遅
1178延スロットなし */
1179 rts
1180 nop
1181_sil_dly_nse1:
1182 mov.l _sil_dly_tim2, r1 /* r4から SIL_DLY_TIM2 を引く */
1183 add r1, r4
1184 cmp/pl r4 /* 結果が 0 以下ならリターン */
1185 bt _sil_dly_nse1
1186 /* 遅
1187延スロットなし */
1188 rts
1189 nop
1190 .align 4
1191_sil_dly_tim1:
1192 .long -SIL_DLY_TIM1
1193_sil_dly_tim2:
1194 .long -SIL_DLY_TIM2
1195
1196
1197/*
1198 * 備忘録
1199 *   dispatcher内
1200(a)行でcmp/eq imm,r0命令を使わない理由
1201 *   
1202 *   dispatcherでr7にruntskの値を代å…
1203¥ã—、分岐å…
1204ˆã®dispatch_r、
1205 *   ret_int_r、activate_rでは無駄なロードをしないようにしてい
1206 *   る。
1207 *   schedtskの有無をチェックするときのcmp/eq imm,r0命令((a)
1208 *   行)がオペランドをr0に固定されているため、それに合わせて、
1209 *   最初はruntskにr0を割り当てていた。
1210 *   しかし、r0は各分岐å…
1211ˆã«ã‚ã‚‹enatexの読み出し(c),(d)行のmov.b
1212 *   命令でも予約しているため、できれば空けておきたい。
1213 *   (mov.b @(imm, r),r0命令はオペランドがr0に固定されている。)
1214 *   従って、runtskはr7に割り当て、(a)行はcmp/eq imm,r0命令から
1215 *   cmp/eq rn,rm命令に変更した。そのため、レジスタに0を代å…
1216¥ã™ã‚‹
1217 *   命令((b)行)が1つ余分にå…
1218¥ã£ã¦ã„る。
1219 *
1220 *   一方、mov.l @(imm, r),r0命令はオペランドがr0に固定されて
1221 *   いない。
1222 *   SH3版のようにmakeoffset.cでラベルBIT_BWを指定すれば、4バ
1223 *   イト単位でオフセットとマスクが生成されるので、mov.l命令が
1224 *   使え、レジスタ割付が楽になるが、enatex判定時のマスクデー
1225 *   タがand命令のイミディエート値に収まり切らなくなるため、
1226 *   ロード命令が1つ余分にå…
1227¥ã‚‹ã€‚
1228 *   どちらも一長一短があるが、いずれにしろ、runtskを再ロード
1229 *   するよりはマシと思われる。
1230 */
Note: See TracBrowser for help on using the repository browser.