0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MIPSのGCCでレジスタアクセス

Last updated at Posted at 2024-05-31

SunPlusのフォトフレームで使われているMIPS SOCのuartのputcのコードは以下になります。

8008d484:       ff00a530        andi    a1,a1,0xff
8008d488:       01118290        lbu     v0,4353(a0)
8008d48c:       00000000        nop
8008d490:       42110200        srl     v0,v0,0x5
8008d494:       01004230        andi    v0,v0,0x1
8008d498:       fbff4010        beqz    v0,0x8008d488
8008d49c:       00000000        nop
8008d4a0:       0800e003        jr      ra
8008d4a4:       081185a0        sb      a1,4360(a0)

ステータスが+1で送信データが+8なので8250互換ではなさそうです。SOCベンダーがIPを1から作る事はないとおもうので、何らかの一般的な仕様だと思うのですが。。。

cで書いてみてました。

void cput(unsigned char *addr, unsigned char ch)
{
        int tmp;

        do {
                tmp = *(addr + 0x1101);
        } while(!((tmp >> 5) & 1));
        *(addr + 0x1108) = ch;
}

これをgcc 4.9.2で-O2でコンパイルして逆アセンブルしてみます。

00000000 <cput>:
   0:   90821101        lbu     v0,4353(a0)
   4:   30420020        andi    v0,v0,0x20
   8:   14400003        bnez    v0,18 <cput+0x18>
   c:   30a500ff        andi    a1,a1,0xff
  10:   08000004        j       10 <cput+0x10>
  14:   00000000        nop
  18:   03e00008        jr      ra
  1c:   a0851108        sb      a1,4360(a0)

無限ループになってしまってます。

おそらくCで書かれた物と思われますが、レジスタを退避してないので、なんらかの最適化はかかっていると思われます。

しかしlbuした後のnopはコンパイラーが付けたとは考えにくいです。これが無いと正常に処理されません。このSOCのuartのバグかもしれません。

おそらくマクロ化したインラインアセンブラで書かれたような気がします。とりあえずべたで書いてみます。

void cput(unsigned char *addr, unsigned char ch)
{
        int tmp;

        do {
                asm volatile ("lbu     %0,0x1101(%1)\n\tnop"
                : "=r" (tmp) : "r" (addr));
        } while(!((tmp >> 5) & 1));
        *(addr + 0x1108) = ch;
}

逆アセンブルしてみます。

00000000 <cput>:
   0:   30a500ff        andi    a1,a1,0xff
   4:   90821101        lbu     v0,4353(a0)
   8:   00000000        nop
   c:   30420020        andi    v0,v0,0x20
  10:   1040fffc        beqz    v0,4 <cput+0x4>
  14:   00000000        nop
  18:   03e00008        jr      ra
  1c:   a0851108        sb      a1,4360(a0)

微妙に違いますが、動きました。

入力も分かったのですが、なんか動きが変です。

0x1100からビットで8,8,(8,8),32,8,(8,8,8),8,(8,8,8)となっていて、なんとも不思議な仕様です。カッコ内は未使用です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?