📄 rs6000.md
字号:
"neg %0,%1")(define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x") (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (const_int 0))) (clobber (match_scratch:SI 2 "=r"))] "" "neg. %2,%1" [(set_attr "type" "compare")])(define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x") (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (neg:SI (match_dup 1)))] "" "neg. %0,%1" [(set_attr "type" "compare")])(define_insn "ffssi2" [(set (match_operand:SI 0 "register_operand" "=&r") (ffs:SI (match_operand:SI 1 "register_operand" "r")))] "" "neg %0,%1\;and %0,%0,%1\;cntlz %0,%0\;sfi %0,%0,32");; There is no need for (set (condition) (compare (ffs) 0)) because that;; can be simplified to an ordinary comparison. A parallel set and compare;; might be used, so include it.(define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x") (compare:CC (ffs:SI (match_operand:SI 1 "register_operand" "r")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=&r") (ffs:SI (match_dup 1)))] "" "neg %0,%1\;and %0,%0,%1\;cntlz %0,%0\;sfi. %0,%0,32" [(set_attr "type" "compare")])(define_insn "mulsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") (match_operand:SI 2 "reg_or_short_operand" "r,I"))) (clobber (match_scratch:SI 3 "=q,q"))] "" "@ muls %0,%1,%2 muli %0,%1,%2")(define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x") (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "gpc_reg_operand" "r")) (const_int 0))) (clobber (match_scratch:SI 3 "=r")) (clobber (match_scratch:SI 4 "=q"))] "" "muls. %3,%1,%2" [(set_attr "type" "delayed_compare")])(define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x") (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "gpc_reg_operand" "r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (mult:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q"))] "" "muls. %0,%1,%2" [(set_attr "type" "delayed_compare")]);; Operand 1 is divided by operand 2; quotient goes to operand;; 0 and remainder to operand 3.;; ??? At some point, see what, if anything, we can do about if (x % y == 0).(define_insn "divmodsi4" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "gpc_reg_operand" "r"))) (set (match_operand:SI 3 "gpc_reg_operand" "=q") (mod:SI (match_dup 1) (match_dup 2)))] "" "divs %0,%1,%2");; For powers of two we can do srai/aze for divide and then adjust for;; modulus. If it isn't a power of two, FAIL so divmodsi4 will be used.(define_expand "divsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "") (div:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")))] "" "{ if (GET_CODE (operands[2]) != CONST_INT || exact_log2 (INTVAL (operands[2])) < 0) FAIL;}")(define_expand "modsi3" [(set (match_dup 3) (div:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" ""))) (parallel [(set (match_dup 4) (ashift:SI (match_dup 3) (match_dup 5))) (clobber (scratch:SI))]) (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 1) (match_dup 4)))] "" "{ int i = exact_log2 (INTVAL (operands[2])); if (GET_CODE (operands[2]) != CONST_INT || i < 0) FAIL; operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); operands[5] = gen_rtx (CONST_INT, VOIDmode, i);}")(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "N")))] "exact_log2 (INTVAL (operands[2])) >= 0" "srai %0,%1,%p2\;aze %0,%0")(define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x") (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "N"))) (clobber (match_scratch:SI 3 "=r"))] "exact_log2 (INTVAL (operands[2])) >= 0" "srai %3,%1,%p2\;aze. %3,%3" [(set_attr "type" "compare")])(define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x") (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "N"))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (div:SI (match_dup 1) (match_dup 2)))] "exact_log2 (INTVAL (operands[2])) >= 0" "srai %0,%1,%p2\;aze. %0,%0" [(set_attr "type" "compare")])(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (udiv:SI (plus:DI (lshift:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")) (const_int 32)) (zero_extend:DI (match_operand:SI 4 "register_operand" "2"))) (match_operand:SI 3 "gpc_reg_operand" "r"))) (set (match_operand:SI 2 "register_operand" "=*q") (umod:SI (plus:DI (lshift:DI (zero_extend:DI (match_dup 1)) (const_int 32)) (zero_extend:DI (match_dup 4))) (match_dup 3)))] "" "div %0,%1,%3");; To do unsigned divide we handle the cases of the divisor looking like a;; negative number. If it is a constant that is less than 2**31, we don't;; have to worry about the branches. So make a few subroutines here.;;;; First comes the normal case.(define_expand "udivmodsi4_normal" [(set (match_dup 4) (const_int 0)) (parallel [(set (match_operand:SI 0 "" "") (udiv:SI (plus:DI (lshift:DI (zero_extend:DI (match_dup 4)) (const_int 32)) (zero_extend:DI (match_operand:SI 1 "" ""))) (match_operand:SI 2 "" ""))) (set (match_operand:SI 3 "" "") (umod:SI (plus:DI (lshift:DI (zero_extend:DI (match_dup 4)) (const_int 32)) (zero_extend:DI (match_dup 1))) (match_dup 2)))])] "" "{ operands[4] = gen_reg_rtx (SImode); }");; This handles the branches.(define_expand "udivmodsi4_tests" [(set (match_operand:SI 0 "" "") (const_int 0)) (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" "")) (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" ""))) (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0)) (label_ref (match_operand:SI 4 "" "")) (pc))) (set (match_dup 0) (const_int 1)) (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2))) (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0))) (set (pc) (if_then_else (lt (match_dup 6) (const_int 0)) (label_ref (match_dup 4)) (pc)))] "" "{ operands[5] = gen_reg_rtx (CCUNSmode); operands[6] = gen_reg_rtx (CCmode);}")(define_expand "udivmodsi4" [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" ""))) (set (match_operand:SI 3 "gpc_reg_operand" "") (umod:SI (match_dup 1) (match_dup 2)))])] "" "{ rtx label = 0; if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0) { operands[2] = force_reg (SImode, operands[2]); label = gen_label_rtx (); emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2], operands[3], label)); } else operands[2] = force_reg (SImode, operands[2]); emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2], operands[3])); if (label) emit_label (label); DONE;}") (define_insn "andsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") (match_operand:SI 2 "and_operand" "?r,L,K,J"))) (clobber (match_scratch:CC 3 "=X,X,x,x"))] "" "@ and %0,%1,%2 rlinm %0,%1,0,%m2,%M2 andil. %0,%1,%b2 andiu. %0,%1,%u2")(define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") (match_operand:SI 2 "and_operand" "r,K,J,L")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r,r,r"))] "" "@ and. %3,%1,%2 andil. %3,%1,%b2 andiu. %3,%1,%u2 rlinm. %3,%1,0,%m2,%M2" [(set_attr "type" "compare,compare,compare,delayed_compare")])(define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") (match_operand:SI 2 "and_operand" "r,K,J,L")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (and:SI (match_dup 1) (match_dup 2)))] "" "@ and. %0,%1,%2 andil. %0,%1,%b2 andiu. %0,%1,%u2 rlinm. %0,%1,0,%m2,%M2" [(set_attr "type" "compare,compare,compare,delayed_compare")]) ;; Take a AND with a constant that cannot be done in a single insn and try to;; split it into two insns. This does not verify that the insns are valid;; since this need not be done as combine will do it.(define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "non_and_cint_operand" "")))] "" [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3))) (set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))] "{ int maskval = INTVAL (operands[2]); int i, transitions, last_bit_value; int orig = maskval, first_c = maskval, second_c; /* We know that MASKVAL must have more than 2 bit-transitions. Start at the low-order bit and count for the third transition. When we get there, make a first mask that has everything to the left of that position a one. Then make the second mask to turn off whatever else is needed. */ for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++) { if (((maskval >>= 1) & 1) != last_bit_value) last_bit_value ^= 1, transitions++; if (transitions > 2) { first_c |= (~0) << i; break; } } second_c = orig | ~ first_c; operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c); operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);}")(define_insn "iorsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r") (match_operand:SI 2 "logical_operand" "r,K,J")))] "" "@ or %0,%1,%2 oril %0,%1,%b2 oriu %0,%1,%u2")(define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x") (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "gpc_reg_operand" "r")) (const_int 0))) (clobber (match_scratch:SI 3 "=r"))] "" "or. %3,%1,%2" [(set_attr "type" "compare")])(define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x") (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "gpc_reg_operand" "r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (ior:SI (match_dup 1) (match_dup 2)))] "" "or. %0,%1,%2" [(set_attr "type" "compare")]);; Split an IOR that we can't do in one insn into two insns, each of which;; does one 16-bit part. This is used by combine.(define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "non_logical_cint_operand" "")))] "" [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3))) (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]"{ operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff0000); operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);}")(define_insn "xorsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r") (match_operand:SI 2 "logical_operand" "r,K,J")))] "" "@ xor %0,%1,%2 xoril %0,%1,%b2 xoriu %0,%1,%u2")(define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x") (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "gpc_reg_operand" "r")) (const_int 0))) (clobber (match_scratch:SI 3 "=r"))] "" "xor. %3,%1,%2" [(set_attr "type" "compare")])(define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x") (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "gpc_reg_operand" "r")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (xor:SI (match_dup 1) (match_dup 2)))] "" "xor. %0,%1,%2" [(set_attr "type" "compare")]);; Split an XOR that we can't do in one insn into two insns, each of which;; does one 16-bit part. This is used by combine.(define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") (match_operand:SI 2 "non_logical_cint_operand" "")))] "" [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3))) (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]"{ operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff0000); operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);}")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -