Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PowerMac G4 hitting illegal instruction #97

Open
andrewlow opened this issue Oct 29, 2013 · 9 comments
Open

PowerMac G4 hitting illegal instruction #97

andrewlow opened this issue Oct 29, 2013 · 9 comments

Comments

@andrewlow
Copy link
Collaborator

The following hits an illegal instruction

./out/ppc.debug/d8  --allow-natives-syntax ./test/mjsunit/mjsunit.js ./test/mjsunit/regress/regress-sqrt.js

Seems to be a problem with fsqrt

Program received signal SIGILL, Illegal instruction.
0x4e943b28 in ?? ()
(gdb) x/20i $pc
=> 0x4e943b28:  fsqrt   f1,f1
@tunniclm
Copy link
Contributor

tunniclm commented Nov 7, 2013

The instructions the G4 processor does not implement are described in the manual http://www.freescale.com/files/32bit/doc/ref_manual/MPC7410UM.pdf

Of these, our 32-bit build uses: fsqrt, fcfid

@tio00
Copy link

tio00 commented Dec 23, 2013

Hi all,

Noob here. I'm continuing from this thread: https://groups.google.com/forum/#!topic/nodejs/ivGMr-C_m1Y

As mentioned there, I have a Titanium Powerbook G4 with Linux MintPPC 11 set up with the code and have also identified some fcfid calls. I would like to help with this, and at this point I'm wondering what the accepted method is to add exceptions for the G4.

Since I snagged the fcfid instruction first, and after some googling, I was wondering if fctiw would be a place to start.

Anyway any pointers on doing this the correct way would be great, Thanks!

@andrewlow
Copy link
Collaborator Author

@mike - as you've got some in progress changes to support the G4 just go ahead and make a branch in this repo. We can merge once you've for the bugs worked out.

@tunniclm
Copy link
Contributor

I have added the branch g4compat

@andrewlow
Copy link
Collaborator Author

I spent a bit of time today looking at the v8 build on a G4 running Ubuntu.
There are only 3 failures in the test suite run and all 3 are related to Math.sqrt(0.01);

$ ./out/ppc.debug/d8
V8 version 3.14.5 (candidate) [console: dumb]
d8> Math.sqrt(0.01)
0.09999999999999999
d8>

Writing a simple C program:

main()
{
printf("%f\n", sqrt(0.01));
}

proves that the basic math library is sane, so I'm guessing the issue is around conversion of then number / rounding - but I haven't put my finger on the exact problem yet.

Given that Mike was 'hacking' in the branch https://github.com/andrewlow/v8ppc/tree/g4compat there might be a bit of work to merge this without breaking things.

@tunniclm
Copy link
Contributor

@andrewlow Be careful that printf() isn't rounding the answer in your C program. Try this to check:

#include <math.h>
#include <stdio.h>
main() {
  printf("sqrt(0.01)=%a\n", sqrt(0.01));
  printf("0.1=%a\n", 0.1);
  printf("sqrt(0.01)%s0.1\n", 0.1==sqrt(0.01) ? "==" : "!=");
}

Here we can compare the precise hexadecimal representation of 0.1 and sqrt(0.01) and see by eye any difference. This is actually not so easy to do (particularly with confidence) when using a decimal representation.

@andrewlow
Copy link
Collaborator Author

@tunniclm good point

One of our Power7 Linux machines

$ ./a.out
sqrt(0.01)=0x1.999999999999ap-4
0.1=0x1.999999999999ap-4
sqrt(0.01)==0.1

The G4

$ ./a.out
sqrt(0.01)=0x1.999999999999ap-4
0.1=0x1.999999999999ap-4
sqrt(0.01)==0.1

@andrewlow
Copy link
Collaborator Author

I've done more digging - I think the C program is mis-leading us.

In JS the Math.sqrt() calls maps down to a call v8::internal::fast_sqrt, which in turn is a call to the C library sqrt().

On Power7 the object that comes back has this hex value for the double:

0x3fb99999      0x9999999a

on the G4

0x3fb99999      0x99999999

I'm starting to wonder if we've left the FPSCR state in the wrong mode?
Power7

fpscr          0xa6064100

G4

fpscr          0xa6024100 

It appears the difference between the two registers is the FR bit ( "Floating-point fraction rounded. The last arithmetic or rounding and conversion instruction that rounded the intermediate result incremented the fraction." ) This makes sense as the Power7 result has been rounded and the FR bit is set appropriately.

I think this is proof the C math library is giving us an unexpected answer, looking at the state of FPSCR prior to making the call to the C math library, we're using the same RN (rounding mode) of 00. (round to nearest)

@andrewlow
Copy link
Collaborator Author

I modified the simple C program above to demonstrate the issue we're seeing. (don't forget to link the math library with -lm)

#include <math.h>
#include <stdio.h>
main() {
  double z = 0.01;
  double x;
  int *p = &x;
  x = sqrt(z);
  printf("%08x, %08x\n", p[0], p[1]);
  printf("sqrt(0.01)=%a constant\n", sqrt(0.01));
  printf("sqrt(0.01)=%a variable\n", sqrt(z));
  printf("0.1=%a\n", 0.1);
  printf("sqrt(0.01)%s0.1\n", 0.1==sqrt(0.01) ? "==" : "!=");
}

Power7

$ ./a.out
3fb99999, 9999999a
sqrt(0.01)=0x1.999999999999ap-4 constant
sqrt(0.01)=0x1.999999999999ap-4 variable
0.1=0x1.999999999999ap-4
sqrt(0.01)==0.1

G4

$ ./a.out
3fb99999, 99999999
sqrt(0.01)=0x1.999999999999ap-4 constant
sqrt(0.01)=0x1.9999999999999p-4 variable
0.1=0x1.999999999999ap-4
sqrt(0.01)==0.1

When we pass in the 0.01 value in a double (as a variable) the G4 doesn't round it correctly (where correctly is defined as how the V8 tests expect it to work).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants