📄 iq2000.md
字号:
;; Flow here is rather complex:;;;; 1) The cmp{si,di,sf,df} routine is called. It deposits the;; arguments into the branch_cmp array, and the type into;; branch_type. No RTL is generated.;;;; 2) The appropriate branch define_expand is called, which then;; creates the appropriate RTL for the comparison and branch.;; Different CC modes are used, based on what type of branch is;; done, so that we can constrain things appropriately. There;; are assumptions in the rest of GCC that break if we fold the;; operands into the branches for integer operations, and use cc0;; for floating point, so we use the fp status register instead.;; If needed, an appropriate temporary is created to hold the;; of the integer compare.(define_expand "cmpsi" [(set (cc0) (compare:CC (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "arith_operand" "")))] "" "{ if (operands[0]) /* avoid unused code message */ { 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" ""))] "" "{ if (operands[0]) /* avoid unused code message */ { branch_cmp[0] = operands[0]; branch_cmp[1] = const0_rtx; branch_type = CMP_SI; DONE; }}");;;; ....................;;;; CONDITIONAL BRANCHES;;;; ....................;; Conditional branches on comparisons with zero.(define_insn "branch_zero" [(set (pc) (if_then_else (match_operator:SI 0 "cmp_op" [(match_operand:SI 2 "register_operand" "d") (const_int 0)]) (label_ref (match_operand 1 "" "")) (pc)))] "" "*{ return iq2000_output_conditional_branch (insn, operands, /*two_operands_p=*/0, /*float_p=*/0, /*inverted_p=*/0, get_attr_length (insn));}" [(set_attr "type" "branch") (set_attr "mode" "none")])(define_insn "branch_zero_inverted" [(set (pc) (if_then_else (match_operator:SI 0 "cmp_op" [(match_operand:SI 2 "register_operand" "d") (const_int 0)]) (pc) (label_ref (match_operand 1 "" ""))))] "" "*{ return iq2000_output_conditional_branch (insn, operands, /*two_operands_p=*/0, /*float_p=*/0, /*inverted_p=*/1, get_attr_length (insn));}" [(set_attr "type" "branch") (set_attr "mode" "none")]);; Conditional branch on equality comparison.(define_insn "branch_equality" [(set (pc) (if_then_else (match_operator:SI 0 "equality_op" [(match_operand:SI 2 "register_operand" "d") (match_operand:SI 3 "register_operand" "d")]) (label_ref (match_operand 1 "" "")) (pc)))] "" "*{ return iq2000_output_conditional_branch (insn, operands, /*two_operands_p=*/1, /*float_p=*/0, /*inverted_p=*/0, get_attr_length (insn));}" [(set_attr "type" "branch") (set_attr "mode" "none")])(define_insn "branch_equality_inverted" [(set (pc) (if_then_else (match_operator:SI 0 "equality_op" [(match_operand:SI 2 "register_operand" "d") (match_operand:SI 3 "register_operand" "d")]) (pc) (label_ref (match_operand 1 "" ""))))] "" "*{ return iq2000_output_conditional_branch (insn, operands, /*two_operands_p=*/1, /*float_p=*/0, /*inverted_p=*/1, get_attr_length (insn));}" [(set_attr "type" "branch") (set_attr "mode" "none")])(define_expand "beq" [(set (pc) (if_then_else (eq:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, EQ); DONE; }}")(define_expand "bne" [(set (pc) (if_then_else (ne:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, NE); DONE; }}")(define_expand "bgt" [(set (pc) (if_then_else (gt:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, GT); DONE; }}")(define_expand "bge" [(set (pc) (if_then_else (ge:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, GE); DONE; }}")(define_expand "blt" [(set (pc) (if_then_else (lt:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, LT); DONE; }}")(define_expand "ble" [(set (pc) (if_then_else (le:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, LE); DONE; }}")(define_expand "bgtu" [(set (pc) (if_then_else (gtu:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, GTU); DONE; }}")(define_expand "bgeu" [(set (pc) (if_then_else (geu:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, GEU); DONE; }}")(define_expand "bltu" [(set (pc) (if_then_else (ltu:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, LTU); DONE; }}")(define_expand "bleu" [(set (pc) (if_then_else (leu:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (operands[0]) /* avoid unused code warning */ { gen_conditional_branch (operands, LEU); DONE; }}");; Recognize bbi and bbin instructions. These use two unusual template;; patterns, %Ax and %Px. %Ax outputs an 'i' if operand `x' is a LABEL_REF;; otherwise it outputs an 'in'. %Px does nothing if `x' is PC ;; and outputs the operand if `x' is a LABEL_REF.(define_insn "" [(set (pc) (if_then_else (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r") (const_int 1) (match_operand:SI 1 "arith_operand" "I")) (const_int 0)) (match_operand 2 "pc_or_label_operand" "") (match_operand 3 "pc_or_label_operand" "")))] "" "bb%A2\\t%0(31-%1),%P2%P3" [(set_attr "length" "4") (set_attr "type" "branch")])(define_insn "" [(set (pc) (if_then_else (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r") (const_int 1) (match_operand:SI 1 "arith_operand" "I")) (const_int 0)) (match_operand 2 "pc_or_label_operand" "") (match_operand 3 "pc_or_label_operand" "")))] "" "bb%A3\\t%0(31-%1),%P2%P3" [(set_attr "length" "4") (set_attr "type" "branch")])(define_insn "" [(set (pc) (if_then_else (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") (const_int 1) (match_operand:SI 1 "arith_operand" "I")) (const_int 0)) (match_operand 2 "pc_or_label_operand" "") (match_operand 3 "pc_or_label_operand" "")))] "" "bb%A2\\t%0(31-%1),%P2%P3" [(set_attr "length" "4") (set_attr "type" "branch")])(define_insn "" [(set (pc) (if_then_else (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") (const_int 1) (match_operand:SI 1 "arith_operand" "I")) (const_int 0)) (match_operand 2 "pc_or_label_operand" "") (match_operand 3 "pc_or_label_operand" "")))] "" "bb%A3\\t%0(31-%1),%P2%P3" [(set_attr "length" "4") (set_attr "type" "branch")])(define_insn "" [(set (pc) (if_then_else (eq (and:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "power_of_2_operand" "I")) (const_int 0)) (match_operand 2 "pc_or_label_operand" "") (match_operand 3 "pc_or_label_operand" "")))] "" "bb%A3\\t%0(%p1),%P2%P3" [(set_attr "length" "4") (set_attr "type" "branch")])(define_insn "" [(set (pc) (if_then_else (ne (and:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "power_of_2_operand" "I")) (const_int 0)) (match_operand 2 "pc_or_label_operand" "") (match_operand 3 "pc_or_label_operand" "")))] "" "bb%A2\\t%0(%p1),%P2%P3" [(set_attr "length" "4") (set_attr "type" "branch")]);;;; ....................;;;; SETTING A REGISTER FROM A COMPARISON;;;; ....................(define_expand "seq" [(set (match_operand:SI 0 "register_operand" "=d") (eq:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0); DONE;}")(define_insn "seq_si_zero" [(set (match_operand:SI 0 "register_operand" "=d") (eq:SI (match_operand:SI 1 "register_operand" "d") (const_int 0)))] "" "sltiu\\t%0,%1,1" [(set_attr "type" "arith") (set_attr "mode" "SI")])(define_expand "sne" [(set (match_operand:SI 0 "register_operand" "=d") (ne:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0); DONE;}")(define_insn "sne_si_zero" [(set (match_operand:SI 0 "register_operand" "=d") (ne:SI (match_operand:SI 1 "register_operand" "d") (const_int 0)))] "" "sltu\\t%0,%.,%1" [(set_attr "type" "arith") (set_attr "mode" "SI")])(define_expand "sgt" [(set (match_operand:SI 0 "register_operand" "=d") (gt:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0); DONE;}")(define_insn "sgt_si" [(set (match_operand:SI 0 "register_operand" "=d,=d") (gt:SI (match_operand:SI 1 "register_operand" "d,d") (match_operand:SI 2 "reg_or_0_operand" "d,J")))] "" "@ slt\\t%0,%z2,%1 slt\\t%0,%z2,%1" [(set_attr "type" "arith,arith") (set_attr "mode" "SI,SI")])(define_expand "sge" [(set (match_operand:SI 0 "register_operand" "=d") (ge:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -