📄 xtensa.md
字号:
(match_operand:SI 2 "arith_operand" "J,r")))] ""{ if (which_alternative == 0) { if ((INTVAL (operands[2]) & 0x1f) < 16) return "srli\t%0, %1, %R2"; else return "extui\t%0, %1, %R2, %L2"; } return "ssr\t%2\;srl\t%0, %1";} [(set_attr "type" "arith,arith") (set_attr "mode" "SI") (set_attr "length" "3,6")])(define_insn "rotlsi3" [(set (match_operand:SI 0 "register_operand" "=a,a") (rotate:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "arith_operand" "J,r")))] "" "@ ssai\t%L2\;src\t%0, %1, %1 ssl\t%2\;src\t%0, %1, %1" [(set_attr "type" "multi,multi") (set_attr "mode" "SI") (set_attr "length" "6,6")])(define_insn "rotrsi3" [(set (match_operand:SI 0 "register_operand" "=a,a") (rotatert:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "arith_operand" "J,r")))] "" "@ ssai\t%R2\;src\t%0, %1, %1 ssr\t%2\;src\t%0, %1, %1" [(set_attr "type" "multi,multi") (set_attr "mode" "SI") (set_attr "length" "6,6")]);; Comparisons.;; Handle comparisons by stashing away the operands and then using that;; information in the subsequent conditional branch.(define_expand "cmpsi" [(set (cc0) (compare:CC (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "nonmemory_operand" "")))] ""{ branch_cmp[0] = operands[0]; branch_cmp[1] = operands[1]; branch_type = CMP_SI; DONE;})(define_expand "tstsi" [(set (cc0) (match_operand:SI 0 "register_operand" ""))] ""{ branch_cmp[0] = operands[0]; branch_cmp[1] = const0_rtx; branch_type = CMP_SI; DONE;})(define_expand "cmpsf" [(set (cc0) (compare:CC (match_operand:SF 0 "register_operand" "") (match_operand:SF 1 "register_operand" "")))] "TARGET_HARD_FLOAT"{ branch_cmp[0] = operands[0]; branch_cmp[1] = operands[1]; branch_type = CMP_SF; DONE;});; Conditional branches.(define_expand "beq" [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, EQ); DONE;})(define_expand "bne" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, NE); DONE;})(define_expand "bgt" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, GT); DONE;})(define_expand "bge" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, GE); DONE;})(define_expand "blt" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, LT); DONE;})(define_expand "ble" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, LE); DONE;})(define_expand "bgtu" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, GTU); DONE;})(define_expand "bgeu" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, GEU); DONE;})(define_expand "bltu" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, LTU); DONE;})(define_expand "bleu" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] ""{ xtensa_expand_conditional_branch (operands, LEU); DONE;});; Branch patterns for standard integer comparisons(define_insn "*btrue" [(set (pc) (if_then_else (match_operator 3 "branch_operator" [(match_operand:SI 0 "register_operand" "r,r") (match_operand:SI 1 "branch_operand" "K,r")]) (label_ref (match_operand 2 "" "")) (pc)))] ""{ if (which_alternative == 1) { switch (GET_CODE (operands[3])) { case EQ: return "beq\t%0, %1, %2"; case NE: return "bne\t%0, %1, %2"; case LT: return "blt\t%0, %1, %2"; case GE: return "bge\t%0, %1, %2"; default: break; } } else if (INTVAL (operands[1]) == 0) { switch (GET_CODE (operands[3])) { case EQ: return (TARGET_DENSITY ? "beqz.n\t%0, %2" : "beqz\t%0, %2"); case NE: return (TARGET_DENSITY ? "bnez.n\t%0, %2" : "bnez\t%0, %2"); case LT: return "bltz\t%0, %2"; case GE: return "bgez\t%0, %2"; default: break; } } else { switch (GET_CODE (operands[3])) { case EQ: return "beqi\t%0, %d1, %2"; case NE: return "bnei\t%0, %d1, %2"; case LT: return "blti\t%0, %d1, %2"; case GE: return "bgei\t%0, %d1, %2"; default: break; } } abort (); return "";} [(set_attr "type" "jump,jump") (set_attr "mode" "none") (set_attr "length" "3,3")])(define_insn "*bfalse" [(set (pc) (if_then_else (match_operator 3 "branch_operator" [(match_operand:SI 0 "register_operand" "r,r") (match_operand:SI 1 "branch_operand" "K,r")]) (pc) (label_ref (match_operand 2 "" ""))))] ""{ if (which_alternative == 1) { switch (GET_CODE (operands[3])) { case EQ: return "bne\t%0, %1, %2"; case NE: return "beq\t%0, %1, %2"; case LT: return "bge\t%0, %1, %2"; case GE: return "blt\t%0, %1, %2"; default: break; } } else if (INTVAL (operands[1]) == 0) { switch (GET_CODE (operands[3])) { case EQ: return (TARGET_DENSITY ? "bnez.n\t%0, %2" : "bnez\t%0, %2"); case NE: return (TARGET_DENSITY ? "beqz.n\t%0, %2" : "beqz\t%0, %2"); case LT: return "bgez\t%0, %2"; case GE: return "bltz\t%0, %2"; default: break; } } else { switch (GET_CODE (operands[3])) { case EQ: return "bnei\t%0, %d1, %2"; case NE: return "beqi\t%0, %d1, %2"; case LT: return "bgei\t%0, %d1, %2"; case GE: return "blti\t%0, %d1, %2"; default: break; } } abort (); return "";} [(set_attr "type" "jump,jump") (set_attr "mode" "none") (set_attr "length" "3,3")])(define_insn "*ubtrue" [(set (pc) (if_then_else (match_operator 3 "ubranch_operator" [(match_operand:SI 0 "register_operand" "r,r") (match_operand:SI 1 "ubranch_operand" "L,r")]) (label_ref (match_operand 2 "" "")) (pc)))] ""{ if (which_alternative == 1) { switch (GET_CODE (operands[3])) { case LTU: return "bltu\t%0, %1, %2"; case GEU: return "bgeu\t%0, %1, %2"; default: break; } } else { switch (GET_CODE (operands[3])) { case LTU: return "bltui\t%0, %d1, %2"; case GEU: return "bgeui\t%0, %d1, %2"; default: break; } } abort (); return "";} [(set_attr "type" "jump,jump") (set_attr "mode" "none") (set_attr "length" "3,3")])(define_insn "*ubfalse" [(set (pc) (if_then_else (match_operator 3 "ubranch_operator" [(match_operand:SI 0 "register_operand" "r,r") (match_operand:SI 1 "ubranch_operand" "L,r")]) (pc) (label_ref (match_operand 2 "" ""))))] ""{ if (which_alternative == 1) { switch (GET_CODE (operands[3])) { case LTU: return "bgeu\t%0, %1, %2"; case GEU: return "bltu\t%0, %1, %2"; default: break; } } else { switch (GET_CODE (operands[3])) { case LTU: return "bgeui\t%0, %d1, %2"; case GEU: return "bltui\t%0, %d1, %2"; default: break; } } abort (); return "";} [(set_attr "type" "jump,jump") (set_attr "mode" "none") (set_attr "length" "3,3")]);; Branch patterns for bit testing(define_insn "*bittrue" [(set (pc) (if_then_else (match_operator 3 "boolean_operator" [(zero_extract:SI (match_operand:SI 0 "register_operand" "r,r") (const_int 1) (match_operand:SI 1 "arith_operand" "J,r")) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] ""{ if (which_alternative == 0) { unsigned bitnum = INTVAL(operands[1]) & 0x1f; operands[1] = GEN_INT(bitnum); switch (GET_CODE (operands[3])) { case EQ: return "bbci\t%0, %d1, %2"; case NE: return "bbsi\t%0, %d1, %2"; default: break; } } else { switch (GET_CODE (operands[3])) { case EQ: return "bbc\t%0, %1, %2"; case NE: return "bbs\t%0, %1, %2"; default: break; } } abort (); return "";} [(set_attr "type" "jump") (set_attr "mode" "none") (set_attr "length" "3")])(define_insn "*bitfalse" [(set (pc) (if_then_else (match_operator 3 "boolean_operator" [(zero_extract:SI (match_operand:SI 0 "register_operand" "r,r") (const_int 1) (match_operand:SI 1 "arith_operand" "J,r")) (const_int 0)]) (pc) (label_ref (match_operand 2 "" ""))))] ""{ if (which_alternative == 0) { unsigned bitnum = INTVAL (operands[1]) & 0x1f; operands[1] = GEN_INT (bitnum); switch (GET_CODE (operands[3])) { case EQ: return "bbsi\t%0, %d1, %2"; case NE: return "bbci\t%0, %d1, %2"; default: break; } } else { switch (GET_CODE (operands[3])) { case EQ: return "bbs\t%0, %1, %2"; case NE: return "bbc\t%0, %1, %2"; default: break; } } abort (); return "";} [(set_attr "type" "jump") (set_attr "mode" "none") (set_attr "length" "3")])(define_insn "*masktrue" [(set (pc) (if_then_else (match_operator 3 "boolean_operator" [(and:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "register_operand" "r")) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] ""{ switch (GET_CODE (operands[3])) { case EQ: return "bnone\t%0, %1, %2"; case NE: return "bany\t%0, %1, %2"; default: break; } abort (); return "";} [(set_attr "type" "jump") (set_attr "mode" "none") (set_attr "length" "3")])(define_insn "*maskfalse" [(set (pc) (if_then_else (match_operator 3 "boolean_operator" [(and:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "register_operand" "r")) (const_int 0)]) (pc) (label_ref (match_operand 2 "" ""))))] ""{ switch (GET_CODE (operands[3])) { case EQ: return "bany\t%0, %1, %2"; case NE: return "bnone\t%0, %1, %2"; default: break; } abort (); return "";} [(set_attr "type" "jump") (set_attr "mode" "none") (set_attr "length" "3")]);; Define the loop insns used by bct optimization to represent the;; start and end of a zero-overhead loop (in loop.c). This start;; template generates the loop insn; the end template doesn't generate;; any instructions since loop end is handled in hardware.(define_insn "zero_cost_loop_start" [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a") (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) (set (reg:SI 19) (plus:SI (match_dup 0) (const_int -1)))] "" "loopnez\t%0, %l1" [(set_attr "type" "jump") (set_attr "mode" "none") (set_attr "length" "3")])(define_insn "zero_cost_loop_end" [(set (pc) (if_then_else (ne (reg:SI 19) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc))) (set (reg:SI 19) (plus:SI (reg:SI 19) (const_int -1)))] ""{ xtensa_emit_loop_end (insn, operands); return "";} [(set_attr "type" "jump") (set_attr "mode" "none") (set_attr "length" "0")]);; Setting a register from a comparison.(define_expand "seq" [(set (match_operand:SI 0 "register_operand" "") (match_dup 1))] ""{ operands[1] = gen_rtx_EQ (SImode, branch_cmp[0], branch_cmp[1]); if (!xtensa_expand_scc (operands)) FAIL; DONE;})(define_expand "sne" [(set (match_operand:SI 0 "register_operand" "") (match_dup 1))] ""{ operands[1] = gen_rtx_NE (SImode, branch_cmp[0], branch_cmp[1]); if (!xtensa_expand_scc (operands)) FAIL; DONE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -