aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2009-10-06 15:52:59 +0200
committerUros Bizjak <uros@gcc.gnu.org>2009-10-06 15:52:59 +0200
commitd2407a7aca3b4db2234d5c27ff1ce43074a84246 (patch)
tree9e16b9b3486a9d7baa3b802c8c7dc4d9651e0e41 /gcc
parent7b7c01e739fb93ab56e9514bfc49fea7e7d63cde (diff)
downloadgcc-d2407a7aca3b4db2234d5c27ff1ce43074a84246.zip
gcc-d2407a7aca3b4db2234d5c27ff1ce43074a84246.tar.gz
gcc-d2407a7aca3b4db2234d5c27ff1ce43074a84246.tar.bz2
i386.md (SWI48, SDWI, DWI): New mode iterators.
* config/i386/i386.md (SWI48, SDWI, DWI): New mode iterators. (DWIH, g, di, doubleint_general_operand): New mode attributes. (general_operand): Handle TI mode. (add<mode>3): Macroize expander from add{qi,hi,si,di,ti}3 patterns using SDWI mode iterator. (*add<mode>3_doubleword): New insn_and_split pattern. Macroize pattern from *add{di,ti}3_1 patterns and corresponding splitters using SDWI mode iterator. (add<mode>3_carry): Macroize insn from add{qi,hi,si,di}3_carry patterns using SWI mode iterator. (*add<mode>3_cc): Macroize insn from add{si,di}3_cc patterns using SWI48 mode iterator. (*add<mode>_1): Ditto from add{si,di}_1 patterns. (*add<mode>_2): Ditto from add{si,di}_2 patterns. (*add<mode>_3): Ditto from add{si,di}_3 patterns. (*add<mode>_5): Ditto from add{si,di}_5 patterns. (sub<mode>3): Macroize expander from sub{qi,hi,si,di,ti}3 patterns using SDWI mode iterator. (*sub<mode>3_doubleword): New insn_and_split pattern. Macroize pattern from *sub{di,ti}3_1 patterns and corresponding splitters using SDWI mode iterator. (sub<mode>3_carry): Macroize insn from sub{qi,hi,si,di}3_carry patterns using SWI mode iterator. (*sub<mode>_1): Ditto from from sub{qi,hi,si,di}_1 patterns. (*sub<mode>_2): Ditto from sub{qi,hi,si,di}_2 patterns. (*sub<mode>_3): Ditto from sub{qi,hi,si,di}_3 patterns. (<plusminus_insn>xf3): Macroize expander from addxf3 and subxf3 patterns using plusminus code iterator. (<plusminus_insn><mode>3): Macroize expander from add<mode>3 and sub<mode>3 patterns using plusminus code iterator. * config/i386/i386.c (override_options): Update call to gen_subdi_carry_rex64 for renamed function. (ix86_expand_int_addcc): Update calls to gen_subdi3_carry_rex64 and gen_adddi3_carry_rex64 for renamed functions. Use indirect calls to instruction expanders. From-SVN: r152495
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog42
-rw-r--r--gcc/config/i386/i386.c21
-rw-r--r--gcc/config/i386/i386.md2316
3 files changed, 966 insertions, 1413 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ae6f463..f9c63e5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,41 @@
+2009-10-06 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (SWI48, SDWI, DWI): New mode iterators.
+ (DWIH, g, di, doubleint_general_operand): New mode attributes.
+ (general_operand): Handle TI mode.
+ (add<mode>3): Macroize expander from add{qi,hi,si,di,ti}3 patterns
+ using SDWI mode iterator.
+ (*add<mode>3_doubleword): New insn_and_split pattern. Macroize
+ pattern from *add{di,ti}3_1 patterns and corresponding splitters
+ using SDWI mode iterator.
+ (add<mode>3_carry): Macroize insn from add{qi,hi,si,di}3_carry
+ patterns using SWI mode iterator.
+ (*add<mode>3_cc): Macroize insn from add{si,di}3_cc patterns
+ using SWI48 mode iterator.
+ (*add<mode>_1): Ditto from add{si,di}_1 patterns.
+ (*add<mode>_2): Ditto from add{si,di}_2 patterns.
+ (*add<mode>_3): Ditto from add{si,di}_3 patterns.
+ (*add<mode>_5): Ditto from add{si,di}_5 patterns.
+ (sub<mode>3): Macroize expander from sub{qi,hi,si,di,ti}3 patterns
+ using SDWI mode iterator.
+ (*sub<mode>3_doubleword): New insn_and_split pattern. Macroize
+ pattern from *sub{di,ti}3_1 patterns and corresponding splitters
+ using SDWI mode iterator.
+ (sub<mode>3_carry): Macroize insn from sub{qi,hi,si,di}3_carry
+ patterns using SWI mode iterator.
+ (*sub<mode>_1): Ditto from from sub{qi,hi,si,di}_1 patterns.
+ (*sub<mode>_2): Ditto from sub{qi,hi,si,di}_2 patterns.
+ (*sub<mode>_3): Ditto from sub{qi,hi,si,di}_3 patterns.
+ (<plusminus_insn>xf3): Macroize expander from addxf3 and subxf3
+ patterns using plusminus code iterator.
+ (<plusminus_insn><mode>3): Macroize expander from add<mode>3 and
+ sub<mode>3 patterns using plusminus code iterator.
+ * config/i386/i386.c (override_options): Update call to
+ gen_subdi_carry_rex64 for renamed function.
+ (ix86_expand_int_addcc): Update calls to gen_subdi3_carry_rex64
+ and gen_adddi3_carry_rex64 for renamed functions. Use indirect
+ calls to instruction expanders.
+
2009-10-06 Martin Jambor <mjambor@suse.cz>
PR bootstrap/41395
@@ -215,8 +253,8 @@
2009-10-05 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
- * config/arm/arm.c (arm_override_options): Really initialize
- flag_dwarf2_cfi_asm to 0.
+ * config/arm/arm.c (arm_override_options): Really initialize
+ flag_dwarf2_cfi_asm to 0.
2009-10-05 Doug Kwan <dougkwan@google.com>
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9df01ba..9da427f 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3394,7 +3394,7 @@ override_options (bool main_args_p)
ix86_gen_pop1 = gen_popdi1;
ix86_gen_add3 = gen_adddi3;
ix86_gen_sub3 = gen_subdi3;
- ix86_gen_sub3_carry = gen_subdi3_carry_rex64;
+ ix86_gen_sub3_carry = gen_subdi3_carry;
ix86_gen_one_cmpl2 = gen_one_cmpldi2;
ix86_gen_monitor = gen_sse3_monitor64;
ix86_gen_andsp = gen_anddi3;
@@ -16171,6 +16171,7 @@ int
ix86_expand_int_addcc (rtx operands[])
{
enum rtx_code code = GET_CODE (operands[1]);
+ rtx (*insn)(rtx, rtx, rtx, rtx);
rtx compare_op;
rtx val = const0_rtx;
bool fpcmp = false;
@@ -16211,16 +16212,16 @@ ix86_expand_int_addcc (rtx operands[])
switch (GET_MODE (operands[0]))
{
case QImode:
- emit_insn (gen_subqi3_carry (operands[0], operands[2], val, compare_op));
+ insn = gen_subqi3_carry;
break;
case HImode:
- emit_insn (gen_subhi3_carry (operands[0], operands[2], val, compare_op));
+ insn = gen_subhi3_carry;
break;
case SImode:
- emit_insn (gen_subsi3_carry (operands[0], operands[2], val, compare_op));
+ insn = gen_subsi3_carry;
break;
case DImode:
- emit_insn (gen_subdi3_carry_rex64 (operands[0], operands[2], val, compare_op));
+ insn = gen_subdi3_carry;
break;
default:
gcc_unreachable ();
@@ -16231,21 +16232,23 @@ ix86_expand_int_addcc (rtx operands[])
switch (GET_MODE (operands[0]))
{
case QImode:
- emit_insn (gen_addqi3_carry (operands[0], operands[2], val, compare_op));
+ insn = gen_addqi3_carry;
break;
case HImode:
- emit_insn (gen_addhi3_carry (operands[0], operands[2], val, compare_op));
+ insn = gen_addhi3_carry;
break;
case SImode:
- emit_insn (gen_addsi3_carry (operands[0], operands[2], val, compare_op));
+ insn = gen_addsi3_carry;
break;
case DImode:
- emit_insn (gen_adddi3_carry_rex64 (operands[0], operands[2], val, compare_op));
+ insn = gen_adddi3_carry;
break;
default:
gcc_unreachable ();
}
}
+ emit_insn (insn (operands[0], operands[2], val, compare_op));
+
return 1; /* DONE */
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 2780080..10c2dc6 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -708,6 +708,23 @@
;; Single word integer modes without QImode.
(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
+;; Single word integer modes without QImode and HImode.
+(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
+
+;; All single and double word integer modes.
+(define_mode_iterator SDWI [(QI "TARGET_QIMODE_MATH")
+ (HI "TARGET_HIMODE_MATH")
+ SI
+ DI
+ (TI "TARGET_64BIT")])
+
+;; Double word integer modes.
+(define_mode_iterator DWI [(DI "!TARGET_64BIT")
+ (TI "TARGET_64BIT")])
+
+;; Half mode for double word integer modes.
+(define_mode_attr DWIH [(DI "SI") (TI "DI")])
+
;; Instruction suffix for integer modes.
(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
@@ -717,12 +734,24 @@
;; Immediate operand constraint for integer modes.
(define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
+;; General operand constraint for word modes.
+(define_mode_attr g [(SI "g") (DI "rme")])
+
+;; Immediate operand constraint for double integer modes.
+(define_mode_attr di [(DI "iF") (TI "e")])
+
;; General operand predicate for integer modes.
(define_mode_attr general_operand
[(QI "general_operand")
(HI "general_operand")
(SI "general_operand")
- (DI "x86_64_general_operand")])
+ (DI "x86_64_general_operand")
+ (TI "x86_64_general_operand")])
+
+;; General operand predicate for double integer modes.
+(define_mode_attr doubleint_general_operand
+ [(DI "general_operand")
+ (TI "x86_64_general_operand")])
;; SSE and x87 SFmode and DFmode floating point modes
(define_mode_iterator MODEF [SF DF])
@@ -2994,7 +3023,6 @@
[(set (match_dup 0)
(match_dup 2))])
-
;; %%% Kill this when call knows how to work this out.
(define_split
[(set (match_operand:SF 0 "push_operand" "")
@@ -6046,195 +6074,57 @@
;; Add instructions
-;; %%% splits for addditi3
-
-(define_expand "addti3"
- [(set (match_operand:TI 0 "nonimmediate_operand" "")
- (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
- (match_operand:TI 2 "x86_64_general_operand" "")))]
- "TARGET_64BIT"
- "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
-
-(define_insn "*addti3_1"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
- (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
- (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
- "#")
-
-(define_split
- [(set (match_operand:TI 0 "nonimmediate_operand" "")
- (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
- (match_operand:TI 2 "x86_64_general_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed"
- [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
- UNSPEC_ADD_CARRY))
- (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
- (parallel [(set (match_dup 3)
- (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
- (match_dup 4))
- (match_dup 5)))
- (clobber (reg:CC FLAGS_REG))])]
- "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
-
-;; %%% splits for addsidi3
-; [(set (match_operand:DI 0 "nonimmediate_operand" "")
-; (plus:DI (match_operand:DI 1 "general_operand" "")
-; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
-
-(define_expand "adddi3"
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
- (match_operand:DI 2 "x86_64_general_operand" "")))]
+(define_expand "add<mode>3"
+ [(set (match_operand:SDWI 0 "nonimmediate_operand" "")
+ (plus:SDWI (match_operand:SDWI 1 "nonimmediate_operand" "")
+ (match_operand:SDWI 2 "<general_operand>" "")))]
""
- "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
+ "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
-(define_insn "*adddi3_1"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
- (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
- (match_operand:DI 2 "general_operand" "roiF,riF")))
+(define_insn_and_split "*add<mode>3_doubleword"
+ [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o")
+ (plus:DWI
+ (match_operand:DWI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DWI 2 "<doubleint_general_operand>" "ro<di>,r<di>")))
(clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
- "#")
-
-(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
- (match_operand:DI 2 "general_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && reload_completed"
- [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
- UNSPEC_ADD_CARRY))
- (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
+ "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (reg:CC FLAGS_REG)
+ (unspec:CC [(match_dup 1) (match_dup 2)]
+ UNSPEC_ADD_CARRY))
+ (set (match_dup 0)
+ (plus:<DWIH> (match_dup 1) (match_dup 2)))])
(parallel [(set (match_dup 3)
- (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
- (match_dup 4))
- (match_dup 5)))
+ (plus:<DWIH>
+ (plus:<DWIH>
+ (ltu:<DWIH> (reg:CC FLAGS_REG) (const_int 0))
+ (match_dup 4))
+ (match_dup 5)))
(clobber (reg:CC FLAGS_REG))])]
- "split_di (&operands[0], 3, &operands[0], &operands[3]);")
+ "split_<mode> (&operands[0], 3, &operands[0], &operands[3]);")
-(define_insn "adddi3_carry_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
- (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
- (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
- (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
+(define_insn "add<mode>3_carry"
+ [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+ (plus:SWI
+ (plus:SWI (match_operand:SWI 3 "ix86_carry_flag_operator" "")
+ (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
- "adc{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "DI")])
-
-(define_insn "*adddi3_cc_rex64"
- [(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
- (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
- UNSPEC_ADD_CARRY))
- (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
- (plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
- "add{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "DI")])
-
-(define_insn "*<plusminus_insn><mode>3_cc_overflow"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (plusminus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
- (match_dup 1)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
- (plusminus:SWI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
- "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*add<mode>3_cconly_overflow"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
- (match_dup 1)))
- (clobber (match_scratch:SWI 0 "=<r>"))]
"ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
- "add{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*sub<mode>3_cconly_overflow"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
- (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
- (match_dup 0)))]
- ""
- "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<plusminus_insn>si3_zext_cc_overflow"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
- (match_operand:SI 2 "general_operand" "g"))
- (match_dup 1)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
- "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
- "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-(define_insn "addqi3_carry"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
- (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
- (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
- (match_operand:QI 2 "general_operand" "qn,qm")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, QImode, operands)"
- "adc{b}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "QI")])
-
-(define_insn "addhi3_carry"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
- (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
- (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
- (match_operand:HI 2 "general_operand" "rn,rm")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, HImode, operands)"
- "adc{w}\t{%2, %0|%0, %2}"
+ "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
(set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
- (set_attr "mode" "HI")])
-
-(define_insn "addsi3_carry"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
- (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
- (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
- (match_operand:SI 2 "general_operand" "ri,rm")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, SImode, operands)"
- "adc{l}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
(define_insn "*addsi3_carry_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
- (match_operand:SI 1 "nonimmediate_operand" "%0"))
- (match_operand:SI 2 "general_operand" "g"))))
+ (zero_extend:DI
+ (plus:SI
+ (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
+ (match_operand:SI 1 "nonimmediate_operand" "%0"))
+ (match_operand:SI 2 "general_operand" "g"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
"adc{l}\t{%2, %k0|%k0, %2}"
@@ -6243,23 +6133,25 @@
(set_attr "pent_pair" "pu")
(set_attr "mode" "SI")])
-(define_insn "*addsi3_cc"
+(define_insn "*add<mode>3_cc"
[(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "ri,rm")]
- UNSPEC_ADD_CARRY))
- (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (PLUS, SImode, operands)"
- "add{l}\t{%2, %0|%0, %2}"
+ (unspec:CC
+ [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
+ UNSPEC_ADD_CARRY))
+ (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
+ (plus:SWI48 (match_dup 1) (match_dup 2)))]
+ "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
+ "add{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
(define_insn "addqi3_cc"
[(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "qn,qm")]
- UNSPEC_ADD_CARRY))
+ (unspec:CC
+ [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:QI 2 "general_operand" "qn,qm")]
+ UNSPEC_ADD_CARRY))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
(plus:QI (match_dup 1) (match_dup 2)))]
"ix86_binary_operator_ok (PLUS, QImode, operands)"
@@ -6267,250 +6159,64 @@
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
-(define_expand "addsi3"
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
- ""
- "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
-
-(define_insn "*lea_1"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "no_seg_address_operand" "p"))]
- "!TARGET_64BIT"
- "lea{l}\t{%a1, %0|%0, %a1}"
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn "*lea_1_rex64"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
- "TARGET_64BIT"
- "lea{l}\t{%a1, %0|%0, %a1}"
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn "*lea_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
- "TARGET_64BIT"
- "lea{l}\t{%a1, %k0|%k0, %a1}"
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn "*lea_2_rex64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (match_operand:DI 1 "no_seg_address_operand" "p"))]
- "TARGET_64BIT"
- "lea{q}\t{%a1, %0|%0, %a1}"
- [(set_attr "type" "lea")
- (set_attr "mode" "DI")])
-
-;; The lea patterns for non-Pmodes needs to be matched by several
-;; insns converted to real lea by splitters.
-
-(define_insn_and_split "*lea_general_1"
- [(set (match_operand 0 "register_operand" "=r")
- (plus (plus (match_operand 1 "index_register_operand" "l")
- (match_operand 2 "register_operand" "r"))
- (match_operand 3 "immediate_operand" "i")))]
- "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
- || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[2])
- && (GET_MODE (operands[0]) == GET_MODE (operands[3])
- || GET_MODE (operands[3]) == VOIDmode)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- rtx pat;
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[2] = gen_lowpart (Pmode, operands[2]);
- operands[3] = gen_lowpart (Pmode, operands[3]);
- pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
- operands[3]);
- if (Pmode != SImode)
- pat = gen_rtx_SUBREG (SImode, pat, 0);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea_general_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
- (match_operand:SI 2 "register_operand" "r"))
- (match_operand:SI 3 "immediate_operand" "i"))))]
- "TARGET_64BIT"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
- (match_dup 2))
- (match_dup 3)) 0)))]
-{
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[2] = gen_lowpart (Pmode, operands[2]);
- operands[3] = gen_lowpart (Pmode, operands[3]);
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea_general_2"
- [(set (match_operand 0 "register_operand" "=r")
- (plus (mult (match_operand 1 "index_register_operand" "l")
- (match_operand 2 "const248_operand" "i"))
- (match_operand 3 "nonmemory_operand" "ri")))]
- "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
- || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && (GET_MODE (operands[0]) == GET_MODE (operands[3])
- || GET_MODE (operands[3]) == VOIDmode)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- rtx pat;
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[3] = gen_lowpart (Pmode, operands[3]);
- pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
- operands[3]);
- if (Pmode != SImode)
- pat = gen_rtx_SUBREG (SImode, pat, 0);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea_general_2_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
- (match_operand:SI 2 "const248_operand" "n"))
- (match_operand:SI 3 "nonmemory_operand" "ri"))))]
- "TARGET_64BIT"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
- (match_dup 2))
- (match_dup 3)) 0)))]
-{
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[3] = gen_lowpart (Pmode, operands[3]);
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea_general_3"
- [(set (match_operand 0 "register_operand" "=r")
- (plus (plus (mult (match_operand 1 "index_register_operand" "l")
- (match_operand 2 "const248_operand" "i"))
- (match_operand 3 "register_operand" "r"))
- (match_operand 4 "immediate_operand" "i")))]
- "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
- || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[3])"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- rtx pat;
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[3] = gen_lowpart (Pmode, operands[3]);
- operands[4] = gen_lowpart (Pmode, operands[4]);
- pat = gen_rtx_PLUS (Pmode,
- gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
- operands[2]),
- operands[3]),
- operands[4]);
- if (Pmode != SImode)
- pat = gen_rtx_SUBREG (SImode, pat, 0);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea_general_3_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (plus:SI (plus:SI (mult:SI
- (match_operand:SI 1 "index_register_operand" "l")
- (match_operand:SI 2 "const248_operand" "n"))
- (match_operand:SI 3 "register_operand" "r"))
- (match_operand:SI 4 "immediate_operand" "i"))))]
- "TARGET_64BIT"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
- (match_dup 2))
- (match_dup 3))
- (match_dup 4)) 0)))]
-{
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[3] = gen_lowpart (Pmode, operands[3]);
- operands[4] = gen_lowpart (Pmode, operands[4]);
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
+(define_insn "*add<mode>3_cconly_overflow"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (plus:SWI
+ (match_operand:SWI 1 "nonimmediate_operand" "%0")
+ (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
+ (match_dup 1)))
+ (clobber (match_scratch:SWI 0 "=<r>"))]
+ "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
+ "add{<imodesuffix>}\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "<MODE>")])
-(define_insn "*adddi_1_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
- (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
- (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
+(define_insn "*add<mode>_1"
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
+ (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
+ "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_LEA:
operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
- return "lea{q}\t{%a2, %0|%0, %a2}";
+ return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
case TYPE_INCDEC:
gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (operands[2] == const1_rtx)
- return "inc{q}\t%0";
+ return "inc{<imodesuffix>}\t%0";
else
{
gcc_assert (operands[2] == constm1_rtx);
- return "dec{q}\t%0";
+ return "dec{<imodesuffix>}\t%0";
}
default:
/* Use add as much as possible to replace lea for AGU optimization. */
if (which_alternative == 2 && TARGET_OPT_AGU)
- return "add{q}\t{%1, %0|%0, %1}";
+ return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
gcc_assert (rtx_equal_p (operands[0], operands[1]));
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
/* Avoid overflows. */
- && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
+ && (<MODE>mode != DImode
+ || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
{
operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{q}\t{%2, %0|%0, %2}";
+ return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
}
- return "add{q}\t{%2, %0|%0, %2}";
+ return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
@@ -6521,9 +6227,9 @@
(const_string "lea")
; Current assemblers are broken and do not allow @GOTOFF in
; ought but a memory context.
- (match_operand:DI 2 "pic_symbolic_operand" "")
+ (match_operand:SWI48 2 "pic_symbolic_operand" "")
(const_string "lea")
- (match_operand:DI 2 "incdec_operand" "")
+ (match_operand:SWI48 2 "incdec_operand" "")
(const_string "incdec")
]
(const_string "alu")))
@@ -6532,122 +6238,104 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "DI")])
+ (set_attr "mode" "<MODE>")])
-;; Convert lea to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed
- && ix86_lea_for_add_ok (PLUS, insn, operands)"
- [(set (match_dup 0)
- (plus:DI (match_dup 1)
- (match_dup 2)))]
- "")
+;; It may seem that nonimmediate operand is proper one for operand 1.
+;; The addsi_1 pattern allows nonimmediate operand at that place and
+;; we take care in ix86_binary_operator_ok to not allow two memory
+;; operands so proper swapping will be done in reload. This allow
+;; patterns constructed from addsi_1 to match.
-(define_insn "*adddi_2_rex64"
- [(set (reg FLAGS_REG)
- (compare
- (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
- (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
- (const_int 0)))
- (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
- (plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (PLUS, DImode, operands)
- /* Current assemblers are broken and do not allow @GOTOFF in
- ought but a memory context. */
- && ! pic_symbolic_operand (operands[2], VOIDmode)"
+(define_insn "*addsi_1_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (zero_extend:DI
+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
+ (match_operand:SI 2 "general_operand" "g,li"))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
{
switch (get_attr_type (insn))
{
+ case TYPE_LEA:
+ operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
+ return "lea{l}\t{%a2, %k0|%k0, %a2}";
+
case TYPE_INCDEC:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (operands[2] == const1_rtx)
- return "inc{q}\t%0";
+ return "inc{l}\t%k0";
else
{
gcc_assert (operands[2] == constm1_rtx);
- return "dec{q}\t%0";
+ return "dec{l}\t%k0";
}
default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- /* ???? We ought to handle there the 32bit case too
- - do we need new constraint? */
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
- /* Avoid overflows. */
- && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
{
operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{q}\t{%2, %0|%0, %2}";
+ return "sub{l}\t{%2, %k0|%k0, %2}";
}
- return "add{q}\t{%2, %0|%0, %2}";
+ return "add{l}\t{%2, %k0|%k0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:DI 2 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu")))
+ (cond [(eq_attr "alternative" "1")
+ (const_string "lea")
+ ; Current assemblers are broken and do not allow @GOTOFF in
+ ; ought but a memory context.
+ (match_operand:SI 2 "pic_symbolic_operand" "")
+ (const_string "lea")
+ (match_operand:SI 2 "incdec_operand" "")
+ (const_string "incdec")
+ ]
+ (const_string "alu")))
(set (attr "length_immediate")
(if_then_else
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "DI")])
+ (set_attr "mode" "SI")])
-(define_insn "*adddi_3_rex64"
- [(set (reg FLAGS_REG)
- (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
- (match_operand:DI 1 "x86_64_general_operand" "%0")))
- (clobber (match_scratch:DI 0 "=r"))]
- "TARGET_64BIT
- && ix86_match_ccmode (insn, CCZmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))
- /* Current assemblers are broken and do not allow @GOTOFF in
- ought but a memory context. */
- && ! pic_symbolic_operand (operands[2], VOIDmode)"
+(define_insn "*addhi_1"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "rn,rm")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_PARTIAL_REG_STALL
+ && ix86_binary_operator_ok (PLUS, HImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (operands[2] == const1_rtx)
- return "inc{q}\t%0";
+ return "inc{w}\t%0";
else
{
gcc_assert (operands[2] == constm1_rtx);
- return "dec{q}\t%0";
+ return "dec{w}\t%0";
}
default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- /* ???? We ought to handle there the 32bit case too
- - do we need new constraint? */
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
- /* Avoid overflows. */
- && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{q}\t{%2, %0|%0, %2}";
- }
- return "add{q}\t{%2, %0|%0, %2}";
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return "sub{w}\t{%2, %0|%0, %2}";
+ }
+ return "add{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:DI 2 "incdec_operand" "")
+ (if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
(set (attr "length_immediate")
@@ -6655,105 +6343,102 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "DI")])
+ (set_attr "mode" "HI")])
-; For comparisons against 1, -1 and 128, we may generate better code
-; by converting cmp to add, inc or dec as done by peephole2. This pattern
-; is matched then. We can't accept general immediate, because for
-; case of overflows, the result is messed up.
-; This pattern also don't hold of 0x8000000000000000, since the value overflows
-; when negated.
-; Also carry flag is reversed compared to cmp, so this conversion is valid
-; only for comparisons not depending on it.
-(define_insn "*adddi_4_rex64"
- [(set (reg FLAGS_REG)
- (compare (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:DI 2 "x86_64_immediate_operand" "e")))
- (clobber (match_scratch:DI 0 "=rm"))]
- "TARGET_64BIT
- && ix86_match_ccmode (insn, CCGCmode)"
+;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
+;; type optimizations enabled by define-splits. This is not important
+;; for PII, and in fact harmful because of partial register stalls.
+
+(define_insn "*addhi_1_lea"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
+ (match_operand:HI 2 "general_operand" "rn,rm,ln")))
+ (clobber (reg:CC FLAGS_REG))]
+ "!TARGET_PARTIAL_REG_STALL
+ && ix86_binary_operator_ok (PLUS, HImode, operands)"
{
switch (get_attr_type (insn))
{
+ case TYPE_LEA:
+ return "#";
case TYPE_INCDEC:
- if (operands[2] == constm1_rtx)
- return "inc{q}\t%0";
+ if (operands[2] == const1_rtx)
+ return "inc{w}\t%0";
else
- {
- gcc_assert (operands[2] == const1_rtx);
- return "dec{q}\t%0";
+ {
+ gcc_assert (operands[2] == constm1_rtx);
+ return "dec{w}\t%0";
}
default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
- if ((INTVAL (operands[2]) == -128
- || (INTVAL (operands[2]) > 0
- && INTVAL (operands[2]) != 128))
- /* Avoid overflows. */
- && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
- return "sub{q}\t{%2, %0|%0, %2}";
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "add{q}\t{%2, %0|%0, %2}";
+ if (CONST_INT_P (operands[2])
+ && (INTVAL (operands[2]) == 128
+ || (INTVAL (operands[2]) < 0
+ && INTVAL (operands[2]) != -128)))
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return "sub{w}\t{%2, %0|%0, %2}";
+ }
+ return "add{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:DI 2 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu")))
+ (if_then_else (eq_attr "alternative" "2")
+ (const_string "lea")
+ (if_then_else (match_operand:HI 2 "incdec_operand" "")
+ (const_string "incdec")
+ (const_string "alu"))))
(set (attr "length_immediate")
(if_then_else
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "DI")])
+ (set_attr "mode" "HI,HI,SI")])
-(define_insn "*adddi_5_rex64"
- [(set (reg FLAGS_REG)
- (compare
- (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
- (match_operand:DI 2 "x86_64_general_operand" "rme"))
- (const_int 0)))
- (clobber (match_scratch:DI 0 "=r"))]
- "TARGET_64BIT
- && ix86_match_ccmode (insn, CCGOCmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))
- /* Current assemblers are broken and do not allow @GOTOFF in
- ought but a memory context. */
- && ! pic_symbolic_operand (operands[2], VOIDmode)"
+(define_insn "*addqi_1"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_PARTIAL_REG_STALL
+ && ix86_binary_operator_ok (PLUS, QImode, operands)"
{
+ int widen = (which_alternative == 2);
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (operands[2] == const1_rtx)
- return "inc{q}\t%0";
+ return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{q}\t%0";
+ {
+ gcc_assert (operands[2] == constm1_rtx);
+ return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
}
default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
- /* Avoid overflows. */
- && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{q}\t{%2, %0|%0, %2}";
- }
- return "add{q}\t{%2, %0|%0, %2}";
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ if (widen)
+ return "sub{l}\t{%2, %k0|%k0, %2}";
+ else
+ return "sub{b}\t{%2, %0|%0, %2}";
+ }
+ if (widen)
+ return "add{l}\t{%k2, %k0|%k0, %k2}";
+ else
+ return "add{b}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:DI 2 "incdec_operand" "")
+ (if_then_else (match_operand:QI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
(set (attr "length_immediate")
@@ -6761,184 +6446,115 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "DI")])
-
+ (set_attr "mode" "QI,QI,SI")])
-(define_insn "*addsi_1"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
- (match_operand:SI 2 "general_operand" "g,ri,0,li")))
+;; %%% Potential partial reg stall on alternative 2. What to do?
+(define_insn "*addqi_1_lea"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
+ (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, SImode, operands)"
+ "!TARGET_PARTIAL_REG_STALL
+ && ix86_binary_operator_ok (PLUS, QImode, operands)"
{
+ int widen = (which_alternative == 2);
switch (get_attr_type (insn))
{
case TYPE_LEA:
- operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
- return "lea{l}\t{%a2, %0|%0, %a2}";
-
+ return "#";
case TYPE_INCDEC:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (operands[2] == const1_rtx)
- return "inc{l}\t%0";
+ return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
else
{
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{l}\t%0";
+ gcc_assert (operands[2] == constm1_rtx);
+ return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
}
default:
- /* Use add as much as possible to replace lea for AGU optimization. */
- if (which_alternative == 2 && TARGET_OPT_AGU)
- return "add{l}\t{%1, %0|%0, %1}";
-
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
-
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{l}\t{%2, %0|%0, %2}";
- }
- return "add{l}\t{%2, %0|%0, %2}";
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ if (widen)
+ return "sub{l}\t{%2, %k0|%k0, %2}";
+ else
+ return "sub{b}\t{%2, %0|%0, %2}";
+ }
+ if (widen)
+ return "add{l}\t{%k2, %k0|%k0, %k2}";
+ else
+ return "add{b}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (cond [(and (eq_attr "alternative" "2")
- (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
- (const_string "lea")
- (eq_attr "alternative" "3")
- (const_string "lea")
- ; Current assemblers are broken and do not allow @GOTOFF in
- ; ought but a memory context.
- (match_operand:SI 2 "pic_symbolic_operand" "")
- (const_string "lea")
- (match_operand:SI 2 "incdec_operand" "")
- (const_string "incdec")
- ]
- (const_string "alu")))
+ (if_then_else (eq_attr "alternative" "3")
+ (const_string "lea")
+ (if_then_else (match_operand:QI 2 "incdec_operand" "")
+ (const_string "incdec")
+ (const_string "alu"))))
(set (attr "length_immediate")
(if_then_else
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "SI")])
-
-;; Convert lea to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand 0 "register_operand" "")
- (plus (match_operand 1 "register_operand" "")
- (match_operand 2 "nonmemory_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
- [(const_int 0)]
-{
- rtx pat;
- /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
- may confuse gen_lowpart. */
- if (GET_MODE (operands[0]) != Pmode)
- {
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[2] = gen_lowpart (Pmode, operands[2]);
- }
- operands[0] = gen_lowpart (SImode, operands[0]);
- pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
- if (Pmode != SImode)
- pat = gen_rtx_SUBREG (SImode, pat, 0);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-})
+ (set_attr "mode" "QI,QI,SI,SI")])
-;; It may seem that nonimmediate operand is proper one for operand 1.
-;; The addsi_1 pattern allows nonimmediate operand at that place and
-;; we take care in ix86_binary_operator_ok to not allow two memory
-;; operands so proper swapping will be done in reload. This allow
-;; patterns constructed from addsi_1 to match.
-(define_insn "addsi_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
- (match_operand:SI 2 "general_operand" "g,li"))))
+(define_insn "*addqi_1_slp"
+ [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
+ (plus:QI (match_dup 0)
+ (match_operand:QI 1 "general_operand" "qn,qnm")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
+ "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
switch (get_attr_type (insn))
{
- case TYPE_LEA:
- operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
- return "lea{l}\t{%a2, %k0|%k0, %a2}";
-
case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{l}\t%k0";
+ if (operands[1] == const1_rtx)
+ return "inc{b}\t%0";
else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{l}\t%k0";
+ {
+ gcc_assert (operands[1] == constm1_rtx);
+ return "dec{b}\t%0";
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
- Exceptions: -128 encodes smaller than 128, so swap sign and op. */
- if (CONST_INT_P (operands[2])
- && (INTVAL (operands[2]) == 128
- || (INTVAL (operands[2]) < 0
- && INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{l}\t{%2, %k0|%k0, %2}";
- }
- return "add{l}\t{%2, %k0|%k0, %2}";
+ /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
+ if (CONST_INT_P (operands[1])
+ && INTVAL (operands[1]) < 0)
+ {
+ operands[1] = GEN_INT (-INTVAL (operands[1]));
+ return "sub{b}\t{%1, %0|%0, %1}";
+ }
+ return "add{b}\t{%1, %0|%0, %1}";
}
}
[(set (attr "type")
- (cond [(eq_attr "alternative" "1")
- (const_string "lea")
- ; Current assemblers are broken and do not allow @GOTOFF in
- ; ought but a memory context.
- (match_operand:SI 2 "pic_symbolic_operand" "")
- (const_string "lea")
- (match_operand:SI 2 "incdec_operand" "")
- (const_string "incdec")
- ]
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-;; Convert lea to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI
- (plus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" ""))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
- [(set (match_dup 0)
- (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
-{
- operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[2] = gen_lowpart (Pmode, operands[2]);
-})
+ (if_then_else (match_operand:QI 1 "incdec_operand" "")
+ (const_string "incdec")
+ (const_string "alu1")))
+ (set (attr "memory")
+ (if_then_else (match_operand 1 "memory_operand" "")
+ (const_string "load")
+ (const_string "none")))
+ (set_attr "mode" "QI")])
-(define_insn "*addsi_2"
+(define_insn "*add<mode>_2"
[(set (reg FLAGS_REG)
(compare
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "g,ri"))
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
(const_int 0)))
- (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
- (plus:SI (match_dup 1) (match_dup 2)))]
+ (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
+ (plus:SWI48 (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (PLUS, SImode, operands)
+ && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
/* Current assemblers are broken and do not allow @GOTOFF in
ought but a memory context. */
&& ! pic_symbolic_operand (operands[2], VOIDmode)"
@@ -6948,30 +6564,35 @@
case TYPE_INCDEC:
gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (operands[2] == const1_rtx)
- return "inc{l}\t%0";
+ return "inc{<imodesuffix>}\t%0";
else
{
gcc_assert (operands[2] == constm1_rtx);
- return "dec{l}\t%0";
+ return "dec{<imodesuffix>}\t%0";
}
default:
gcc_assert (rtx_equal_p (operands[0], operands[1]));
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* ???? In DImode, we ought to handle there the 32bit case too
+ - do we need new constraint? */
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
+ /* Avoid overflows. */
+ && (<MODE>mode != DImode
+ || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
{
operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{l}\t{%2, %0|%0, %2}";
+ return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
}
- return "add{l}\t{%2, %0|%0, %2}";
+ return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:SI 2 "incdec_operand" "")
+ (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
(set (attr "length_immediate")
@@ -6979,7 +6600,7 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
;; See comment for addsi_1_zext why we do use nonimmediate_operand
(define_insn "*addsi_2_zext"
@@ -7008,7 +6629,7 @@
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
&& (INTVAL (operands[2]) == 128
@@ -7032,46 +6653,44 @@
(const_string "*")))
(set_attr "mode" "SI")])
-(define_insn "*addsi_3"
+(define_insn "*addhi_2"
[(set (reg FLAGS_REG)
- (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
- (match_operand:SI 1 "nonimmediate_operand" "%0")))
- (clobber (match_scratch:SI 0 "=r"))]
- "ix86_match_ccmode (insn, CCZmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))
- /* Current assemblers are broken and do not allow @GOTOFF in
- ought but a memory context. */
- && ! pic_symbolic_operand (operands[2], VOIDmode)"
+ (compare
+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "rmn,rn"))
+ (const_int 0)))
+ (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
+ (plus:HI (match_dup 1) (match_dup 2)))]
+ "ix86_match_ccmode (insn, CCGOCmode)
+ && ix86_binary_operator_ok (PLUS, HImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (operands[2] == const1_rtx)
- return "inc{l}\t%0";
+ return "inc{w}\t%0";
else
{
gcc_assert (operands[2] == constm1_rtx);
- return "dec{l}\t%0";
+ return "dec{w}\t%0";
}
default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{l}\t{%2, %0|%0, %2}";
- }
- return "add{l}\t{%2, %0|%0, %2}";
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return "sub{w}\t{%2, %0|%0, %2}";
+ }
+ return "add{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:SI 2 "incdec_operand" "")
+ (if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
(set (attr "length_immediate")
@@ -7079,98 +6698,95 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "SI")])
+ (set_attr "mode" "HI")])
-;; See comment for addsi_1_zext why we do use nonimmediate_operand
-(define_insn "*addsi_3_zext"
+(define_insn "*addqi_2"
[(set (reg FLAGS_REG)
- (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
- (match_operand:SI 1 "nonimmediate_operand" "%0")))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
- && ix86_binary_operator_ok (PLUS, SImode, operands)
- /* Current assemblers are broken and do not allow @GOTOFF in
- ought but a memory context. */
- && ! pic_symbolic_operand (operands[2], VOIDmode)"
+ (compare
+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:QI 2 "general_operand" "qmn,qn"))
+ (const_int 0)))
+ (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
+ (plus:QI (match_dup 1) (match_dup 2)))]
+ "ix86_match_ccmode (insn, CCGOCmode)
+ && ix86_binary_operator_ok (PLUS, QImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
if (operands[2] == const1_rtx)
- return "inc{l}\t%k0";
+ return "inc{b}\t%0";
else
{
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{l}\t%k0";
+ gcc_assert (operands[2] == constm1_rtx
+ || (CONST_INT_P (operands[2])
+ && INTVAL (operands[2]) == 255));
+ return "dec{b}\t%0";
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
- Exceptions: -128 encodes smaller than 128, so swap sign and op. */
+ /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
if (CONST_INT_P (operands[2])
- && (INTVAL (operands[2]) == 128
- || (INTVAL (operands[2]) < 0
- && INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{l}\t{%2, %k0|%k0, %2}";
- }
- return "add{l}\t{%2, %k0|%k0, %2}";
+ && INTVAL (operands[2]) < 0)
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return "sub{b}\t{%2, %0|%0, %2}";
+ }
+ return "add{b}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:SI 2 "incdec_operand" "")
+ (if_then_else (match_operand:QI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "SI")])
+ (set_attr "mode" "QI")])
-; For comparisons against 1, -1 and 128, we may generate better code
-; by converting cmp to add, inc or dec as done by peephole2. This pattern
-; is matched then. We can't accept general immediate, because for
-; case of overflows, the result is messed up.
-; This pattern also don't hold of 0x80000000, since the value overflows
-; when negated.
-; Also carry flag is reversed compared to cmp, so this conversion is valid
-; only for comparisons not depending on it.
-(define_insn "*addsi_4"
+(define_insn "*add<mode>_3"
[(set (reg FLAGS_REG)
- (compare (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_scratch:SI 0 "=rm"))]
- "ix86_match_ccmode (insn, CCGCmode)
- && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
+ (compare
+ (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
+ (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
+ (clobber (match_scratch:SWI48 0 "=r"))]
+ "ix86_match_ccmode (insn, CCZmode)
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))
+ /* Current assemblers are broken and do not allow @GOTOFF in
+ ought but a memory context. */
+ && ! pic_symbolic_operand (operands[2], VOIDmode)"
{
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
- if (operands[2] == constm1_rtx)
- return "inc{l}\t%0";
+ gcc_assert (rtx_equal_p (operands[0], operands[1]));
+ if (operands[2] == const1_rtx)
+ return "inc{<imodesuffix>}\t%0";
else
{
- gcc_assert (operands[2] == const1_rtx);
- return "dec{l}\t%0";
+ gcc_assert (operands[2] == constm1_rtx);
+ return "dec{<imodesuffix>}\t%0";
}
default:
gcc_assert (rtx_equal_p (operands[0], operands[1]));
+ /* ???? In DImode, we ought to handle there the 32bit case too
+ - do we need new constraint? */
/* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
- if ((INTVAL (operands[2]) == -128
- || (INTVAL (operands[2]) > 0
- && INTVAL (operands[2]) != 128)))
- return "sub{l}\t{%2, %0|%0, %2}";
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "add{l}\t{%2, %0|%0, %2}";
+ if (CONST_INT_P (operands[2])
+ /* Avoid overflows. */
+ && (<MODE>mode != DImode
+ || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
+ && (INTVAL (operands[2]) == 128
+ || (INTVAL (operands[2]) < 0
+ && INTVAL (operands[2]) != -128)))
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
+ }
+ return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:SI 2 "incdec_operand" "")
+ (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
(set (attr "length_immediate")
@@ -7178,17 +6794,18 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
-(define_insn "*addsi_5"
+;; See comment for addsi_1_zext why we do use nonimmediate_operand
+(define_insn "*addsi_3_zext"
[(set (reg FLAGS_REG)
(compare
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
- (match_operand:SI 2 "general_operand" "g"))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=r"))]
- "ix86_match_ccmode (insn, CCGOCmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))
+ (neg:SI (match_operand:SI 2 "general_operand" "g"))
+ (match_operand:SI 1 "nonimmediate_operand" "%0")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
+ "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
+ && ix86_binary_operator_ok (PLUS, SImode, operands)
/* Current assemblers are broken and do not allow @GOTOFF in
ought but a memory context. */
&& ! pic_symbolic_operand (operands[2], VOIDmode)"
@@ -7196,18 +6813,16 @@
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (operands[2] == const1_rtx)
- return "inc{l}\t%0";
+ return "inc{l}\t%k0";
else
{
gcc_assert (operands[2] == constm1_rtx);
- return "dec{l}\t%0";
+ return "dec{l}\t%k0";
}
default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
&& (INTVAL (operands[2]) == 128
@@ -7215,9 +6830,9 @@
&& INTVAL (operands[2]) != -128)))
{
operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{l}\t{%2, %0|%0, %2}";
+ return "sub{l}\t{%2, %k0|%k0, %2}";
}
- return "add{l}\t{%2, %0|%0, %2}";
+ return "add{l}\t{%2, %k0|%k0, %2}";
}
}
[(set (attr "type")
@@ -7231,40 +6846,28 @@
(const_string "*")))
(set_attr "mode" "SI")])
-(define_expand "addhi3"
- [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
- (match_operand:HI 2 "general_operand" "")))]
- "TARGET_HIMODE_MATH"
- "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
-
-;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
-;; type optimizations enabled by define-splits. This is not important
-;; for PII, and in fact harmful because of partial register stalls.
-
-(define_insn "*addhi_1_lea"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
- (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
- (match_operand:HI 2 "general_operand" "rn,rm,ln")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_PARTIAL_REG_STALL
- && ix86_binary_operator_ok (PLUS, HImode, operands)"
+(define_insn "*addhi_3"
+ [(set (reg FLAGS_REG)
+ (compare
+ (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
+ (match_operand:HI 1 "nonimmediate_operand" "%0")))
+ (clobber (match_scratch:HI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCZmode)
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
{
switch (get_attr_type (insn))
{
- case TYPE_LEA:
- return "#";
case TYPE_INCDEC:
if (operands[2] == const1_rtx)
return "inc{w}\t%0";
else
- {
+ {
gcc_assert (operands[2] == constm1_rtx);
return "dec{w}\t%0";
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
&& (INTVAL (operands[2]) == 128
@@ -7278,100 +6881,100 @@
}
}
[(set (attr "type")
- (if_then_else (eq_attr "alternative" "2")
- (const_string "lea")
- (if_then_else (match_operand:HI 2 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu"))))
+ (if_then_else (match_operand:HI 2 "incdec_operand" "")
+ (const_string "incdec")
+ (const_string "alu")))
(set (attr "length_immediate")
(if_then_else
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "HI,HI,SI")])
+ (set_attr "mode" "HI")])
-(define_insn "*addhi_1"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
- (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "rn,rm")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_PARTIAL_REG_STALL
- && ix86_binary_operator_ok (PLUS, HImode, operands)"
+(define_insn "*addqi_3"
+ [(set (reg FLAGS_REG)
+ (compare
+ (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
+ (match_operand:QI 1 "nonimmediate_operand" "%0")))
+ (clobber (match_scratch:QI 0 "=q"))]
+ "ix86_match_ccmode (insn, CCZmode)
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
{
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
if (operands[2] == const1_rtx)
- return "inc{w}\t%0";
+ return "inc{b}\t%0";
else
{
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{w}\t%0";
+ gcc_assert (operands[2] == constm1_rtx
+ || (CONST_INT_P (operands[2])
+ && INTVAL (operands[2]) == 255));
+ return "dec{b}\t%0";
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
- Exceptions: -128 encodes smaller than 128, so swap sign and op. */
+ /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
if (CONST_INT_P (operands[2])
- && (INTVAL (operands[2]) == 128
- || (INTVAL (operands[2]) < 0
- && INTVAL (operands[2]) != -128)))
+ && INTVAL (operands[2]) < 0)
{
operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{w}\t{%2, %0|%0, %2}";
+ return "sub{b}\t{%2, %0|%0, %2}";
}
- return "add{w}\t{%2, %0|%0, %2}";
+ return "add{b}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:HI 2 "incdec_operand" "")
+ (if_then_else (match_operand:QI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "HI")])
+ (set_attr "mode" "QI")])
-(define_insn "*addhi_2"
+; For comparisons against 1, -1 and 128, we may generate better code
+; by converting cmp to add, inc or dec as done by peephole2. This pattern
+; is matched then. We can't accept general immediate, because for
+; case of overflows, the result is messed up.
+; This pattern also don't hold of 0x8000000000000000, since the value
+; overflows when negated.
+; Also carry flag is reversed compared to cmp, so this conversion is valid
+; only for comparisons not depending on it.
+
+(define_insn "*adddi_4"
[(set (reg FLAGS_REG)
(compare
- (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "rmn,rn"))
- (const_int 0)))
- (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
- (plus:HI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (PLUS, HImode, operands)"
+ (match_operand:DI 1 "nonimmediate_operand" "0")
+ (match_operand:DI 2 "x86_64_immediate_operand" "e")))
+ (clobber (match_scratch:DI 0 "=rm"))]
+ "TARGET_64BIT
+ && ix86_match_ccmode (insn, CCGCmode)"
{
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{w}\t%0";
+ if (operands[2] == constm1_rtx)
+ return "inc{q}\t%0";
else
{
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{w}\t%0";
+ gcc_assert (operands[2] == const1_rtx);
+ return "dec{q}\t%0";
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ gcc_assert (rtx_equal_p (operands[0], operands[1]));
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
- if (CONST_INT_P (operands[2])
- && (INTVAL (operands[2]) == 128
- || (INTVAL (operands[2]) < 0
- && INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{w}\t{%2, %0|%0, %2}";
- }
- return "add{w}\t{%2, %0|%0, %2}";
+ if ((INTVAL (operands[2]) == -128
+ || (INTVAL (operands[2]) > 0
+ && INTVAL (operands[2]) != 128))
+ /* Avoid overflows. */
+ && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
+ return "sub{q}\t{%2, %0|%0, %2}";
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return "add{q}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:HI 2 "incdec_operand" "")
+ (if_then_else (match_operand:DI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
(set (attr "length_immediate")
@@ -7379,43 +6982,51 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "HI")])
+ (set_attr "mode" "DI")])
-(define_insn "*addhi_3"
+; For comparisons against 1, -1 and 128, we may generate better code
+; by converting cmp to add, inc or dec as done by peephole2. This pattern
+; is matched then. We can't accept general immediate, because for
+; case of overflows, the result is messed up.
+; This pattern also don't hold of 0x80000000, since the value overflows
+; when negated.
+; Also carry flag is reversed compared to cmp, so this conversion is valid
+; only for comparisons not depending on it.
+
+(define_insn "*addsi_4"
[(set (reg FLAGS_REG)
- (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
- (match_operand:HI 1 "nonimmediate_operand" "%0")))
- (clobber (match_scratch:HI 0 "=r"))]
- "ix86_match_ccmode (insn, CCZmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ (compare
+ (match_operand:SI 1 "nonimmediate_operand" "0")
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_scratch:SI 0 "=rm"))]
+ "ix86_match_ccmode (insn, CCGCmode)
+ && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
{
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{w}\t%0";
+ if (operands[2] == constm1_rtx)
+ return "inc{l}\t%0";
else
{
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{w}\t%0";
+ gcc_assert (operands[2] == const1_rtx);
+ return "dec{l}\t%0";
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ gcc_assert (rtx_equal_p (operands[0], operands[1]));
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
- if (CONST_INT_P (operands[2])
- && (INTVAL (operands[2]) == 128
- || (INTVAL (operands[2]) < 0
- && INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{w}\t{%2, %0|%0, %2}";
- }
- return "add{w}\t{%2, %0|%0, %2}";
+ if ((INTVAL (operands[2]) == -128
+ || (INTVAL (operands[2]) > 0
+ && INTVAL (operands[2]) != 128)))
+ return "sub{l}\t{%2, %0|%0, %2}";
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return "add{l}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:HI 2 "incdec_operand" "")
+ (if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
(set (attr "length_immediate")
@@ -7423,13 +7034,15 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "HI")])
+ (set_attr "mode" "SI")])
; See comments above addsi_4 for details.
+
(define_insn "*addhi_4"
[(set (reg FLAGS_REG)
- (compare (match_operand:HI 1 "nonimmediate_operand" "0")
- (match_operand:HI 2 "const_int_operand" "n")))
+ (compare
+ (match_operand:HI 1 "nonimmediate_operand" "0")
+ (match_operand:HI 2 "const_int_operand" "n")))
(clobber (match_scratch:HI 0 "=rm"))]
"ix86_match_ccmode (insn, CCGCmode)
&& (INTVAL (operands[2]) & 0xffff) != 0x8000"
@@ -7447,7 +7060,7 @@
default:
gcc_assert (rtx_equal_p (operands[0], operands[1]));
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if ((INTVAL (operands[2]) == -128
|| (INTVAL (operands[2]) > 0
@@ -7468,138 +7081,124 @@
(const_string "*")))
(set_attr "mode" "HI")])
+; See comments above addsi_4 for details.
-(define_insn "*addhi_5"
+(define_insn "*addqi_4"
[(set (reg FLAGS_REG)
(compare
- (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
- (match_operand:HI 2 "general_operand" "rmn"))
- (const_int 0)))
- (clobber (match_scratch:HI 0 "=r"))]
- "ix86_match_ccmode (insn, CCGOCmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ (match_operand:QI 1 "nonimmediate_operand" "0")
+ (match_operand:QI 2 "const_int_operand" "n")))
+ (clobber (match_scratch:QI 0 "=qm"))]
+ "ix86_match_ccmode (insn, CCGCmode)
+ && (INTVAL (operands[2]) & 0xff) != 0x80"
{
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{w}\t%0";
+ if (operands[2] == constm1_rtx
+ || (CONST_INT_P (operands[2])
+ && INTVAL (operands[2]) == 255))
+ return "inc{b}\t%0";
else
{
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{w}\t%0";
+ gcc_assert (operands[2] == const1_rtx);
+ return "dec{b}\t%0";
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
- Exceptions: -128 encodes smaller than 128, so swap sign and op. */
- if (CONST_INT_P (operands[2])
- && (INTVAL (operands[2]) == 128
- || (INTVAL (operands[2]) < 0
- && INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{w}\t{%2, %0|%0, %2}";
- }
- return "add{w}\t{%2, %0|%0, %2}";
+ gcc_assert (rtx_equal_p (operands[0], operands[1]));
+ if (INTVAL (operands[2]) < 0)
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return "add{b}\t{%2, %0|%0, %2}";
+ }
+ return "sub{b}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "HI")])
-
-(define_expand "addqi3"
- [(set (match_operand:QI 0 "nonimmediate_operand" "")
- (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
- (match_operand:QI 2 "general_operand" "")))]
- "TARGET_QIMODE_MATH"
- "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
+ (set_attr "mode" "QI")])
-;; %%% Potential partial reg stall on alternative 2. What to do?
-(define_insn "*addqi_1_lea"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
- (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
- (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_PARTIAL_REG_STALL
- && ix86_binary_operator_ok (PLUS, QImode, operands)"
+(define_insn "*add<mode>_5"
+ [(set (reg FLAGS_REG)
+ (compare
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "%0")
+ (match_operand:SWI48 2 "<general_operand>" "<g>"))
+ (const_int 0)))
+ (clobber (match_scratch:SWI48 0 "=r"))]
+ "ix86_match_ccmode (insn, CCGOCmode)
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))
+ /* Current assemblers are broken and do not allow @GOTOFF in
+ ought but a memory context. */
+ && ! pic_symbolic_operand (operands[2], VOIDmode)"
{
- int widen = (which_alternative == 2);
switch (get_attr_type (insn))
{
- case TYPE_LEA:
- return "#";
case TYPE_INCDEC:
+ gcc_assert (rtx_equal_p (operands[0], operands[1]));
if (operands[2] == const1_rtx)
- return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
+ return "inc{<imodesuffix>}\t%0";
else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
+ {
+ gcc_assert (operands[2] == constm1_rtx);
+ return "dec{<imodesuffix>}\t%0";
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ gcc_assert (rtx_equal_p (operands[0], operands[1]));
+ /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
+ /* Avoid overflows. */
+ && (<MODE>mode != DImode
+ || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- if (widen)
- return "sub{l}\t{%2, %k0|%k0, %2}";
- else
- return "sub{b}\t{%2, %0|%0, %2}";
- }
- if (widen)
- return "add{l}\t{%k2, %k0|%k0, %k2}";
- else
- return "add{b}\t{%2, %0|%0, %2}";
+ {
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
+ return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
+ }
+ return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (eq_attr "alternative" "3")
- (const_string "lea")
- (if_then_else (match_operand:QI 2 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu"))))
+ (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
+ (const_string "incdec")
+ (const_string "alu")))
(set (attr "length_immediate")
(if_then_else
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "QI,QI,SI,SI")])
+ (set_attr "mode" "<MODE>")])
-(define_insn "*addqi_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
- (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_PARTIAL_REG_STALL
- && ix86_binary_operator_ok (PLUS, QImode, operands)"
+(define_insn "*addhi_5"
+ [(set (reg FLAGS_REG)
+ (compare
+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
+ (match_operand:HI 2 "general_operand" "rmn"))
+ (const_int 0)))
+ (clobber (match_scratch:HI 0 "=r"))]
+ "ix86_match_ccmode (insn, CCGOCmode)
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
{
- int widen = (which_alternative == 2);
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
if (operands[2] == const1_rtx)
- return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
+ return "inc{w}\t%0";
else
{
gcc_assert (operands[2] == constm1_rtx);
- return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
+ return "dec{w}\t%0";
}
default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (CONST_INT_P (operands[2])
&& (INTVAL (operands[2]) == 128
@@ -7607,19 +7206,13 @@
&& INTVAL (operands[2]) != -128)))
{
operands[2] = GEN_INT (-INTVAL (operands[2]));
- if (widen)
- return "sub{l}\t{%2, %k0|%k0, %2}";
- else
- return "sub{b}\t{%2, %0|%0, %2}";
+ return "sub{w}\t{%2, %0|%0, %2}";
}
- if (widen)
- return "add{l}\t{%k2, %k0|%k0, %k2}";
- else
- return "add{b}\t{%2, %0|%0, %2}";
+ return "add{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:QI 2 "incdec_operand" "")
+ (if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
(set (attr "length_immediate")
@@ -7627,165 +7220,7 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "QI,QI,SI")])
-
-(define_insn "*addqi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
- (plus:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qn,qnm")))
- (clobber (reg:CC FLAGS_REG))]
- "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[1] == const1_rtx)
- return "inc{b}\t%0";
- else
- {
- gcc_assert (operands[1] == constm1_rtx);
- return "dec{b}\t%0";
- }
-
- default:
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
- if (CONST_INT_P (operands[1])
- && INTVAL (operands[1]) < 0)
- {
- operands[1] = GEN_INT (-INTVAL (operands[1]));
- return "sub{b}\t{%1, %0|%0, %1}";
- }
- return "add{b}\t{%1, %0|%0, %1}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:QI 1 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu1")))
- (set (attr "memory")
- (if_then_else (match_operand 1 "memory_operand" "")
- (const_string "load")
- (const_string "none")))
- (set_attr "mode" "QI")])
-
-(define_insn "*addqi_2"
- [(set (reg FLAGS_REG)
- (compare
- (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "qmn,qn"))
- (const_int 0)))
- (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
- (plus:QI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (PLUS, QImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{b}\t%0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx
- || (CONST_INT_P (operands[2])
- && INTVAL (operands[2]) == 255));
- return "dec{b}\t%0";
- }
-
- default:
- /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
- if (CONST_INT_P (operands[2])
- && INTVAL (operands[2]) < 0)
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{b}\t{%2, %0|%0, %2}";
- }
- return "add{b}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:QI 2 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu")))
- (set_attr "mode" "QI")])
-
-(define_insn "*addqi_3"
- [(set (reg FLAGS_REG)
- (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
- (match_operand:QI 1 "nonimmediate_operand" "%0")))
- (clobber (match_scratch:QI 0 "=q"))]
- "ix86_match_ccmode (insn, CCZmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{b}\t%0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx
- || (CONST_INT_P (operands[2])
- && INTVAL (operands[2]) == 255));
- return "dec{b}\t%0";
- }
-
- default:
- /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
- if (CONST_INT_P (operands[2])
- && INTVAL (operands[2]) < 0)
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "sub{b}\t{%2, %0|%0, %2}";
- }
- return "add{b}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:QI 2 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu")))
- (set_attr "mode" "QI")])
-
-; See comments above addsi_4 for details.
-(define_insn "*addqi_4"
- [(set (reg FLAGS_REG)
- (compare (match_operand:QI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_operand" "n")))
- (clobber (match_scratch:QI 0 "=qm"))]
- "ix86_match_ccmode (insn, CCGCmode)
- && (INTVAL (operands[2]) & 0xff) != 0x80"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == constm1_rtx
- || (CONST_INT_P (operands[2])
- && INTVAL (operands[2]) == 255))
- return "inc{b}\t%0";
- else
- {
- gcc_assert (operands[2] == const1_rtx);
- return "dec{b}\t%0";
- }
-
- default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (INTVAL (operands[2]) < 0)
- {
- operands[2] = GEN_INT (-INTVAL (operands[2]));
- return "add{b}\t{%2, %0|%0, %2}";
- }
- return "sub{b}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:HI 2 "incdec_operand" "")
- (const_string "incdec")
- (const_string "alu")))
- (set_attr "mode" "QI")])
-
+ (set_attr "mode" "HI")])
(define_insn "*addqi_5"
[(set (reg FLAGS_REG)
@@ -7811,7 +7246,7 @@
}
default:
- /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
+ /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
if (CONST_INT_P (operands[2])
&& INTVAL (operands[2]) < 0)
{
@@ -7827,8 +7262,7 @@
(const_string "alu")))
(set_attr "mode" "QI")])
-
-(define_insn "addqi_ext_1"
+(define_insn "*addqi_ext_1_rex64"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
(const_int 8)
(const_int 8))
@@ -7837,9 +7271,9 @@
(match_operand 1 "ext_register_operand" "0")
(const_int 8)
(const_int 8))
- (match_operand:QI 2 "general_operand" "Qmn")))
+ (match_operand:QI 2 "nonmemory_operand" "Qn")))
(clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT"
+ "TARGET_64BIT"
{
switch (get_attr_type (insn))
{
@@ -7852,7 +7286,7 @@
|| (CONST_INT_P (operands[2])
&& INTVAL (operands[2]) == 255));
return "dec{b}\t%h0";
- }
+ }
default:
return "add{b}\t{%2, %h0|%h0, %2}";
@@ -7865,7 +7299,7 @@
(set_attr "modrm" "1")
(set_attr "mode" "QI")])
-(define_insn "*addqi_ext_1_rex64"
+(define_insn "addqi_ext_1"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
(const_int 8)
(const_int 8))
@@ -7874,9 +7308,9 @@
(match_operand 1 "ext_register_operand" "0")
(const_int 8)
(const_int 8))
- (match_operand:QI 2 "nonmemory_operand" "Qn")))
+ (match_operand:QI 2 "general_operand" "Qmn")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
+ "!TARGET_64BIT"
{
switch (get_attr_type (insn))
{
@@ -7889,7 +7323,7 @@
|| (CONST_INT_P (operands[2])
&& INTVAL (operands[2]) == 255));
return "dec{b}\t%h0";
- }
+ }
default:
return "add{b}\t{%2, %h0|%h0, %2}";
@@ -7921,178 +7355,304 @@
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
-;; The patterns that match these are at the end of this file.
-
-(define_expand "addxf3"
- [(set (match_operand:XF 0 "register_operand" "")
- (plus:XF (match_operand:XF 1 "register_operand" "")
- (match_operand:XF 2 "register_operand" "")))]
- "TARGET_80387"
- "")
+(define_insn "*lea_1_rex64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (match_operand:DI 1 "no_seg_address_operand" "p"))]
+ "TARGET_64BIT"
+ "lea{q}\t{%a1, %0|%0, %a1}"
+ [(set_attr "type" "lea")
+ (set_attr "mode" "DI")])
-(define_expand "add<mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "")
- (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
- (match_operand:MODEF 2 "nonimmediate_operand" "")))]
- "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
- "")
-
-;; Subtract instructions
+(define_insn "*lea_1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operand:SI 1 "no_seg_address_operand" "p"))]
+ "!TARGET_64BIT"
+ "lea{l}\t{%a1, %0|%0, %a1}"
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
-;; %%% splits for subditi3
+(define_insn "*lea_1_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
+ "TARGET_64BIT"
+ "lea{l}\t{%a1, %k0|%k0, %a1}"
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
-(define_expand "subti3"
- [(set (match_operand:TI 0 "nonimmediate_operand" "")
- (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
- (match_operand:TI 2 "x86_64_general_operand" "")))]
+(define_insn "*lea_2_rex64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
"TARGET_64BIT"
- "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
+ "lea{l}\t{%a1, %0|%0, %a1}"
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
-(define_insn "*subti3_1"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
- (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
- (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
- "#")
+;; The lea patterns for non-Pmodes needs to be matched by
+;; several insns converted to real lea by splitters.
-(define_split
- [(set (match_operand:TI 0 "nonimmediate_operand" "")
- (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
- (match_operand:TI 2 "x86_64_general_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed"
- [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
- (parallel [(set (match_dup 3)
- (minus:DI (match_dup 4)
- (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
- (match_dup 5))))
- (clobber (reg:CC FLAGS_REG))])]
- "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
+(define_insn_and_split "*lea_general_1"
+ [(set (match_operand 0 "register_operand" "=r")
+ (plus (plus (match_operand 1 "index_register_operand" "l")
+ (match_operand 2 "register_operand" "r"))
+ (match_operand 3 "immediate_operand" "i")))]
+ "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
+ || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
+ && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && GET_MODE (operands[0]) == GET_MODE (operands[2])
+ && (GET_MODE (operands[0]) == GET_MODE (operands[3])
+ || GET_MODE (operands[3]) == VOIDmode)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx pat;
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[1] = gen_lowpart (Pmode, operands[1]);
+ operands[2] = gen_lowpart (Pmode, operands[2]);
+ operands[3] = gen_lowpart (Pmode, operands[3]);
+ pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
+ operands[3]);
+ if (Pmode != SImode)
+ pat = gen_rtx_SUBREG (SImode, pat, 0);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
+ DONE;
+}
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
-;; %%% splits for subsidi3
+(define_insn_and_split "*lea_general_1_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (plus:SI (plus:SI
+ (match_operand:SI 1 "index_register_operand" "l")
+ (match_operand:SI 2 "register_operand" "r"))
+ (match_operand:SI 3 "immediate_operand" "i"))))]
+ "TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
+ (match_dup 2))
+ (match_dup 3)) 0)))]
+{
+ operands[1] = gen_lowpart (Pmode, operands[1]);
+ operands[2] = gen_lowpart (Pmode, operands[2]);
+ operands[3] = gen_lowpart (Pmode, operands[3]);
+}
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
-(define_expand "subdi3"
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
- (match_operand:DI 2 "x86_64_general_operand" "")))]
- ""
- "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
+(define_insn_and_split "*lea_general_2"
+ [(set (match_operand 0 "register_operand" "=r")
+ (plus (mult (match_operand 1 "index_register_operand" "l")
+ (match_operand 2 "const248_operand" "i"))
+ (match_operand 3 "nonmemory_operand" "ri")))]
+ "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
+ || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
+ && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && (GET_MODE (operands[0]) == GET_MODE (operands[3])
+ || GET_MODE (operands[3]) == VOIDmode)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx pat;
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[1] = gen_lowpart (Pmode, operands[1]);
+ operands[3] = gen_lowpart (Pmode, operands[3]);
+ pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
+ operands[3]);
+ if (Pmode != SImode)
+ pat = gen_rtx_SUBREG (SImode, pat, 0);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
+ DONE;
+}
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
-(define_insn "*subdi3_1"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
- (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
- (match_operand:DI 2 "general_operand" "roiF,riF")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
- "#")
+(define_insn_and_split "*lea_general_2_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (plus:SI (mult:SI
+ (match_operand:SI 1 "index_register_operand" "l")
+ (match_operand:SI 2 "const248_operand" "n"))
+ (match_operand:SI 3 "nonmemory_operand" "ri"))))]
+ "TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
+ (match_dup 2))
+ (match_dup 3)) 0)))]
+{
+ operands[1] = gen_lowpart (Pmode, operands[1]);
+ operands[3] = gen_lowpart (Pmode, operands[3]);
+}
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
-(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
- (match_operand:DI 2 "general_operand" "")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && reload_completed"
- [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
- (parallel [(set (match_dup 3)
- (minus:SI (match_dup 4)
- (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
- (match_dup 5))))
- (clobber (reg:CC FLAGS_REG))])]
- "split_di (&operands[0], 3, &operands[0], &operands[3]);")
+(define_insn_and_split "*lea_general_3"
+ [(set (match_operand 0 "register_operand" "=r")
+ (plus (plus (mult (match_operand 1 "index_register_operand" "l")
+ (match_operand 2 "const248_operand" "i"))
+ (match_operand 3 "register_operand" "r"))
+ (match_operand 4 "immediate_operand" "i")))]
+ "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
+ || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
+ && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && GET_MODE (operands[0]) == GET_MODE (operands[3])"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx pat;
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[1] = gen_lowpart (Pmode, operands[1]);
+ operands[3] = gen_lowpart (Pmode, operands[3]);
+ operands[4] = gen_lowpart (Pmode, operands[4]);
+ pat = gen_rtx_PLUS (Pmode,
+ gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
+ operands[2]),
+ operands[3]),
+ operands[4]);
+ if (Pmode != SImode)
+ pat = gen_rtx_SUBREG (SImode, pat, 0);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
+ DONE;
+}
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
-(define_insn "subdi3_carry_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
- (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
- (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
- (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
- "sbb{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "DI")])
+(define_insn_and_split "*lea_general_3_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (plus:SI (plus:SI
+ (mult:SI
+ (match_operand:SI 1 "index_register_operand" "l")
+ (match_operand:SI 2 "const248_operand" "n"))
+ (match_operand:SI 3 "register_operand" "r"))
+ (match_operand:SI 4 "immediate_operand" "i"))))]
+ "TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
+ (match_dup 2))
+ (match_dup 3))
+ (match_dup 4)) 0)))]
+{
+ operands[1] = gen_lowpart (Pmode, operands[1]);
+ operands[3] = gen_lowpart (Pmode, operands[3]);
+ operands[4] = gen_lowpart (Pmode, operands[4]);
+}
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
-(define_insn "*subdi_1_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
- (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
- (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
+;; Convert lea to the lea pattern to avoid flags dependency.
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
- "sub{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "DI")])
-
-(define_insn "*subdi_2_rex64"
- [(set (reg FLAGS_REG)
- (compare
- (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
- (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
- (const_int 0)))
- (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
- (minus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (MINUS, DImode, operands)"
- "sub{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "DI")])
-
-(define_insn "*subdi_3_rex63"
- [(set (reg FLAGS_REG)
- (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
- (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
- (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
- (minus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
- && ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sub{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "DI")])
+ "TARGET_64BIT && reload_completed
+ && ix86_lea_for_add_ok (PLUS, insn, operands)"
+ [(set (match_dup 0)
+ (plus:DI (match_dup 1)
+ (match_dup 2)))]
+ "")
-(define_insn "subqi3_carry"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
- (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
- (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
- (match_operand:QI 2 "general_operand" "qn,qm"))))
+;; Convert lea to the lea pattern to avoid flags dependency.
+(define_split
+ [(set (match_operand 0 "register_operand" "")
+ (plus (match_operand 1 "register_operand" "")
+ (match_operand 2 "nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (MINUS, QImode, operands)"
- "sbb{b}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "QI")])
+ "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
+ [(const_int 0)]
+{
+ rtx pat;
+ /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
+ may confuse gen_lowpart. */
+ if (GET_MODE (operands[0]) != Pmode)
+ {
+ operands[1] = gen_lowpart (Pmode, operands[1]);
+ operands[2] = gen_lowpart (Pmode, operands[2]);
+ }
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
+ if (Pmode != SImode)
+ pat = gen_rtx_SUBREG (SImode, pat, 0);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
+ DONE;
+})
-(define_insn "subhi3_carry"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
- (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
- (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
- (match_operand:HI 2 "general_operand" "rn,rm"))))
+;; Convert lea to the lea pattern to avoid flags dependency.
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" ""))))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (MINUS, HImode, operands)"
- "sbb{w}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "HI")])
+ "TARGET_64BIT && reload_completed
+ && true_regnum (operands[0]) != true_regnum (operands[1])"
+ [(set (match_dup 0)
+ (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
+{
+ operands[1] = gen_lowpart (Pmode, operands[1]);
+ operands[2] = gen_lowpart (Pmode, operands[2]);
+})
+
+;; Subtract instructions
-(define_insn "subsi3_carry"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
- (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
- (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
- (match_operand:SI 2 "general_operand" "ri,rm"))))
+(define_expand "sub<mode>3"
+ [(set (match_operand:SDWI 0 "nonimmediate_operand" "")
+ (minus:SDWI (match_operand:SDWI 1 "nonimmediate_operand" "")
+ (match_operand:SDWI 2 "<general_operand>" "")))]
+ ""
+ "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
+
+(define_insn_and_split "*sub<mode>3_doubleword"
+ [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o")
+ (minus:DWI
+ (match_operand:DWI 1 "nonimmediate_operand" "0,0")
+ (match_operand:DWI 2 "<doubleint_general_operand>" "ro<di>,r<di>")))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sbb{l}\t{%2, %0|%0, %2}"
+ "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_dup 1) (match_dup 2)))
+ (set (match_dup 0)
+ (minus:<DWIH> (match_dup 1) (match_dup 2)))])
+ (parallel [(set (match_dup 3)
+ (minus:<DWIH>
+ (match_dup 4)
+ (plus:<DWIH>
+ (ltu:<DWIH> (reg:CC FLAGS_REG) (const_int 0))
+ (match_dup 5))))
+ (clobber (reg:CC FLAGS_REG))])]
+ "split_<mode> (&operands[0], 3, &operands[0], &operands[3]);")
+
+(define_insn "sub<mode>3_carry"
+ [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+ (minus:SWI
+ (match_operand:SWI 1 "nonimmediate_operand" "0,0")
+ (plus:SWI
+ (match_operand:SWI 3 "ix86_carry_flag_operator" "")
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
+ (clobber (reg:CC FLAGS_REG))]
+ "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
+ "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
(set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
-(define_insn "subsi3_carry_zext"
+(define_insn "*subsi3_carry_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
(minus:SI (match_operand:SI 1 "register_operand" "0")
@@ -8105,22 +7665,28 @@
(set_attr "pent_pair" "pu")
(set_attr "mode" "SI")])
-(define_expand "subsi3"
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
+(define_insn "*sub<mode>3_cconly_overflow"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (minus:SWI
+ (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
+ (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
+ (match_dup 0)))]
""
- "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
+ "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "icmp")
+ (set_attr "mode" "<MODE>")])
-(define_insn "*subsi_1"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
- (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
- (match_operand:SI 2 "general_operand" "ri,rm")))
+(define_insn "*sub<mode>_1"
+ [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+ (minus:SWI
+ (match_operand:SWI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
(clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sub{l}\t{%2, %0|%0, %2}"
+ "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
+ "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
(define_insn "*subsi_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -8133,19 +7699,31 @@
[(set_attr "type" "alu")
(set_attr "mode" "SI")])
-(define_insn "*subsi_2"
+(define_insn "*subqi_1_slp"
+ [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
+ (minus:QI (match_dup 0)
+ (match_operand:QI 1 "general_operand" "qn,qm")))
+ (clobber (reg:CC FLAGS_REG))]
+ "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "sub{b}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "alu1")
+ (set_attr "mode" "QI")])
+
+(define_insn "*sub<mode>_2"
[(set (reg FLAGS_REG)
(compare
- (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
- (match_operand:SI 2 "general_operand" "ri,rm"))
+ (minus:SWI
+ (match_operand:SWI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
(const_int 0)))
- (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
- (minus:SI (match_dup 1) (match_dup 2)))]
+ (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+ (minus:SWI (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sub{l}\t{%2, %0|%0, %2}"
+ && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
+ "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
(define_insn "*subsi_2_zext"
[(set (reg FLAGS_REG)
@@ -8163,17 +7741,17 @@
[(set_attr "type" "alu")
(set_attr "mode" "SI")])
-(define_insn "*subsi_3"
+(define_insn "*sub<mode>_3"
[(set (reg FLAGS_REG)
- (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
- (match_operand:SI 2 "general_operand" "ri,rm")))
- (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
- (minus:SI (match_dup 1) (match_dup 2)))]
+ (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
+ (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+ (minus:SWI (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCmode)
- && ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sub{l}\t{%2, %0|%0, %2}"
+ && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
+ "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
(define_insn "*subsi_3_zext"
[(set (reg FLAGS_REG)
@@ -8187,118 +7765,52 @@
&& ix86_binary_operator_ok (MINUS, SImode, operands)"
"sub{l}\t{%2, %1|%1, %2}"
[(set_attr "type" "alu")
- (set_attr "mode" "DI")])
-
-(define_expand "subhi3"
- [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
- (match_operand:HI 2 "general_operand" "")))]
- "TARGET_HIMODE_MATH"
- "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
-
-(define_insn "*subhi_1"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
- (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
- (match_operand:HI 2 "general_operand" "rn,rm")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (MINUS, HImode, operands)"
- "sub{w}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "HI")])
-
-(define_insn "*subhi_2"
- [(set (reg FLAGS_REG)
- (compare
- (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
- (match_operand:HI 2 "general_operand" "rn,rm"))
- (const_int 0)))
- (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
- (minus:HI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (MINUS, HImode, operands)"
- "sub{w}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "HI")])
-
-(define_insn "*subhi_3"
- [(set (reg FLAGS_REG)
- (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
- (match_operand:HI 2 "general_operand" "rn,rm")))
- (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
- (minus:HI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCmode)
- && ix86_binary_operator_ok (MINUS, HImode, operands)"
- "sub{w}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "HI")])
-
-(define_expand "subqi3"
- [(set (match_operand:QI 0 "nonimmediate_operand" "")
- (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
- (match_operand:QI 2 "general_operand" "")))]
- "TARGET_QIMODE_MATH"
- "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
+ (set_attr "mode" "SI")])
-(define_insn "*subqi_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
- (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
- (match_operand:QI 2 "general_operand" "qn,qm")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (MINUS, QImode, operands)"
- "sub{b}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "QI")])
-(define_insn "*subqi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
- (minus:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qn,qm")))
- (clobber (reg:CC FLAGS_REG))]
- "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "sub{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
-
-(define_insn "*subqi_2"
- [(set (reg FLAGS_REG)
- (compare
- (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
- (match_operand:QI 2 "general_operand" "qn,qm"))
- (const_int 0)))
- (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
- (minus:QI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (MINUS, QImode, operands)"
- "sub{b}\t{%2, %0|%0, %2}"
+(define_insn "*<plusminus_insn><mode>3_cc_overflow"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (plusminus:SWI
+ (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
+ (match_dup 1)))
+ (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+ (plusminus:SWI (match_dup 1) (match_dup 2)))]
+ "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+ "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
- (set_attr "mode" "QI")])
+ (set_attr "mode" "<MODE>")])
-(define_insn "*subqi_3"
- [(set (reg FLAGS_REG)
- (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
- (match_operand:QI 2 "general_operand" "qn,qm")))
- (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
- (minus:QI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCmode)
- && ix86_binary_operator_ok (MINUS, QImode, operands)"
- "sub{b}\t{%2, %0|%0, %2}"
+(define_insn "*<plusminus_insn>si3_zext_cc_overflow"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (plusminus:SI
+ (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
+ (match_operand:SI 2 "general_operand" "g"))
+ (match_dup 1)))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
+ "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
+ "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
[(set_attr "type" "alu")
- (set_attr "mode" "QI")])
+ (set_attr "mode" "SI")])
;; The patterns that match these are at the end of this file.
-(define_expand "subxf3"
+(define_expand "<plusminus_insn>xf3"
[(set (match_operand:XF 0 "register_operand" "")
- (minus:XF (match_operand:XF 1 "register_operand" "")
- (match_operand:XF 2 "register_operand" "")))]
+ (plusminus:XF
+ (match_operand:XF 1 "register_operand" "")
+ (match_operand:XF 2 "register_operand" "")))]
"TARGET_80387"
"")
-(define_expand "sub<mode>3"
+(define_expand "<plusminus_insn><mode>3"
[(set (match_operand:MODEF 0 "register_operand" "")
- (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
- (match_operand:MODEF 2 "nonimmediate_operand" "")))]
+ (plusminus:MODEF
+ (match_operand:MODEF 1 "register_operand" "")
+ (match_operand:MODEF 2 "nonimmediate_operand" "")))]
"(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
|| (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
"")