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;
}

 

Parents Reply Children
No Data