Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 349691
Collapse All | Expand All

(-)branches/gcc-4_4-branch/gcc/config/pa/pa.c (-37 / +144 lines)
Lines 6118-6123 Link Here
6118
    }
6118
    }
6119
}
6119
}
6120
6120
6121
/* Return TRUE if INSN, a jump insn, has an unfilled delay slot and
6122
   it branches into the delay slot.  Otherwise, return FALSE.  */
6123
6124
static bool
6125
branch_to_delay_slot_p (rtx insn)
6126
{
6127
  rtx jump_insn;
6128
6129
  if (dbr_sequence_length ())
6130
    return FALSE;
6131
6132
  jump_insn = next_active_insn (JUMP_LABEL (insn));
6133
  while (insn)
6134
    {
6135
      insn = next_active_insn (insn);
6136
      if (jump_insn == insn)
6137
	return TRUE;
6138
6139
      /* We can't rely on the length of asms.  So, we return FALSE when
6140
	 the branch is followed by an asm.  */
6141
      if (!insn
6142
	  || GET_CODE (PATTERN (insn)) == ASM_INPUT
6143
	  || asm_noperands (PATTERN (insn)) >= 0
6144
	  || get_attr_length (insn) > 0)
6145
	break;
6146
    }
6147
6148
  return FALSE;
6149
}
6150
6151
/* Return TRUE if INSN, a forward jump insn, needs a nop in its delay slot.
6152
6153
   This occurs when INSN has an unfilled delay slot and is followed
6154
   by an asm.  Disaster can occur if the asm is empty and the jump
6155
   branches into the delay slot.  So, we add a nop in the delay slot
6156
   when this occurs.  */
6157
6158
static bool
6159
branch_needs_nop_p (rtx insn)
6160
{
6161
  rtx jump_insn;
6162
6163
  if (dbr_sequence_length ())
6164
    return FALSE;
6165
6166
  jump_insn = next_active_insn (JUMP_LABEL (insn));
6167
  while (insn)
6168
    {
6169
      insn = next_active_insn (insn);
6170
      if (!insn || jump_insn == insn)
6171
	return TRUE;
6172
6173
      if (!(GET_CODE (PATTERN (insn)) == ASM_INPUT
6174
	   || asm_noperands (PATTERN (insn)) >= 0)
6175
	  && get_attr_length (insn) > 0)
6176
	break;
6177
    }
6178
6179
  return FALSE;
6180
}
6181
6182
/* Return TRUE if INSN, a forward jump insn, can use nullification
6183
   to skip the following instruction.  This avoids an extra cycle due
6184
   to a mis-predicted branch when we fall through.  */
6185
6186
static bool
6187
use_skip_p (rtx insn)
6188
{
6189
  rtx jump_insn = next_active_insn (JUMP_LABEL (insn));
6190
6191
  while (insn)
6192
    {
6193
      insn = next_active_insn (insn);
6194
6195
      /* We can't rely on the length of asms, so we can't skip asms.  */
6196
      if (!insn
6197
	  || GET_CODE (PATTERN (insn)) == ASM_INPUT
6198
	  || asm_noperands (PATTERN (insn)) >= 0)
6199
	break;
6200
      if (get_attr_length (insn) == 4
6201
	  && jump_insn == next_active_insn (insn))
6202
	return TRUE;
6203
      if (get_attr_length (insn) > 0)
6204
	break;
6205
    }
6206
6207
  return FALSE;
6208
}
6209
6121
/* This routine handles all the normal conditional branch sequences we
6210
/* This routine handles all the normal conditional branch sequences we
6122
   might need to generate.  It handles compare immediate vs compare
6211
   might need to generate.  It handles compare immediate vs compare
6123
   register, nullification of delay slots, varying length branches,
6212
   register, nullification of delay slots, varying length branches,
Lines 6129-6135 Link Here
6129
output_cbranch (rtx *operands, int negated, rtx insn)
6218
output_cbranch (rtx *operands, int negated, rtx insn)
6130
{
6219
{
6131
  static char buf[100];
6220
  static char buf[100];
6132
  int useskip = 0;
6221
  bool useskip;
6133
  int nullify = INSN_ANNULLED_BRANCH_P (insn);
6222
  int nullify = INSN_ANNULLED_BRANCH_P (insn);
6134
  int length = get_attr_length (insn);
6223
  int length = get_attr_length (insn);
6135
  int xdelay;
6224
  int xdelay;
Lines 6143-6149 Link Here
6143
     slot and the same branch target as this branch.  We could check
6232
     slot and the same branch target as this branch.  We could check
6144
     for this but jump optimization should eliminate nop jumps.  It
6233
     for this but jump optimization should eliminate nop jumps.  It
6145
     is always safe to emit a nop.  */
