2014年6月5日木曜日

Unmask floating point exception #2

この投稿の追加投稿。

Gcc 4.4.7 にて下記の除算のみを行うソースをコンパイルして逆アセンブルすると除算は、SSE2の命令である"DIVSD" (*1 p.728)が出力されていることが確認できます。

-div.c-
#include <stdio.h>

int
main(void)
{
  double a,b,c;

  a=3.0;
  b=0.0;
  c=a/b;

  return 0;
}

$ gcc -o div div.c
$ objdump -d div > div.d

-div.d のmainの一部-
  40048f:       f2 0f 10 45 e8          movsd  -0x18(%rbp),%xmm0
  400494:       f2 0f 5e 45 f0          divsd  -0x10(%rbp),%xmm0
  400499:       f2 0f 11 45 f8          movsd  %xmm0,-0x8(%rbp)



 前回投稿したコードは、x87 FPUのFPE(Floating Point Exception)のマスクを解除するものであり、当たり前ですがSSE2のFPEを解除しているわけではないので、mainの最後でdouble同士の除算をしてもSSE2の命令が出力されているのでFPEは発生しません。

今回は、SSE2のFPEのマスクを外すコードをメモ。
 - sse2.c -
     1    #include <stdio.h>
     2   
     3    int
     4    main(void)
     5    {
     6      double a,b,c;
     7      unsigned char buff[512] __attribute__((aligned(16)));
     8   
     9      a=3.0;
    10      b=0.0;
    11      c=1.0;
    12   
    13      c = a/b;
    14   
    15      asm volatile(
    16        "fxsave %0" // get valueof mxcsr register
    17        :"=m"(buff):);
    18   
    19      printf("SSE2 FPE bit mask= %X\n", buff[25]);
    20      buff[25] = buff[25] ^ 0x2;
    21      printf("SSE2 FPE bit mask= %X\n", buff[25]);
    22   
    23      asm volatile(
    24        "fxrstor %0"  // set operand to mxcsr register
    25        : :"m"(*buff));
    26   
    27      c = a/b;
    28   
    29      return 0;
    30    }


fxsave(*1 P.846)/fxstor(*1 P.843) は、指定されたメモリ領域から/にMXCSR(*1 P.230)というSSE2の浮動小数点演算時に用いる情報を保持するレジスターに/の値を保存する。
20行目で該当するビットをクリアすることで、ゼロ割によるFPEのマスクを外している。

$ gcc --o sse2 sse2.c
$ ./sse2
SSE2 FPE bit mask= 1F
SSE2 FPE bit mask= 1D
Floating exception (core dumped)

[補足]
ちなみに、-mfpmath=387 というオプションをつけてコンパイルするとx87 FPUの除算命令を出力する。




*1 Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B, and 3C

2014年5月30日金曜日

[Windows 8.1] UEFI設定画面の確実な入り方

Windows 8.1がインストールされたPCで用があってUEFIの下記設定変更を行い。
・ディバイスの起動順の変更
・UEFIのセキュアブートの無効化
別のディバイスからブートして作業。作業終了後UEFIの設定を元にもどそうと設定画面に入るためのキーを押すが設定画面が表示されないし、Windowsも起動しない。

しょうがなく、電源ボタン長押しで電源断後、再度電源ボタンを押して暫くするとWindowsは起動した。

そんな事があったので対処法をメモ。
管理者権限のあるコマンドプロンプトで

shutdown /r /o
/r - Full shutdown and restart computer
/o - Go to the advanced options menu and restart computer. Must be used with /r option.

すると再起動後に"オプションの選択"という画面が表示されるので、トラブルシューティング]-[詳細オプション]-[UEFI ファームウェアの設定]の順にクリックする。



2014年5月22日木曜日

Unmask floating point exception


 x86 なプロセッサ上のLinuxでは、浮動小数点同士の除算でゼロ割を行ってもSIGFPEは普通発生しない。これは、FPU control word*1 というFPUのレジスタ中のFloating point exception のマスク状態を表すフラグが立っているためである。

gfortran -ffpe-trap=zero というオプションを指定すると浮動小数点のゼロ割でSIGFPEが発生するようになる。今回は、gcc インラインアセンブラでFloating point exception のマスクを解除してみた。



#include <stdio.h>

int
main(void)
{
  double a,b,c;
  unsigned short int fctr;

  a=3.0;
  b=0.0;
  c=1.0;

  asm volatile(
    "fstcw %w1\n\t" // get FPU control word
    "fdiv %3,%2"
    :"=&t"(c):"m"(fctr),"f"(a),"f"(b));
  printf("c= %f     FPU control word= %X\n", c, fctr);

  fctr = fctr ^ 0x4;
  printf("Value for FPU control word= %X\n", fctr);

  asm volatile(
    "fldcw %w1\n\t"  // set operand to FPU control word
    "fdiv %3,%2"
    :"=&t"(c):"m"(fctr),"f"(a),"f"(b));
  printf("c= %f     FPU control word= %X\n", c, fctr);

  return 0;
}


[実行結果]
$ ./a.out
c= inf     FPU control word= 37F
Value for FPU control word= 37B
Floating exception (core dumped)


*1 Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B, and 3C p.p.189-190

2013年12月2日月曜日

[webGL] DEM データビュワー by webGL

地理情報プロファイル Ver.2.XでフォーマットされたDEMデータのビュワーを作ってみた。
というか手段(webGL)が完璧に目的化しているけど。。。

とりあえず形には、なったので公開。

本当は、file apiでクライアント側のテキスチャ画像を選択できる様にしたかったが、サーバー上の画像ファイルしか貼れないのがthree.jsの仕様らしく断念。

いや違うまたは、別の方法があればどなたか教えてください。


2013年11月9日土曜日

2013年10月22日火曜日

[c] (広義の)コンパイルの工程

分かっていなかった事が分かったので
コンパイルの工程を復習するために hello.cに依存しているtest.cのコンパイル過程を
FreeBSD 9.1 RELEASE で出力してみた。

-hello.h-
#ifndef HELLO_H
#define HELLO_H

int sayHello(void);

#endif

-hello.c-
#include "stdio.h"
#include "hello.h"

int
sayHello(void)
{
  printf("hello\n");
  return 0;
}

-test.c-
#include <stdio.h>
#include "hello.h"

int
main(int argc, char **argv)
{
  sayHello();
  return 0;
}


なお、あらかじめhello.cは中間ファイル(オブジェクトコード)hello.oを生成済み。

$ gcc -o test -save-temps -v hello.o test.c

-save-temps … 通常は、削除される中間ファイルをカレントディレクトリに残す
-v … 途中コマンドを標準エラー出力にコマンドのバージョン情報も含めて出力する

以下が出力したコマンド

Using built-in specs.
Target: amd64-undermydesk-freebsd
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 4.2.1 20070831 patched [FreeBSD]
 /usr/libexec/cc1 -E -quiet -v -D_LONGLONG test.c -fpch-preprocess -o test.i #1
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/gcc/4.2
 /usr/include
End of search list.
 /usr/libexec/cc1 -fpreprocessed test.i -quiet -dumpbase test.c -auxbase test -version -o test.s #2
GNU C version 4.2.1 20070831 patched [FreeBSD] (amd64-undermydesk-freebsd)
compiled by GNU C version 4.2.1 20070831 patched [FreeBSD].
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: a8daf30220ba0c32c21af96787b683e6
 /usr/bin/as -V -Qy -o test.o test.s #3
GNU assembler version 2.17.50 [FreeBSD] 2007-07-03 (x86_64-unknown-freebsd) using BFD version 2.17.50 [FreeBSD] 2007-07-03
 /usr/bin/ld --eh-frame-hdr -V -dynamic-linker /libexec/ld-elf.so.1 -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib -L/usr/lib hello.o test.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o #4
GNU ld 2.17.50 [FreeBSD] 2007-07-03
  Supported emulations:
   elf_x86_64_fbsd
   elf_i386_fbsd


#1 プリプロセス
cc1 がコンパイラ本体らしい
以下が出力されたtest.i の一部
マクロ展開とインクルードファイルの中身の出力が行われていることが確認できる。

# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 39 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 40 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/sys/_null.h" 1 3 4
# 41 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/sys/_types.h" 1 3 4
# 33 "/usr/include/sys/_types.h" 3 4
# 1 "/usr/include/machine/_types.h" 1 3 4
# 51 "/usr/include/machine/_types.h" 3 4
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef short __int16_t;
typedef unsigned short __uint16_t;
typedef int __int32_t;

=中略=

# 2 "test.c" 2
# 1 "hello.h" 1



int sayHello(void);
# 3 "test.c" 2

int
main(int argc, char **argv)
{
  sayHello();
  return 0;
}

#2 アセンブリコード生成


-test.s-
.file "test.c"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB3:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
subq $16, %rsp
.LCFI2:
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
call sayHello
movl $0, %eax
leave
ret
.LFE3:
.size main, .-main
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zR"
.uleb128 0x1
.sleb128 -8
.byte 0x10
.uleb128 0x1
.byte 0x3
.byte 0xc
.uleb128 0x7
.uleb128 0x8
=以下略=


#3 アセンブル
アセンブルのコードを機械語に変換 オブジェクトファイル(*.o)を出力する


#4 リンク
必要なライブラリをリンクして、最終的な実行形式ファイル(ELF)を出力する。
以下は、出力されたバイナリに依存する共有ライブラリを表示

$ ldd test

test:
libc.so.7 => /lib/libc.so.7 (0x800819000)


2013年10月20日日曜日

[FreeBSD] style(9) 単語

man style(9) の翻訳で分からなかった単語の意味を列挙します。

implicit 暗に示す
assume 思い込む
silent on 言及しないで
History is silent on this event. 歴史は、この事件に関しては何も記していない。
brevity 簡潔な
trim 削減する
onlike in this one これとは違って
obtain B from A AからBを得る
elsewhre そのほかの場所では、
(a) applicable 適用可能である
enclose 囲む
okay to A Aして大丈夫です。
side effect 副作用
either どちらか一方
parentheses 確固
expantion 拡張
right-justigy 右寄せにする
encapsulate 要約する
compound statement 複合ステートメント
invocation 呼び出し
conditionally 条件的に
discern がわかる。はっきりと認める。
subjectively 主観的に
corresponding 一致する、対応する
preceding 先行する、前述の、上記の、先立つ
abbreviate 略して書く
identifier 識別子
in preference to A Aに勇戦して。 Aよりはむしろ。
overiding 他の全てに優先する
qualifier 修飾語句
suffice 満足させる
know if A is B AがBであるかどうかを知る
whereas であるのに ところが に反して
convention 慣習 しきたり、
elsewhere ほかの場所
relevant a 関連のある
preferably なるべく むしろ 好んで
compelling 強制的な むりやりの
precedent 慣例
either A or B AまたはB A,Bのどちらでも A,Bのいづれかを
preferable より好ましい
line up 整列する
briefly 簡単に
consistency 一貫性
obvioud 明白な
complicate 複雑にする
unary 単項の
binary operator 二項演算子
precedence 先行、上位
obvious 明白な
desire 強く願う
elicit 誘い出す、引き出す
complaint 不平、ぐち
whatever〜 どんな〜でも
compliant with に従う
consistent with 調和して、矛盾しないで
apporoximately ほぼ
diverge 分岐する、離れる
desire 要望
practice 実践