link もっと前
   2020年 5月 12日 -
      2020年 5月 3日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

link 編集する

GCC を調べる - その 9 - マシンモードの追加

以前(2020年 3月 27日の日記2020年 3月 28日の日記2020年 3月 29日の日記参照)ベクトルレジスタを扱えるようにした際に、下記の問題が残っていました。

  • 変数が int なので sizeof(v) が 4 になる、ベクトルを扱いたい
  • 最適化オプションを O0 にするとコンパイラが internal error を出す

1つ目の問題に取り組んでいきたいと思います。RISC-V 32 の場合、int の変数は 32bit 整数のデータ型として扱われます。GCC 内部の表現(RTL)では SImode というマシンモード(※)で表されます。他の大きさのデータ型を示すマシンモードも当然存在していて 8, 16, 64bit 整数はそれぞれ BImode, HImode, DImode で表されます。

普通の型に対応するモードは GCC が定義済みですが、ベクトル型を表すモードは標準では存在しないため、自分で新規に定義する必要があります。

(※)マシンモード(Machine Mode)については、GCC Internals の 14.6 Machine Modes に簡単な説明と標準的なモードの一覧が載っています。これによれば SI は Single Integer の略らしいです。変な名前だなあ。

マシンモードはどこにある?

以前(2020年 3月 14日の日記参照)説明したとおりですが、軽くおさらいすると、標準的なマシンモードは gcc/machmode.def、アーキテクチャ固有のマシンモードは gcc/config/arch/arch-modes.def にあります。例えば RISC-V なら gcc/config/riscv/riscv-modes.def です。

現在のところ RISC-V 固有のマシンモードは 1つしか定義されていません。

riscv-modes.def

FLOAT_MODE (TF, 16, ieee_quad_format);

このファイルにベクトル型を表すマシンモードを追加します。

riscv-modes.def に追加したモード

VECTOR_MODE (INT, SI, 8);
VECTOR_MODE (INT, SI, 16);
VECTOR_MODE (INT, SI, 32);
VECTOR_MODE (INT, SI, 64);

とりあえず整数(INT, SI)が 8, 16, 32, 64(それぞれ 32, 64, 128, 256 バイト)個連結されているデータ型を想定して作りました。ベクトル型を語る上では浮動小数点型も大事ですが、とりあえず今回は整数型のみを定義しています。

マシンモード追加できたかな

マシンモードを正しく追加できたか確かめる方法は色々あるのでしょうけど、個人的に簡単だと思うのは一旦ビルドしてしまう方法です。

GCC をビルドするとビルド用のディレクトリ(以降 build_gcc と呼びます)に、モードが全部書いてあるヘッダ insn-modes.h が生成されます。生成されたヘッダを検索すれば一発です。

モードが定義されているヘッダ

// gcc/build_gcc/insn-modes.h

enum machine_mode
{
  E_VOIDmode,              /* machmode.def:189 */
#define HAVE_VOIDmode
#ifdef USE_ENUM_MODES
#define VOIDmode E_VOIDmode
#else
#define VOIDmode ((void) 0, E_VOIDmode)
#endif
  E_BLKmode,               /* machmode.def:193 */
#define HAVE_BLKmode
#ifdef USE_ENUM_MODES
#define BLKmode E_BLKmode
#else
#define BLKmode ((void) 0, E_BLKmode)
#endif

...

  E_V32SImode,             /* config/riscv/riscv-modes.def:26 */
#define HAVE_V32SImode
#ifdef USE_ENUM_MODES
#define V32SImode E_V32SImode
#else
#define V32SImode ((void) 0, E_V32SImode)
#endif
  E_V64SImode,             /* config/riscv/riscv-modes.def:27 */
#define HAVE_V64SImode
#ifdef USE_ENUM_MODES
#define V64SImode E_V64SImode
#else
#define V64SImode ((void) 0, E_V64SImode)
#endif

...

新たなマシンモード V64SImode(SI が 64個連結されたデータ型)が追加されたことがわかると思います。コメントにマシンモードの定義されている場所も書かれていて、とても親切です。

ほぼ全域に渡って意味不明コードだらけの GCC では珍しい部類の、わかりやすさ&親切さです。自動生成コードには気を使っているんでしょうか?他のところもこれくらい親切だと嬉しいんですけどねえ。

[編集者: すずき]
[更新: 2020年 5月 13日 21:32]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

ヤマザキ春のパン祭り

今年のヤマザキ春のパン祭りは、2枚もゲットできました。


2020年、春のパン祭りの戦利品

去年は品川勤務かつコンビニ昼飯がメインだったので、ヤマザキパンを買う機会がほぼなく、お皿をもらえるほど点がたまりませんでした。今年は COVID-19 による在宅勤務で、近所のスーパーでパンを買う機会が大幅に増えたため、2枚も手に入ったわけです。在宅勤務の意外な効果です。

コンビニに行かない人にとっては意外かもしれませんが、コンビニはヤマザキパンをほとんど置いていません。自社のプライベートブランドのパンばかりです。10年位前は他社のパンも置いていたんですが、今やコンビニは 9割方がプライベートブランドのパンです。

コンビニのプライベートブランドのパンは、大手メーカー(ヤマザキパン、敷島製パン、フジパンなど)が作っていますが、コストの都合か何だか知りませんが、味に劣る気がします。好みの問題なのかな……?

強化ガラス

パン祭りのお皿、裏側に何か書いてるなーと思って写真を撮ってみました。


お皿の裏の説明

ちょっと見づらいので文字に起こすと、

ARTICLE YAMAZAKI
MADE IN FRANCE

ZENMEN
BUTSURIKYOUKA
GARASU

「全面物理強化ガラス」ってローマ字で書いてありますね。フランス製なのに何でローマ字?フランス語で書かれても読めないから?

見ていて素朴な疑問が沸きました。あえて「全面」と強調する理由はなんでしょうね?皿のように厚みのない製品で「片面」物理強化ガラスにすることは可能?可能だったとしてもやる意味がある?

[編集者: すずき]
[更新: 2020年 5月 13日 23:29]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

Python の変な API

Python の文字列置換は "string".replace() ですが、正規表現ライブラリ re だと、なぜか re.sub() です。同じ機能なのに、API の名前も、引数の指定順序も違います。どうしてこうなった。

改定の度に魔界化する C/C++ に比べると、Python は明瞭に思えます。とはいえ Python も何だかんだ長い歴史ですし、祓いきれない闇があるんでしょうねえ。

メモ: 技術系の話は Facebook から転記しておくことにした。

[編集者: すずき]
[更新: 2020年 5月 13日 21:44]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

Kindle for PC はダウンロードが遅い?

Kindle のアプリは Kindle Fire 版、Android 版、PC 版など、いくつか種類があります。普段使っているのは Kindle Fire と Kindle for PC です。どうも Kindle for PC のダウンロードが遅い気がします。

Kindle Fire も決して速いとは思いませんが、大抵はマンガ 1冊が 1〜2分でダウンロードできているので、5Mbps くらいは出ているんじゃないかと思います。

Kindle for PC はかなり遅い(1〜2Mbps くらい、日によって違う)です。同じネットワークを使っているのに、差が出るものですかね?PC 向けだけ帯域ケチるとか、そんな面倒なことしないよなあ?うーん?

Kindle アプリの動きがまた変わったけど、いつもどこかがダメ

Kindle Fire HD のアプリはたまにアップデートされて動きが変わります。今年の頭くらいだったか?覚えてないですけど、また動作が変わりました。

良くなったところ
フィルター「すべて」を選択したとき、本が多すぎると、数十秒フリーズしたり、アプリがクラッシュするバグが直ったこと
悪くなったところ
本のグループが意図せず表示されてしまうバグが埋め込まれたこと

新たなバグは再現率 100%です。再現方法も簡単です。

  • ホーム → 「本」のタブ → すべての本を表示、をタップ
  • 本の一覧が表示される
  • グループ化された本をタップ(マンガの1〜最新巻までをグルーピングする機能)を選択
  • ホームボタンでホームへ → 「本」のタブ → すべての本を表示、をタップ
  • 先ほど見ていたグループ化された本が表示される(バグ)

この順に操作したとき、本来は本の一覧が出なければなりませんが、グループ化された本が再表示されてしまいます。明らかにバグってます。

このバグは、ユーザー側の操作で回避可能です。

  • グループ化された本が意図せず表示される(バグ)
  • ホームボタン「ではなく」戻るボタンでホームに戻る
  • もう一度、すべての本を表示、をタップ
  • 本の一覧が表示される

ユーザーの操作に影響が出るバグですし、テスターに触らせたら数分で見つけそうなのにね?Kindle って UI のテストしてないのかなあ??

[編集者: すずき]
[更新: 2020年 5月 13日 23:56]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

RISC-V の gas

マクロの名前に Typo と思しきものがあったので、riscv-binutils-gdb(サイトへのリンク)に Pull Request をしてみました。

RISC-V 向けの gas の実装では、命令に対応した名前のマクロがあります。

命令の名前とマクロの名前の関係

//opcodes/riscv-opc.c

//通常は命令の名前からドットを除いて、大文字にした名前
//    vadd.vv -> MATCH_VADDVV

{"vadd.vv",    0, INSN_CLASS_V,  "Vd,Vt,VsVm", MATCH_VADDVV, MASK_VADDVV, match_opcode, 0 },
{"vadd.vx",    0, INSN_CLASS_V,  "Vd,Vt,sVm", MATCH_VADDVX, MASK_VADDVX, match_opcode, 0 },
{"vadd.vi",    0, INSN_CLASS_V,  "Vd,Vt,ViVm", MATCH_VADDVI, MASK_VADDVI, match_opcode, 0 },


//Reduce 系の命令だけ名前が違う
//    vredsum.vs -> MATCH_VREDSUMV"S" のはずなのに、MATCH_VREDSUMV"V" になっている

{"vredsum.vs", 0, INSN_CLASS_V, "Vd,Vt,VsVm", MATCH_VREDSUMVV, MASK_VREDSUMVV, match_opcode, 0},

パッチの中身は簡単で、ベクトル命令の一部で、命令の名前とマクロの名前が違っていたので修正しただけです。この手の間違いがいくつあるか分からなかったので、ちょっとした Python スクリプトを書いてチェックしました。

マクロの名前チェックに使ったスクリプト

#!/usr/bin/python

import re
import sys

fname = sys.argv[1]
f = open(fname, 'r')

line = f.readline()
while line:
	if not line.startswith('{"'):
		line = f.readline()
		continue;
	line = line.strip().replace('}', '')
	line = re.sub('\{"([^,]*)",', r'\1,', line)
	line = re.sub('".*",', '', line)
	line = re.sub(' *', '', line)
	items = line.split(',')

	insnOrg = items[0]
	insn = items[0].upper()
	classInsn = items[2]
	matchInsn = items[3]
	maskInsn = items[4]
	aliasInsn = items[6]
	if not classInsn.startswith('INSN_CLASS_V'):
		line = f.readline()
		continue;
	if not matchInsn.startswith('MATCH_') or not maskInsn.startswith('MASK_'):
		line = f.readline()
		continue;
	if aliasInsn.startswith('INSN_ALIAS'):
		line = f.readline()
		continue;

	insn = insn.replace('.', '')
	matchInsn = matchInsn.replace('MATCH_', '')
	maskInsn = maskInsn.replace('MASK_', '')
	if matchInsn != maskInsn:
		print("MATCH != MASK: {:s} != {:s}".format(matchInsn, maskInsn))
	if insn != matchInsn:
		print("INSN != MATCH: {:s} != {:s}".format(insnOrg, matchInsn))
	line = f.readline()

条件を適当に継ぎ足して書いたのと、Python の経験値が低いのが相まって、エレガントさの欠片もないですね。仕方ない。実行結果はこんな感じです。

マクロの名前チェックに使ったスクリプト
$ ../checker.py opcodes/riscv-opc.c

INSN != MATCH: vzext.vf2 != VZEXT_VF2
INSN != MATCH: vsext.vf2 != VSEXT_VF2
INSN != MATCH: vzext.vf4 != VZEXT_VF4
INSN != MATCH: vsext.vf4 != VSEXT_VF4
INSN != MATCH: vzext.vf8 != VZEXT_VF8
INSN != MATCH: vsext.vf8 != VSEXT_VF8
INSN != MATCH: vredsum.vs != VREDSUMVV
INSN != MATCH: vredmaxu.vs != VREDMAXUVV
INSN != MATCH: vredmax.vs != VREDMAXVV
INSN != MATCH: vredminu.vs != VREDMINUVV
INSN != MATCH: vredmin.vs != VREDMINVV
INSN != MATCH: vredand.vs != VREDANDVV
INSN != MATCH: vredor.vs != VREDORVV
INSN != MATCH: vredxor.vs != VREDXORVV
INSN != MATCH: vwredsumu.vs != VWREDSUMUVV
INSN != MATCH: vwredsum.vs != VWREDSUMVV
INSN != MATCH: vfredosum.vs != VFREDOSUMV
INSN != MATCH: vfredsum.vs != VFREDSUMV
INSN != MATCH: vfredmax.vs != VFREDMAXV
INSN != MATCH: vfredmin.vs != VFREDMINV
INSN != MATCH: vfwredosum.vs != VFWREDOSUMV
INSN != MATCH: vfwredsum.vs != VFWREDSUMV
INSN != MATCH: vcompress.vm != VCOMPRESSV

明らかに Typo に見えるのは vred/vfred/vcompress 系の命令で、vs と vv を取り違えています。

微妙なところなのは vzext です。他はドットを除いた名前なのに、vzext だけドットをアンダースコアに置換した名前です。ルールに一貫性が無いだけか、Typo か、どちらとも言い難いため、今回出した Pull Request では修正していません。

Pull Request 受け付けてるのかな?

リポジトリを見ていてちょっと気になったのは SiFive の人以外、変更がほとんどないことです。著名プロジェクトでは珍しいです。もしかすると GitHub で Pull Request を受け付けてない(※1)可能性があります。

変更を提案するのはここじゃないとか、そもそも変更は受け付けてませんとか、何でも良いので反応があると嬉しいですね、週明けまで待ちましょうかね……。

(※1)本家および開発の場が GitHub 以外に存在していて、GitHub をミラーにしているプロジェクトの場合、GitHub 上で何か言っても無視されることがあるようです。

[編集者: すずき]
[更新: 2020年 5月 10日 15:44]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

プレーヤー人口が増えるのは良いことだ

Splatoon 2 のガチマッチ(C ランク)の難易度が下がった気がします。

1〜2 か月前は、20kill 対 0kill で負けたり、1分でノックアウトされたり、超フルボッコで負けまくるのが当たり前で、すっかりやる気がなくなっていましたが、今日久しぶりにやったら一度も負けず、あっさり C+ ランクになりました。

アクションゲームの腕は 1か月やそこらで急に上達しないので、私が上達したというよりも、絶対勝てないおかしいレベルのプレーヤーとマッチする割合が減った、そんな感じです。

Stay Home とかゴールデンウイークとかで、Splatoon 2 のプレーヤー人口が盛り返して、初心者クラス(C-〜C+ ランクあたり)に合う人が増えたんじゃないかと推測しています。

最初からこのくらいの難易度だったら、ガチマッチ嫌いにならずに済んだんですけど、すっかりガチマッチ嫌いになってしまった(レギュラーマッチは好き)ので、もう遅いんだよな〜……。

[編集者: すずき]
[更新: 2020年 5月 6日 23:21]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

C 言語のマクロ

C 言語のマクロによる置換を、循環参照させたらどうなるでしょう?

循環するマクロ定義

A B C D
#define A B
A B C D
#define B C
A B C D
#define C A
A B C D

結論から言うと問題ありません。下記のような結果になります。

循環するマクロ定義、置換結果

A B C D

B B C D

C C C D

A B C D

4つ目の結果は、置換前の A B C D と何も変わっていないように見えますが、実はそうではありません。下記のように定義するとわかります。

循環するマクロ定義、マクロによる置換結果を見やすくする

A B C D
#define A 1 B
A B C D 
#define B 2 C
A B C D 
#define C 3 A
A B C D
循環するマクロ定義、置換結果が見やすいはず

A B C D

1 B B C D

1 2 C 2 C C D

1 2 3 A 2 3 1 B 3 1 2 C D

4つ目の結果の「A」を例にとると、A -> B -> C -> A と 3回のマクロの置換が行われた結果、A に戻っているわけです。#define A B のマクロは 1度しか適用されないようです。

C 言語の仕様

C 言語の仕様(C11 final draft (N1570) - 6.10.3.4 Rescanning and further replacement の第 2項)を見ると、

2
If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file's preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.

(直訳)
2
置換されるマクロの名前が replacement list のスキャン中に見つかった場合(ソースファイルの残りの前処理トークンは含まれません)、そのマクロは置換されません。 さらに、入れ子になった置換が、置換されているマクロの名前に遭遇した場合、それは置換されません。 後にそのマクロ名の前処理トークンが置換されていたであろうコンテキストで(再)検査されても、これらの置換されていないマクロ名の前処理トークンはそれ以上の置換はできなくなります。

正直言って何言ってんだお前……?って感じがしますけども、平たく言うと同じマクロを 2回適用しない、ように読めます。

複雑版

下記のように同じマクロで何度も置換できそうなマクロを定義してみます。

循環するマクロ定義、より複雑版

#define A B C
#define B C A
#define C A B
A B C D
循環するマクロ定義、より複雑版、結果

A B A A C A B C B B A B C A C C B C D

1つ 1つのトークンがどのマクロで展開されているか図示します。


循環するマクロ定義、展開の様子

複雑に見えますが、どのトークンを見ても同じマクロを 2回適用されたものはないことがわかります。

関数型マクロの謎

しかし関数型マクロの場合は、不思議な挙動を示します。

循環する関数型マクロ定義

#define F(a) a G
#define G(a) a F(a)

F(7)(8)(9)
循環する関数型マクロ定義、結果


7 8 8 G(9)

展開の様子は下記のようになると思われますが、


循環する関数マクロ定義、展開の様子

どうして 7 8 8 G(9) で展開が終わるのかが良くわかりません……。マクロ F(a) を 2回適用しない、というルールならば、7 8 F(8)(9) で止まらなければおかしいように思いますが、結果を見るとなぜか F(8) も展開されています。

[編集者: すずき]
[更新: 2020年 5月 6日 23:04]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2020年 5月 12日 -
      2020年 5月 3日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 5/31 01:18

カレンダー

<2020>
<<<05>>>
-----12
3456789
10111213141516
17181920212223
24252627282930
31------

最近のコメント 5件

  • link 20年05月02日
    すずき 「ちょっと調べたところ、コアが焼けると騒ぎ...」
    (更新:05/08 15:43)
  • link 20年05月02日
    すずき 「結構、怖い制御に見えますね&hellip...」
    (更新:05/08 15:23)
  • link 20年05月02日
    hdk 「デスクトップ用のNVIDIA Quadr...」
    (更新:05/07 20:30)
  • link 20年01月27日
    すずき 「詳細は調べていないので、コード中のコメン...」
    (更新:04/18 23:05)
  • link 20年01月27日
    superzeros 「少し気になったのでglibcの履歴を調べ...」
    (更新:04/16 21:07)

最近の記事 3件

link もっとみる
  • link 20年06月01日
    すずき 「[GCC を調べる - その 13-4 - ベクトル命令のオフ] ...」
    (更新:05/31 01:18)
  • link 20年05月31日
    すずき 「[GCC を調べる - その 13-3 - オフセット付きアド] ...」
    (更新:05/30 22:00)
  • link 20年05月30日
    すずき 「[GCC を調べる - その 13-2 - オフセット付きアド] ...」
    (更新:05/30 21:53)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報