GNURL78やLLVM-RL78でのover 64KB ROMのchecksumを計算するcodeを考えてみるスレッド

こんにちは。NoMaYです。

最近、以下のスレッドに関わったのですが、暫く時間が経った後で思い返してみると、farキーワードの起源の8086のマイクロソフトコンパイラでの仕様とか、CC-RL及びそれに準ずるLLVM-RL78での仕様とか、それらを鑑みると、投稿した以下のコードでの64KB境界を跨いだfarポインタのインクリメントやポインタ比較は素朴に期待したようには動かないのが本来の仕様である可能性が高い筈、と思い直しました。そこで、コードを考え直してみることにしました。

続く。

C言語からのアセンブラ関数呼び出しについて
community-ja.renesas.com/cafe_rene/forums-groups/beginners/f/002-2095199602/9532/c

上のスレッドに投稿した、素朴に期待したようには動かないのが本来の仕様である可能性が高い、そんなコード(現状はGNURL78でOKだが):

#include <stdint.h>
const uint16_t __far psum_rom = 0x1234; /* This variable is placed at the end of the ROM by linker script. */
uint16_t _RomSum(void);
uint16_t __attribute__((noinline, optimize("no-isolate-erroneous-paths-dereference"))) _RomSum(void)
{
    // FIXME: In case of using the immediate value in stead of `&psum_rom`, if other than -O0 is used,
    // the generated code has no ES register handling. It seems to be a bug of GNURL78 (ex. 4.9.2.202201).

    const uint16_t __far *prom, *sum_s, *sum_e;
    uint16_t sum = 0;

    sum_s = 0;
    sum_e = &psum_rom; // (const uint16_t __far *)0x017DFEUL; --> No ES register handling.
    for( prom = sum_s; prom < sum_e; prom++ )
    {
        sum += *prom;
    }
    return sum;
}

 

  • こんにちは。NoMaYです。

    昔話ですけれども、near/farのキーワードの起源となった8086のマイクロソフトコンパイラ(ボーランドコンパイラもだったような(両方使っていましたが記憶が曖昧です))には、near/farの他にfarの上位互換のようなhugeというキーワードがありました。farとhugeの違いは以下の英語版Wikipediaにも書かれているように、ポインタ演算時に、farは下位16ビットから上位側へ桁上がりや桁借りが行われない、のに対し、hugeは下位16ビットから上位側へ桁上がりや桁借りが行われる、という違いがありました。

    en.wikipedia.org/wiki/Intel_8086#Segmentation

    Some compilers also support huge pointers, which are like far pointers except that pointer arithmetic on a huge pointer treats it as a linear 20-bit pointer, while pointer arithmetic on a far pointer wraps around within its 16-bit offset without touching the segment part of the address.


    他方、その頃、私はGCCを使っていなかったので、GCCではどういう仕様になっていたのか、というか8086向けGCCはもともと存在しなかったような(曖昧な記憶では80386向けDOSエクステンダ上で動作するDJGPP(DJ Delorie氏が開発)というGCC以前にはx86向けのものは存在しなかったような)気もしますが、私はそのあたりのことが分かりません。

    そして、GCCのドキュメントには、現在のx86向けのGCCに関してはnear/far/hugeというキーワードは存在しないようでした。

    なお、GCCのドキュメントには、M32CやRL78に関して__farキーワードの記載があるものの、例えばRL78では以下の通りとなっていて、ポインタ演算時に下位16ビットから上位側へ桁上がりや桁借りが行われるのかどうか不明です。

    gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html#RL78-Named-Address-Spaces

    6.17.4 RL78 Named Address Spaces

    On the RL78 target, variables qualified with __far are accessed with 32-bit pointers (20-bit addresses) rather than the default 16-bit addresses. Non-far variables are assumed to appear in the topmost 64KiB of the address space.


    さらに、GCC for Renesas RL78 4.9.2.202201のリリースノートにも以下の記載があるだけで、ポインタ演算時に下位16ビットから上位側へ桁上がりや桁借りが行われるのかどうか不明です。

    インストールフォルダ¥release_notes.pdf

    KNOWN ISSUES IN GCC 4.9.2.202201-GNURL78

    This section describes the known issues in the GCC 4.9.2.202201-GNURL78 release.

      1. ES is used without being initialized.

        Workaround:

        In order to initialize ES, the address should be stored in a far pointer before usage. So instead of:

        ((volatile reg __far*)0x000FFF).bit._1 = 0;

        the code will be:

        volatile reg __far *address0 = 0x000FFF;

        (*address0).bit._1 = 0;

      …略…


    ちなみに、CC-RLは以下の通りとなっていまして、ポインタ演算時に、__farに関しては下位16ビットから上位側へ桁上がりや桁借りが行われない、ことが明記されています。そして、LLVM-RL78はCC-RLの仕様を完コピすることを目標に開発が行われていますので、CC-RLと同じ仕様でなければならない、ということになります。

    tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V8.08.00/CS+.chm/Compiler-CCRL.chm/Output/ccrl04c0206y0003.html

    - ポインタ演算

     - farポインタの加算は下位2バイトで行ないます。上位は変化しません。

     - farポインタの減算は下位2バイトで行ないます。上位は変化しません。

     - nearポインタとfarポインタ間の減算は,右項の型を左項の型にキャストしてから減算します。

     - nearポインタと整数の演算結果は,nearポインタとします。


    - ポインタ比較

     - オプション-strict_std指定時は,ポインタと整数間で直接比較できません。しかし,オプション-strict_std非指定時は,警告を出して直接比較を可能とします。
    警告時の比較は,整数型をポインタ型に合わせて比較します。整数型からポインタ型への変換は,キャストの項目に書いた規則に従います。

     - オプション-strict_std指定時は,変数ポインタと関数ポインタで直接比較できません。しかし,オプション-strict_std非指定時は,警告を出して直接比較を可能とします。
    警告時の比較は,次のように機能します。

     -farポインタの等値演算(==,!=)は,下位3バイトで行ないます。最上位の1バイトは演算結果に影響しません。

     -farポインタの関係演算は,下位2バイトのみで比較します。上位の2バイトは演算結果に影響しません。
    上位バイトを含めて比較する場合は,unsigned longにキャストしてから比較する必要があります。


    続く。

    [関連リンク]

    Google検索: GCC OR GNURL78 variable far
    www.google.com/search?q=GCC+OR+GNURL78+variable+far

    全ROMチェックサム計算プログラム ← CC-RLに関するスレッドです[訂正]すみません、CA78K0Rみたいな気がします
    community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rl78/f/forum18/1315/rom/6084#6084

    CS+のメモリ表示についての質問 ← CC-RLに関するスレッドです
    community-ja.renesas.com/cafe_rene/forums-groups/beginners/f/002-2095199602/7056/cs/37779#37779

    [余談]

    DJ Delorie氏はRedHat社でGNURL78の開発もされていたようです。

  • こんにちは。NoMaYです。

    ところで、RL78向けのもうひとつのコンパイラであるIAR社のコンパイラには__near/__farに加えて__hugeがありますので、64KB境界を跨いだポインタ操作が必要な場合は素朴に__hugeを使えば事足りることになっています。

    他方、__hugeの無いCC-RL(やLLVM-RL78)で64KB境界を跨いだポインタ操作が必要な場合はどうするかというと、前の投稿の関連リンクにURLを書いたスレッドで行われていたように、CC-RLの以下のキャスト仕様に基づき、uint32_tを__farポインタへ随時キャストしながら行うのが常套手段かと思うのです。

    tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V8.08.00/CS+.chm/Compiler-CCRL.chm/Output/ccrl04c0206y0003.html

    - 変数からポインタへの変換

    signed char sc;
    signed short ss;
    signed long sl;

    unsigned char uc;
    unsigned short us;
    unsigned long ul;

    void func3(){

            (char __near*)uc;       //0x00, uc
            (char __near*)sc;       //(0x00 or 0xff), sc

            (char __far*)uc;        //nn, 0x00, 0x00, uc
            (char __far*)us;        //nn, 0x00, us(1), us(0)
            (char __far*)ul;        //nn, ul(2), ul(1), ul(0)
            (char __far*)sc;        //nn, (0x0000 or 0xffff), sc
            (char __far*)ss;        //nn, (0x00 or 0xff), ss(1), ss(0)
            (char __far*)sl;        //nn, sl(2), sl(1), sl(0)

            (__far FT*)uc;          //nn, 0x00, 0x00, uc
            (__far FT*)us;          //nn, 0x00, us(1), us(0)
            (__far FT*)ul;          //nn, ul(2), ul(1), ul(0)

            (__far FT*)sc;          //nn, (0x0000 or 0xffff), sc
            (__far FT*)ss;          //nn, (0x00 or 0xff), ss(1), ss(0)
            (__far FT*)sl;          //nn, sl(2), sl(1), sl(0)
    }



    ですので、CC-RL(やLLVM-RL78)で64KB境界(64KB,128KB,192KB,等)を跨ぐチェックサムのコードは以下のようにするのが常套手段かと思うのです。(16ビット単位で加算する例です。)

    uint16_t _RomSum(void)
    {
        uint32_t prom, sum_s, sum_e;
        uint16_t sum = 0;

        sum_s = 0;
        sum_e = 0x017DFEUL;
        for( prom = sum_s; prom < sum_e; prom += 2 )
        {
            sum += *(uint16_t __far *)prom;
        }

        return sum;
    }

     
    続く。

  • こんにちは。NoMaYです。

    今になって思い至ったのですが、2つ前に書いた以下のことを鑑みると、GNURL78の__farが、桁上がりや桁借りをやらないことによる効率向上よりも、もともとGCCに無かった__farを追加するにあたり開発期間/開発費用を節約する為にいっそのことポインタ演算に関してuint32_tと同じ扱いにしたことによる結果として桁上がりや桁借りもやるようになっていた、という気もしてきました。

    > 他方、その頃、私はGCCを使っていなかったので、GCCではどういう仕様になっていたのか、というか8086向けGCCはもともと存在しなかったような(曖昧な記憶では80386向けDOSエクステンダ上で動作するDJGPP(DJ Delorie氏が開発)というGCC以前にはx86向けのものは存在しなかったような)気もしますが、私はそのあたりのことが分かりません。

    > そして、GCCのドキュメントには、現在のx86向けのGCCに関してはnear/far/hugeというキーワードは存在しないようでした。

    そこで、以下のソースをコンパイルしてリストファイルを眺めてみたところ、これは確かにそういうことだよなぁ、という結論に至りました。

    ということで、このスレッドは私の勘違いでした、ということで終わりにします。すみません。



    ソース:

    uint16_t __far *ptr;
    void test(void)
    {
        ptr++;
    }

     
    -O0でのリストファイル:

     0000 AF 00 00                      movw ax, !_ptr
     0003 BD F0                         movw r8, ax
     0005 AF 00 00                      movw ax, !_ptr+2
     0008 BD F2                         movw r10, ax
     000a AD F0                         movw ax, r8
     000c 04 02 00                      addw ax, #2
     000f BD F0                         movw r8, ax
     0011 AD F2                         movw ax, r10
     0013 61 D8                         sknc
     0015 A1                            incw ax
     0016 BD F2                         movw r10,ax
     0018 AD F0                         movw ax, r8
     001a BF 00 00                      movw !_ptr, ax
     001d AD F2                         movw ax, r10
     001f BF 00 00                      movw !_ptr+2, ax
     0022 D7                            ret

     
    -O1,-O2,-O3,-Os,-Ogでのリストファイル:

     0000 AF 00 00                      movw ax, !_ptr
     0003 04 02 00                      addw ax, #2
     0006 BF 00 00                      movw !_ptr, ax
     0009 AF 00 00                      movw ax, !_ptr+2
     000c 61 D8                         sknc
     000e A1                            incw ax
     000f BF 00 00                      movw !_ptr+2,ax
     0012 D7                            ret

     

  • こんにちは。NoMaYです。

    すみません、ちょっと蛇足になるかな、とも思いますけれども、以下のコードをGNURL78でコンパイルしたら、また、ESレジスタを操作していないコード、というか別の観点から言えば、ESプレフィクス無しでアクセスするコード、を生成しますね。これは、やはり、GNURL78のバグのような気がします。(細かいことを言えば、GNURL78での、uint32_tから__farポインタへのキャスト仕様が明記されていない(というより、私が探せていない?、ということ)ですので、「動作は不定である」と開発者さんから返事が返ってきたら、そこで話が終わってしまう部類のことですけれども。)

    GNURL78_far_pointer_issue_20220914.zip    [追記] 2022/09/16 追加しました(プロジェクトのファイル一式です)

    GNURL78での生成コードがおかしいソース:

    uint16_t _RomSum(void)
    {
        uint32_t prom, sum_s, sum_e;
        uint16_t sum = 0;

        sum_s = 0;
        sum_e = 0x017DFEUL;
        for( prom = sum_s; prom < sum_e; prom += 2 )
        {
            sum += *(uint16_t __far *)prom;
        }

        return sum;
    }

     
    なお、あれこれ試行錯誤してみたところ、以下のようにすると(私が勝手に?)期待したようなコードが生成されるようでした。ただ、それこそ闇雲にやっていたら運良く気付いた、という部類のことであって、C言語の文法からのロジカルな帰結では全く無いです。そういうタイプの対症療法に過ぎないのですけれども、、、

    GNURL78で期待したコードが生成されるソース:

    uint16_t _RomSum(void)
    {
        uint32_t prom, sum_s, sum_e;
        uint16_t sum = 0;

        sum_s = 0;
        sum_e = 0x017DFEUL;
        for( prom = sum_s; prom < sum_e; prom += 2 )
        {
    #if defined(__GNUC__) && !defined(__llvm__)
            sum += *(volatile uint16_t __far *)prom; /* Using `volatile` is just a `workaround` for GNURL78. */
    #else
            sum += *(uint16_t __far *)prom;
    #endif
        }

        return sum;
    }

     
    以下、リストファイル(最適化レベルは-Os)です。

    上側のソース:
    ESレジスタを操作していないコード、および、ESプレフィクス無しでアクセスするコード、が生成される
    ⇒ GNURL78のバグなのでは?

                                        .section    .text._RomSum,"ax",@progbits
                                        .global __RomSum
                                    __RomSum:
                                        ; start of function
                                        ; push 2: r16
                                        ; uses ES register ← 実際はESレジスタを操作していない
     0000 61 EF                         sel rb2
     0002 C1                            push    ax ; r16
     0003 61 CF                         sel     rb0
     0005 C9 F0 00 00                   movw    r8, #0
     0009 C9 F4 00 00                   movw    r12, #0
     000d C9 F6 00 00                   movw    r14, #0
                                    .L2:
     0011 AD F4                         movw    ax, r12
     0013 16                            movw    hl, ax
     0014 AB                            movw    ax, [hl] ← ESプレフィクス無し
     0015 06 F0                         addw    ax, r8
     0017 BD F0                         movw    r8, ax
     0019 AD F4                         movw    ax, r12
     001b 04 02 00                      addw    ax, #2
     001e BD F4                         movw    r12, ax
     0020 AD F6                         movw    ax, r14
     0022 61 D8                         sknc
     0024 A1                            incw    ax
     0025 BD F6                         movw    r14,ax
     0027 AD F6                         movw    ax, r14
     0029 44 01 00                      cmpw    ax, #1
     002c AD F4                         movw    ax, r12
     002e 61 F8                         sknz
     0030 44 FE 7D                      cmpw    ax, #32254
     0033 61 E8                         skz
     0035 EC 00 00 00                   br      !!.L2
     0039 61 EF                         sel     rb2
     003b C0                            pop     ax ; r16
     003c 61 CF                         sel     rb0
     003e D7                            ret

     
    下側のソース:
    ESレジスタを操作している、および、ESプレフィクスありでアクセスしている
    ⇒ OKそう

                                        .section    .text._RomSum,"ax",@progbits
                                        .global __RomSum
                                    __RomSum:
                                        ; start of function
                                        ; push 4: r16 r18
                                        ; uses ES register
     0000 61 EF                         sel     rb2
     0002 C1                            push    ax ; r16
     0003 C3                            push    bc ; r18
     0004 61 CF                         sel     rb0
     0006 C9 F0 00 00                   movw    r8, #0
     000a C9 F4 00 00                   movw    r12, #0
     000e C9 F6 00 00                   movw    r14, #0
                                    .L2:
     0012 AD F4                         movw    ax, r12
     0014 BD E8                         movw    r16, ax
     0016 AD F6                         movw    ax, r14
     0018 60                            mov     a, x
     0019 9E FD                         mov     es, a
     001b FA E8                         movw    hl, r16
     001d 11 AB                         movw    ax, es:[hl]
     001f 06 F0                         addw    ax, r8
     0021 BD F0                         movw    r8, ax
     0023 AD F4                         movw    ax, r12
     0025 04 02 00                      addw    ax, #2
     0028 BD F4                         movw    r12, ax
     002a AD F6                         movw    ax, r14
     002c 61 D8                         sknc
     002e A1                            incw    ax
     002f BD F6                         movw    r14,ax
     0031 AD F6                         movw    ax, r14
     0033 44 01 00                      cmpw    ax, #1
     0036 AD F4                         movw    ax, r12
     0038 61 F8                         sknz
     003a 44 FE 7D                      cmpw    ax, #32254
     003d 61 E8                         skz
     003f EC 00 00 00                   br      !!.L2
     0043 61 EF                         sel     rb2
     0045 C2                            pop     bc ; r18
     0046 C0                            pop     ax ; r16
     0047 61 CF                         sel     rb0
     0049 D7                            ret

     
    [追記]

    ちなみに、先日の投稿でのGCC for Renesas RL78 4.9.2.202201のリリースノートの件の「1. ES is used without being initialized.」という項目の内容からインスピレーションを得て以下のコードも試しましたが、依然として同じく、ESレジスタを操作していないコード、および、ESプレフィクス無しでアクセスするコード、が生成されていました。(最適化レベルは-Osで試しました。余談ですが、それなりの強さの最適化が行われる最適化レベルですので、ソースの字面を少しぐらい弄っても(もっとも`字面`以上のものではありますけれども)コードが変化しないことはそれなりに良くあることですね。)

    GNURL78での生成コードがおかしい:

    uint16_t _RomSum(void)
    {
        uint32_t prom, sum_s, sum_e;
        uint16_t sum = 0;

        sum_s = 0;
        sum_e = 0x017DFEUL;
        for( prom = sum_s; prom < sum_e; prom += 2 )
        {
    #if defined(__GNUC__) && !defined(__llvm__)
            uint16_t __far *address = (uint16_t __far *)prom;
            sum += *address; /* NG! The generated code has neither `mov es,a` nor `movw ax,es:[hl]`. */
    #else
            sum += *(uint16_t __far *)prom;
    #endif
        }

        return sum;
    }

     

  • こんにちは。NoMaYです。

    すみません、また、ちょっと蛇足になるかな、とも思いますけれども、発端となったスレッドにも投稿していますが、以下のコードもGNURL78でコンパイルすると、ESレジスタを操作していないコード、というか別の観点から言えば、ESプレフィクス無しでアクセスするコード、を生成します。これも、やはり、GNURL78のバグのような気がします。

    GNURL78_far_pointer_issue_20220915.zip    [追記] 2022/09/16 追加しました(プロジェクトのファイル一式です)

    GNURL78での生成コードがおかしいソース:

    uint16_t _RomSum(void)
    {
        // FIXME: If one of -O2, -O3, -Os is used, the generated code calls `abort()` immediately.
        // FIXME: In case of using the immediate value in stead of `&psum_rom`, if other than -O0, -Og is
        // used, the generated code has no ES register handling. (Note: If one of -O2, -O3, -Os is used,
        // the generated code calls `abort()` immediately. Therefore `other than -O0, -Og` means only -O1.)

        const uint16_t __far *prom, *sum_s, *sum_e;
        uint16_t sum = 0;

        sum_s = 0;
        //sum_e = &psum_rom; // (const uint16_t __far *)0x017DFEUL; --> No ES register handling.
        sum_e = (const uint16_t __far *)0x017DFEUL;
        for( prom = sum_s; prom < sum_e; prom++ )
        {
            sum += *prom;
        }

        return sum;
    }

     
    そして、これも、前の投稿と同様な記述にすると(私が勝手に?)期待したようなコードが生成されるようでした。これも、前の投稿に書いたことですが、前の投稿で、それこそ闇雲にやっていたら運良く気付いた、という部類のことであって、C言語の文法からのロジカルな帰結では全く無いです。そういうタイプの対症療法に過ぎないのですけれども、、、

    GNURL78で期待したコードが生成されるソース: (発端となったスレッドと同じ__attribute__()の追加もしています)

    uint16_t __attribute__((noinline, optimize("no-isolate-erroneous-paths-dereference"))) _RomSum(void)
    {
        const uint16_t __far *prom, *sum_s, *sum_e;
        uint16_t sum = 0;

        sum_s = 0;
        sum_e = (const uint16_t __far *)0x017DFEUL;
        for( prom = sum_s; prom < sum_e; prom++ )
        {
            sum += *(volatile uint16_t __far *)prom; /* Using cast with `volatile` is just a `workaround` for GNURL78. */
        }

        return sum;
    }

     
    以下、リストファイル(最適化レベルは-O1)です。(発端となっだスレッドにも投稿していますが、上側のソースでソッコーでabort()を呼び出すコードが生成されてしまいますので、ここでは-Osではなく-O1としています。)

    上側のソース:
    ESレジスタを操作していないコード、および、ESプレフィクス無しでアクセスするコード、が生成される
    ⇒ GNURL78のバグなのでは?

                                        .section    .text._RomSum,"ax",@progbits
                                        .global __RomSum
                                    __RomSum:
                                        ; start of function
                                        ; push 2: r16
                                        ; uses ES register ← 実際はESレジスタを操作していない
     0000 61 EF                         sel rb2
     0002 C1                            push    ax ; r16
     0003 61 CF                         sel     rb0
     0005 C9 F4 00 00                   movw    r12, #0
     0009 C9 F6 00 00                   movw    r14, #0
     000d C9 F0 00 00                   movw    r8, #0
                                    .L2:
     0011 AD F4                         movw    ax, r12
     0013 BD F2                         movw    r10, ax
     0015 FA F2                         movw    hl, r10
     0017 AB                            movw    ax, [hl] ← ESプレフィクス無し
     0018 06 F0                         addw    ax, r8
     001a BD F0                         movw    r8, ax
     001c AD F4                         movw    ax, r12
     001e 04 02 00                      addw    ax, #2
     0021 BD F4                         movw    r12, ax
     0023 AD F6                         movw    ax, r14
     0025 61 D8                         sknc
     0027 A1                            incw    ax
     0028 BD F6                         movw    r14,ax
     002a AD F6                         movw    ax, r14
     002c 44 01 00                      cmpw    ax, #1
     002f AD F4                         movw    ax, r12
     0031 61 F8                         sknz
     0033 44 FE 7D                      cmpw    ax, #32254
     0036 61 E8                         skz
     0038 EC 11 00 00                   br      !!.L2
     003c 61 EF                         sel     rb2
     003e C0                            pop     ax ; r16
     003f 61 CF                         sel     rb0
     0041 D7                            ret

     
    下側のソース:
    ESレジスタを操作している、および、ESプレフィクスありでアクセスしている
    ⇒ OKそう


                                        .global __RomSum
                                    __RomSum:
                                        ; start of function
                                        ; push 4: r16 r18
                                        ; uses ES register
     0000 61 EF                         sel     rb2
     0002 C1                            push    ax ; r16
     0003 C3                            push    bc ; r18
     0004 61 CF                         sel     rb0
     0006 C9 F4 00 00                   movw    r12, #0
     000a C9 F6 00 00                   movw    r14, #0
     000e C9 F0 00 00                   movw    r8, #0
                                    .L2:
     0012 AD F4                         movw    ax, r12
     0014 BD E8                         movw    r16, ax
     0016 AD F6                         movw    ax, r14
     0018 60                            mov     a, x
     0019 9E FD                         mov     es, a
     001b FA E8                         movw    hl, r16
     001d 11 AB                         movw    ax, es:[hl]
     001f 06 F0                         addw    ax, r8
     0021 BD F0                         movw    r8, ax
     0023 AD F4                         movw    ax, r12
     0025 04 02 00                      addw    ax, #2
     0028 BD F4                         movw    r12, ax
     002a AD F6                         movw    ax, r14
     002c 61 D8                         sknc
     002e A1                            incw    ax
     002f BD F6                         movw    r14,ax
     0031 AD F6                         movw    ax, r14
     0033 44 01 00                      cmpw    ax, #1
     0036 AD F4                         movw    ax, r12
     0038 61 F8                         sknz
     003a 44 FE 7D                      cmpw    ax, #32254
     003d 61 E8                         skz
     003f EC 12 00 00                   br      !!.L2
     0043 61 EF                         sel     rb2
     0045 C2                            pop     bc ; r18
     0046 C0                            pop     ax ; r16
     0047 61 CF                         sel     rb0
     0049 D7                            ret

      

  • こんにちは。NoMaYです。

    前の2つの投稿にそれぞれプロジェクトのファイル一式を固めたzipファイルを添付しました(追加しました)。この後、llvm-gcc-renesas.comのGNURL78フォーラムに不具合報告をしようと思ってます。 ### バグは言わなきゃ直らない。

    GNURL78_far_pointer_issue_20220914.zip
    GNURL78_far_pointer_issue_20220915.zip

  • こんにちは。NoMaYです。

    不具合報告をllvm-gcc-renesas.comのGNURL78フォーラムに投稿したところ、時期は未定であるけれども修正する方向で考えています、とのリプライがありました。(というか意訳ですけれども。)