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 です
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 です