[Simh] O2 optimization on Linux (was: VMS 4.6 crashes on Linux)

Timothe Litt litt at ieee.org
Sun Jan 2 11:58:41 EST 2011


Good job narrowing things down.
 
Hmmm, somewhat curious.  The gnu assembler syntax is a bit odd wrt
0x80000000; I wonder if there's an overflow where it displays "$-8388608".  
(This is -0x80000000).  But given this localization, I went back to first
principles and looked at what the emulation is trying to do.
 
Independent of this compiler matter, it looks to me like the test for P1BR
is wrong.
 
In my copy of DEC STD 032 Section 4.6.2 P1 Region paragraphs 2 & 3 say:
 ...
    The address in P1BR is not necessarily an address in system space, but
all the addresses
    of PTEs must be in system space.
 
    ,,,An attempt to load P1BR with a value less than 2**31 - 2**23
(7F800000 hex) or greater
       than 2**31 + 2**30 - 2**23 - 4 results in a reserved operand fault in
some implementations.
 
(This all has to do with the fact that P1PT is defined as the PTEs that
don't exist, v.s. P0PT which
is defined as the ones that do.) So, simh's test appears to me to be too
strict.
 
PxBR contain (page-aligned) virtual addresses; in the case of P0BR, a system
virtual address.
So the addition of 0x80000000 seems bogus.  It will always overflow in the
P0BR case, and either overflow or corrupt the value in the P1BR case.
Overflow of a signed number is undefined in C; unsigned the carry is
ignored.  You said that t is an int32; so both compilers could be right.
 
And sure enough, it doesn't exist in earlier versions of simh.  But let's
get back to what the emulator should really be doing.
 
op_ldpctx and op_mtpr both seem confused about the correct tests.  I'm not
sure which tests the 780 implemented, but it appears that this got confused
when the 780 code was added.  Assuming a test is required, what's there
appears to be wrong. (Bob, do you have/can you check the 780 ucode?)
 
Further:
Section 4.6.1 P0 Region paragraph 4 says: 
    ,,,An attempt to load P0BR with a value less than 2**31 or greater
       than 2**31 + 2**30 - 4 results in a reserved operand fault in some
implementations.
 
It looks to me as though ML_PXBR_TEST should be renamed ML_P0BR_TEST and
applied only to P0BR values.  So we have:
 
#define ML_P0BR_TEST(r)  if ((((uint32)(r)) < 0x80000000u) || \ 
                             (((uint32)(r)) > 0xbffffffcu)) RSVD_OPND_FAULT

 
 
Then we implement another test for P1BR. ML_P1BR_TEST woudl be something
like (untested):
 
#define ML_P1BR_TEST(r)  if ((((uint32)(r)) < 0x7f800000u) || \ 
                             (((uint32)(r)) > 0xbf7ffffcu)) RSVD_OPND_FAULT

Then the 
    ML_PXBR_TEST (t + 0x800000); /* validate P1BR */
in op_ldpctx becomes:

   ML_P1BR_TEST (t); /* validate P1BR */

and the same change in op_mtpr (case MT_P1BR:)
 
The TB refill code already handles the check that the calculated PTE address
is in system space.
 
You'll note that I don't check for page alignment - the operation of the
processor in kernel mode is UNDEFINED if PxBR<8:0> is non-zero.
We could add
 
                             (((uint32)(r)) & 0x0001FFu) || \
to both macros, though I don't know if this matches any processor or if
there's any software that would break.
Since UNDEFINED includes "it might work as you expect", I wouldn't do this
in the simulator (though I would in ucode!).
 
Give the new tests a whirl (in both environments) & let us know what
happens.



---------------------------------------------------------
This communication may not represent my employer's views,
if any, on the matters discussed.
  

 

  _____  

From: Peter Allan [mailto:petermallan at googlemail.com] 
Sent: Sunday, January 02, 2011 09:13
To: Timothe Litt
Cc: simh at trailing-edge.com
Subject: Re: [Simh] O2 optimization on Linux (was: VMS 4.6 crashes on Linux)


Timothe,
 
I just tried your suggestion, but it does not help. I have got the assembler
outputs on the two systems. It is of course very long, so I am putting what
I reckon to be the relevant parts here. I can send you the full listings if
you need them.
 
I say these are the relevant parts based on: 
 
The 780 emulator works if I comment out the line
 
   ML_PXBR_TEST (t + 0x800000);
 
from vax_cpu1.c
 
It also works if I change the line
 
   ML_PXBR_TEST (t + 0x800000);
 
to
 
   t2 = t + 0x800000;
   ML_PXBR_TEST (t2);
 
having defined t2 to be int32, since t is defined to be int32.
 
It looks like the macro is not handling the addition of 0x800000 correctly.
There is another part of the code where this is done. I did not need to
change that to get the emulator to work, but perhaps what I am doing does
not exercise that part of the code.
 
--- C code extracted from vax_cpu1.c

ASTLVL = t;                                             /* restore AST */
t = ReadLP (pcbpa + 88);
ML_PXBR_TEST (t + 0x800000);                            /* validate P1BR */

--- Extract from vax_cpu1.s compiled on Fedora Core 14  -- This is what
works
 
.L318:
        movl    -32(%rbp), %eax
        movl    %eax, ASTLVL(%rip)
        movl    -20(%rbp), %eax
        addl    $88, %eax
        movl    %eax, %edi
        call    ReadLP
        movl    %eax, -32(%rbp)
        movl    -32(%rbp), %eax
        addl    $8388608, %eax
        testl   %eax, %eax
        jns     .L319
        movl    -32(%rbp), %eax
        addl    $8388608, %eax
        andl    $3, %eax
        testl   %eax, %eax
        je      .L320
