📄 arm.md
字号:
int i; if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256) { operands[2] = force_reg (SImode, GEN_INT (~INTVAL (operands[2]))); emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1])); DONE; } for (i = 9; i <= 31; i++) { if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2])) { emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i), const0_rtx)); DONE; } else if ((((HOST_WIDE_INT) 1) << i) - 1 == ~INTVAL (operands[2])) { rtx shift = GEN_INT (i); rtx reg = gen_reg_rtx (SImode); emit_insn (gen_lshrsi3 (reg, operands[1], shift)); emit_insn (gen_ashlsi3 (operands[0], reg, shift)); DONE; } } operands[2] = force_reg (SImode, operands[2]); } } ")(define_insn_and_split "*arm_andsi3_insn" [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r") (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))] "TARGET_ARM" "@ and%?\\t%0, %1, %2 bic%?\\t%0, %1, #%B2 #" "TARGET_ARM && GET_CODE (operands[2]) == CONST_INT && !(const_ok_for_arm (INTVAL (operands[2])) || const_ok_for_arm (~INTVAL (operands[2])))" [(clobber (const_int 0))] " arm_split_constant (AND, SImode, curr_insn, INTVAL (operands[2]), operands[0], operands[1], 0); DONE; " [(set_attr "length" "4,4,16") (set_attr "predicable" "yes")])(define_insn "*thumb_andsi3_insn" [(set (match_operand:SI 0 "register_operand" "=l") (and:SI (match_operand:SI 1 "register_operand" "%0") (match_operand:SI 2 "register_operand" "l")))] "TARGET_THUMB" "and\\t%0, %0, %2" [(set_attr "length" "2")])(define_insn "*andsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (and:SI (match_operand:SI 1 "s_register_operand" "r,r") (match_operand:SI 2 "arm_not_operand" "rI,K")) (const_int 0))) (set (match_operand:SI 0 "s_register_operand" "=r,r") (and:SI (match_dup 1) (match_dup 2)))] "TARGET_ARM" "@ and%?s\\t%0, %1, %2 bic%?s\\t%0, %1, #%B2" [(set_attr "conds" "set")])(define_insn "*andsi3_compare0_scratch" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r,r") (match_operand:SI 1 "arm_not_operand" "rI,K")) (const_int 0))) (clobber (match_scratch:SI 2 "=X,r"))] "TARGET_ARM" "@ tst%?\\t%0, %1 bic%?s\\t%2, %0, #%B1" [(set_attr "conds" "set")])(define_insn "*zeroextractsi_compare0_scratch" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (zero_extract:SI (match_operand:SI 0 "s_register_operand" "r") (match_operand 1 "const_int_operand" "n") (match_operand 2 "const_int_operand" "n")) (const_int 0)))] "TARGET_ARM && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32 && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)" "* operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2])); output_asm_insn (\"tst%?\\t%0, %1\", operands); return \"\"; " [(set_attr "conds" "set")])(define_insn_and_split "*ne_zeroextractsi" [(set (match_operand:SI 0 "s_register_operand" "=r") (ne:SI (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")) (const_int 0))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)" "#" "TARGET_ARM && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)" [(parallel [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))]) (set (match_dup 0) (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) (match_dup 0) (const_int 1)))] " operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[3])); " [(set_attr "conds" "clob") (set_attr "length" "8")])(define_insn_and_split "*ne_zeroextractsi_shifted" [(set (match_operand:SI 0 "s_register_operand" "=r") (ne:SI (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "const_int_operand" "n") (const_int 0)) (const_int 0))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM" "#" "TARGET_ARM" [(parallel [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))]) (set (match_dup 0) (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) (match_dup 0) (const_int 1)))] " operands[2] = GEN_INT (32 - INTVAL (operands[2])); " [(set_attr "conds" "clob") (set_attr "length" "8")])(define_insn_and_split "*ite_ne_zeroextractsi" [(set (match_operand:SI 0 "s_register_operand" "=r") (if_then_else:SI (ne (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")) (const_int 0)) (match_operand:SI 4 "arm_not_operand" "rIK") (const_int 0))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32) && !reg_overlap_mentioned_p (operands[0], operands[4])" "#" "TARGET_ARM && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32) && !reg_overlap_mentioned_p (operands[0], operands[4])" [(parallel [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))]) (set (match_dup 0) (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) (match_dup 0) (match_dup 4)))] " operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[3])); " [(set_attr "conds" "clob") (set_attr "length" "8")])(define_insn_and_split "*ite_ne_zeroextractsi_shifted" [(set (match_operand:SI 0 "s_register_operand" "=r") (if_then_else:SI (ne (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "const_int_operand" "n") (const_int 0)) (const_int 0)) (match_operand:SI 3 "arm_not_operand" "rIK") (const_int 0))) (clobber (reg:CC CC_REGNUM))] "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])" "#" "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])" [(parallel [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) (const_int 0))) (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))]) (set (match_dup 0) (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) (match_dup 0) (match_dup 3)))] " operands[2] = GEN_INT (32 - INTVAL (operands[2])); " [(set_attr "conds" "clob") (set_attr "length" "8")])(define_split [(set (match_operand:SI 0 "s_register_operand" "") (zero_extract:SI (match_operand:SI 1 "s_register_operand" "") (match_operand:SI 2 "const_int_operand" "") (match_operand:SI 3 "const_int_operand" ""))) (clobber (match_operand:SI 4 "s_register_operand" ""))] "TARGET_THUMB" [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))] "{ HOST_WIDE_INT temp = INTVAL (operands[2]); operands[2] = GEN_INT (32 - temp - INTVAL (operands[3])); operands[3] = GEN_INT (32 - temp); }")(define_split [(set (match_operand:SI 0 "s_register_operand" "") (match_operator:SI 1 "shiftable_operator" [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "") (match_operand:SI 3 "const_int_operand" "") (match_operand:SI 4 "const_int_operand" "")) (match_operand:SI 5 "s_register_operand" "")])) (clobber (match_operand:SI 6 "s_register_operand" ""))] "TARGET_ARM" [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3))) (set (match_dup 0) (match_op_dup 1 [(lshiftrt:SI (match_dup 6) (match_dup 4)) (match_dup 5)]))] "{ HOST_WIDE_INT temp = INTVAL (operands[3]); operands[3] = GEN_INT (32 - temp - INTVAL (operands[4])); operands[4] = GEN_INT (32 - temp); }") (define_split [(set (match_operand:SI 0 "s_register_operand" "") (sign_extract:SI (match_operand:SI 1 "s_register_operand" "") (match_operand:SI 2 "const_int_operand" "") (match_operand:SI 3 "const_int_operand" "")))] "TARGET_THUMB" [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))] "{ HOST_WIDE_INT temp = INTVAL (operands[2]); operands[2] = GEN_INT (32 - temp - INTVAL (operands[3])); operands[3] = GEN_INT (32 - temp); }")(define_split [(set (match_operand:SI 0 "s_register_operand" "") (match_operator:SI 1 "shiftable_operator" [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "") (match_operand:SI 3 "const_int_operand" "") (match_operand:SI 4 "const_int_operand" "")) (match_operand:SI 5 "s_register_operand" "")])) (clobber (match_operand:SI 6 "s_register_operand" ""))] "TARGET_ARM" [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3))) (set (match_dup 0) (match_op_dup 1 [(ashiftrt:SI (match_dup 6) (match_dup 4)) (match_dup 5)]))] "{ HOST_WIDE_INT temp = INTVAL (operands[3]); operands[3] = GEN_INT (32 - temp - INTVAL (operands[4])); operands[4] = GEN_INT (32 - temp); }") ;;; ??? This pattern is bogus. If operand3 has bits outside the range;;; represented by the bitfield, then this will produce incorrect results.;;; Somewhere, the value needs to be truncated. On targets like the m68k,;;; which have a real bit-field insert instruction, the truncation happens;;; in the bit-field insert instruction itself. Since arm does not have a;;; bit-field insert instruction, we would have to emit code here to truncate;;; the value before we insert. This loses some of the advantage of having;;; this insv pattern, so this pattern needs to be reevalutated.(define_expand "insv" [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "") (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" "")) (match_operand:SI 3 "reg_or_int_operand" ""))] "TARGET_ARM" " { int start_bit = INTVAL (operands[2]); int width = INTVAL (operands[1]); HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1; rtx target, subtarget; target = operands[0]; /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical subreg as the final target. */ if (GET_CODE (target) == SUBREG) { subtarget = gen_reg_rtx (SImode); if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target))) < GET_MODE_SIZE (SImode)) target = SUBREG_REG (target); } else subtarget = target; if (GET_CODE (operands[3]) == CONST_INT) { /* Since we are inserting a known constant, we may be able to reduce the number of bits that we have to clear so that the mask becomes simple. */ /* ??? This code does not check to see if the new mask is actually simpler. It may not be. */ rtx op1 = gen_reg_rtx (SImode); /* ??? Truncate operand3 to fit in the bitfield. See comment before start of this pattern. */ HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]); HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit); emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2))); emit_insn (gen_iorsi3 (subtarget, op1, gen_int_mode (op3_value << start_bit, SImode))); } else if (start_bit == 0 && !(const_ok_for_arm (mask) || const_ok_for_arm (~mask))) { /* A Trick, si
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -