目次: GCC
前回(2020年7月19日の日記参照)は四則演算と論理演算(and, or, xor)を定義しました。今回はNot演算を定義します。他の論理演算と異なり、Not演算は2オペランドしか取りませんから、define_insnを別に書く必要があります。
;; gcc/config/riscv/riscv.md
(define_insn "one_cmpl<mode>2"
[(set (match_operand:ANYV 0 "register_operand" "=v")
(not:ANYV (match_operand:ANYV 1 "register_operand" "%v")))]
"TARGET_VECTOR"
"vnot.vt%0,%1"
[(set_attr "type" "logical")
(set_attr "vecmode" "<MODE>")])
前回同様に、ベクトル拡張記法(Vector Extensions (Using the GNU Compiler Collection (GCC)))を使ってビット毎Notを使うプログラムを書きます。
typedef int __v64si __attribute__((__vector_size__(256)));
void test()
{
__v64si v10, v11;
static int b[1024 * 1024] = {0};
__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v10) : "A"(b[10]));
__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v11) : "A"(b[20]));
v10 = ~v11;
__asm__ volatile ("vsw.v %1, %0\n" : "=A"(b[40]) : "v"(v10));
}
コンパイルするとエラーが発生します。何かお気に召さないようです。
$ riscv32-unknown-elf-gcc b.c -nostdlib -Og -march=rv32gcv -mabi=ilp32f during RTL pass: reload dump file: b.c.282r.reload b.c: In function 'test': b.c:14:1: internal compiler error: in setup_operand_alternative, at lra.c:814 14 | } | ^ 0xea5c36 setup_operand_alternative gcc/gcc/lra.c:814 0xea70c2 lra_set_insn_recog_data(rtx_insn*) gcc/gcc/lra.c:1073 0xea30f9 lra_get_insn_recog_data gcc/gcc/lra-int.h:488 0xeab0b9 remove_scratches_1 gcc/gcc/lra.c:2058 0xeab4c4 remove_scratches gcc/gcc/lra.c:2094 0xeac629 lra(_IO_FILE*) gcc/gcc/lra.c:2396 0xe1a41f do_reload gcc/gcc/ira.c:5523 0xe1ae5c execute gcc/gcc/ira.c:5709
コードを見ると最後のオペランドに % を付けるべきではないそうです。確かにdefine_insnを見ると % が要らないのに付いています。
// gcc/lra.c
/* Setup info about operands in alternatives of LRA DATA of insn. */
static void
setup_operand_alternative (lra_insn_recog_data_t data,
const operand_alternative *op_alt)
{
int i, j, nop, nalt;
int icode = data->icode;
struct lra_static_insn_data *static_data = data->insn_static_data;
static_data->commutative = -1;
nop = static_data->n_operands;
nalt = static_data->n_alternatives;
static_data->operand_alternative = op_alt;
for (i = 0; i < nop; i++)
{
static_data->operand[i].early_clobber_alts = 0;
static_data->operand[i].is_address = false;
if (static_data->operand[i].constraint[0] == '%') //★★% が付いていればcommutative
{
/* We currently only support one commutative pair of operands. */
if (static_data->commutative < 0)
static_data->commutative = i;
else
lra_assert (icode < 0); /* Asm */
/* The last operand should not be marked commutative. */
lra_assert (i != nop - 1); //★★このアサートに引っかかる
}
}
...
素直に応じるとエラーは消えます。
(define_insn "one_cmpl<mode>2"
[(set (match_operand:ANYV 0 "register_operand" "=v")
(not:ANYV (match_operand:ANYV 1 "register_operand" " v")))] ★★% を消す
"TARGET_VECTOR"
"vnot.vt%0,%1"
[(set_attr "type" "logical")
(set_attr "vecmode" "<MODE>")])
四則演算、論理演算(3オペランド系)と、Not演算(2オペランド系)が揃いました。残りの頻出する演算はビットシフト系かな?
最後のオペランドをcommutativeにしてはいけない理由は、GCCのConstraintsの説明を見るとわかります。
`%' Declares the instruction to be commutative for this operand and the following operand. This means that the compiler may interchange the two operands if that is the cheapest way to make all operands fit the constraints. GCC can only handle one commutative pair in an asm; if you use more, the compiler may fail. Note that you need not use the modifier if the two alternatives are strictly identical; this would only waste time in the reload pass. The modifier is not operational after register allocation, so the result of define_peephole2 and define_splits performed after reload cannot rely on `%' to make the intended insn match.
難しいことを言っていますが、commutativeは % を付けたオペランドと「次」のオペランドが可換だと宣言することだそうです。最後のオペランドには「次」のオペランドがありませんから、% を付けてはいけません。なるほど。
RISC-Vの場合は論理演算のdefine_insnの2番目のオペランドに % が使われています。
;; gcc/config/riscv/riscv.md
;; This code iterator allows the three bitwise instructions to be generated
;; from the same template.
(define_code_iterator any_bitwise [and ior xor])
...
(define_insn "<optab><mode>3"
[(set (match_operand:X 0 "register_operand" "=r,r")
(any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
(match_operand:X 2 "arith_operand" " r,I")))]
""
"<insn>%i2t%0,%1,%2"
[(set_attr "type" "logical")
(set_attr "mode" "<MODE>")])
例えばand r1, r2, r3とand r1, r3, r2は結果が同じですから、2番目と3番目のオペランドは入れ替え可能です。3つの論理演算(any_bitwiseはand, or, xorのこと)はいずれも同様に入れ替え可能ですので、このような定義になっています。
目次: ROCK64/ROCKPro64
最近はたくさんのARMのシングルボードコンピュータ(SBC)が市販されています。2019年以降のボードも追加してみました。値段は変動するので参考です。
古い世代のSoCを採用したボード達です。
以前(2019年5月15日の日記参照)載せた情報も含んでいます。
目次: 車
コロナ騒ぎが始まって、遠出することもなくなり、かれこれ4か月以上?車に乗らず放置していました。
骨折した奥さんを整形外科におくるため、JAFさんに車のバッテリー上がりを直してもらったんですけど、バッテリー電圧がなんと1Vしかありません。えー??
車のバッテリー(鉛蓄電池)の端子電圧は12V程度が正常ですから、10Vの見間違い?と思いましたけど、何回見ても1.0Vでした。乾電池だってもうちょっと電圧あるでしょう。
今まで何度となくバッテリー上がりさせ、バッテリー破壊もこれで4度目(2007年、2013年、2016年、2020年)ですけど、1Vまで下がったのは初めてです。
割とお高いGS YUASA 80D23L大容量バッテリーを使っていたのですが、いかなるバッテリーであろうと、このレベルの過放電には無力ですね。エンジン掛かった後も全く充電される気配がありませんでした。
近所のイエローハットまでバッテリー交換しに行く道中が一番嫌でした。
こんな状態で、産業道路〜環七〜第二京浜と走るのはかなり怖いです。無事に辿り着けて良かったけども。
また懲りずにPanasonic 85D23Lの大容量バッテリーに交換しておきました。3万円くらいしました。たっけぇ……。今年は車検もあるし、全然乗ってない割に金ばっかり掛かってます。不思議ですね。
メモ: 技術系の話はFacebookから転記しておくことにした。
< | 2020 | > | ||||
<< | < | 07 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | - |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.18.
using GD 2.3.3(png support.)