e2 studio v7.5.0のStack Analysis ViewはGNURXでは1箇所でも関数ポインタで関数呼び出しするとERRORになって使えませんね

こんにちは。NoMaYです。

e2 studio 7.5.0+RXスマートコンフィグレータplugin 7.5.0+GNURX 2019q2(4.8.4.201902)で作業していてスタック解析ビューの致命的な(だと私は思う)制限事項に気付きました。1箇所でも関数ポインタで関数呼び出しする箇所があると、以下の画面コピーの通り(原因が大変分かり難い)エラーになってしまうのですが、そもそもR_BSPモジュールにそういう箇所が存在していますので、実務的には全く使えない、ということになりますね。(ちなみに、FreeRTOS Kernelのソースにもそういう箇所が存在していますし、FITの各モジュールでのコールバック関数の呼び出しも関数ポインタを使用した関数呼び出しですね。)

現象再現プロジェクトのファイル一式
issue_20191007.zip    162KB

e2 studioのスタック解析ビューはGNURXでは関数ポインタで関数呼び出ししているとエラーになる


素朴に関数呼び出ししているのであればスタック解析ビューにスタック情報が表示される

 

  • NoMaY さん
    ほや です。こんにちは。

    既知の問題として挙がっていますね。
    IDE-28579
    : Stack Analysis doesn't work in the case of function pointers
    https://www2.renesas.eu/_custom/software/ree_eclipse/e2studio7/docs/releasenotes/7.5.0/openissues.htm

  • ほや さん、こんにちは。NoMaYです。

    情報有難う御座います。このページをブラウザのお気に入りメニューに登録しないといけないですね、、、

    バグ内容

    [GCCRX, GCCRL, GNU ARM Embedded] In a project that has function pointers, the Stack Analysis view cannot work correctly and not display information.


    [GCCRX, GCCRL, GNU ARM Embedded] (私の訳です)関数ポインタの使われているプロジェクトではスタック解析ビューは正しく動作せず情報を表示しません。


    回避策

    Add options to display stack information as warning message in Stack Analysis view to the specified files (except file has function pointers) which you want to see the stack size and rebuild, stack size information for functions in these files can display in Stack Analysis view.


    (意訳すると)関数ポインタの使われているソースを見つけてスタック情報を生成させないようにファイル単位でスタック情報生成オプションを外して下さい(付加しないようにして下さい)。
    (原文は、スタック情報を見たいファイル(ただし関数ポインタの使われていないソースであること)にだけスタック情報生成オプションを付加して下さい、かな。)


    思うに、原文の方法では甚だ、私の意訳の方法でもやっぱり、必要スタックサイズを見積もりたいのだけれど、というニーズには厳しいかな、という気がしました。

  • こんにちは。NoMaYです。

    e2 studio v7.6.0がリリースされましたが、バグリストを見ると、修正されたようでした。(ちなみに、さっそくこのページもブラウザのお気に入りメニュー/ブックマークメニューに登録しました。)

    e²studio 7.6 Known Issues List
    List generated on 02/10/2019 17:40:14
    www2.renesas.eu/_custom/software/ree_eclipse/e2studio7/docs/releasenotes/7.6.0/openissues.htm

    IDE-28579

    Stack Analysis doesn't work in the case of function pointers

    Stack Analysis View

    [GCCRX, GCCRL, GNU ARM Embedded] In a project that has function pointers, the Stack Analysis view cannot work correctly and not display information. [Workaround] Add options to display stack information as warning message in Stack Analysis view to the specified files (except file has function pointers) which you want to see the stack size and rebuild, stack size information for functions in these files can display in Stack Analysis view. This issue is fixed by e2 studio 7.6.


    [思い付き]

    このページですが、e2 studioのヘルプメニューから開けるようになっていたら便利かも、、、

    [追記]

    オイオイwww


    IDE-29941

    e2 GDB Server stopped working when setting Eventpoints

    GDB server RX

    When you terminate a debug session after running it for a long time (more than 45 minutes), GDB server sometimes crash.


  • こんにちは。NoMaYです。

    この不具合が修正されたというe2 studio v7.6.0を実際に動かしてみると、確かにGNURXでもスタック解析ビューにスタック情報が表示されるようになりました。ただ、以前に作成したCC-RX版FreeRTOSプロジェクトと現在手元で作成中のGNURX版FreeRTOSプロジェクトを較べると、違和感を感じるほどにスタックサイズが小さいです。もちろん、1つの理由としてすぐに思い浮かぶのが、今回、試しにnewlib-nanoのpre-buildを使ってビルドしたのですが、このライブラリの分は計上されていないと思います。もう1つは、予感として、引数や戻り番地の分が計上されていないかも知れない、という気がします。後日、調べてみようと思います。

    以下、画面コピーです。

    e2 studio v7.6.0でGNURXでもスタック解析ビューにスタック情報が表示されるようになった


    以前にCC-RXでスタック解析ビューにスタック情報を表示させた時はスタック使用量がもっと多かったのだが、、、

  • こんにちは。NoMaYです。

    別スレッド『GNURX用のCCRXmachine.hとCCRXmachine.cというソースがe2 studioフォルダにありました(内容は概ね名前から予想される通りのものでした)』に投稿したのですが、先月リリースされたGNURX 8.3.0.202002(及びGNURL78 4.9.2.202002)でスタック使用量の計算方法の修正があったようなので調べてみました。

    調査に使ったプロジェクトのファイル一式
    issue_20200509.zip    742KB

    上記に含まれるビルド結果のフォルダ一覧
    HardwareDebug.8.3.0.201904.O0 → GNURX 8.3.0.201904 最適化無し (-O0)
    HardwareDebug.8.3.0.201904.O2 → GNURX 8.3.0.201904 最適化レベル2 (-O2)
    HardwareDebug.8.3.0.201904.Og → GNURX 8.3.0.201904 デバッグ優先最適化 (-Og)
    HardwareDebug.8.3.0.202002.O0 → GNURX 8.3.0.202002 最適化無し (-O0)
    HardwareDebug.8.3.0.202002.O2 → GNURX 8.3.0.202002 最適化レベル2 (-O2)
    HardwareDebug.8.3.0.202002.Og → GNURX 8.3.0.202002 デバッグ優先最適化 (-Og)

    結果は以下の表の通り、かなり期待値と一致するようになっていました。ただ、まだ以下の不一致が残っていました。また、一致していても疑念のある項目もあります。

    GNURX 8.3.0.202002で残っているスタック使用量の不一致の内容

    (1) 最適化ありの場合に通常の関数で表示値が期待値より4バイト多い (表の赤色文字/ピンク色背景の箇所)
    (2) 割り込み関数でPSWの分を計上し忘れている気がします (表の赤色文字/黄色背景の箇所)

    GNURX 8.3.0.202002でスタック使用量が一致していても疑念のある内容(ただし直感でしかないですが)

    (3) 最適化ありの場合に通常の関数で基本的に表示値が期待値より4バイト多いが別要因発生により運良く一致? (表の青色文字/ピンク色背景の箇所)
    (4) 割り込み関数では基本的にPSWの分を計上し忘れているが別要因発生により運良く一致? (表の青色文字/黄色背景の箇所)

        GNURX 8.3.0.201904   GNURX 8.3.0.202002  
        -O0 -O2 -Og   -O0 -O2 -Og  
        表示値 期待値 表示値 期待値 表示値 期待値   表示値 期待値 表示値 期待値 表示値 期待値  
    func0   0 8 0 4 0 4   8 8 8 4 8 4  
    func1   4 12 0 4 0 4   12 12 8 4 8 4  
    func4   16 24 0 4 0 4   24 24 8 4 8 4  
    func5   20 32 4 8 4 8   28 32 12 8 12 8  
    func8   32 52 16 24 16 24   52 52 24 24 24 24  
    main   48 100 32 72 32 72   100 100 72 72 72 72  
    INT_Excep_PERIB_INTB181   0 12 0 8 0 8   8 12 8 8 8 8  

    スタック解析ビューの表示は以下の画面コピーの通り、[呼び出し先関数との合計を表示]に設定しています。また、期待値はリストファイルのアセンブラコードから求めたものです。



    以下、それぞれのスタック解析ビューの画面コピーです。

    GNURX 8.3.0.201904 最適化無し (-O0)


    GNURX 8.3.0.201904 最適化レベル2 (-O2)


    GNURX 8.3.0.201904 デバッグ優先最適化 (-Og)


    GNURX 8.3.0.202002 最適化無し (-O0)


    GNURX 8.3.0.202002 最適化レベル2 (-O2)


    GNURX 8.3.0.202002 デバッグ優先最適化 (-Og)


    以下、ソースコード(抜粋)と幾つかのリストファイル(抜粋)です。

    src/Test.c

    uint32_t func0( void )
    {
        return 0;
    }

    uint32_t func1( uint32_t a1 )
    {
        return a1;
    }

    uint32_t func4( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4 )
    {
        return a1 + a2 + a3 + a4;
    }

    uint32_t func5( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5 )
    {
        return a1 + a2 + a3 + a4 + a5;
    }

    uint32_t func8( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5,
    uint32_t a6, uint32_t a7, uint32_t a8 )
    {
        return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
    }

    src/TestStackAnalysisForGNURX.c

    extern volatile uint32_t a1, a2, a3, a4, a5, a6, a7, a8;
    extern volatile uint32_t r0, r1, r4, r5, r8;
    int main(void)
    {
        r0 = func0();
        r1 = func1( a1 );
        r4 = func4( a1, a2, a3, a4 );
        r5 = func5( a1, a2, a3, a4, a5 );
        r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 );
    #if 1
        (*fptr)();
    #elif 0
        func();
    #endif

        while(1)
        {
            // TODO: add application code here
        }
        return 0;
    }

    generate/interrupt_handlers.h

    void INT_Excep_PERIB_INTB181(void) __attribute__ ((interrupt));

    generate/inthandler.c

    void INT_Excep_PERIB_INTB181(void){ }

    HardwareDebug.8.3.0.202002.O2/Test.lst

       7                                _func0:
      12:../src/Test.c **** uint32_t func0( void )
      13:../src/Test.c **** {
      14:../src/Test.c ****     return 0;
      15:../src/Test.c **** }
      13 0000 66 01                         mov.L   #0, r1
      14 0002 02                            rts ⇒ スタック使用量の期待値 = 4
      20                                _func1:
      17:../src/Test.c **** uint32_t func1( uint32_t a1 )
      18:../src/Test.c **** {
      19:../src/Test.c ****     return a1;
      20:../src/Test.c **** }
      26 0000 02                            rts ⇒ スタック使用量の期待値 = 4
      32                                _func4:
      22:../src/Test.c **** uint32_t func4( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4 )
      23:../src/Test.c **** {
      24:../src/Test.c ****     return a1 + a2 + a3 + a4;
      38 0000 4B 34                         add r3, r4
      40 0002 4B 24                         add r2, r4
      25:../src/Test.c **** }
      42 0004 4B 41                         add r4, r1
      44 0006 02                            rts ⇒ スタック使用量の期待値 = 4
      50                                _func5:
      27:../src/Test.c **** uint32_t func5( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
    uint32_t a5 )
      28:../src/Test.c **** {
      54 0000 60 40                         sub #4, r0
      29:../src/Test.c ****     return a1 + a2 + a3 + a4 + a5;
      58 0002 06 89 04 02                   add 8[r0].L, r4
      60 0006 4B 34                         add r3, r4
      61 0008 4B 24                         add r2, r4
      30:../src/Test.c **** }
      63 000a 4B 41                         add r4, r1
      65 000c 67 01                         rtsd    #4 ⇒ スタック使用量の期待値 = 8
      71                                _func8:
      32:../src/Test.c **** uint32_t func8( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
    uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8 )
      33:../src/Test.c **** {
      75 0000 7E A7                         push.l  r7
      77 0002 71 00 F0                      add #-16, r0
      34:../src/Test.c ****     return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
      81 0005 75 47 18                      mov.L   #24, r7
      82 0008 4B 07                         add r0, r7
      83 000a A8 F5                         mov.L   8[r7], r5
      85 000c 06 89 75 03                   add 12[r7].L, r5
      86 0010 06 89 75 01                   add 4[r7].L, r5
      87 0014 06 88 75                      add [r7].L, r5
      88 0017 4B 45                         add r4, r5
      89 0019 4B 35                         add r3, r5
      90 001b 4B 25                         add r2, r5
      35:../src/Test.c **** }
      92 001d 4B 51                         add r5, r1
      94 001f 3F 77 05                      rtsd    #20, r7-r7 ⇒ スタック使用量の期待値 = 24

    HardwareDebug.8.3.0.202002.O2/inthandler.lst

     1370                               _INT_Excep_PERIB_INTB181:
     1372                                   ; Note: Interrupt Handler
     1373 0000 7F 95                        rte ⇒ スタック使用量の期待値 = 8

    HardwareDebug.8.3.0.202002.O2/TestStackAnalysisForGNURX.lst

      18                                _main:
      55:../src/TestStackAnalysisForGNURX.c **** int main(void)
      56:../src/TestStackAnalysisForGNURX.c **** {
      21 0000 6E 6C                         pushm   r6-r12 
      23 0002 71 00 F0                      add #-16, r0 ⇒ main()内のスタック使用量の期待値 = 48 = 4(戻り番地分)+28(r6~r12)+16(此処)
      57:../src/TestStackAnalysisForGNURX.c ****
      58:../src/TestStackAnalysisForGNURX.c ****     r0 = func0();
      59:../src/TestStackAnalysisForGNURX.c ****     r1 = func1( a1 );
      27 0005 FB 72 00 00 00 00             mov.L   #_a1, r7
      58:../src/TestStackAnalysisForGNURX.c ****     r1 = func1( a1 );
      29 000b 05 00 00 00                   bsr _func0
      58:../src/TestStackAnalysisForGNURX.c ****     r1 = func1( a1 );
      32 000f FB A2 00 00 00 00             mov.L   #_r0, r10
      33 0015 E3 A1                         mov.L   r1, [r10]
      60:../src/TestStackAnalysisForGNURX.c ****     r4 = func4( a1, a2, a3, a4 );
      36 0017 FB B2 00 00 00 00             mov.L   #_a2, r11
      59:../src/TestStackAnalysisForGNURX.c ****     r1 = func1( a1 );
      38 001d EC 71                         mov.L   [r7], r1
      40 001f FB 62 00 00 00 00             mov.L   #_a3, r6
      41 0025 FB A2 00 00 00 00             mov.L   #_a4, r10
      61:../src/TestStackAnalysisForGNURX.c ****     r5 = func5( a1, a2, a3, a4, a5 );
      43 002b FB C2 00 00 00 00             mov.L   #_a5, r12
      59:../src/TestStackAnalysisForGNURX.c ****     r4 = func4( a1, a2, a3, a4 );
      45 0031 05 00 00 00                   bsr _func1
      59:../src/TestStackAnalysisForGNURX.c ****     r4 = func4( a1, a2, a3, a4 );
      48 0035 FB 52 00 00 00 00             mov.L   #_r1, r5
      49 003b E3 51                         mov.L   r1, [r5]
      60:../src/TestStackAnalysisForGNURX.c ****     r4 = func4( a1, a2, a3, a4 );
      52 003d EC 71                         mov.L   [r7], r1
      53 003f EC B2                         mov.L   [r11], r2
      54 0041 EC 63                         mov.L   [r6], r3
      55 0043 EC A4                         mov.L   [r10], r4
      56 0045 05 00 00 00                   bsr _func4
      60:../src/TestStackAnalysisForGNURX.c ****     r4 = func4( a1, a2, a3, a4 );
      59 0049 FB 52 00 00 00 00             mov.L   #_r4, r5
      60 004f E3 51                         mov.L   r1, [r5]
      63 0051 EC 71                         mov.L   [r7], r1
      64 0053 EC B2                         mov.L   [r11], r2
      65 0055 EC 63                         mov.L   [r6], r3
      66 0057 EC A4                         mov.L   [r10], r4
      67 0059 EC C5                         mov.L   [r12], r5
      68 005b E3 05                         mov.L   r5, [r0]
      69 005d 05 00 00 00                   bsr _func5
      72 0061 FB 52 00 00 00 00             mov.L   #_r5, r5
      73 0067 E3 51                         mov.L   r1, [r5]
      62:../src/TestStackAnalysisForGNURX.c ****     r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 );
      76 0069 EC 71                         mov.L   [r7], r1
      77 006b EC B2                         mov.L   [r11], r2
      78 006d EC 63                         mov.L   [r6], r3
      79 006f EC A4                         mov.L   [r10], r4
      80 0071 EC C6                         mov.L   [r12], r6
      81 0073 FB 72 00 00 00 00             mov.L   #_a6, r7
      82 0079 EC 75                         mov.L   [r7], r5
      83 007b FB 72 00 00 00 00             mov.L   #_a7, r7
      84 0081 EC 77                         mov.L   [r7], r7
      85 0083 FB A2 00 00 00 00             mov.L   #_a8, r10
      86 0089 EC AA                         mov.L   [r10], r10
      87 008b E3 06                         mov.L   r6, [r0]
      88 008d A0 0D                         mov.L   r5, 4[r0]
      89 008f E7 0A 03                      mov.L   r10, 12[r0]
      90 0092 A0 87                         mov.L   r7, 8[r0]
      91 0094 05 00 00 00                   bsr _func8
      63:../src/TestStackAnalysisForGNURX.c **** #if 1
      64:../src/TestStackAnalysisForGNURX.c ****     (*fptr)();
      94 0098 FB 72 00 00 00 00             mov.L   #_fptr, r7
      95 009e EC 77                         mov.L   [r7], r7
      62:../src/TestStackAnalysisForGNURX.c ****     r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 );
      97 00a0 FB A2 00 00 00 00             mov.L   #_r8, r10
      98 00a6 E3 A1                         mov.L   r1, [r10]
     101 00a8 7F 17                         jsr r7
     103                                    .balign 8,3,3
     104                                .L4:
      65:../src/TestStackAnalysisForGNURX.c **** #elif 0
      66:../src/TestStackAnalysisForGNURX.c ****     func();
      67:../src/TestStackAnalysisForGNURX.c **** #endif
      68:../src/TestStackAnalysisForGNURX.c ****
      69:../src/TestStackAnalysisForGNURX.c ****     while(1)
      70:../src/TestStackAnalysisForGNURX.c ****     {
      71:../src/TestStackAnalysisForGNURX.c ****         // TODO: add application code here
      72:../src/TestStackAnalysisForGNURX.c ****     }
     109 00aa 2E 00                         bra .L4

     

  • こんにちは。NoMaYです。

    今度はCC-RXでスタック使用量の見積もりの表示が期待値と一致するかどうか先日のGNURXと同様に調べてみました。結果は以下の表の通り、問題は見つかりませんでした。なお、今回気付いたのですが、CC-RXでは、GNURX(及びCC-RL)と異なり、スタック使用量の計算方法に以下の相違点がありました。(なお、諸般の事情で、CC-RXはV2.03、CC-RLはV1.02、です。) プログラムが必要とするスタック領域サイズを見積もるという観点からは、CC-RXの方法がGNURX(及びCC-RL)の方法より誤差が少なくなるので望ましいと思います。(誤差の具体例が、CC-RLですが、別スレッド『RL78 FreeRTOS APIを特別なおまじない記述無しで割り込みルーチンから呼び出せるようにしてみた(CC-RL/GNURL78)』にあります。)

    CC-RXとGNURX(及びCC-RL)のスタック使用量の計算方法の相違(CC-RXの方法がGNURX(及びCC-RL)の方法より望ましい)

    CC-RXの場合:
    スタック渡し引数で使用されるスタックは呼び出しの関数に計上される

    GNURX(及びCC-RL)の場合:
    スタック渡し引数で使用されるスタックは呼び出しの関数に計上される

    調査に使ったプロジェクトのファイル一式
    issue_20200515.zip    987KB

    上記に含まれるビルド結果のフォルダ一覧
    DefaultBuild.v203.optimize0.speed → CC-RX V2.03 最適化レベル0/実行性能重視 (-optimize=0 -speed)
    DefaultBuild.v203.optimize2.speed → CC-RX V2.03 最適化レベル最大/実行性能重視 (-optimize=max -speed)

      CC-RX V2.03
      -optimize=0 -speed -optimize=max -speed
      表示値 期待値 表示値 期待値
    func0 8 8 4 4
    func1 12 12 4 4
    func4 24 24 4 4
    func5 32 32 8 8
    func8 56 56 20 20
    main 64 64 44 44
    Excep_PERIA_INTA209 8 8 8 8

    スタック解析ビューの表示は以下の画面コピーの通り、[呼び出し先関数との合計を表示]に設定しています。また、期待値はリストファイルのアセンブラコードから求めたものです。



    以下、それぞれのスタック解析ビューの画面コピーです。

    CC-RX V2.03 最適化レベル0/実行性能重視 (-optimize=0 -speed)


    CC-RX V2.03 最適化レベル最大/実行性能重視 (-optimize=max -speed)


    以下、幾つかのリストファイル(抜粋)です。

    DefaultBuild.v203.optimize_0.speed/src/Test.lst

    00000000                         _func0:
                                     ;      12 uint32_t func0( void )
    00000000 6040                           SUB #04H, R0
                                     ;      13 {
                                     ;      14     return 0;
    00000002 F80600                         MOV.L #00000000H, [R0]
    00000005 6601                           MOV.L #00000000H, R1
                                     ;      15 }
    0000007 6701                            RTSD #04H ⇒ スタック使用量の期待値 = 8 = 4(戻り番地分)+04H

     

    00000009                         _func1:
                                            .STACK  _func1=12
                                     ;      17 uint32_t func1( uint32_t a1 )
    00000009 6080                           SUB #08H, R0
    0000000B A009                           MOV.L R1, 04H[R0]
                                     ;      18 {
                                     ;      19     return a1;
    0000000D E301                           MOV.L R1, [R0]
                                     ;      20 }
    0000000F 6702                           RTSD #08H ⇒ スタック使用量の期待値 = 12 = 4(戻り番地分)+08H

     

    00000011                         _func4:
                                            .STACK  _func4=24
                                     ;      22 uint32_t func4( uint32_t a1,  uint32_t a2, uint32_t a3,
                                     uint32_t a4 )
    00000011 7100EC                         ADD #0FFFFFFECH, R0
    00000014 A101                           MOV.L R1, 10H[R0]
    00000016 A08A                           MOV.L R2, 0CH[R0]
    00000018 A083                           MOV.L R3, 08H[R0]
    0000001A A00C                           MOV.L R4, 04H[R0]
                                     ;      23 {
                                     ;      24     return a1 + a2 + a3 + a4;
    0000001C A901                           MOV.L 10H[R0], R1
    0000001E 06890103                       ADD 0CH[R0].L, R1
    00000022 06890102                       ADD 08H[R0].L, R1
    00000026 4B41                           ADD R4, R1
    00000028 E301                           MOV.L R1, [R0]
                                     ;      25 }
    0000002A 6705                           RTSD #14H ⇒ スタック使用量の期待値 = 24 = 4(戻り番地分)+14H

     

    0000002C                         _func5:
                                            .STACK  _func5=28
                                     ;      27 uint32_t func5( uint32_t a1,  uint32_t a2, uint32_t a3,
                                     uint32_t a4, uint32_t a5 )
    0000002C 7100E8                         ADD #0FFFFFFE8H, R0
    0000002F A109                           MOV.L R1, 14H[R0]
    00000031 A102                           MOV.L R2, 10H[R0]
    00000033 A08B                           MOV.L R3, 0CH[R0]
    00000035 A084                           MOV.L R4, 08H[R0]
    00000037 A98A                           MOV.L 1CH[R0], R2 ← スタック渡し引数
    00000039 A00A                           MOV.L R2, 04H[R0]
                                     ;      28 {
                                     ;      29     return a1 + a2 + a3 + a4 + a5;
    0000003B A909                           MOV.L 14H[R0], R1
    0000003D 06890104                       ADD 10H[R0].L, R1
    00000041 06890103                       ADD 0CH[R0].L, R1
    00000045 06890102                       ADD 08H[R0].L, R1
    00000049 4B21                           ADD R2, R1
    0000004B E301                           MOV.L R1, [R0]
                                     ;      30 }
    0000004D 6706                           RTSD #18H ⇒ スタック使用量の期待値 = 32 = 4(スタック渡し引数分)+4(戻り番地分)+18H

     

    0000004F                         _func8:
                                            .STACK  _func8=40
                                     ;      32 uint32_t func8( uint32_t a1,  uint32_t a2, uint32_t a3,
                                     uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8 )
    0000004F 7100DC                         ADD #0FFFFFFDCH, R0
    00000052 A201                           MOV.L R1, 20H[R0]
    00000054 A18A                           MOV.L R2, 1CH[R0]
    00000056 A183                           MOV.L R3, 18H[R0]
    00000058 A10C                           MOV.L R4, 14H[R0]
    0000005A E5000A04                       MOV.L 28H[R0], 10H[R0] ← スタック渡し引数
    0000005E E5000B03                       MOV.L 2CH[R0], 0CH[R0] ← スタック渡し引数
    00000062 E5000C02                       MOV.L 30H[R0], 08H[R0] ← スタック渡し引数
    00000066 AB0A                           MOV.L 34H[R0], R2 ← スタック渡し引数
    00000068 A00A                           MOV.L R2, 04H[R0]
                                     ;      33 {
                                     ;      34     return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
    0000006A AA01                           MOV.L 20H[R0], R1
    0000006C 06890107                       ADD 1CH[R0].L, R1
    00000070 06890106                       ADD 18H[R0].L, R1
    00000074 06890105                       ADD 14H[R0].L, R1
    00000078 06890104                       ADD 10H[R0].L, R1
    0000007C 06890103                       ADD 0CH[R0].L, R1
    00000080 06890102                       ADD 08H[R0].L, R1
    00000084 4B21                           ADD R2, R1
    00000086 E301                           MOV.L R1, [R0]
                                     ;      35 }
    00000088 6709                           RTSD #24H ⇒ スタック使用量の期待値 = 56 = 16(スタック渡し引数分)+4(戻り番地分)+24H

    DefaultBuild.v203.optimize_0.speed/generate/intprg.lst

    00000168                         _Excep_PERIA_INTA209:
                                            .STACK  _Excep_PERIA_INTA209=8
                                            .RVECTOR    209,_Excep_PERIA_INTA209
                                     ;     558
                                     ;     559 // PERIA INTA209
                                     ;     560 void Excep_PERIA_INTA209(void){ }
    00000168 7F95                           RTE ⇒ スタック使用量の期待値 = 8

    DefaultBuild.v203.optimize_0.speed/src/TestStackAnalysisForCCRX.lst

    00000001                         _main:
                                            .STACK  _main=24
                                     ;      41 int main(void)
    00000001 7EA6                           PUSH.L R6 ⇒ main()内のスタック使用量の期待値 = 8 = 4(戻り番地分)+4(此処)
                                     ;      42 {
                                     ;      44     r0 = func0();
    00000003 05rrrrrr             A         BSR _func0
    00000007 FBE2rrrrrrrr                   MOV.L #_r0, R14
    0000000D E3E1                           MOV.L R1, [R14]
                                     ;      45     r1 = func1( a1 );
    0000000F FBE2rrrrrrrr                   MOV.L #_a1, R14
    00000015 ECE1                           MOV.L [R14], R1
    00000017 05rrrrrr             A         BSR _func1
    0000001B FBE2rrrrrrrr                   MOV.L #_r1, R14
    00000021 E3E1                           MOV.L R1, [R14]
                                     ;      46     r4 = func4( a1, a2, a3, a4 );
    00000023 FBE2rrrrrrrr                   MOV.L #_a1, R14
    00000029 ECE1                           MOV.L [R14], R1
    0000002B FBE2rrrrrrrr                   MOV.L #_a2, R14
    00000031 ECE2                           MOV.L [R14], R2
    00000033 FBE2rrrrrrrr                   MOV.L #_a3, R14
    00000039 ECE3                           MOV.L [R14], R3
    0000003B FBE2rrrrrrrr                   MOV.L #_a4, R14
    00000041 ECE4                           MOV.L [R14], R4
    00000043 05rrrrrr             A         BSR _func4
    00000047 FBE2rrrrrrrr                   MOV.L #_r4, R14
    0000004D E3E1                           MOV.L R1, [R14]
                                     ;      47     r5 = func5( a1, a2, a3, a4, a5 );
    0000004F FBE2rrrrrrrr                   MOV.L #_a1, R14
    00000055 ECE1                           MOV.L [R14], R1
    00000057 FBE2rrrrrrrr                   MOV.L #_a2, R14
    0000005D ECE2                           MOV.L [R14], R2
    0000005F FBE2rrrrrrrr                   MOV.L #_a3, R14
    00000065 ECE3                           MOV.L [R14], R3
    00000067 FBE2rrrrrrrr                   MOV.L #_a4, R14
    0000006D ECE4                           MOV.L [R14], R4
    0000006F FBE2rrrrrrrr                   MOV.L #_a5, R14
    00000075 ECEE                           MOV.L [R14], R14
    00000077 6040                           SUB #04H, R0
    00000079 E30E                           MOV.L R14, [R0]
    0000007B 05rrrrrr             A         BSR _func5
    0000007F 6240                           ADD #04H, R0
    00000081 FBE2rrrrrrrr                   MOV.L #_r5, R14
    00000087 E3E1                           MOV.L R1, [R14]
                                     ;      48     r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 );
    00000089 FBE2rrrrrrrr                   MOV.L #_a1, R14
    0000008F ECE1                           MOV.L [R14], R1
    00000091 FBE2rrrrrrrr                   MOV.L #_a2, R14
    00000097 ECE2                           MOV.L [R14], R2
    00000099 FBE2rrrrrrrr                   MOV.L #_a3, R14
    0000009F ECE3                           MOV.L [R14], R3
    000000A1 FBE2rrrrrrrr                   MOV.L #_a4, R14
    000000A7 ECE4                           MOV.L [R14], R4
    000000A9 FBE2rrrrrrrr                   MOV.L #_a5, R14
    000000AF ECEE                           MOV.L [R14], R14
    000000B1 FBF2rrrrrrrr                   MOV.L #_a6, R15
    000000B7 ECF5                           MOV.L [R15], R5
    000000B9 FBF2rrrrrrrr                   MOV.L #_a7, R15
    000000BF ECFF                           MOV.L [R15], R15
    000000C1 FB62rrrrrrrr                   MOV.L #_a8, R6
    000000C7 EC66                           MOV.L [R6], R6
    000000C9 7100F0                         ADD #0FFFFFFF0H, R0
    000000CC A08E                           MOV.L R6, 0CH[R0]
    000000CE E70F02                         MOV.L R15, 08H[R0]
    000000D1 A00D                           MOV.L R5, 04H[R0]
    000000D3 E30E                           MOV.L R14, [R0]
    000000D5 05rrrrrr             A         BSR _func8
    000000D9 710010                         ADD #10H, R0
    000000DC FBE2rrrrrrrr                   MOV.L #_r8, R14
    000000E2 E3E1                           MOV.L R1, [R14]
                                     ;      49 #if 1
                                     ;      50     (*fptr)();
    000000E4 FBE2rrrrrrrr                   MOV.L #_fptr, R14
    000000EA ECEE                           MOV.L [R14], R14
    000000EC 7F1E                           JSR R14
    000000EE                         L17:   ; bb24
                                     ;      51 #elif 0
                                     ;      52     func();
                                     ;      53 #endif
                                     ;      54
                                     ;      55     while(1)
    000000EE 2Err                 B         BRA L17
                                     ;      56     {
                                     ;      57         // TODO: add application code here
                                     ;      58     }
                                     ;      59 }