8 #include <sys/socket.h>
10 #include <sys/fcntl.h>
25 static const char g_fpu[] = "vfpu";
27 static bool g_running = false;
28 static int g_fpu_socket[2] = {-1,-1};
29 static pid_t g_fpu_pid = -1;
33 * @returns 0 on success, errno of the failing function on failure
38 // create unix socket pair
40 if (socketpair(AF_UNIX, SOCK_STREAM, 0, g_fpu_socket) != 0)
45 if (g_fpu_pid < 0) // error check
53 // Remap stdio to the socket
54 dup2(g_fpu_socket[0],fileno(stdin));
55 dup2(g_fpu_socket[0],fileno(stdout));
57 // Unbuffer things; buffers are a pain
58 setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL);
60 Debug("Child about to suppress stderr and exec vfpu");
61 dup2(open("/dev/null", O_APPEND), fileno(stderr)); //LALALA I AM NOT LISTENING TO YOUR STUPID ERRORS GHDL
62 execl(g_fpu, g_fpu,NULL);
63 int err = errno; // Because errno will be set again by the next system call
64 Fatal("Uh oh! %s\n", strerror(err)); // We will never see this if something goes wrong... oh dear
65 exit(err); // Child exits here.
70 g_running = true; // We are ready!
80 // Tell the child to stop running the VHDL simulation
81 if (close(g_fpu_socket[1]) != 0)
84 if (kill(g_fpu_pid, SIGKILL) != 0)
90 float Exec(float opa, float opb, Opcode op, Rmode rmode)
92 unsigned a; memcpy(&a, &opa, sizeof(float));
93 unsigned b; memcpy(&b, &opb, sizeof(float));
95 unsigned r = (unsigned)(Exec(Register(a), Register(b), op, rmode).to_ulong());
96 float result; memcpy(&result, &r, sizeof(float));
101 * Tell the VFPU to execute an instruction, wait for it to finish, return the result
102 * TODO: Make this not mix C++ and C so badly?
103 * TODO: It will still only work for magic 32 bit FPU
105 Register Exec(const Register & a, const Register & b, Opcode op, Rmode rmode)
110 s << hex << setw(8) << setfill('0') << a.to_ullong() << "\n" << b.to_ullong() << "\n" << setw(3) << op <<"\n" << setw(2) << rmode << "\n\n";
112 //Debug("Writing: %s", str.c_str());
114 // So we used C++ streams to make our C string...
115 assert(write(g_fpu_socket[1], str.c_str(), str.size()) == (int)str.size());
118 int len = read(g_fpu_socket[1], buffer, sizeof(buffer));
120 buffer[--len] = '\0'; // Get rid of newline
121 //Debug("Read: %s", buffer);
124 for (int i = 0; i < len/2; ++i)
126 unsigned byte; // It is ONE byte (2 nibbles == 2 hex digits)
127 sscanf(buffer+2*i, "%02x", &byte);
128 result |= (byte << 8*(len/2-i-1));
132 s2 << hex << result.to_ullong();
133 //Debug("Result is: %s", s2.str().c_str());