コグノスケ


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

link もっと前
2020年3月19日 >>> 2020年3月6日
link もっと後

2020年3月19日

ナンバープレート変更(大阪→品川)

目次:

引っ越してから1年もの間、車検証の住所変更をせずにほったらかしていました(本当は良くない)が、重い腰を上げ、大阪ナンバーにお別れを告げて、品川ナンバーになりました。

手続きに興味があったので、あえてディーラーにお任せせず自分でやってみました。面白かったですが相当面倒くさいです。もう自分でやることはないでしょうね。

手続きの概要

今回は「変更登録」という手続きをしました。車検証の住所変更&ナンバープレートの変更です。他県から東京都に引っ越した人が該当します。手続きはざっくりいうと、

  • 警察(車庫証明)1回目
  • (3日〜1週間後)
  • 警察(車庫証明)2回目
  • 市役所(住民票)1回
  • 陸運局(車検証)1回

どうがんばって圧縮しても、平日を2回消費します。普通は警察、警察、陸運局、の3回消費すると思います。警察も陸運局も平日しか受け付けしていないので、勤め人にはなかなか辛いです。

詳細な手続き

興味のある人は居なさそうですが、メモ代わりに書いておきます。まずは車庫証明用の書類が必要です。

  • (借家の場合)大家さんに「保管場所使用承諾証明書」を書いてもらう
  • 自分で「自動車保管場所証明申請書」を書く
  • 自分で「保管場所標章交付申請書」を書く
  • 自分で「保管場所の所在図・配置図」を書く

ここまでの書類は全部の警視庁のサイト(保管場所証明申請手続 - 警視庁)からゲットできます。

管轄の警察
上記の「4つの書類」を出して「領収証書」を貰います。「何月何日にもう一回来てね」と教えてくれます。
私の場合は「蒲田警察署」でした。それと金額は忘れましたが、収入印紙を買う必要があります。その場で手に入るので、財布だけあれば特に準備不要です。
管轄の警察
「領収証書」を渡すと「車庫証明」を貰います。私は3日後でしたが、場合によるらしくだいたい3日〜1週間後みたいです。
市役所
「住民票」を貰います。窓口に行ってお金払うとくれます。
運輸局(陸運局)に「車で」行く
私の場合は「関東運輸局 東京運輸支局」でした。鮫洲にあります。免許センターの隣と言った方がわかるかも。
超大事なことなのですが、ナンバープレートを交換しなければならないので、車で行きましょう、でないと窓口で追い返されます。
国土交通省のサイトにある「1号様式」が申請書類です(自動車:OCR申請書各種様式について - 国土交通省)が、正直訳わかんないです。書類は事前に書きましたが、事前相談の窓口でめっちゃ直されました。
運輸局
「1号様式」と「車庫証明(警察でもらう)」と「住民票」と「古い車検証」を出すと「新たな車検証」と「スタンプが押された紙」がもらえます。
古い車検証は没収されます。次は自動車税事務所に行ってねと言われます。建物は隣接しているので楽です。
自動車税事務所
「変更登録の書類」と「スタンプが押された紙」を出すと、スタンプが増えて帰ってきます。
書類は事務所内にあります。旧住所を聞かれますので、どこかにメモしておいた方がいいかも。思い出せる人は問題ないです。
運輸局
「古いナンバー」と「新しい車検証」と「スタンプが押された紙」を出すと「新しいナンバー」をくれます。
関東運輸局は「自分でナンバーを交換する」方式みたいで、自分でナンバーの封印を破壊するのはなかなか出来ない体験です。工具は普通のドライバーです、運輸局で貸してくれます。
ナンバーの封印は思ったよりもヘナヘナしていて、あっさり壊れました。慣れている人は数秒で壊せそうでした。
運輸局
「新しいナンバー」と「車」を運輸局の建物の前に持っていくと「ナンバーの封印」と「新しい車検証」をくれます。
車体番号見るのでボンネット開けてくれっていわれます。封印はおっちゃんが付けてくれます。

ナンバーの封印を付けてもらったら、そのまま車で運輸局からおさらばです。

感想

やってみた感想は「RPGのクエストみたい」です。書類と書類を交換していくと、最後に車検証とナンバープレートが貰えます、みたいな感じですね。車のナンバー(と自動車税)管理の一環が垣間見えて、なかなか面白い社会科見学でした。

個人的にはナンバープレートの封印を破壊するのは、普段やらない体験で「え?自分で壊すの??」と緊張しました(関東運輸局だけセルフで、他地域ではやらないみたいです)。私の車は粗雑に扱っているせいなのか、フロント側のナンバーのネジが錆びて固着しており、あやうくネジをなめそうでした。次はもう外せないかもしれない。

昨今のコロナ騒ぎのせいか、いずれの窓口もガラッガラに空いていて快適でした。混んでいたら地獄だったと思います。

編集者:すずき(2023/09/30 15:15)

コメント一覧

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



2020年3月14日

GCCを調べる - その7 - machine mode定義ファイルの場所

目次: GCC

GCCはアーキテクチャごとに設定ファイルがあってgcc/config/(アーキテクチャ名)/ という名前のディレクトリ下に配置されています。

その中にmachine modeを設定するファイルがあります。例えばRISC-Vならgcc/config/riscv/riscv-modes.defですし、AArch64ならgcc/config/aarch64/aarch64-modes.defです。machine modeとは何かはちょっと横に置いて、このファイルの探し方が割と不思議な作りだったので紹介します。

GCCのビルドプロセスは非常にややこしいです。xxxx-modes.defはGCCのコードで直接使われず、前処理で使われます。GCCのビルドディレクトリを (build_dir) と書くとすると、

  • genmodes.cから (build_dir)/build/genmodesというプログラムを作成
  • genmodesの出力を使い (build_dir)/insn-modes.cを生成
  • insn-modes.cをGCCのビルドに使う

こんな仕組みになっています。起点となるgenmodes.cから見ます。

xxxx-modes.defのファイル名を決める部分

// gcc/genmodes.c

static void
create_modes (void)
{
#include "machmode.def"  //★★これに全てのモードが定義されている


// gcc/machmode.def

/* Allow the target to specify additional modes of various kinds.  */
#if HAVE_EXTRA_MODES
# include EXTRA_MODES_FILE  //★★追加のファイルがあればinclude
#endif


// gcc/genmodes.c

#ifdef EXTRA_MODES_FILE
# define HAVE_EXTRA_MODES 1
#else
# define HAVE_EXTRA_MODES 0
# define EXTRA_MODES_FILE ""
#endif

EXTRA_MODES_FILEというマクロにファイル名が定義されていれば、そのファイルもincludeする仕組みになっています。C言語を見慣れている人もかなり面食らう書き方ですが、GCCは「*.defファイルをincludeする」という技を乱発します。メチャクチャすぎる。

EXTRA_MODES_FILEをマクロを定義するのはconfig.gccとconfigureです。

xxxx-modes.defのファイル名を決める部分

# gcc/config.gcc

extra_modes=
if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-modes.def
then
	extra_modes=${cpu_type}/${cpu_type}-modes.def    # ★★aarch64-modes.defのような名前のファイルが存在すればそのファイルを使う
fi


# gcc/configure

# Collect target-machine-specific information.
. ${srcdir}/config.gcc || exit 1    # ★★config.gccの設定を取り込む

...

# Look for a file containing extra machine modes.
if test -n "$extra_modes" && test -f $srcdir/config/$extra_modes; then
  extra_modes_file='$(srcdir)'/config/${extra_modes}    # ★★extra_modesはconfig.gccで定義したものが導入される


cat >>confdefs.h <<_ACEOF
#define EXTRA_MODES_FILE "config/$extra_modes"    # ★★config/aarch64/aarch64-modes.defのような値になる
_ACEOF

fi

やっとたどり着きました。GCCってちょっとしたことでも、ものすごく複雑にできていて、読むのが辛いというか、読んでも意味不明なことが多いです。うーん、辛い。

編集者:すずき(2023/09/24 11:47)

コメント一覧

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



2020年3月10日

誕生日

37歳になりました。おめでとう俺、ありがとう俺。30代も残りわずかです。

何歳になろうが、本人は特に何も変わってませんが、周りから見ると確実にオジサンです。若者へ説教と昔の自慢話だけは絶対しないように気をつけます。

今に始まったことじゃないんですが、いつも何歳だか良くわからなくなります。もちろん (現在の西暦) - (生まれた西暦) で、1月1日〜3月9日は -1すれば良いのはわかってますが、ぱっと答えられません。なぜなのか……。

編集者:すずき(2020/03/15 02:33)

コメント一覧

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



2020年3月9日

TinkerBoardが起動しなくなった

目次: ROCK64/ROCKPro64

ASUS TinkerBoardで動かしているlinux-nextを最新版に更新したところ、下記のようなエラーを出力して起動しなくなりました。

linux-next起動時のエラー
[    0.000000] __clk_core_init: Failed to get phase for clk 'sdmmc_drv'
[    0.000000] rockchip_clk_register_branches: failed to register clock sdmmc_drv: -22
[    0.000000] rockchip_clk_register_branches: failed to register clock sdmmc_sample: -17
[    0.000000] rockchip_clk_register_branches: failed to register clock sdio0_drv: -17
[    0.000000] rockchip_clk_register_branches: failed to register clock sdio0_sample: -17
[    0.000000] rockchip_clk_register_branches: failed to register clock sdio1_drv: -17
[    0.000000] rockchip_clk_register_branches: failed to register clock sdio1_sample: -17
[    0.000000] rockchip_clk_register_branches: failed to register clock emmc_drv: -17
[    0.000000] rockchip_clk_register_branches: failed to register clock emmc_sample: -17

エラーメッセージで検索しても、特にめぼしい報告やパッチに引っかかりません。うーん。困りましたね。

原因解析

仕方ないので、更新履歴をgit bisectすると2/13から2/14の間にクロックドライバが変更されたことが原因だとわかりました。

git bisectで見つけた原因となる変更Commit:2760878662a2

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index dc8bdfbd6a0c..ed1797857bae 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3457,7 +3457,12 @@ static int __clk_core_init(struct clk_core *core)
 	 * Since a phase is by definition relative to its parent, just
 	 * query the current clock phase, or just assume it's in phase.
 	 */
-	clk_core_get_phase(core);
+	ret = clk_core_get_phase(core);
+	if (ret < 0) {
+		pr_warn("%s: Failed to get phase for clk '%s'\n", __func__,
+			core->name);
+		goto out;
+	}
 
 	/*
 	 * Set clk's duty cycle.

しかしこの変更は真っ当に見えます。今までエラーを無視していたところをエラーチェックするようにしているだけだからです。

どの辺りでエラーが出るか調べるためprintkを適当に入れたりしながら追ってみると、下記の場所で躓いていました。

クロック周りのコード

// drivers/clk/clk.c

static int __clk_core_init(struct clk_core *core)
{
...
	/*
	 * Set clk's phase by clk_core_get_phase() caching the phase.
	 * Since a phase is by definition relative to its parent, just
	 * query the current clock phase, or just assume it's in phase.
	 */
	phase = clk_core_get_phase(core);  //★★変更が影響している場所
	if (phase < 0) {
		ret = phase;
		pr_warn("%s: Failed to get phase for clk '%s'\n", __func__,
			core->name);
		//goto out;
	}


// drivers/clk/clk.c

static int clk_core_get_phase(struct clk_core *core)
{
	int ret;

	lockdep_assert_held(&prepare_lock);
	if (!core->ops->get_phase)
		return 0;

	/* Always try to update cached phase if possible */
	ret = core->ops->get_phase(core->hw);  //★★ここでエラーが発生していた
	if (ret >= 0)
		core->phase = ret;

	return ret;
}

独自のget_phaseを持っているドライバがエラーを返すと、clk_core_get_phase() もエラーを返し、先程のエラーメッセージが表示されるみたいです。しかし、この処理自体におかしな箇所はないように思います。真っ当です。

おそらく実装がおかしいのはRockchipのMMCドライバのクロック周りの方でしょう。エラーメッセージに出ているsdmmc_drvを頼りにコードを追います。

Rockchip RK3228クロック周りのコード

// drivers/clk/rockchip/clk-rk3228.c

PNAME(mux_mmc_src_p)		= { "cpll", "gpll", "xin24m", "usb480m" };
...
	COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0,
			RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS,
			RK2928_CLKGATE_CON(2), 11, GFLAGS),
	...
	//★★sdmmc_drvはこの部分由来です
	MMC(SCLK_SDMMC_DRV,    "sdmmc_drv",    "sclk_sdmmc", RK3228_SDMMC_CON0, 1),


