===================================================================
@@ -1640,7 +1640,7 @@
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2) (match_dup 3))]
{
- split_di (&operands[1], 1, &operands[2], &operands[3]);
+ split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
operands[1] = gen_lowpart (DImode, operands[2]);
operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
@@ -1657,7 +1657,7 @@
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2) (match_dup 3))]
{
- split_di (&operands[1], 1, &operands[2], &operands[3]);
+ split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
operands[1] = gen_lowpart (DImode, operands[2]);
operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
@@ -2050,7 +2050,7 @@
&& !x86_64_immediate_operand (operands[1], DImode) && 1"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
- "split_di (&operands[0], 2, &operands[2], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
@@ -2061,7 +2061,7 @@
&& !x86_64_immediate_operand (operands[1], DImode)"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
- "split_di (&operands[0], 2, &operands[2], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "nonimmediate_operand"
@@ -3598,7 +3598,7 @@
(zero_extend:DI (match_dup 0)))]
"TARGET_64BIT"
[(set (match_dup 4) (const_int 0))]
- "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
;; %%% Kill me once multi-word ops are sane.
(define_insn "zero_extendsidi2_1"
@@ -3626,7 +3626,7 @@
"!TARGET_64BIT && reload_completed
&& true_regnum (operands[0]) == true_regnum (operands[1])"
[(set (match_dup 4) (const_int 0))]
- "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand" "")
@@ -3636,7 +3636,7 @@
&& !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
[(set (match_dup 3) (match_dup 1))
(set (match_dup 4) (const_int 0))]
- "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
(define_insn "zero_extend<mode>di2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -3801,7 +3801,7 @@
(parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
(clobber (reg:CC FLAGS_REG))])
(set (match_dup 4) (match_dup 1))]
- "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+ "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
;; Extend to memory case when source register does not die.
(define_split
@@ -3812,7 +3812,7 @@
"reload_completed"
[(const_int 0)]
{
- split_di (&operands[0], 1, &operands[3], &operands[4]);
+ split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
emit_move_insn (operands[3], operands[1]);
@@ -3842,7 +3842,7 @@
"reload_completed"
[(const_int 0)]
{
- split_di (&operands[0], 1, &operands[3], &operands[4]);
+ split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
if (true_regnum (operands[3]) != true_regnum (operands[1]))
emit_move_insn (operands[3], operands[1]);
@@ -5570,7 +5570,7 @@
(ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
(match_dup 5))))
(clobber (reg:CC FLAGS_REG))])]
- "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
+ "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
(define_insn "*add<mode>3_cc"
[(set (reg:CC FLAGS_REG)
@@ -6600,7 +6600,7 @@
(ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
(match_dup 5))))
(clobber (reg:CC FLAGS_REG))])]
- "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
+ "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
(define_insn "*sub<mode>_1"
[(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
@@ -8593,7 +8593,7 @@
[(set (match_dup 2)
(neg:DWIH (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
- "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
+ "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
(define_insn "*neg<mode>2_1"
[(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
@@ -10072,7 +10072,7 @@
{
operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
- split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
+ split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
})
(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
@@ -10100,7 +10100,7 @@
{
operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
- split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
+ split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
})
(define_insn "*<rotate_insn><mode>3_1"
@@ -16055,8 +16055,8 @@
(match_dup 7)
(match_dup 8)))]
{
- split_di (&operands[2], 2, &operands[5], &operands[7]);
- split_di (&operands[0], 1, &operands[2], &operands[3]);
+ split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
+ split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
})
(define_insn "*movxfcc_1"
===================================================================
@@ -64,8 +64,7 @@ extern bool legitimate_pic_address_disp_
extern void print_reg (rtx, int, FILE*);
extern void ix86_print_operand (FILE *, rtx, int);
-extern void split_di (rtx[], int, rtx[], rtx[]);
-extern void split_ti (rtx[], int, rtx[], rtx[]);
+extern void split_double_mode (enum machine_mode, rtx[], int, rtx[], rtx[]);
extern const char *output_set_got (rtx, rtx);
extern const char *output_387_binary_op (rtx, rtx*);
===================================================================
@@ -13248,15 +13248,33 @@ i386_asm_output_addr_const_extra (FILE *
return true;
}
-/* Split one or more DImode RTL references into pairs of SImode
+/* Split one or more double-mode RTL references into pairs of half-mode
references. The RTL can be REG, offsettable MEM, integer constant, or
- CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
+ CONST_DOUBLE. "operands" is a pointer to an array of double-mode RTLs to
split and "num" is its length. lo_half and hi_half are output arrays
that parallel "operands". */
void
-split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
+split_double_mode (enum machine_mode mode, rtx operands[],
+ int num, rtx lo_half[], rtx hi_half[])
{
+ enum machine_mode half_mode;
+ unsigned int byte;
+
+ switch (mode)
+ {
+ case TImode:
+ half_mode = DImode;
+ break;
+ case DImode:
+ half_mode = SImode;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ byte = GET_MODE_SIZE (half_mode);
+
while (num--)
{
rtx op = operands[num];
@@ -13265,44 +13283,17 @@ split_di (rtx operands[], int num, rtx l
but we still have to handle it. */
if (MEM_P (op))
{
- lo_half[num] = adjust_address (op, SImode, 0);
- hi_half[num] = adjust_address (op, SImode, 4);
+ lo_half[num] = adjust_address (op, half_mode, 0);
+ hi_half[num] = adjust_address (op, half_mode, byte);
}
else
{
- lo_half[num] = simplify_gen_subreg (SImode, op,
+ lo_half[num] = simplify_gen_subreg (half_mode, op,
GET_MODE (op) == VOIDmode
- ? DImode : GET_MODE (op), 0);
- hi_half[num] = simplify_gen_subreg (SImode, op,
+ ? mode : GET_MODE (op), 0);
+ hi_half[num] = simplify_gen_subreg (half_mode, op,
GET_MODE (op) == VOIDmode
- ? DImode : GET_MODE (op), 4);
- }
- }
-}
-/* Split one or more TImode RTL references into pairs of DImode
- references. The RTL can be REG, offsettable MEM, integer constant, or
- CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
- split and "num" is its length. lo_half and hi_half are output arrays
- that parallel "operands". */
-
-void
-split_ti (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
-{
- while (num--)
- {
- rtx op = operands[num];
-
- /* simplify_subreg refuse to split volatile memory addresses, but we
- still have to handle it. */
- if (MEM_P (op))
- {
- lo_half[num] = adjust_address (op, DImode, 0);
- hi_half[num] = adjust_address (op, DImode, 8);
- }
- else
- {
- lo_half[num] = simplify_gen_subreg (DImode, op, TImode, 0);
- hi_half[num] = simplify_gen_subreg (DImode, op, TImode, 8);
+ ? mode : GET_MODE (op), byte);
}
}
}
@@ -16273,9 +16264,10 @@ ix86_expand_compare (enum rtx_code code,
void
ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
{
+ enum machine_mode mode = GET_MODE (op0);
rtx tmp;
- switch (GET_MODE (op0))
+ switch (mode)
{
case SFmode:
case DFmode:
@@ -16306,18 +16298,11 @@ ix86_expand_branch (enum rtx_code code,
tmp = op0, op0 = op1, op1 = tmp;
code = swap_condition (code);
}
- if (GET_MODE (op0) == DImode)
- {
- split_di (&op0, 1, lo+0, hi+0);
- split_di (&op1, 1, lo+1, hi+1);
- submode = SImode;
- }
- else
- {
- split_ti (&op0, 1, lo+0, hi+0);
- split_ti (&op1, 1, lo+1, hi+1);
- submode = DImode;
- }
+
+ split_double_mode (mode, &op0, 1, lo+0, hi+0);
+ split_double_mode (mode, &op1, 1, lo+1, hi+1);
+
+ submode = mode == DImode ? SImode : DImode;
/* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to
avoid two branches. This costs one extra insn, so disable when
@@ -16474,7 +16459,7 @@ ix86_expand_carry_flag_compare (enum rtx
enum machine_mode mode =
GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
- /* Do not handle DImode compares that go through special path. */
+ /* Do not handle double-mode compares that go through special path. */
if (mode == (TARGET_64BIT ? TImode : DImode))
return false;
@@ -17686,8 +17671,8 @@ ix86_expand_int_addcc (rtx operands[])
}
-/* Split operands 0 and 1 into SImode parts. Similar to split_di, but
- works for floating pointer parameters and nonoffsetable memories.
+/* Split operands 0 and 1 into half-mode parts. Similar to split_double_mode,
+ but works for floating pointer parameters and nonoffsetable memories.
For pushes, it returns just stack offsets; the values will be saved
in the right order. Maximally three parts are generated. */
@@ -17740,7 +17725,7 @@ ix86_split_to_parts (rtx operand, rtx *p
if (!TARGET_64BIT)
{
if (mode == DImode)
- split_di (&operand, 1, &parts[0], &parts[1]);
+ split_double_mode (mode, &operand, 1, &parts[0], &parts[1]);
else
{
int i;
@@ -17791,7 +17776,7 @@ ix86_split_to_parts (rtx operand, rtx *p
else
{
if (mode == TImode)
- split_ti (&operand, 1, &parts[0], &parts[1]);
+ split_double_mode (mode, &operand, 1, &parts[0], &parts[1]);
if (mode == XFmode || mode == TFmode)
{
enum machine_mode upper_mode = mode==XFmode ? SImode : DImode;
@@ -17862,7 +17847,7 @@ ix86_split_long_move (rtx operands[])
/* The DFmode expanders may ask us to move double.
For 64bit target this is single move. By hiding the fact
here we simplify i386.md splitters. */
- if (GET_MODE_SIZE (GET_MODE (operands[0])) == 8 && TARGET_64BIT)
+ if (TARGET_64BIT && GET_MODE_SIZE (GET_MODE (operands[0])) == 8)
{
/* Optimize constant pool reference to immediates. This is used by
fp moves, that force all constants to memory to allow combining. */
@@ -18104,7 +18089,7 @@ ix86_split_ashl (rtx *operands, rtx scra
if (CONST_INT_P (operands[2]))
{
- (mode == DImode ? split_di : split_ti) (operands, 2, low, high);
+ split_double_mode (mode, operands, 2, low, high);
count = INTVAL (operands[2]) & (single_width * 2 - 1);
if (count >= single_width)
@@ -18127,7 +18112,7 @@ ix86_split_ashl (rtx *operands, rtx scra
return;
}
- (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
+ split_double_mode (mode, operands, 1, low, high);
if (operands[1] == const1_rtx)
{
@@ -18204,7 +18189,7 @@ ix86_split_ashl (rtx *operands, rtx scra
if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]);
- (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
+ split_double_mode (mode, operands, 1, low, high);
emit_insn ((mode == DImode
? gen_x86_shld
: gen_x86_64_shld) (high[0], low[0], operands[2]));
@@ -18237,7 +18222,7 @@ ix86_split_ashr (rtx *operands, rtx scra
if (CONST_INT_P (operands[2]))
{
- (mode == DImode ? split_di : split_ti) (operands, 2, low, high);
+ split_double_mode (mode, operands, 2, low, high);
count = INTVAL (operands[2]) & (single_width * 2 - 1);
if (count == single_width * 2 - 1)
@@ -18281,7 +18266,7 @@ ix86_split_ashr (rtx *operands, rtx scra
if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]);
- (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
+ split_double_mode (mode, operands, 1, low, high);
emit_insn ((mode == DImode
? gen_x86_shrd
@@ -18318,7 +18303,7 @@ ix86_split_lshr (rtx *operands, rtx scra
if (CONST_INT_P (operands[2]))
{
- (mode == DImode ? split_di : split_ti) (operands, 2, low, high);
+ split_double_mode (mode, operands, 2, low, high);
count = INTVAL (operands[2]) & (single_width * 2 - 1);
if (count >= single_width)
@@ -18349,7 +18334,7 @@ ix86_split_lshr (rtx *operands, rtx scra
if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]);
- (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
+ split_double_mode (mode, operands, 1, low, high);
emit_insn ((mode == DImode
? gen_x86_shrd
@@ -26144,7 +26129,7 @@ ix86_force_to_memory (enum machine_mode
case DImode:
{
rtx operands[2];
- split_di (&operand, 1, operands, operands + 1);
+ split_double_mode (mode, &operand, 1, operands, operands + 1);
emit_insn (
gen_rtx_SET (VOIDmode,
gen_rtx_MEM (SImode,