*参照元 [#nde0522a] *参照元 [#p476292e] #backlinks *説明 [#rf7a49b4] -パス: [[gcc-8.3/gcc/(build_dir)/insn-recog.c]] *説明 [#kb3dc79d] -パス: 複数あり --riscv 版: [[gcc-8.3/gcc/recog()(riscv)]] -FIXME: これは何? --説明 --自動生成されていて、人が読むようなコードには見えない……。 -RTX のコード(SET とか PLUS とか)と、オペランドの型から合致する命令を導き出すようになっているように見える。 -md ファイルの下記★部分は、recog() に取り込まれ、オペランドの型の判定に使われる。 (define_insn "*movdi_64bit" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*f,*m") (match_operand:DI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f,*f"))] ★"TARGET_64BIT ★ && (register_operand (operands[0], DImode) ★ || reg_or_0_operand (operands[1], DImode))" { return riscv_output_move (operands[0], operands[1]); } [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore") (set_attr "mode" "DI")]) -取り込まれた部分には #line 1260 "gcc/gcc/config/riscv/riscv.md" のように line ディレクティブで注釈が入るので、 少なくともどのファイルから取り込まれた条件か悩むことはない。 -recog() の他にも recog_3(), recog_17() のように似た名前の関数がたくさん生成される。 関数の先頭では必ず operands という変数が下記のように rtx * const operands ATTRIBUTE_UNUSED = &recog_data.operand[0]; 定義されるので、md ファイルで条件を記述する際は operands[0] のように書くようだ。 --[[gcc-8.3/gcc/rtx]] --[[gcc-8.3/gcc/recog_data(global)]] **参考 [#yb55ec8f] **引数 [#z069c4ad] -rtx x1 -- --[[gcc-8.3/gcc/rtx]] -rtx_insn *insn -- --[[gcc-8.3/gcc/rtx_insn]] -int *pnum_clobbers -- *実装 [#q4729137] -各アーキテクチャのページを参照してください。 **返り値 [#cf61236c] -int -- *コメント [#n83929fc] **参考 [#q3f1e151] *実装 [#pb1b88e6] int recog (rtx x1 ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED, int *pnum_clobbers ATTRIBUTE_UNUSED) { rtx * const operands ATTRIBUTE_UNUSED = &recog_data.operand[0]; rtx x2, x3, x4, x5, x6, x7, x8, x9; rtx x10, x11, x12, x13, x14, x15, x16, x17; rtx x18, x19, x20, x21, x22, x23, x24, x25; rtx x26, x27; int res ATTRIBUTE_UNUSED; recog_data.insn = NULL; switch (GET_CODE (x1)) { case SET: return recog_17 (x1, insn, pnum_clobbers); case UNSPEC_VOLATILE: if (XVECLEN (x1, 0) != 1) return -1; switch (XINT (x1, 1)) { case 5: x2 = XVECEXP (x1, 0, 0); if (x2 != const_int_rtx[MAX_SAVED_CONST_INT + 0]) return -1; return 144; /* fence */ case 6: x2 = XVECEXP (x1, 0, 0); if (x2 != const_int_rtx[MAX_SAVED_CONST_INT + 0]) return -1; return 145; /* fence_i */ case 4: x2 = XVECEXP (x1, 0, 0); if (x2 != const_int_rtx[MAX_SAVED_CONST_INT + 0]) return -1; return 231; /* blockage */ case 0: if (pnum_clobbers == NULL) return -1; x2 = XVECEXP (x1, 0, 0); operands[0] = x2; if (!const_int_operand (operands[0], E_VOIDmode)) return -1; *pnum_clobbers = 2; return 242; /* gpr_save */ case 1: x2 = XVECEXP (x1, 0, 0); operands[0] = x2; if (!const_int_operand (operands[0], E_VOIDmode)) return -1; return 243; /* gpr_restore */ case 3: x2 = XVECEXP (x1, 0, 0); operands[0] = x2; if (!csr_operand (operands[0], E_SImode) || ! #line 2274 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (TARGET_HARD_FLOAT)) return -1; return 246; /* riscv_fsflags */ default: return -1; } case PARALLEL: switch (XVECLEN (x1, 0)) { case 2: x2 = XVECEXP (x1, 0, 0); switch (GET_CODE (x2)) { case SET: x3 = XEXP (x2, 1); switch (GET_CODE (x3)) { case IF_THEN_ELSE: if (pattern24 (x2) != 0) return -1; x4 = XVECEXP (x1, 0, 1); if (GET_CODE (x4) != CLOBBER) return -1; x5 = XEXP (x3, 0); x6 = XEXP (x5, 0); x7 = XEXP (x6, 0); operands[2] = x7; x8 = XEXP (x3, 1); x9 = XEXP (x8, 0); operands[1] = x9; x10 = XEXP (x4, 0); operands[4] = x10; x11 = XEXP (x6, 1); if (XWINT (x11, 0) == 1L) { switch (pattern61 (x6)) { case 0: if ( #line 241 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (!TARGET_64BIT)) return 180; /* *branch_on_bitsi */ break; case 1: if ( #line 241 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (TARGET_64BIT)) return 181; /* *branch_on_bitdi */ break; default: break; } } x12 = XEXP (x6, 2); if (x12 != const_int_rtx[MAX_SAVED_CONST_INT + 0]) return -1; switch (pattern62 (x6)) { case 0: if (! #line 241 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (!TARGET_64BIT)) return -1; return 182; /* *branch_on_bit_rangesi */ case 1: if (! #line 241 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (TARGET_64BIT)) return -1; return 183; /* *branch_on_bit_rangedi */ default: return -1; } case UNSPEC: x13 = XEXP (x2, 0); operands[0] = x13; switch (XVECLEN (x3, 0)) { case 2: x4 = XVECEXP (x1, 0, 1); if (GET_CODE (x4) != CLOBBER) return -1; x14 = XVECEXP (x3, 0, 0); operands[1] = x14; x15 = XVECEXP (x3, 0, 1); operands[2] = x15; x10 = XEXP (x4, 0); operands[3] = x10; switch (XINT (x3, 1)) { case 9: switch (GET_MODE (operands[0])) { case E_SImode: switch (pattern56 (x3, E_SImode)) { case 0: if (!( #line 1880 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (TARGET_HARD_FLOAT) && ((( #line 241 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (!TARGET_64BIT) && #line 272 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (TARGET_HARD_FLOAT)) && #line 272 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (TARGET_HARD_FLOAT)) && #line 241 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (!TARGET_64BIT)))) return -1; return 188; /* flt_quietsfsi4 */ case 1: if (!( #line 1880 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (TARGET_HARD_FLOAT) && ((( #line 241 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (!TARGET_64BIT) && #line 273 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (TARGET_DOUBLE_FLOAT)) && #line 273 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (TARGET_DOUBLE_FLOAT)) && #line 241 "/home/katsuhiro/share/projects/oss/crosstool-builder-new/./gcc/gcc/config/riscv/riscv.md" (!TARGET_64BIT)))) return -1; return 192; /* flt_quietdfsi4 */ default: return -1; } // ずっと続く *コメント [#s349181d]