Specifying explicit parallel to define_insn of a named pattern.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I am working on porting GCC to a 32 bit RISC (based on MIPS).

In the machine descriptions, I have specified the division operation as
shown below.

(-----Cut-----)
(define_insn_and_split "<div_mod_optab_name>si3"
  [(parallel[                       <== *(1)
   (set (match_operand:SI 0 "register_operand")
        (any_div_op:SI (match_operand:SI 1 "register_operand")
                       (match_operand:SI 2 "register_operand")))
   (clobber (reg:SI LO_REG_NUM))
   (clobber (reg:SI HI_REG_NUM))
   ])
]
  ""
  "#"
  "reload_completed"
  [(parallel[(set (match_dup 3)
                   (any_div_op:SI (match_dup 1)
                                  (match_dup 2)))
              (clobber (reg:SI HI_REG_NUM))])
   (set (match_dup 0)
        (match_dup 3))]                    
  "
    { test(); 
    operands[3] = gen_rtx_REG(SImode,LO_REG_NUM); }
  "    
)

(define_insn "*<div_mod_optab_name>si3"
  [(parallel[
   (set (match_operand:SI 0 "lo_register_operand" "=l")
                  (any_div_op:SI (match_operand:SI 1 "register_operand"
"=b")
                                 (match_operand:SI 2 "register_operand" "
b")))
   (clobber (reg:SI HI_REG_NUM))])]
  ""
  { 
    output_check_div_by_zero(operands);
    return "<div_mod_insn_name>\t%1,%2";
  }
(-----Cut-----)

When I specify parallel explicitly *(1) as shown above, the 'genemit'
program generates the function 'add_clobbers' as shown below.

(-----Cut-----)
void
add_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number) {
  switch (insn_code_number)
    {
    case 50:
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 31);
      break;

    case 49:
    case 48:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 31);
      break;

    case 8:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 32);
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 33);
      break;

    default:
      gcc_unreachable ();
    }
}
(-----Cut-----)

In the above case clobber expressions are not recognized for division
operations (signed and unsigned division). 

But, when I remove the explicit parallel from the machine description as
shown below, 

(-----Cut-----)
 (define_insn_and_split "<div_mod_optab_name>si3"
  [
   (set (match_operand:SI 0 "register_operand")
        (any_div_op:SI (match_operand:SI 1 "register_operand")
                       (match_operand:SI 2 "register_operand")))
   (clobber (reg:SI LO_REG_NUM))
   (clobber (reg:SI HI_REG_NUM))
   
]
  ""
  "#"
  "reload_completed"
  [(parallel[(set (match_dup 3)
                   (any_div_op:SI (match_dup 1)
                                  (match_dup 2)))
              (clobber (reg:SI HI_REG_NUM))])
   (set (match_dup 0)
        (match_dup 3))]                    
  "
    { test(); 
    operands[3] = gen_rtx_REG(SImode,LO_REG_NUM); }
  "    
)

(define_insn "*<div_mod_optab_name>si3"
  [(parallel[
   (set (match_operand:SI 0 "lo_register_operand" "=l")
                  (any_div_op:SI (match_operand:SI 1 "register_operand"
"=b")
                                 (match_operand:SI 2 "register_operand" "
b")))
   (clobber (reg:SI HI_REG_NUM))])]
  ""
  { 
    output_check_div_by_zero(operands);
    return "<div_mod_insn_name>\t%1,%2";
  }
(-----Cut-----)

The 'genemit' program generates 'add_clobbers' as shown below.

(-----Cut-----)
void
add_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number) {
  switch (insn_code_number)
    {
    case 50:
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 31);
      break;

    case 49:
    case 48:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 31);
      break;

    case 10:                <== this was generated
for our division operation.
    case 9:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 33);
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 32);
      break;

    case 8:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 32);
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 33);
      break;

    default:
      gcc_unreachable ();
    }
}
(-----Cut-----)

The clobbers defined in the machine descriptions are now recognized. The
additional case constructs are generated (case 9 and 10).

I checked the source code of the gen_emit program, specifically the function
'gen_insn (rtx insn, int lineno)' function.

When the vector read from machine description for division is

(-----Snip-----)
  [
   (set (match_operand:SI 0 "register_operand")
        (any_div_op:SI (match_operand:SI 1 "register_operand")
                       (match_operand:SI 2 "register_operand")))
   (clobber (reg:SI LO_REG_NUM))
   (clobber (reg:SI HI_REG_NUM))
   
]
(-----Snip-----)

The check in <if (i != XVECLEN (insn, 1) - 1> returns 2. That means number
of expressions in the vector is 3.

But when the vector read from machine description for division is

(-----Snip-----)
  [ (parallel [
   (set (match_operand:SI 0 "register_operand")
        (any_div_op:SI (match_operand:SI 1 "register_operand")
                       (match_operand:SI 2 "register_operand")))
   (clobber (reg:SI LO_REG_NUM))
   (clobber (reg:SI HI_REG_NUM))
   ])
]
(-----Snip-----)

The check (if (i != XVECLEN (insn, 1) - 1) returns 0. That means number of
expressions in the vector is 1.

>From seeing the source code, I believe the code for recognizing clobbers
will not work when we specify explicit parallel.

Please confirm my understanding.

Also I am also aware that GCC implicitly surrounds parallel when there are
multiple expressions in the template of 'define_insn'.

So specifying parallel at the start of 'define_insn' of a named pattern has
a different meaning? 

In my case I feel explicit parallel is not needed and can be removed.

Please confirm.


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux