コグノスケ


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

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

2020年6月1日

GCCを調べる - その13-4 - ベクトル命令のオフセット付きアドレスだけを禁止

目次: GCC

前回(2020年5月31日の日記参照)見たとおり、メモリというかオフセット付きアドレスを全部禁止するのは明らかにやりすぎで、他の命令に悪影響を及ぼしていました。スカラ命令はオフセット付きアドレスを許可し、ベクトル命令だけオフセット付きアドレスを禁止したいところです。

オペランドを許可する、しないを判断するコードを改造すればできるでしょうか?コードを見てみます。

constraint "m" の定義(再掲)

// gcc/common.md

(define_memory_constraint "TARGET_MEM_CONSTRAINT"
  "Matches any valid memory."
  (and (match_code "mem")
       (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0),
						 MEM_ADDR_SPACE (op))")))
constraint "m" の条件判定コード

// gcc/recog.c

//★★各引数の値
//mode = E_V64SImode
//addr = (plus:SI (reg/f:SI 108)
//           (const_int 256 [0x100]))
//as = 0

int
memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
			     rtx addr, addr_space_t as)
{
#ifdef GO_IF_LEGITIMATE_ADDRESS
...
#else
  return targetm.addr_space.legitimate_address_p (mode, addr, 0, as);
#endif
}


// gcc/targhook.c

//★★各引数の値
//mode = E_V64SImode
//mem  = (plus:SI (reg/f:SI 108)
//           (const_int 256 [0x100]))
//strict = 0
//as = 0

bool
default_addr_space_legitimate_address_p (machine_mode mode, rtx mem,
					 bool strict,
					 addr_space_t as ATTRIBUTE_UNUSED)
{
  return targetm.legitimate_address_p (mode, mem, strict);
}


// gcc/config/riscv/riscv.c

#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P	riscv_legitimate_address_p


// gcc/config/riscv/riscv.c

//★★各引数の値
//mode = E_V64SImode
//mem  = (plus:SI (reg/f:SI 108)
//           (const_int 256 [0x100]))
//strict_p = 0

static bool
riscv_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
{
  struct riscv_address_info addr;

  return riscv_classify_address (&addr, x, mode, strict_p);
}


// gcc/config/riscv/riscv.c

//★★各引数の値
//x    = (plus:SI (reg/f:SI 108)
//           (const_int 256 [0x100]))
//mode = E_V64SImode
//strict_p = 0

static bool
riscv_classify_address (struct riscv_address_info *info, rtx x,
			machine_mode mode, bool strict_p)
{
  switch (GET_CODE (x))
    {

...

    case PLUS:
      info->type = ADDRESS_REG;
      info->reg = XEXP (x, 0);
      info->offset = XEXP (x, 1);

      //★★各変数の値
      //info->reg    = x->u.fld[0].rt_rtx = (reg/f:SI 108)
      //info->offset = x->u.fld[1].rt_rtx = (const_int 256 [0x100])

      return (riscv_valid_base_register_p (info->reg, mode, strict_p)
	      && riscv_valid_offset_p (info->offset, mode));

...

    }
}

関数memory_address_addr_space_p() のaddrを見ると、メモリアドレスを表すRTLしか渡されません。この情報だけではスカラ命令のオペランドか、ベクトル命令のオペランドか、判断するのは困難です。

ベクトル命令はmachine modeがV64SIであることを利用するとうまくいくかもしれません。関数riscv_classify_address() を変更し、mode == V64SIだったらPLUSなどREG以外を使ったRTLに対しfalseを返せば良さそうです。

mode == V64SIのときfalseを返す

// gcc/config/riscv/riscv.c

//★★各引数の値
//x    = (plus:SI (reg/f:SI 108)
//           (const_int 256 [0x100]))
//mode = E_V64SImode
//strict_p = 0

static bool
riscv_classify_address (struct riscv_address_info *info, rtx x,
			machine_mode mode, bool strict_p)
{
  switch (GET_CODE (x))
    {

...

    case PLUS:
      if (mode == E_V64SImode)  //★★machine modeがV64SIならオフセット付きアドレスは許可しない
        return false;

      info->type = ADDRESS_REG;
      info->reg = XEXP (x, 0);
      info->offset = XEXP (x, 1);

      return (riscv_valid_base_register_p (info->reg, mode, strict_p)
	      && riscv_valid_offset_p (info->offset, mode));

...

    }
}
mode == V64SIのときfalseを返す変更を加えたとき、アセンブラの差分

$ diff -u b_before.s b_mod.s

--- b_before.s  2020-05-28 21:17:24.607184754 +0900
+++ b_mod.s     2020-05-30 22:37:02.370663628 +0900
@@ -35,7 +35,8 @@
 
 # 0 "" 2
  #NO_APP
-       vsw.v   v0,256(a5)
+       addi    a4,a5,256
+       vsw.v   v0,0(a4)
        .loc 1 9 2
        addi    a4,s0,-336
  #APP

結果だけ見ると良さそうですが、将来的にオフセットアドレスが使えるベクトル命令が出てきたときに、判別不能になり困ります。その場しのぎ感が否めません。もっと良い方法はあるでしょうか?

もっと簡単な方法

実はもっと簡単な方法で対処できます。変更すべき箇所については、この取り組みの発端「constraint "m" をチェックしていそうな箇所から調査を開始した」ことを思い出していただければ想像が付くと思います。constraint "m" を使っている箇所はdefine_insnです。

追加したdefine_insn(再掲)

;; gcc/config/riscv/riscv.md

(define_attr "vecmode" "unknown,V64SI"
  (const_string "unknown"))

(define_insn "*movv64si_internal"
  [(set (match_operand:V64SI 0 "nonimmediate_operand" "=v,v,m")
	(match_operand:V64SI 1 "move_operand"         " v,m,v"))]    //★★constraint "m" を使っている場所
  "(register_operand (operands[0], V64SImode)
    || reg_or_0_operand (operands[1], V64SImode))" return riscv_output_move (operands[0], operands[1]); 
  [(set_attr "move_type" "move,load,store")
   (set_attr "vecmode" "V64SI")])

この "m" を変更して、オフセット付きアドレスオペランドだけを拒否したいですが、そんな都合の良いconstraintはあるでしょうか?実はRISC-Vには既にあります。constraint "A" です。

constraint "A" の定義

;; gcc/config/riscv/constraints.md

(define_memory_constraint "A"
  "An address that is held in a general-purpose register."
  (and (match_code "mem")
       (match_test "GET_CODE(XEXP(op,0)) == REG")))

コードを見ると、constraint "A" が見ている条件は、種別がメモリであり、オペランドがREG(オフセットありだとPLUSなどになる)であることです。先程の改造と同じ発想ですね。mをAに変更します。

変更後のdefine_insn

;; gcc/config/riscv/riscv.md

(define_insn "*movv64si_internal"
  [(set (match_operand:V64SI 0 "nonimmediate_operand" "=v,v,A")
	(match_operand:V64SI 1 "move_operand"         " v,A,v"))]    //★★constraint "A" に変更
...
constraint "A" を使ったとき、アセンブラの差分

$ diff -u b_before.s b_final.s

--- b_before.s  2020-05-28 21:17:24.607184754 +0900
+++ b_final.s   2020-05-28 21:20:20.219175573 +0900
@@ -35,7 +35,8 @@
 
 # 0 "" 2
  #NO_APP
-       vsw.v   v0,256(a5)
+       addi    a4,a5,256
+       vsw.v   v0,0(a4)
        .loc 1 9 2
        addi    a4,s0,-336
  #APP

出力結果のアセンブリも良い感じですし、ビルドの際にアセンブラも文句を言わなくなりました。

長きに渡りましたが、やっとベクトル型を使ったGCC拡張インラインアセンブラが書けるようになりました。良かった良かった。

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

コメント一覧

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



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

管理用メニュー

link 記事を新規作成

<2020>
<<<06>>>
-123456
78910111213
14151617181920
21222324252627
282930----

最近のコメント5件

  • link 21年3月13日
    すずきさん (03/05 15:13)
    「あー、このプログラムがまずいんですね。ご...」
  • link 21年3月13日
    emkさん (03/05 12:44)
    「キャストでvolatileを外してアクセ...」
  • link 24年1月24日
    すずきさん (02/19 18:37)
    「簡単にできる方法はPowerShellの...」
  • link 24年1月24日
    KKKさん (02/19 02:30)
    「追伸です。\nネットで調べたらマイクロソ...」
  • link 24年1月24日
    KKKさん (02/19 02:25)
    「私もエラーで困ってます\n手動での回復パ...」

最近の記事20件

  • link 24年3月25日
    すずき (03/26 03:20)
    「[Might and Magic Book One TASのその後] 目次: Might and Magicファミコン版以前(...」
  • link 21年10月4日
    すずき (03/26 03:14)
    「[Might and Magicファミコン版 - まとめリンク] 目次: Might and Magicファミコン版TASに挑...」
  • link 24年3月19日
    すずき (03/20 02:52)
    「[モジュラージャックの規格] 古くは電話線で、今だとEthernetで良く見かけるモジュラージャックというコネクタとレセプタク...」
  • link 23年4月10日
    すずき (03/19 11:48)
    「[Linux - まとめリンク] 目次: Linuxカーネル、ドライバ関連。Linuxのstruct pageって何?Linu...」
  • link 24年3月18日
    すずき (03/19 11:47)
    「[画面のブランクを無効にする] 目次: LinuxROCK 3 model CのDebian bullseyeイメージは10分...」
  • link 24年3月3日
    すずき (03/19 11:07)
    「[解像度の設定を保存する] 目次: LinuxRaspberry Pi 3 Model B (以降RasPi 3B)のHDMI...」
  • link 24年3月14日
    すずき (03/16 23:03)
    「[JavaとM5Stamp C3とBluetooth LE - Bluetoothデバイスとの通信] 目次: ArduinoM...」
  • link 24年3月8日
    すずき (03/16 23:03)
    「[JavaとM5Stamp C3とBluetooth LE - BluetoothデバイスとServiceの列挙] 目次: A...」
  • link 23年6月2日
    すずき (03/16 21:11)
    「[Arduino - まとめリンク] 目次: Arduino一覧が欲しくなったので作りました。 M5Stackとesp32とA...」
  • link 23年5月15日
    すずき (03/16 00:57)
    「[車 - まとめリンク] 目次: 車三菱FTOの話。群馬県へのドライブ将来車を買い替えるとしたら?FTOのオイル交換とオイル漏...」
  • link 24年3月9日
    すずき (03/16 00:56)
    「[車のバッテリー完全に死亡で交換かと思いきや] 目次: 車またまた車のバッテリーが干上がって死にました。写真は撮っていませんが...」
  • link 24年3月10日
    すずき (03/15 03:34)
    「[誕生日] 早いもので41歳になりました。昨年の日記(2023年3月10日の日記参照)を見ると、コロナの流行を心配していました...」
  • link 24年3月6日
    すずき (03/12 01:18)
    「[Raspberry Pi 3 model Bの代わりにROCK 3 model C] 目次: Arduino最近、M5Sta...」
  • link 24年3月4日
    すずき (03/06 00:09)
    「[volatileをnon-volatileで参照してはいけない] 目次: GCC過去の日記(2021年3月13日の日記参照)...」
  • link 20年6月2日
    すずき (03/06 00:06)
    「[GCC - まとめリンク] 目次: GCCGCCについて。GCCを調べる - その1 - ビルドGCCを調べる - その2 ...」
  • link 15年5月9日
    すずき (03/05 03:00)
    「[自作ARMエミュレータ - 今さら気づいたブートローダのバグ] 目次: Linuxずっと気づいていなかった自作ARMエミュレ...」
  • link 23年6月1日
    すずき (03/05 02:59)
    「[自宅サーバー - まとめリンク] 目次: 自宅サーバーこの日記システム、Wikiの話。カウンターをPerlからPHPに移植日...」
  • link 15年5月3日
    すずき (03/05 02:59)
    「[GRUB2が起動しなくなってしまった] 目次: 自宅サーバーサーバにインストールしていたDebian 32bit版 のJes...」
  • link 15年5月2日
    すずき (03/05 02:58)
    「[systemdを使うのをあきらめた] 目次: 自宅サーバー独自ビルドのカーネルだと/sys/fs/cgroupが無いと言われ...」
  • link 15年4月30日
    すずき (03/05 02:56)
    「[Debian 8.0 Jessie] 目次: 自宅サーバーDebianのアップデートが来ていたので、試しに職場のPCをアップ...」
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 www.katsuster.net
RDFファイル RSS 1.0

最終更新: 03/26 03:20