Patch for effecient encoding of test instruction

Jan Hubicka hubicka@atrey.karlin.mff.cuni.cz
Mon Apr 12 06:41:00 GMT 1999


Hi
While waiting for decision about reg-stack format I've decided to look
at my old i386.md changes, split out those that are trivial and helpfull
and try to get them into egcs-1.2.

So hope this patch will get in smoothly :)

It changes encoding of test instruction in two ways. It takes into account,
that testl imm, eax instruction is much faster on pentium than testb or testw.
(due to bug in prediction logic)
It also changes encoding of test instruction in conditional jumps often
genrated by -mno-ieee-fp compilation to use byte instead of long type
on non pentium CPUs. This makes code shorter and avoids partial register
stalls on PPro.

There is common solution for Pentium and PentiumPro recomended by intel
manual to use AND insn for this. But we can't model this case correctly
with current i386.md file.

Mon Apr 12 15:36:04 MET DST 1999 Jan Hubicka <hubicka@freesoft.cz>

	* i386.md: Avoid outputing non-pariable testw and testl on Pentium.
	Use shorter opcode for testing flags stored in EAX.

*** i386.md.old	Mon Apr 12 15:09:18 1999
--- i386.md	Mon Apr 12 15:24:28 1999
***************
*** 767,773 ****
    /* For small integers, we may actually use testb. */
    if (GET_CODE (operands[1]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
!       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
      {
        /* We may set the sign bit spuriously.  */
  
--- 767,776 ----
    /* For small integers, we may actually use testb. */
    if (GET_CODE (operands[1]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
!       && (! REG_P (operands[0]) || QI_REG_P (operands[0]))
!       /* A Pentium test is pairable only with eax. Not with ah or al.  */
!       && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
!           || optimize_size))
      {
        /* We may set the sign bit spuriously.  */
  
*************** byte_xor_operation:
*** 5562,5568 ****
    mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
    operands[1] = GEN_INT (mask);
  
!   if (QI_REG_P (operands[0]))
      {
        if ((mask & ~0xff) == 0)
          {
--- 5565,5574 ----
    mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
    operands[1] = GEN_INT (mask);
  
!   if (QI_REG_P (operands[0])
!       /* A Pentium test is pairable only with eax. Not with ah or al.  */
!       && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
!           || optimize_size))
      {
        if ((mask & ~0xff) == 0)
          {
*************** byte_xor_operation:
*** 5596,5602 ****
    mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
    operands[1] = GEN_INT (mask);
  
!   if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
      {
        if ((mask & ~0xff) == 0)
          {
--- 5602,5611 ----
    mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
    operands[1] = GEN_INT (mask);
  
!   if (! REG_P (operands[0]) || QI_REG_P (operands[0])
!       /* A Pentium test is pairable only with eax. Not with ah or al.  */
!       && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
!           || optimize_size))
      {
        if ((mask & ~0xff) == 0)
          {
*************** byte_xor_operation:
*** 5775,5782 ****
  	default:
  	  abort ();
  	}
!       operands[3] = GEN_INT (c);
!       output_asm_insn (AS2 (testl,%3,%2), operands);
        return eq ? AS1 (sete,%0) : AS1 (setne, %0);
      }
  
--- 5784,5799 ----
  	default:
  	  abort ();
  	}
!       if (!TARGET_PENTIUM || optimize_size)
!         {
!           operands[3] = GEN_INT (c >> 8);
!           output_asm_insn (AS2 (test%B0,%3,%h2), operands);
!         }
!       else
!         {
!           operands[3] = GEN_INT (c);
!           output_asm_insn (AS2 (test%L0,%3,%2), operands);
!         }
        return eq ? AS1 (sete,%0) : AS1 (setne, %0);
      }
  
*************** byte_xor_operation:
*** 5952,5959 ****
  	default:
  	  abort ();
  	}
!       operands[3] = GEN_INT (c);
!       output_asm_insn (AS2 (testl,%3,%2), operands);
        return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
      }
    if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
--- 5969,5984 ----
  	default:
  	  abort ();
  	}
!       if (!TARGET_PENTIUM || optimize_size)
!         {
!           operands[3] = GEN_INT (c >> 8);
!           output_asm_insn (AS2 (test%B0,%3,%h2), operands);
!         }
!       else
!         {
!           operands[3] = GEN_INT (c);
!           output_asm_insn (AS2 (test%L0,%3,%2), operands);
!         }
        return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
      }
    if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
*************** byte_xor_operation:
*** 6006,6013 ****
  	default:
  	  abort ();
  	}
!       operands[3] = GEN_INT (c);
!       output_asm_insn (AS2 (testl,%3,%2), operands);
        return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
      }
    if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
--- 6031,6046 ----
  	default:
  	  abort ();
  	}
!       if (!TARGET_PENTIUM || optimize_size)
!         {
!           operands[3] = GEN_INT (c >> 8);
!           output_asm_insn (AS2 (test%B0,%3,%h2), operands);
!         }
!       else
!         {
!           operands[3] = GEN_INT (c);
!           output_asm_insn (AS2 (test%L0,%3,%2), operands);
!         }
        return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
      }
    if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))


More information about the Gcc-patches mailing list