Hi Jeff, Hi Alex,

  Whilst working with the AM33 port I recently came across a piece of
  code in the glibc sources which triggered an ICE in gcc because it
  was generating an insn which did not match the constraints:

    error: insn does not satisfy its constraints:
    (insn (set (reg:SI a0)
          (ior:SI (reg:SI a0)
                  (const_int 2))) {*mn10300.md:1330}
                  
  This was generated by this code:

    unsigned long
    foo (void)
    {
      char * sp = __builtin_frame_address (0);
      return * (unsigned long *) ((unsigned long) sp | 2);
    }

  I believe that it is the call to __builtin_frame_address() which is
  placing the variable "sp" into an address register and hence causing
  the problem when it is treated as a data value and applied to a bit
  operator.

  I found an easy solution for the AM33 and AM33-2 ports - allow the
  use of integers in the second alternative of the IORSI3 insn
  pattern.  This is permitted by the AM33 ISA and a simple patch to
  the mn10300.md file is all that is needed:

    *** gcc/config/mn10300/mn10300.md   8 May 2005 09:37:17 -0000       1.60
    --- gcc/config/mn10300/mn10300.md   13 Jun 2005 17:36:39 -0000
    ***************
    *** 1305,1311 ****
      (define_insn ""
        [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
        (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
    !           (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
        "TARGET_AM33"
        "*
      {
    --- 1305,1311 ----
      (define_insn ""
        [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
        (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
    !           (match_operand:SI 2 "nonmemory_operand" "dxi,daxi")))]
        "TARGET_AM33"
        "*
     {

  There are two problems however:

    1. The basic MN10300 does not support bit operations on address
       registers so the patch does not work for the basic MN10300
       IORSI3 pattern.  My initial thought was that this situation
       would arise under such unusual circumstances that there was no
       need to try to optimise GCC and instead it would be enough to
       code a second alternative as:

         push a data register
         copy the address register into the data register
         perform the bit operation
         copy the result back into the address register
         pop the data register.

       Unfortunately I do not know enough MN10300 assembler to code
       this correctly.  I tried, but failed :-(

    2. The problem also affects the AND and XOR patterns (and the test
       case can easily be altered to trigger the ICE for these
       patterns).  I think from a visual inspection of the patterns
       that extending the patch to cover these instructions should
       also work, but I am wary about the AND pattern - it looks like
       it uses short cuts for certain sizes of integer and I do not
       know enough about the AM33 ISA to know if these short cuts are
       valid when address registers are involved.

  Can you offer any advice ?  Is this a reload problem whereby "sp"
  should be moved into a data register ?
  
Cheers
  Nick

Reply via email to