i370 port

Paul Edwards mutazilah@gmail.com
Fri Sep 18 12:23:00 GMT 2009


>> > As an alternative to the operand predicate, you might also add
>> > an extra check to the insn condition.  For example, something
>> > along the following lines should work:
>> >
>> > (define_insn ""
>> >   [(set (match_operand:SI 0 "register_operand" "=d")
>> >         (mult:SI (match_operand:SI 1 "register_operand" "0")
>> >                  (match_operand:SI 2 "const_int_operand" "K")))]
>> >   "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
>>
>> My eyes lit up when I saw that!  However, it produced a compiler
>> error when I tried it.  But undeterred, I tried this:

Sorry.  I just copied the last line into the existing pattern, didn't
notice that you'd changed the predicate too.

>> (define_insn ""
>>   [(set (match_operand:SI 0 "register_operand" "=d")
>>         (mult:SI (match_operand:SI 1 "register_operand" "0")
>>                  (match_operand:SI 2 "immediate_operand" "K")))]
>>   "(GET_CODE (operands[2]) == CONST_INT
>>    && REG_P (operands[0])
>>    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
>
> Huh.  Instead of adding an explicit CONST_INT check, my approach
> above used a const_int_operand predicate (instead of immediate_operand).
> That should have had the exact same effect ...   I'm not sure why the
> REG_P check on the other operand would be necessary at this point.

I just copied that from the existing condition too.  Once I realised
that I could put a check in advance, I just copied the check
across basically.  I'd seen that before, it just hadn't sunk in that
I could use it for this situation.

I will try out your original suggestion again properly.  :-)

>> And it worked (verified by self-compile)!  And I relaxed the
>> constraint on the "M" instruction as well.  Those old warnings
>> are apparently irrelevant now.  Thank you sir.  :-)
>
> OK, that's good to know.

Indeed.

And as I mentioned, there's just one real bug that I know of left.  I can
bypass the bug in the GCC code that I am compiling, by forcing a
function call.

C:\devel\gccnew\gcc>gccmvs -DUSE_MEMMGR -Os -S -ansi -pedantic-errors -DHAVE_CON
FIG_H -DIN_GCC -DPUREISO -I ../../pdos/pdpclib -I . -I config/i370 -I 
../include
         varasm.c
varasm.c: In function `force_const_mem':
varasm.c:3021: internal compiler error: in instantiate_virtual_regs_lossage, 
at
function.c:3765
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gccmvs.sourceforge.net> for instructions.

This is the code that is triggering off that bug:

force_const_mem (enum machine_mode mode, rtx x)
{
  int hash;
  struct constant_descriptor_rtx *desc;
...
    if (compare_constant_rtx (mode, x, desc))


static int
compare_constant_rtx (enum machine_mode mode, rtx x,
^I^I      struct constant_descriptor_rtx *desc)
{
  struct rtx_const value;

  decode_rtx_const (mode, x, &value);

  /* Compare constant contents.  */
#if defined(XTARGET_MVS) /* +++ seems we have a machine definition problem 
*/
  return (memcmp) (&value, &desc->value, sizeof (struct rtx_const)) == 0;
#else
  return memcmp (&value, &desc->value, sizeof (struct rtx_const)) == 0;
#endif
}


You can see how I normally work around this problem by forcing a
function call.

If I do that force, then I get this code generated:

L445     EQU   *
         LTR   3,3
         BE    L442
         MVC   88(4,13),0(11)
         MVC   92(4,13),4(11)
         LA    2,560(,13)
         ST    2,96(13)
         LA    1,88(,13)
         L     15,=A(@@F17)
         BALR  14,15
         ST    2,88(13)
         LR    2,3
         A     2,=F'8'
         ST    2,92(13)
         MVC   96(4,13),=F'196'
         LA    1,88(,13)
         L     15,=V(MEMCMP)
         BALR  14,15
         LTR   15,15

which is bizarre.  It seems to be comparing two values that are 8 bytes
apart, for a length of 196.  Can't imagine that doing anything useful.

It's almost certainly an i370 port bug, but I haven't had any bright
ideas on how to fix that yet.  :-)

BFN.  Paul.



More information about the Gcc mailing list