6234
     is always safe to emit a nop.  */
6146
  if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
6235
  if (branch_to_delay_slot_p (insn))
6147
    return "nop";
6236
    return "nop";
6148
6237
6149
  /* The doubleword form of the cmpib instruction doesn't have the LEU
6238
  /* The doubleword form of the cmpib instruction doesn't have the LEU
Lines 6167-6178 Link Here
6167
  /* A forward branch over a single nullified insn can be done with a
6256
  /* A forward branch over a single nullified insn can be done with a
6168
     comclr instruction.  This avoids a single cycle penalty due to
6257
     comclr instruction.  This avoids a single cycle penalty due to
6169
     mis-predicted branch if we fall through (branch not taken).  */
6258
     mis-predicted branch if we fall through (branch not taken).  */
6170
  if (length == 4
6259
  useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE;
6171
      && next_real_insn (insn) != 0
6172
      && get_attr_length (next_real_insn (insn)) == 4
6173
      && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
6174
      && nullify)
6175
    useskip = 1;
6176
6260
6177
  switch (length)
6261
  switch (length)
6178
    {
6262
    {
Lines 6192-6198 Link Here
6192
	if (useskip)
6276
	if (useskip)
6193
	  strcat (buf, " %2,%r1,%%r0");
6277
	  strcat (buf, " %2,%r1,%%r0");
6194
	else if (nullify)
6278
	else if (nullify)
6195
	  strcat (buf, ",n %2,%r1,%0");
6279
	  {
6280
	    if (branch_needs_nop_p (insn))
6281
	      strcat (buf, ",n %2,%r1,%0%#");
6282
	    else
6283
	      strcat (buf, ",n %2,%r1,%0");
6284
	  }
6196
	else
6285
	else
6197
	  strcat (buf, " %2,%r1,%0");
6286
	  strcat (buf, " %2,%r1,%0");
6198
	break;
6287
	break;
Lines 6455-6461 Link Here
6455
output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
6544
output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
6456
{
6545
{
6457
  static char buf[100];
6546
  static char buf[100];
6458
  int useskip = 0;
6547
  bool useskip;
6459
  int nullify = INSN_ANNULLED_BRANCH_P (insn);
6548
  int nullify = INSN_ANNULLED_BRANCH_P (insn);
6460
  int length = get_attr_length (insn);
6549
  int length = get_attr_length (insn);
6461
  int xdelay;
6550
  int xdelay;
Lines 6465-6471 Link Here
6465
     is only used when optimizing; jump optimization should eliminate the
6555
     is only used when optimizing; jump optimization should eliminate the
6466
     jump.  But be prepared just in case.  */
6556
     jump.  But be prepared just in case.  */
6467
6557
6468
  if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
6558
  if (branch_to_delay_slot_p (insn))
6469
    return "nop";
6559
    return "nop";
6470
6560
6471
  /* If this is a long branch with its delay slot unfilled, set `nullify'
6561
  /* If this is a long branch with its delay slot unfilled, set `nullify'
Lines 6481-6493 Link Here
6481
  /* A forward branch over a single nullified insn can be done with a
6580
  /* A forward branch over a single nullified insn can be done with a
6482
     extrs instruction.  This avoids a single cycle penalty due to
6581
     extrs instruction.  This avoids a single cycle penalty due to
6483
     mis-predicted branch if we fall through (branch not taken).  */
6582
     mis-predicted branch if we fall through (branch not taken).  */
6484
6583
  useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE;
6485
  if (length == 4
6486
      && next_real_insn (insn) != 0
6487
      && get_attr_length (next_real_insn (insn)) == 4
6488
      && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
6489
      && nullify)
6490
    useskip = 1;
6491
6584
6492
  switch (length)
6585
  switch (length)
6493
    {
6586
    {
Lines 6511-6521 Link Here
6511
	if (useskip)
6594
	if (useskip)
6512
	  strcat (buf, " %0,%1,1,%%r0");
6595
	  strcat (buf, " %0,%1,1,%%r0");
6513
	else if (nullify && negated)
6596
	else if (nullify && negated)
6514
	  strcat (buf, ",n %0,%1,%3");
6597
	  {
6598
	    if (branch_needs_nop_p (insn))
6599
	      strcat (buf, ",n %0,%1,%3%#");
6600
	    else
6601
	      strcat (buf, ",n %0,%1,%3");
6602
	  }
6515
	else if (nullify && ! negated)
6603
	else if (nullify && ! negated)
6516
	  strcat (buf, ",n %0,%1,%2");
6604
	  {
6605
	    if (branch_needs_nop_p (insn))
6606
	      strcat (buf, ",n %0,%1,%2%#");
6607
	    else
6608
	      strcat (buf, ",n %0,%1,%2");
6609
	  }
6517
	else if (! nullify && negated)
6610
	else if (! nullify && negated)
6518
	  strcat (buf, "%0,%1,%3");
6611
	  strcat (buf, " %0,%1,%3");
6519
	else if (! nullify && ! negated)
6612
	else if (! nullify && ! negated)
6520
	  strcat (buf, " %0,%1,%2");
6613
	  strcat (buf, " %0,%1,%2");
6521
	break;
6614
	break;
Lines 6636-6642 Link Here
6636
output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
6729
output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
6637
{
6730
{
6638
  static char buf[100];
6731
  static char buf[100];
6639
  int useskip = 0;
6732
  bool useskip;
6640
  int nullify = INSN_ANNULLED_BRANCH_P (insn);
6733
  int nullify = INSN_ANNULLED_BRANCH_P (insn);
6641
  int length = get_attr_length (insn);
6734
  int length = get_attr_length (insn);
6642
  int xdelay;
6735
  int xdelay;
Lines 6646-6652 Link Here
6646
     is only used when optimizing; jump optimization should eliminate the
6739
     is only used when optimizing; jump optimization should eliminate the
6647
     jump.  But be prepared just in case.  */
6740
     jump.  But be prepared just in case.  */
6648
6741
6649
  if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
6742
  if (branch_to_delay_slot_p (insn))
6650
    return "nop";
6743
    return "nop";
6651
6744
6652
  /* If this is a long branch with its delay slot unfilled, set `nullify'
6745
  /* If this is a long branch with its delay slot unfilled, set `nullify'
Lines 6662-6674 Link Here
6662
  /* A forward branch over a single nullified insn can be done with a
6755
  /* A forward branch over a single nullified insn can be done with a
6663
     extrs instruction.  This avoids a single cycle penalty due to
6756
     extrs instruction.  This avoids a single cycle penalty due to
6664
     mis-predicted branch if we fall through (branch not taken).  */
6757
     mis-predicted branch if we fall through (branch not taken).  */
6665
6758
  useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE;
6666
  if (length == 4
6667
      && next_real_insn (insn) != 0
6668
      && get_attr_length (next_real_insn (insn)) == 4
6669
      && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
6670
      && nullify)
6671
    useskip = 1;
6672
6759
6673
  switch (length)
6760
  switch (length)
6674
    {
6761
    {
Lines 6692-6702 Link Here
6692
	if (useskip)
6779
	if (useskip)
6693
	  strcat (buf, "{ %0,1,%%r0| %0,%%sar,1,%%r0}");
6780
	  strcat (buf, "{ %0,1,%%r0| %0,%%sar,1,%%r0}");
6694
	else if (nullify && negated)
6781
	else if (nullify && negated)
6695
	  strcat (buf, "{,n %0,%3|,n %0,%%sar,%3}");
6782
	  {
6783
	    if (branch_needs_nop_p (insn))
6784
	      strcat (buf, "{,n %0,%3%#|,n %0,%%sar,%3%#}");
6785
	    else
6786
	      strcat (buf, "{,n %0,%3|,n %0,%%sar,%3}");
6787
	  }
6696
	else if (nullify && ! negated)
6788
	else if (nullify && ! negated)
6697
	  strcat (buf, "{,n %0,%2|,n %0,%%sar,%2}");
6789
	  {
6790
	    if (branch_needs_nop_p (insn))
6791
	      strcat (buf, "{,n %0,%2%#|,n %0,%%sar,%2%#}");
6792
	    else
6793
	      strcat (buf, "{,n %0,%2|,n %0,%%sar,%2}");
6794
	  }
6698
	else if (! nullify && negated)
6795
	else if (! nullify && negated)
6699
	  strcat (buf, "{%0,%3|%0,%%sar,%3}");
6796
	  strcat (buf, "{ %0,%3| %0,%%sar,%3}");
6700
	else if (! nullify && ! negated)
6797
	else if (! nullify && ! negated)
6701
	  strcat (buf, "{ %0,%2| %0,%%sar,%2}");
6798
	  strcat (buf, "{ %0,%2| %0,%%sar,%2}");
6702
	break;
6799
	break;
Lines 6818-6824 Link Here
6818
  /* A conditional branch to the following instruction (e.g. the delay slot) is
6915
  /* A conditional branch to the following instruction (e.g. the delay slot) is
6819
     asking for a disaster.  Be prepared!  */
6916
     asking for a disaster.  Be prepared!  */
6820
6917
6821
  if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
6918
  if (branch_to_delay_slot_p (insn))
6822
    {
6919
    {
6823
      if (which_alternative == 0)
6920
      if (which_alternative == 0)
6824
	return "ldo %1(%0),%0";
6921
	return "ldo %1(%0),%0";
Lines 6855-6861 Link Here
6855
	{
6952
	{
6856
	case 4:
6953
	case 4:
6857
	  if (nullify)
6954
	  if (nullify)
6858
	    return "addib,%C2,n %1,%0,%3";
6955
	    {
6956
	      if (branch_needs_nop_p (insn))
6957
		return "addib,%C2,n %1,%0,%3%#";
6958
	      else
6959
		return "addib,%C2,n %1,%0,%3";
6960
	    }
6859
	  else
6961
	  else
6860
	    return "addib,%C2 %1,%0,%3";
6962
	    return "addib,%C2 %1,%0,%3";
6861
      
6963
      
Lines 6963-6969 Link Here
6963
  /* A conditional branch to the following instruction (e.g. the delay slot) is
7065
  /* A conditional branch to the following instruction (e.g. the delay slot) is
6964
     asking for a disaster.  Be prepared!  */
7066
     asking for a disaster.  Be prepared!  */
6965
7067
6966
  if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
7068
  if (branch_to_delay_slot_p (insn))
6967
    {
7069
    {
6968
      if (which_alternative == 0)
7070
      if (which_alternative == 0)
6969
	return "copy %1,%0";
7071
	return "copy %1,%0";
Lines 7001-7007 Link Here
7001
	{
7103
	{
7002
	case 4:
7104
	case 4:
7003
	  if (nullify)
7105
	  if (nullify)
7004
	    return "movb,%C2,n %1,%0,%3";
7106
	    {
7107
	      if (branch_needs_nop_p (insn))
7108
		return "movb,%C2,n %1,%0,%3%#";
7109
	      else
7110
		return "movb,%C2,n %1,%0,%3";
7111
	    }
7005
	  else
7112
	  else
7006
	    return "movb,%C2 %1,%0,%3";
7113
	    return "movb,%C2 %1,%0,%3";
7007
7114

Return to bug 349691