.L319:
        movl    $-24, %esi
        movl    $save_env, %edi
        call    longjmp
.L320:
        movl    -32(%rbp), %eax

--- Extract from vax_cpu1.s compiled on CentOS 5.5  --  This is what fails
 
.L540:
        movl    -4(%rbp), %eax
        movl    %eax, ASTLVL(%rip)
        movl    -8(%rbp), %eax
        addl    $88, %eax
        movl    %eax, %edi
        call    ReadLP
        movl    %eax, -4(%rbp)
        cmpl    $-8388608, -4(%rbp)
        jge     .L542
        movl    -4(%rbp), %eax
        addl    $8388608, %eax
        andl    $3, %eax
        testl   %eax, %eax
        je      .L544
.L542:
        movl    $-24, %esi
        movl    $save_env, %edi
        call    longjmp
.L544:
        movl    -4(%rbp), %eax
----------

My assembler is a bit rusty, but there are clear differences between the
two.
 
Peter Allan

 
On 31 December 2010 18:07, Timothe Litt <litt at ieee.org> wrote:


This test appears to be implementing the constraint that p0/1 base register
values must be in in system space (bit 31 set) & longword aligned (bits 0,1
clear).
 
I don't think it's parens; there seem to be enough.  
 
If this is a 64-bit environment, you might be seeing a sign extension /
unsigned promotion issue in the complier.
 
You might try this to make what's desired explicit:
 
#define ML_PXBR_TEST(r)  if (((((uint32)(r))&  0x80000000u) == 0) || \ 

                           ((r)&  0x00000003)) RSVD_OPND_FAULT

But it would really help to see the assembler generated for the two cases -
especially the one that fails.


---------------------------------------------------------
This communication may not represent my employer's views,
if any, on the matters discussed.
  

 

  _____  

From: simh-bounces at trailing-edge.com [mailto:simh-bounces at trailing-edge.com]
On Behalf Of Peter Allan
Sent: Friday, December 31, 2010 12:32
To: simh at trailing-edge.com
Subject: Re: [Simh] O2 optimization on Linux (was: VMS 4.6 crashes on Linux)




On 28 December 2010 22:00, Bob Supnik <bob at supnik.org> wrote:


Jason Stevens wrote:

You didn't build it with -O2 on linux did you?  There is some weird
things with GCC and SIMH's VAX...  I can only speak to 4.X BSD, but I
was able to identify two procedures that when optimized with -O2 break
4BSD on SIMH....

I kind of detailed it here:

http://www.mail-archive.com/simh@trailing-edge.com/msg00463.html

And the procedures in question were:

op_ldpctx
op_mtpr

---

Interestingly, those routines are the ONLY places in the VAX simulator where
these macros are used:

/* Machine specific reserved operand tests (all NOPs) */

#define ML_PA_TEST(r)
#define ML_LR_TEST(r)
#define ML_SBR_TEST(r)
#define ML_PXBR_TEST(r)
#define LP_AST_TEST(r)
#define LP_MBZ84_TEST(r)
#define LP_MBZ92_TEST(r)

On the 780, they are real tests:

/* Machine specific reserved operand tests */

#define ML_LR_TEST(r)    if ((uint32)((r)&  0xFFFFFF)>  0x200000)
RSVD_OPND_FAULT
#define ML_PXBR_TEST(r)  if ((((r)&  0x80000000) == 0) || \
                           ((r)&  0x00000003)) RSVD_OPND_FAULT
#define ML_SBR_TEST(r)   if ((r)&  0x00000003) RSVD_OPND_FAULT
#define ML_PA_TEST(r)    if ((r)&  0x00000003) RSVD_OPND_FAULT
#define LP_AST_TEST(r)   if ((r)>  AST_MAX) RSVD_OPND_FAULT
#define LP_MBZ84_TEST(r) if ((r)&  0xF8C00000) RSVD_OPND_FAULT
#define LP_MBZ92_TEST(r) if ((r)&  0x7FC00000) RSVD_OPND_FAULT

---

One (or more) of those six tests is the smoking gun, and if I had to put my
money on it, I think it's this one:

#define ML_LR_TEST(r)    if ((uint32)((r)&  0xFFFFFF)>  0x200000)
RSVD_OPND_FAULT

Try adding an extra level of parentheses:

if (((uint32)((r)&  0xFFFFFF))>  0x200000) RSVD_OPND_FAULT


just to be sure that the uint32 cast isn't be applied to the whole
comparison, instead of just the first term.

If that fails to get it running, then try "no-oping" all of the macros to
see if VMS 4.6 will boot.  If it does, then enable each of the macros in
turn, to see where the simulator fails.

/Bob


_______________________________________________
Simh mailing list
Simh at trailing-edge.com
http://mailman.trailing-edge.com/mailman/listinfo/simh



Bob,
 
I tried removing the macro definitions one by one. The one that causes the
problem is ML_PXBR_TEST, i.e. if this is defined as nothing and the rest are
left as per vax780_defs.h, then the 780 emulator works on CentOS 5.5. This
is the macro with two comparisons in it. I wonder if that is significant?
 
I tried putting in some extra parentheses, but this did not help. 
 
Of course, it all still works on Fedora Core 14. I will see if I can compare
the assembler that is generated for vax_cpu1.c on the two systems.
 
Peter Allan
 


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.trailing-edge.com/pipermail/simh/attachments/20110102/a4dcbb60/attachment-0002.html>


More information about the Simh mailing list