loepere@WOMBAT.WESTFORD.CCUR.COM (09/19/89)
I believe that the following set of changes corrects support for "long
long" on Mips. (By the way, when building gnulib2, the Makefile line
invoking gcc should name ./gcc.) These changes are for gcc-1.35.98. -
Keith
- New definition of movdi (I should do some combination with logic in
movsi some day):
(define_insn "movdi"
[(set (match_operand:DI 0 "general_operand" "=r,*r,*m,*r,*r")
(match_operand:DI 1 "general_operand" "r,*m,*r,J,i"))]
""
"*
{
extern rtx adj_offsettable_operand ();
switch (which_alternative)
{
case 0:
{
rtx xops[2];
if (REGNO (operands[0]) != (REGNO (operands[1]) +1))
{
/* TAKE CARE OF OVERLAPS */
xops[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
xops[1] = gen_rtx (REG, SImode, REGNO (operands[1]));
output_asm_insn (\"add%:\\t%0,$0,%1\\t#movdi %1 -> %0\", xops);
xops[0] = gen_rtx (REG, SImode, REGNO (xops[0])+1);
xops[1] = gen_rtx (REG, SImode, REGNO (xops[1])+1);
output_asm_insn (\"add%:\\t%0,$0,%1\\t#movdi %1 -> %0\", xops);
}
else
{
/* TAKE CARE OF OVERLAPS */
xops[0] = gen_rtx (REG, SImode, REGNO (operands[0])+1);
xops[1] = gen_rtx (REG, SImode, REGNO (operands[1])+1);
output_asm_insn (\"add%:\\t%0,$0,%1\\t#movdi %1 -> %0\", xops);
xops[0] = gen_rtx (REG, SImode, REGNO (xops[0])-1);
xops[1] = gen_rtx (REG, SImode, REGNO (xops[1])-1);
output_asm_insn (\"add%:\\t%0,$0,%1\\t#movdi %1 -> %0\", xops);
}
break;
}
case 1:
{
/* No overlap here */
rtx xops[2];
xops[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
if (GET_CODE (operands[1]) == MEM)
xops[1] = gen_rtx (MEM, SImode, XEXP (operands[1], 0));
else abort ();
output_asm_insn (\"lw\\t%0,%1\\t#movdi %1 (mem) -> %0\", xops);
xops[0] = gen_rtx (REG, SImode, REGNO (operands[0])+1);
xops[1] = adj_offsettable_operand (xops[1], 4);
output_asm_insn (\"lw\\t%0,%1\\t#movdi %1(mem) -> %0\", xops);
break;
}
case 2:
{
/* No overlap here */
rtx xops[2];
xops[1] = gen_rtx (REG, SImode, REGNO (operands[1]));
if (GET_CODE (operands[0]) == MEM)
xops[0] = gen_rtx (MEM, SImode, XEXP (operands[0], 0));
else abort ();
output_asm_insn (\"sw\\t%1,%0\\t#movdi %1 -> %0(mem)\", xops);
xops[1] = gen_rtx (REG, SImode, REGNO (operands[1])+1);
xops[0] = adj_offsettable_operand (xops[0], 4);
output_asm_insn (\"sw\\t%1,%0\\t#movdi %1 -> %0 (mem)\", xops);
break;
}
case 3:
{
/* No overlap here */
rtx xops[1];
xops[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
output_asm_insn (\"add%:\\t%0,$0,$0\\t#movdi\\t0 -> %0\", xops);
xops[0] = gen_rtx (REG, SImode, REGNO (operands[0])+1);
output_asm_insn (\"add%:\\t%0,$0,$0\\t#movdi\\t0 -> %0\", xops);
break;
}
case 4:
{
/* No overlap here */
rtx xops[3];
switch (GET_CODE (operands[1]))
{
case CONST_INT:
case CONST_DOUBLE:
{
int values[2];
short half;
if (GET_CODE (operands[1]) == CONST_INT)
{
values[0] = 0;
values[1] = INTVAL (operands[1]);
}
else
{
values[0] = CONST_DOUBLE_HIGH (operands[1]);
values[1] = CONST_DOUBLE_LOW (operands[1]);
}
for (half = 0; half <= 1; half++)
{
xops[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + half);
if (values[half] == 0)
output_asm_insn (\"add%:\\t%0,$0,$0\\t#movdi\\t0 -> %0\", xops);
else
{
xops[2] = gen_rtx (CONST_INT, VOIDmode, values[half]);
if ((values[half] >> 16)
&& (values[half] & 0xffff))
{
if (!((-values[half]) >> 16))
{
xops[1] = gen_rtx (CONST_INT, VOIDmode,
values[half] & 0xffff);
output_asm_insn (\"addi%:\\t%0,$0,%x1\\t#movdi low part of %2\",
xops);
}
else
{
xops[1] = gen_rtx (CONST_INT, VOIDmode,
values[half]>>16);
output_asm_insn (\"lui\\t%0,%x1\\t#movdi high part of %2\", xops);
xops[1] = gen_rtx (CONST_INT, VOIDmode,
values[half] & 0xffff);
output_asm_insn (\"ori\\t%0,%x1\\t#movdi low part of %2\", xops);
}
}
else if (values[half] >> 16)
{
xops[1] = gen_rtx (CONST_INT, VOIDmode,
values[half]>>16);
output_asm_insn (\"lui\\t%0,%x1\\t#movdi high part of %2\", xops);
}
else
{
xops[1] = gen_rtx (CONST_INT, VOIDmode,
values[half] & 0xffff);
output_asm_insn (\"ori\\t%0,$0,%x1\\t#movdi low part of %2\",
xops);
}
}
}
break;
}
case SYMBOL_REF:
case LABEL_REF:
case CONST:
{
xops[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
output_asm_insn (\"add%:\\t%0,$0,$0\\t#movdi\\t0 -> %0\", xops);
xops[0] = gen_rtx (REG, SImode, REGNO (operands[0])+1);
xops[1] = operands[1];
output_asm_insn (\"la\\t%0,%a1\\t#movdi %a1 -> %0\", xops);
break;
}
default:
abort ();
}
break;
}
}
return \"\";
}")
- Also, remove the extra assignment to xops[1] toward the end of movsi:
(INTVAL (operands[1]))>>16);
output_asm_insn (\"lui\\t%0,%x1\\t#movsi high part of %2\", xops);
- xops[1] = gen_rtx (CONST_INT, VOIDmode,
- (INTVAL (operands[1])) & 0xffff);
}
else
- Diffs to out-mips.c:
***************
*** 133,138
static struct
{
! enum arg_state nxs_if_f, nxs_if_g;
! short reg_if_f, reg_if_g;
}
arg_state_table[(int) (ARG_STA_GGGG + 1)] = ARG_STA_AUTOMA;
--- 133,138 -----
static struct
{
! enum arg_state nxs_if_f, nxs_if_g, nxs_if_d;
! short reg_if_f, reg_if_g, reg_if_d;
}
arg_state_table[(int) (ARG_STA_DD + 1)] = ARG_STA_AUTOMA;
***************
*** 136,140
short reg_if_f, reg_if_g;
}
! arg_state_table[(int) (ARG_STA_GGGG + 1)] = ARG_STA_AUTOMA;
--- 136,140 -----
short reg_if_f, reg_if_g, reg_if_d;
}
! arg_state_table[(int) (ARG_STA_DD + 1)] = ARG_STA_AUTOMA;
***************
*** 154,158
= (FP_REGS == PREFERRED_RELOAD_CLASS_FM (mode, GR_REGS)
? arg_state_table[(int)((cum->arg_rec_state))].nxs_if_f
! : arg_state_table[(int)((cum->arg_rec_state))].nxs_if_g);
(cum->arg_num)++;
--- 154,160 -----
= (FP_REGS == PREFERRED_RELOAD_CLASS_FM (mode, GR_REGS)
? arg_state_table[(int)((cum->arg_rec_state))].nxs_if_f
! : ((mode == DImode)
! ? arg_state_table[(int)((cum->arg_rec_state))].nxs_if_d
! : arg_state_table[(int)((cum->arg_rec_state))].nxs_if_g));
(cum->arg_num)++;
***************
*** 171,175
= (FP_REGS == PREFERRED_RELOAD_CLASS_FM (mode, GR_REGS)
? arg_state_table[(int)((cum->arg_rec_state))].reg_if_f
! : arg_state_table[(int)((cum->arg_rec_state))].reg_if_g);
if (mode == BLKmode)
--- 173,179 -----
= (FP_REGS == PREFERRED_RELOAD_CLASS_FM (mode, GR_REGS)
? arg_state_table[(int)((cum->arg_rec_state))].reg_if_f
! : ((mode == DImode)
! ? arg_state_table[(int)((cum->arg_rec_state))].reg_if_d
! : arg_state_table[(int)((cum->arg_rec_state))].reg_if_g));
if (mode == BLKmode)
- Diffs to tm-mips.h:
***************
*** 680,716
/* 's book page D-22 */
! #define CUMULATIVE_ARGS struct { enum arg_state arg_rec_state;int restype,arg_num;}
enum arg_state { ARG_STA_INIT =0,
ARG_STA_F =1, /* $f12 */
ARG_STA_FF =2, /* $f12 $f14 */
ARG_STA_FG =3, /* $f12 $6 */
! ARG_STA_FGG =4, /* $f12 $6 $7 */
! ARG_STA_FGF =5, /* $f12 $6 STACK */
! ARG_STA_G =6, /* $4 */
! ARG_STA_GF =7, /* $4 ($6,$7) */
! ARG_STA_GG =8, /* $4 $5 */
! ARG_STA_GGF =9, /* $4 $5 ($6,$7) */
! ARG_STA_GGG =10,/* $4 $5 $6 */
! ARG_STA_GGGF =11,/* $4 $5 $6 STACK */
! ARG_STA_GGGG =12 /* $4 $5 $6 $7 */
};
#define ARG_STA_AUTOMA \
{ \
! {ARG_STA_F,ARG_STA_G,44,4 }, /* ARG_STA_INIT */ \
! {ARG_STA_FF,ARG_STA_FG,46,6 }, /* ARG_STA_F */ \
! {ARG_STA_FF,ARG_STA_FF,-1,-1 }, /* ARG_STA_FF */ \
! {ARG_STA_FGF,ARG_STA_FGG,-1,7 }, /* ARG_STA_FG */ \
! {ARG_STA_FGG,ARG_STA_FGG,-1,-1 }, /* ARG_STA_FGG */ \
! {ARG_STA_FGF,ARG_STA_FGF,-1,-1 }, /* ARG_STA_FGF */ \
! {ARG_STA_GF,ARG_STA_GG,-2,5 }, /* ARG_STA_G */ \
! {ARG_STA_GF,ARG_STA_GF,-1,-1 }, /* ARG_STA_GF */ \
! {ARG_STA_GGF,ARG_STA_GGG,-2,6 }, /* ARG_STA_GG */ \
! {ARG_STA_GGF,ARG_STA_GGF,-1,-1 }, /* ARG_STA_GGF */ \
! {ARG_STA_GGGF,ARG_STA_GGGG,-1,7 }, /* ARG_STA_GGG */ \
! {ARG_STA_GGGF,ARG_STA_GGGF,-1,-1 }, /* ARG_STA_GGGF */ \
! {ARG_STA_GGGG,ARG_STA_GGGG,-1,-1 } /* ARG_STA_GGGG */ \
}
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
--- 680,746 -----
/* 's book page D-22 */
! #define CUMULATIVE_ARGS cumulative_args_t
+ /* F means that a floating point (single or double) value was encountered;
+ G means a general value (<= 32 bits) and D means a long long (double) value. */
+
enum arg_state { ARG_STA_INIT =0,
ARG_STA_F =1, /* $f12 */
ARG_STA_FF =2, /* $f12 $f14 */
ARG_STA_FG =3, /* $f12 $6 */
! ARG_STA_FGF =4, /* $f12 $6 STACK */
! ARG_STA_FGG =5, /* $f12 $6 $7 */
! ARG_STA_FGD =6, /* $f12 $6 STACK */
! ARG_STA_FD =7, /* $f12 ($6,$7) */
! ARG_STA_G =8, /* $4 */
! ARG_STA_GF =9, /* $4 ($6,$7) */
! ARG_STA_GG =10,/* $4 $5 */
! ARG_STA_GGF =11,/* $4 $5 ($6,$7) */
! ARG_STA_GGG =12,/* $4 $5 $6 */
! ARG_STA_GGGF =13,/* $4 $5 $6 STACK */
! ARG_STA_GGGG =14,/* $4 $5 $6 $7 */
! ARG_STA_GGGD =15,/* $4 $5 $6 STACK */
! ARG_STA_GGD =16,/* $4 $5 ($6,$7) */
! ARG_STA_GD =17,/* $4 ($6,$7) */
! ARG_STA_D =18,/* ($4,$5) */
! ARG_STA_DF =19,/* ($4,$5) ($6,$7) */
! ARG_STA_DG =20,/* ($4,$5) $6 */
! ARG_STA_DGF =21,/* ($4,$5) $6 STACK */
! ARG_STA_DGG =22,/* ($4,$5) $6 $7 */
! ARG_STA_DGD =23,/* ($4,$5) $6 STACK */
! ARG_STA_DD =24 /* ($4,$5) ($6,$7) */
};
+
#define ARG_STA_AUTOMA \
{ \
! {ARG_STA_F,ARG_STA_G,ARG_STA_D,44,4,4}, /* ARG_STA_INIT */ \
! {ARG_STA_FF,ARG_STA_FG,ARG_STA_FD,46,6,6}, /* ARG_STA_F */ \
! {ARG_STA_FF,ARG_STA_FF,ARG_STA_FF,-1,-1,-1}, /* ARG_STA_FF */ \
! {ARG_STA_FGF,ARG_STA_FGG,ARG_STA_FGD,-1,7,-1}, /* ARG_STA_FG */ \
! {ARG_STA_FGF,ARG_STA_FGF,ARG_STA_FGF,-1,-1,-1}, /* ARG_STA_FGF */ \
! {ARG_STA_FGG,ARG_STA_FGG,ARG_STA_FGG,-1,-1,-1}, /* ARG_STA_FGG */ \
! {ARG_STA_FGD,ARG_STA_FGD,ARG_STA_FGD,-1,-1,-1}, /* ARG_STA_FGD */ \
! {ARG_STA_FD,ARG_STA_FD,ARG_STA_FD,-1,-1,-1}, /* ARG_STA_FD */ \
! {ARG_STA_GF,ARG_STA_GG,ARG_STA_GD,-2,5,6}, /* ARG_STA_G */ \
! {ARG_STA_GF,ARG_STA_GF,ARG_STA_GF,-1,-1,-1}, /* ARG_STA_GF */ \
! {ARG_STA_GGF,ARG_STA_GGG,ARG_STA_GGD,-2,6,6}, /* ARG_STA_GG */ \
! {ARG_STA_GGF,ARG_STA_GGF,ARG_STA_GGF,-1,-1,-1}, /* ARG_STA_GGF */ \
! {ARG_STA_GGGF,ARG_STA_GGGG,ARG_STA_GGGD,-1,7,-1}, /* ARG_STA_GGG */ \
! {ARG_STA_GGGF,ARG_STA_GGGF,ARG_STA_GGGF,-1,-1,-1}, /* ARG_STA_GGGF */ \
! {ARG_STA_GGGG,ARG_STA_GGGG,ARG_STA_GGGG,-1,-1,-1}, /* ARG_STA_GGGG */ \
! {ARG_STA_GGGD,ARG_STA_GGGD,ARG_STA_GGGD,-1,-1,-1}, /* ARG_STA_GGGD */ \
! {ARG_STA_GGD,ARG_STA_GGD,ARG_STA_GGD,-1,-1,-1}, /* ARG_STA_GGD */ \
! {ARG_STA_GD,ARG_STA_GD,ARG_STA_GD,-1,-1,-1}, /* ARG_STA_GD */ \
! {ARG_STA_DF,ARG_STA_DG,ARG_STA_DD,-2,6,6}, /* ARG_STA_D */ \
! {ARG_STA_DF,ARG_STA_DF,ARG_STA_DF,-1,-1,-1}, /* ARG_STA_DF */ \
! {ARG_STA_DGF,ARG_STA_DGG,ARG_STA_DGD,-1,7,-1}, /* ARG_STA_DG */ \
! {ARG_STA_DGF,ARG_STA_DGF,ARG_STA_DGF,-1,-1,-1}, /* ARG_STA_DGF */ \
! {ARG_STA_DGG,ARG_STA_DGG,ARG_STA_DGG,-1,-1,-1}, /* ARG_STA_DGG */ \
! {ARG_STA_DGD,ARG_STA_DGD,ARG_STA_DGD,-1,-1,-1}, /* ARG_STA_DGD */ \
! {ARG_STA_DD,ARG_STA_DD,ARG_STA_DD,-1,-1,-1} /* ARG_STA_DD */ \
}
+ typedef struct { enum arg_state arg_rec_state;int restype,arg_num;} cumulative_args_t;
+
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.