Skip to content

Commit e3f64b6

Browse files
author
jakub
committed
PR target/82628
* config/i386/predicates.md (x86_64_dwzext_immediate_operand): New. * config/i386/constraints.md (Wf): New constraint. * config/i386/i386.md (UNSPEC_SBB): New unspec. (cmp<dwi>_doubleword): Removed. (sub<mode>3_carry_ccc, *sub<mode>3_carry_ccc_1): New patterns. (sub<mode>3_carry_ccgz): Use unspec instead of compare. * config/i386/i386.c (ix86_expand_branch) <case E_TImode>: Don't expand with cmp<dwi>_doubleword. For LTU and GEU use sub<mode>3_carry_ccc instead of sub<mode>3_carry_ccgz and use CCCmode. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254011 138bc75d-0d04-0410-961f-82ee72b054a4
1 parent c61ffa8 commit e3f64b6

File tree

5 files changed

+109
-36
lines changed

5 files changed

+109
-36
lines changed

gcc/ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
2017-10-23 Jakub Jelinek <[email protected]>
22

3+
PR target/82628
4+
* config/i386/predicates.md (x86_64_dwzext_immediate_operand): New.
5+
* config/i386/constraints.md (Wf): New constraint.
6+
* config/i386/i386.md (UNSPEC_SBB): New unspec.
7+
(cmp<dwi>_doubleword): Removed.
8+
(sub<mode>3_carry_ccc, *sub<mode>3_carry_ccc_1): New patterns.
9+
(sub<mode>3_carry_ccgz): Use unspec instead of compare.
10+
* config/i386/i386.c (ix86_expand_branch) <case E_TImode>: Don't
11+
expand with cmp<dwi>_doubleword. For LTU and GEU use
12+
sub<mode>3_carry_ccc instead of sub<mode>3_carry_ccgz and use CCCmode.
13+
314
* common.opt (gcolumn-info): Enable by default.
415
* doc/invoke.texi (gcolumn-info): Document new default.
516

gcc/config/i386/constraints.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@
332332
of it satisfies the e constraint."
333333
(match_operand 0 "x86_64_hilo_int_operand"))
334334

335+
(define_constraint "Wf"
336+
"32-bit signed integer constant zero extended from word size
337+
to double word size."
338+
(match_operand 0 "x86_64_dwzext_immediate_operand"))
339+
335340
(define_constraint "Z"
336341
"32-bit unsigned integer constant, or a symbolic reference known
337342
to fit that range (for immediate operands in zero-extending x86-64

gcc/config/i386/i386.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22378,27 +22378,45 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
2237822378
switch (code)
2237922379
{
2238022380
case LE: case LEU: case GT: case GTU:
22381-
std::swap (op0, op1);
22381+
std::swap (lo[0], lo[1]);
22382+
std::swap (hi[0], hi[1]);
2238222383
code = swap_condition (code);
2238322384
/* FALLTHRU */
2238422385

2238522386
case LT: case LTU: case GE: case GEU:
2238622387
{
22387-
rtx (*cmp_insn) (rtx, rtx, rtx);
22388+
rtx (*cmp_insn) (rtx, rtx);
22389+
rtx (*sbb_insn) (rtx, rtx, rtx);
22390+
bool uns = (code == LTU || code == GEU);
2238822391

2238922392
if (TARGET_64BIT)
22390-
cmp_insn = gen_cmpti_doubleword;
22393+
{
22394+
cmp_insn = gen_cmpdi_1;
22395+
sbb_insn
22396+
= uns ? gen_subdi3_carry_ccc : gen_subdi3_carry_ccgz;
22397+
}
2239122398
else
22392-
cmp_insn = gen_cmpdi_doubleword;
22399+
{
22400+
cmp_insn = gen_cmpsi_1;
22401+
sbb_insn
22402+
= uns ? gen_subsi3_carry_ccc : gen_subsi3_carry_ccgz;
22403+
}
22404+
22405+
if (!nonimmediate_operand (lo[0], submode))
22406+
lo[0] = force_reg (submode, lo[0]);
22407+
if (!x86_64_general_operand (lo[1], submode))
22408+
lo[1] = force_reg (submode, lo[1]);
2239322409

22394-
if (!register_operand (op0, mode))
22395-
op0 = force_reg (mode, op0);
22396-
if (!x86_64_hilo_general_operand (op1, mode))
22397-
op1 = force_reg (mode, op1);
22410+
if (!register_operand (hi[0], submode))
22411+
hi[0] = force_reg (submode, hi[0]);
22412+
if ((uns && !nonimmediate_operand (hi[1], submode))
22413+
|| (!uns && !x86_64_general_operand (hi[1], submode)))
22414+
hi[1] = force_reg (submode, hi[1]);
2239822415

22399-
emit_insn (cmp_insn (gen_rtx_SCRATCH (mode), op0, op1));
22416+
emit_insn (cmp_insn (lo[0], lo[1]));
22417+
emit_insn (sbb_insn (gen_rtx_SCRATCH (submode), hi[0], hi[1]));
2240022418

22401-
tmp = gen_rtx_REG (CCGZmode, FLAGS_REG);
22419+
tmp = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
2240222420

2240322421
ix86_expand_branch (code, tmp, const0_rtx, label);
2240422422
return;

gcc/config/i386/i386.md

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
UNSPEC_STOS
113113
UNSPEC_PEEPSIB
114114
UNSPEC_INSN_FALSE_DEP
115+
UNSPEC_SBB
115116

116117
;; For SSE/MMX support:
117118
UNSPEC_FIX_NOTRUNC
@@ -1273,26 +1274,6 @@
12731274
(compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
12741275
(match_operand:SWI48 1 "<general_operand>")))])
12751276

1276-
(define_insn_and_split "cmp<dwi>_doubleword"
1277-
[(set (reg:CCGZ FLAGS_REG)
1278-
(compare:CCGZ
1279-
(match_operand:<DWI> 1 "register_operand" "0")
1280-
(match_operand:<DWI> 2 "x86_64_hilo_general_operand" "ro<di>")))
1281-
(clobber (match_scratch:<DWI> 0 "=r"))]
1282-
""
1283-
"#"
1284-
"reload_completed"
1285-
[(set (reg:CC FLAGS_REG)
1286-
(compare:CC (match_dup 1) (match_dup 2)))
1287-
(parallel [(set (reg:CCGZ FLAGS_REG)
1288-
(compare: CCGZ
1289-
(match_dup 4)
1290-
(plus:DWIH
1291-
(ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
1292-
(match_dup 5))))
1293-
(clobber (match_dup 3))])]
1294-
"split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
1295-
12961277
(define_insn "*cmp<mode>_ccno_1"
12971278
[(set (reg FLAGS_REG)
12981279
(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
@@ -6911,13 +6892,46 @@
69116892
(set_attr "pent_pair" "pu")
69126893
(set_attr "mode" "SI")])
69136894

6914-
(define_insn "*sub<mode>3_carry_ccgz"
6895+
(define_insn "sub<mode>3_carry_ccc"
6896+
[(set (reg:CCC FLAGS_REG)
6897+
(compare:CCC
6898+
(zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6899+
(plus:<DWI>
6900+
(ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6901+
(zero_extend:<DWI>
6902+
(match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6903+
(clobber (match_scratch:DWIH 0 "=r"))]
6904+
""
6905+
"sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6906+
[(set_attr "type" "alu")
6907+
(set_attr "mode" "<MODE>")])
6908+
6909+
(define_insn "*sub<mode>3_carry_ccc_1"
6910+
[(set (reg:CCC FLAGS_REG)
6911+
(compare:CCC
6912+
(zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6913+
(plus:<DWI>
6914+
(ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6915+
(match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6916+
(clobber (match_scratch:DWIH 0 "=r"))]
6917+
""
6918+
{
6919+
operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6920+
return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6921+
}
6922+
[(set_attr "type" "alu")
6923+
(set_attr "mode" "<MODE>")])
6924+
6925+
;; The sign flag is set from the
6926+
;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6927+
;; result, the overflow flag likewise, but the overflow flag is also
6928+
;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6929+
(define_insn "sub<mode>3_carry_ccgz"
69156930
[(set (reg:CCGZ FLAGS_REG)
6916-
(compare:CCGZ
6917-
(match_operand:DWIH 1 "register_operand" "0")
6918-
(plus:DWIH
6919-
(ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6920-
(match_operand:DWIH 2 "x86_64_general_operand" "rme"))))
6931+
(unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6932+
(match_operand:DWIH 2 "x86_64_general_operand" "rme")
6933+
(ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6934+
UNSPEC_SBB))
69216935
(clobber (match_scratch:DWIH 0 "=r"))]
69226936
""
69236937
"sbb{<imodesuffix>}\t{%2, %0|%0, %2}"

gcc/config/i386/predicates.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,31 @@
366366
}
367367
})
368368

369+
;; Return true if VALUE is a constant integer whose value is
370+
;; x86_64_immediate_operand value zero extended from word mode to mode.
371+
(define_predicate "x86_64_dwzext_immediate_operand"
372+
(match_code "const_int,const_wide_int")
373+
{
374+
switch (GET_CODE (op))
375+
{
376+
case CONST_INT:
377+
if (!TARGET_64BIT)
378+
return UINTVAL (op) <= HOST_WIDE_INT_UC (0xffffffff);
379+
return UINTVAL (op) <= HOST_WIDE_INT_UC (0x7fffffff);
380+
381+
case CONST_WIDE_INT:
382+
if (!TARGET_64BIT)
383+
return false;
384+
return (CONST_WIDE_INT_NUNITS (op) == 2
385+
&& CONST_WIDE_INT_ELT (op, 1) == 0
386+
&& (trunc_int_for_mode (CONST_WIDE_INT_ELT (op, 0), SImode)
387+
== (HOST_WIDE_INT) CONST_WIDE_INT_ELT (op, 0)));
388+
389+
default:
390+
gcc_unreachable ();
391+
}
392+
})
393+
369394
;; Return true if size of VALUE can be stored in a sign
370395
;; extended immediate field.
371396
(define_predicate "x86_64_immediate_size_operand"

0 commit comments

Comments
 (0)