// drivers/clk/rockchip/clk.h

#define MMC(_id, cname, pname, offset, shift)			\
	{							\
		.id		= _id,				\
		.branch_type	= branch_mmc,			\  //★★この値がカギかな?
		.name		= cname,			\
		.parent_names	= (const char *[]){ pname },	\
		.num_parents	= 1,				\
		.muxdiv_offset	= offset,			\
		.div_shift	= shift,			\
	}


// drivers/clk/rockchip/clk-rk3228.c

static void __init rk3228_clk_init(struct device_node *np)
{
...
	rockchip_clk_register_branches(ctx, rk3228_clk_branches,  //★★ここでbranch_typeを見ている箇所がある
				  ARRAY_SIZE(rk3228_clk_branches));
...
}
//★★注: rk3228_clk_initはRK3228のクロックコア初期化関数
//    デバイスツリー内のcompatible = "rockchip,rk3228-cru" を持つノードに応じて呼ばれる
CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);


// drivers/clk/rockchip/clk.c

void __init rockchip_clk_register_branches(
				      struct rockchip_clk_provider *ctx,
				      struct rockchip_clk_branch *list,
				      unsigned int nr_clk)
{
...
	for (idx = 0; idx < nr_clk; idx++, list++) {
		flags = list->flags;

		/* catch simple muxes */
		switch (list->branch_type) {
		...
		case branch_mmc:  //★★branch_type == branch_mmcだったら
			clk = rockchip_clk_register_mmc(  //★★クロックの登録をしている
				list->name,
				list->parent_names, list->num_parents,
				ctx->reg_base + list->muxdiv_offset,
				list->div_shift
			);
			break;
		...


// drivers/clk/rockchip/clk-mmc-phase.c

struct clk *rockchip_clk_register_mmc(const char *name,
				const char *const *parent_names, u8 num_parents,
				void __iomem *reg, int shift)
{
...
	init.name = name;
	init.flags = 0;
	init.num_parents = num_parents;
	init.parent_names = parent_names;
	init.ops = &rockchip_mmc_clk_ops;  //★★クロックの操作関数を登録している
...


// drivers/clk/rockchip/clk-mmc-phase.c

static const struct clk_ops rockchip_mmc_clk_ops = {
	.recalc_rate	= rockchip_mmc_recalc,
	.get_phase	= rockchip_mmc_get_phase,  //★★get_phaseはこの関数
	.set_phase	= rockchip_mmc_set_phase,
};


// drivers/clk/rockchip/clk-mmc-phase.c

static int rockchip_mmc_get_phase(struct clk_hw *hw)
{
	struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw);
	unsigned long rate = clk_hw_get_rate(hw);
	u32 raw_value;
	u16 degrees;
	u32 delay_num = 0;

	/* See the comment for rockchip_mmc_set_phase below */
	if (!rate)
		return -EINVAL;  //★★エラーを返している
...

原因らしき箇所が見つかりました。クロック周波数(rate)が設定されていなくても、エラーを返す必要はなく、phaseの初期値0を返せば良いはずですから、return -EINVALをreturn 0にすれば良さそうです。

変更すると無事linux-nextが起動できるようになりました。良かった良かった。

またこのパターン!

こんなバグを2週間以上放置するなんてlinuxらしくないなと思って、パッチを送ろうとしましたが……、なんだかとっても嫌な予感がしたので、rochchip_mmc_get_phaseでLKMLを検索してみました。

検索してびっくり、なんと、全く同じ指摘をしているパッチが先週LKMLに送られています(LKMLへのリンク)。しかも既にclk-nextに取り込まれているじゃないですか。ですがlinux-nextへの反映はまだのようです。

明日まで待っていればclk-nextがlinux-nextに取り込まれるので、何もしなくても解決していたんです。パッチ投稿が3/4なので、今回は本当に気づくタイミングが悪かったです。

LKMLに投稿されていたパッチ

Author: Jerome Brunet < >
Date:   Tue Mar 3 20:29:56 2020 +0100

    clk: rockchip: fix mmc get phase
    
    If the mmc clock has no rate, it can be assumed to be constant.
    In such case, there is no measurable phase shift. Just return 0
    in this case instead of returning an error.
    
    Fixes: 2760878662a2 ("clk: Bail out when calculating phase fails during clk
    registration")
    Tested-by: Markus Reichl <m.reichl@fivetechno.de>
    Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>

diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index 4abe7ff31f53..975454a3dd72 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -51,9 +51,9 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw)
 	u16 degrees;
 	u32 delay_num = 0;
 
-	/* See the comment for rockchip_mmc_set_phase below */
+	/* Constant signal, no measurable phase shift */
 	if (!rate)
-		return -EINVAL;
+		return 0;
 
 	raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);

前にも、原因を突き止めたら、解決済みだったというパターン(2018年12月4日の日記2019年9月18日の日記)がありました。

またこの「鶏と卵のパターン」にやられました。ついてない。

コードに特攻する前に、ちゃんと探せば?って思われるかもしれませんが、困ったことにエラーメッセージで検索してもパッチに辿り着けないんです。調べに調べて原因と対策がわかった後に、はぁ?もうパッチあるじゃん!?と気づくから、徒労感が激しい……。

編集者:すずき(2023/09/24 13:22)

コメント一覧

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



2020年3月6日

GCCを調べる - その6 - ベクトルレジスタ用のregister constraintを足す

目次: GCC

GCCのインラインアセンブラでは __asm__("ins %0" : "=r"(aaa) : : ); のように、"=r" という不思議な文字列が出てきます。

これはconstraintsと呼ばれ(GCCのマニュアルへのリンク)、引数がレジスタ(r)なのかメモリアドレス(m)なのか、書き換えられるのか(=)などを説明しています。

どんな文字でも書けるわけではなく、変な文字(例えば 'v')を指定すると「impossible constraint in 'asm'」と怒られます。これは一体どこでチェックしているのでしょう?また、どうやって足せばよいでしょうか?

エラーを出している箇所

このエラーを出すのは、パスでいうと234r.vregsです。

ちなみにbuild_gccというディレクトリ名はGCCのビルドディレクトリのことです。GCCは自動生成コードをかなりの量出力するので、そちらも合わせて見る必要があります。

エラーメッセージを出している箇所

// gcc/function.c

static void
instantiate_virtual_regs_in_insn (rtx_insn *insn)
{
...
  if (asm_noperands (PATTERN (insn)) >= 0)
    {
      if (!check_asm_operands (PATTERN (insn)))  //★★このエラーチェックに引っかかっている
	{
	  error_for_asm (insn, "impossible constraint in %<asm%>");  //★★このエラーメッセージが出ている


// gcc/recog.c

int
check_asm_operands (rtx x)
{
...
  for (i = 0; i < noperands; i++)
    {
      const char *c = constraints[i];
      if (c[0] == '%')
	c++;
      if (! asm_operand_ok (operands[i], c, constraints))  //★★このエラーチェックに引っかかっている
	return 0;
    }

このチェックは何をしているのかというと、lookup_constraint() で文字(例えば 'v')をテーブルから探し、constraintの種類に変換します。未知の文字の場合はCONSTRAINT_UNKNOWNになります。

次にget_constraint_type() でどのカテゴリに属するか見ます。この関数はおかしくて、なぜかCONSTRAINT__UNKNOWNをCT_REGISTERと判定します。レジスタじゃないですよね?意味不明です。

asm文のconstraintを見ている箇所

// gcc/recog.c

int
asm_operand_ok (rtx op, const char *constraint, const char **constraints)
{
  int result = 0;
...
  while (*constraint)
    {
      enum constraint_num cn;
      char c = *constraint;
      int len;
      switch (c)
	{
...
	default:
	  cn = lookup_constraint (constraint);  //★★文字からconstraint_numに変換
						//    未知の文字の場合CONSTRAINT__UNKNOWNになる
	  switch (get_constraint_type (cn))
	    {
	    case CT_REGISTER:  //★★なぜかここに行く
	      if (!result
		  && reg_class_for_constraint (cn) != NO_REGS  //★★レジスタのconstraintがNO_REGSになるとNG
		  && GET_MODE (op) != BLKmode
		  && register_operand (op, VOIDmode))
		result = 1;
	      break;


// build_gcc/gcc/tm-preds.h

static inline enum constraint_num
lookup_constraint (const char *p)
{
  unsigned int index = lookup_constraint_array[(unsigned char) *p];  //★★この配列がカギ
  return (index == UCHAR_MAX
          ? lookup_constraint_1 (p)
          : (enum constraint_num) index);
}

enum constraint_num
{
  CONSTRAINT__UNKNOWN = 0,
  CONSTRAINT_r,
  CONSTRAINT_f,
...

static inline enum constraint_type
get_constraint_type (enum constraint_num c)
{
  if (c >= CONSTRAINT_p)
    {
      if (c >= CONSTRAINT_G)
        return CT_FIXED_FORM;
      return CT_ADDRESS;
    }
  if (c >= CONSTRAINT_m)
    return CT_MEMORY;
  if (c >= CONSTRAINT_I)
    return CT_CONST_INT;
  return CT_REGISTER;  //★★cがCONSTRAINT__UNKNOWNつまり0の場合、どれにも当てはまらずCT_REGISTERと判断される
}


// build_gcc/insn-preds.c

const unsigned char lookup_constraint_array[] = {
  CONSTRAINT__UNKNOWN,
  CONSTRAINT__UNKNOWN,
...
  MIN ((int) CONSTRAINT_r, (int) UCHAR_MAX),
  MIN ((int) CONSTRAINT_s, (int) UCHAR_MAX),
  CONSTRAINT__UNKNOWN,
  CONSTRAINT__UNKNOWN,
  CONSTRAINT__UNKNOWN,  //★★'v' は未定義、未知の文字の場合は全てCONSTRAINT__UNKNOWNになる
  CONSTRAINT__UNKNOWN,
...


// build_gcc/gcc/tm-preds.h

static inline enum reg_class
reg_class_for_constraint (enum constraint_num c)
{
  if (insn_extra_register_constraint (c))
    return reg_class_for_constraint_1 (c);  //★★ここで見つからないとNO_REGSが返されてNG
  return NO_REGS;
}


// build_gcc/gcc/insn-preds.c

enum reg_class
reg_class_for_constraint_1 (enum constraint_num c)
{
  switch (c)
    {
    case CONSTRAINT_r: return GENERAL_REGS;
    case CONSTRAINT_f: return TARGET_HARD_FLOAT ? FP_REGS : NO_REGS;
    case CONSTRAINT_j: return SIBCALL_REGS;
    case CONSTRAINT_l: return JALR_REGS;
    default: break;  //★★CONSTRAINT__UNKNOWNはどのcaseにも当てはまらないのでNO_REGSが返されてNG
    }
  return NO_REGS;
}

明らかにレジスタとは思えないCONSTRAINT__UNKNOWNが返ってきますが、なぜかCT_REGISTERだと思って処理し始め、最終的にエラーとして弾きます。結果オーライですがこれで良いんでしょうか。GCCのコードは訳がわかりません……。

register_constraintの足し方

ではvを正当なconstraintの一員にするにはどうしたら良いでしょうか?

第一歩としてはGCCのconfigディレクトリの下にある *.mdファイル(MarkdownではなくMachine Descriptorです)を編集します。

define_register_constraintを足す

;; config/riscv/riscv.md

(include "predicates.md")
(include "constraints.md")


;; config/riscv/constraints.md

(define_register_constraint "v" "TARGET_VECTOR ? VP_REGS : NO_REGS"
  "A vector register (if available).")

これを足すと(他にも色々やらないといけないんですけど)、先程のreg_class_for_constraint_1() に変化が生じます。

asm文のconstraintチェックが変わる

// build_gcc/gcc/insn-preds.c

enum reg_class
reg_class_for_constraint_1 (enum constraint_num c)
{
  switch (c)
    {
    case CONSTRAINT_r: return GENERAL_REGS;
    case CONSTRAINT_f: return TARGET_HARD_FLOAT ? FP_REGS : NO_REGS;
    case CONSTRAINT_j: return SIBCALL_REGS;
    case CONSTRAINT_v: return TARGET_VECTOR ? VP_REGS : NO_REGS;  //★★これが足されて通過するようになる
    case CONSTRAINT_l: return JALR_REGS;
    default: break;
    }
  return NO_REGS;
}

GCCはこの手のピタゴラスイッチの塊で、何を変えると望みの機能が実装できるか、全くわかりません。こんなもの良くメンテナンスできるなあ、と思います。

編集者:すずき(2023/09/24 11:47)

コメント一覧

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



link もっと前
2020年3月19日 >>> 2020年3月6日
link もっと後

管理用メニュー

link 記事を新規作成

<2020>
<<<03>>>
1234567
891011121314
15161718192021
22232425262728
293031----

最近のコメント5件

  • link 24年10月1日
    すずきさん (10/06 03:41)
    「xrdpで十分動作しているので、Wayl...」
  • link 24年10月1日
    hdkさん (10/03 19:05)
    「GNOMEをお使いでしたら今はWayla...」
  • link 24年10月1日
    すずきさん (10/03 10:12)
    「私は逆にVNCサーバーに繋ぐ使い方をした...」
  • link 24年10月1日
    hdkさん (10/03 08:30)
    「おー、面白いですね。xrdpはすでに立ち...」
  • link 14年6月13日
    2048player...さん (09/26 01:04)
    「最後に、この式を出すのに紙4枚(A4)も...」

最近の記事20件

  • link 24年10月31日
    すずき (11/04 15:17)
    「[DENSOの最終勤務日] 最終勤務日でした、入門カードや会社のPCを返却してきました。在籍期間はNSITEXE(品川のオフィ...」
  • link 22年7月8日
    すずき (11/02 20:34)
    「[マンガ紹介 - まとめリンク] 目次: マンガ紹介一覧が欲しくなったので作りました。5作品乙女ゲームの破滅フラグしかない悪役...」
  • link 24年10月30日
    すずき (11/02 20:33)
    「[マンガ紹介] 目次: マンガ紹介お気に入りのマンガ紹介シリーズ。最近完結した短めの作品を紹介します。マイナススキル持ち四人が...」
  • link 19年3月28日
    すずき (11/02 13:27)
    「[マンガ紹介] 目次: マンガ紹介お気に入りのマンガ紹介シリーズ。こわもてかわもて(全2巻、2019年)(アマゾンへのリンク)...」
  • link 21年6月20日
    すずき (11/02 13:22)
    「[読書一生分が93万円?] 目次: マンガ紹介書籍通販のhontoがこんなキャンペーンをやっています。honto読書一生分プレ...」
  • link 17年10月27日
    すずき (11/02 13:11)
    「[異世界&最強系漫画の種類] 目次: マンガ紹介少し前にアニメ化されて盛り上がって(おそらく負の方向に…)いた「...」
  • link 24年10月28日
    すずき (10/30 23:49)
    「[Linuxからリモートデスクトップ] 目次: Linux開発用のLinuxマシンの画面を見るにはいろいろな手段がありますが、...」
  • link 23年4月10日
    すずき (10/30 23:46)
    「[Linux - まとめリンク] 目次: Linux関係の深いまとめリンク。目次: RISC-V目次: ROCK64/ROCK...」
  • link 24年10月24日
    すずき (10/25 02:35)
    「[ONKYOからM-AUDIOのUSB DACへ] 目次: PCかれこれ10年以上(2013年3月16日の日記参照)活躍してく...」
  • link 24年7月25日
    すずき (10/25 02:24)
    「[OpenSBIを調べる - デバイスツリーの扱い(別方法)] 目次: LinuxOpenSBIのブート部分を調べます。Ope...」
  • link 24年8月7日
    すずき (10/25 02:23)
    「[Debian独自の挙動をするQEMUとbinfmt_misc] 目次: Linux前回はbinfmt_miscの使い方や動作...」
  • link 24年9月9日
    すずき (10/25 02:22)
    「[GDBの便利コマンド] 目次: LinuxGDBは便利ですが、少し使わないでいるとあっという間にコマンドを忘れます。便利&使...」
  • link 24年10月20日
    すずき (10/25 02:22)
    「[ゲームを買ったら遊びましょう2] 目次: ゲーム前回の振り返り(2022年5月13日の日記参照)から2年半経ちました。所持し...」
  • link 24年8月2日
    すずき (10/25 02:21)
    「[Debian on RISC-V] 目次: LinuxOpenSBI + Linuxの環境まで動いたので、次はLinuxのデ...」
  • link 24年8月6日
    すずき (10/25 02:21)
    「[他アーキテクチャ向けバイナリを実行する仕組みbinfmt_misc] 目次: LinuxRISC-V 64bit用の実行ファ...」
  • link 24年8月27日
    すずき (10/25 02:20)
    「[Milk-V Jupiterが届いた] 目次: RISC-VMilk-V Jupiterが届きました。お値段が非常に安かった...」
  • link 24年9月13日
    すずき (10/25 02:20)
    「[OpenSBIを調べる - OpenSBIとRISC-V ISA extensions] 目次: Linux今回はOpenS...」
  • link 24年10月11日
    すずき (10/25 02:19)
    「[企業のドメイン] 今の企業は公式サイトを持っていなほうが珍しいと思いますが、ドメイン名の使い方は各社でバラバラで面白いです。...」
  • link 24年10月21日
    すずき (10/25 02:18)
    「[OpenPilotを調べる - プロセス間通信msgqの仕組み] 目次: OpenPilot最近はOSSの運転支援ソフトウェ...」
  • link 24年10月6日
    すずき (10/25 02:11)
    「[OpenPilotを調べる - ビルドと実行] 目次: OpenPilot最近はOSSの運転支援ソフトウェアOpenPilo...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
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 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

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

合計:  counter total
本日:  counter today

link About www2.katsuster.net
RDFファイル RSS 1.0

最終更新: 11/04 15:17