やまものブログ

メモ書きブログです (^_^;A

ARM 浮動小数点Floating-Point Status and Control register(FPSCR)

Cortex-A プログラマーズガイド (DEN0013C) の Example 7-1 にあったサンプルコード
VCMP d0, d1
VMRS APSR_nzcv, FPSCR
BNE label

を試してみました。

下記が実際に動かしたコードです。
.text
.global    _start
_start:
    VCMP.F64    d0, d1
    VMRS    APSR_nzcv, FPSCR
    BNE    label1
label0:    mov    r0, #0
    b    s_exit
label1:    mov    r0, #1
s_exit:    mov    r7, #1
    svc    #0


これ(ファイル名fpflags0.s)のコンパイルには -mfpu オプションが必要でした。
$ arm-xilinx-linux-gnueabi-as -g -mfpu=vfp  -o fpflags0.o fpflags0.s
$ arm-xilinx-linux-gnueabi-ld fpflags0.o


このコードをそのまま実行すると d0, d1 ともにゼロで等しい値のため、戻り値ゼロで exit システムコールが実行されます。
この動作を gdb で確認しました。浮動小数点関連で以下2つのコマンドを使いました。

浮動小数点ハードウェア情報の表示
(gdb) info float

● 倍精度レジスタの変更
(gdb) set $d<レジスタの番号> = <数値>

あと、cpsr の確認に ”info register” を使っています。

まず、以下がそのまま実行して確認した内容です。

(gdb) target remote localhost:1234
Remote debugging using localhost:1234
_start () at fpflags0.s:4
4        VCMP.F64    d0, d1
(gdb) info float
fpscr          0x0    0
s0             0    (raw 0x00000000)
s1             0    (raw 0x00000000)
。。。 s2-s31 は省略 。。。
(gdb) info register

。。。 r0-pc は省略 。。。
cpsr           0x10    16
(gdb) s
5        VMRS    APSR_nzcv, FPSCR
(gdb) s
6        BNE    label1
(gdb) info float
fpscr          0x60000000    1610612736
s0             0    (raw 0x00000000)
s1             0    (raw 0x00000000)
。。。 s2-s31 は省略 。。。
(gdb) info register
。。。 r0-pc は省略 。。。
cpsr           0x60000010    1610612752
(gdb) s
label0 () at fpflags0.s:7
7    label0:    mov    r0, #0
(gdb) s
8        b    s_exit
(gdb) s
s_exit () at fpflags0.s:10
10    s_exit:    mov    r7, #1
(gdb) s
11        svc    #0
(gdb) s
[Inferior 1 (process 948) exited normally]
(gdb) quit


以上では fpscr, cpsr ともに 0x6... となったのでビット[30]
Z, bit[30] Zero condition flag.
が 1 です


次に d0 の値をデバッガで書き換えて d1 と不一致にして実行しました。

(gdb) target remote localhost:1234
Remote debugging using localhost:1234
_start () at fpflags0.s:4
4        VCMP.F64    d0, d1
(gdb) set $d0 = 0xdeadbeefaaccff55
(gdb) info float
                 
fpscr          0x0    0
s0             -3.64148517e-13    (raw 0xaaccff55)
s1             -6.2598534e+18    (raw 0xdeadbeef)
。。。 s2-s31 は省略 。。。
(gdb) s
5        VMRS    APSR_nzcv, FPSCR
(gdb) info float
fpscr          0x80000000    -2147483648
s0             -3.64148517e-13    (raw 0xaaccff55)
s1             -6.2598534e+18    (raw 0xdeadbeef)
。。。 s2-s31 は省略 。。。
(gdb) s
6        BNE    label1
(gdb) info register
。。。 r0-pc は省略 。。。
cpsr           0x80000010    -2147483632
(gdb) s
label1 () at fpflags0.s:9
9    label1:    mov    r0, #1
(gdb) s
s_exit () at fpflags0.s:10
10    s_exit:    mov    r7, #1
(gdb) s
11        svc    #0
(gdb) s
[Inferior 1 (process 952) exited with code 01]
(gdb) quit


ここでは fpscr, cpsr ともに 0x8... なのでビット[31]
N, bit[31] Negative condition flag.
が 1 です