/*[0,pi/4)に簡約*/ uint32_t fsin(uint32_t f){ if(fcmp(f,0) == 0) return fneg(fsin(f - (1 << 31))); if(fcmp(f,0x40c90fda) == 2) return fsin(fadd(f,0xc0c90fda)); if(fcmp(f,MYPI) == 0){ if(fcmp(f,MYPI2) == 0){ if(fcmp(f,MYPI4) == 0) return kernel_sin(f); else return kernel_cos(fadd(MYPI2,fneg(f))); }else{ if(fcmp(f,fadd(MYPI4,MYPI2)) == 0) kernel_cos(fadd(f,fneg(MYPI2))); else kernel_sin(fadd(MYPI,fneg(f))); } }else{ f = fadd(f,fneg(MYPI)); if(fcmp(f,MYPI2) == 0){ if(fcmp(f,MYPI4) == 0) return fneg(kernel_sin(f)); else return fneg(kernel_cos(fadd(MYPI2,fneg(f)))); }else{ if(fcmp(f,fadd(MYPI4,MYPI2)) == 0) fneg(kernel_cos(fadd(f,fneg(MYPI2)))); else fneg(kernel_sin(fadd(MYPI,fneg(f)))); } } }
uint32_t kernel_cos(uint32_t f){ uint32_t x2 = fmul(f,f); uint32_t x3 = fmul(f,x2); uint32_t x4 = fmul(x2,x2); uint32_t x6 = fmul(x3,x3); return fadd(fadd(0x3f800000,fmul(0xbf000000,x2)), fadd(fmul(0x3d2aa789,x4),fmul(0xbab38106,x6))); }
uint32_t kernel_sin(uint32_t f){ uint32_t x2 = fmul(f,f); uint32_t x3 = fmul(f,x2); uint32_t x4 = fmul(x2,x2); uint32_t x5 = fmul(x3,x2); uint32_t x7 = fmul(x3,x4); return fadd(fadd(f,fmul(0xb94d64b6,x7)), fadd(fmul(0xbe2aaaac,x3),fmul(0x3c088666,x5))); }
void fcom(const temp_real * src1, const temp_real * src2) { temp_real a; a = *src1; a.exponent ^= 0x8000; fadd(&a,src2,&a); ftst(&a); }
void draw_crusher(BITMAP *bmp) { static fixed angle = 0; int x, y, x1, y1, x2, y2; x = crusher.x+crusher.w/2-get_bitmap(BMP_CRUSHER)->w/2; y = crusher.y+crusher.h/2-get_bitmap(BMP_CRUSHER)->h/2+8; /* crusher body */ draw_sprite(bmp, get_bitmap(BMP_CRUSHER), x, y); /* crusher motor */ draw_sprite(bmp, get_bitmap(BMP_CRUSHER_MOTOR), x1 = x-get_bitmap(BMP_CRUSHER_MOTOR)->w+1+rand()%3-1, y1 = y+rand()%3-1); /* crusher pulley */ rotate_sprite(bmp, get_bitmap(BMP_CRUSHER_PULLEY), x2 = x+17-get_bitmap(BMP_CRUSHER_PULLEY)->w/2+rand()%3-1, y2 = y+13-get_bitmap(BMP_CRUSHER_PULLEY)->h/2+rand()%3-1, angle); /* strap */ do_line(bmp, x1+12, y1+8, x2+get_bitmap(BMP_CRUSHER_PULLEY)->w/2-1, y2, makecol(0, 0, 0), strap_proc); do_line(bmp, x1+12, y1+18, x2+get_bitmap(BMP_CRUSHER_PULLEY)->w/2-1, y2+get_bitmap(BMP_CRUSHER_PULLEY)->h-1, makecol(0, 0, 0), strap_proc); angle = fadd(angle, itofix(16)); if (angle > itofix(256)) angle = fsub(angle, itofix(256)); /* scorer */ draw_sprite(bmp, get_bitmap(BMP_SCORER), x+get_bitmap(BMP_CRUSHER)->w, y+get_bitmap(BMP_CRUSHER)->h-get_bitmap(BMP_SCORER)->h); /* alarm */ if (alarm_time_blue >= 0) { masked_blit(get_bitmap(BMP_SCORER_ALARM), bmp, 0, 0, x+get_bitmap(BMP_CRUSHER)->w+63, y+get_bitmap(BMP_CRUSHER)->h-get_bitmap(BMP_SCORER)->h+27, 8, 9); } if (alarm_time_red >= 0) { masked_blit(get_bitmap(BMP_SCORER_ALARM), bmp, get_bitmap(BMP_SCORER_ALARM)->w-8, 0, x+get_bitmap(BMP_CRUSHER)->w+75, y+get_bitmap(BMP_CRUSHER)->h-get_bitmap(BMP_SCORER)->h+27, 8, 9); } }
void shmem_int8_add_f(FORTRAN_POINTER_T target, FORTRAN_POINTER_T value, MPI_Fint *pe) { ompi_fortran_integer8_t out_value = 0; oshmem_op_t* op = oshmem_op_sum_fint8; MCA_ATOMIC_CALL(fadd(FPTR_2_VOID_PTR(target), (void *)&out_value, FPTR_2_VOID_PTR(value), sizeof(out_value), OMPI_FINT_2_INT(*pe), op)); }
ompi_fortran_real4_t shmem_real4_fetch_f(FORTRAN_POINTER_T target, MPI_Fint *pe) { ompi_fortran_real4_t out_value = 0; ompi_fortran_real4_t value = 0; MCA_ATOMIC_CALL(fadd(oshmem_ctx_default, FPTR_2_VOID_PTR(target), (void *)&out_value, value, sizeof(out_value), OMPI_FINT_2_INT(*pe))); return out_value; }
void shmem_int4_inc_f(FORTRAN_POINTER_T target, MPI_Fint *pe) { ompi_fortran_integer4_t out_value = 0; ompi_fortran_integer4_t value = 1; oshmem_op_t* op = oshmem_op_sum_fint4; MCA_ATOMIC_CALL(fadd(FPTR_2_VOID_PTR(target), (void *)&out_value, (const void*)&value, sizeof(out_value), OMPI_FINT_2_INT(*pe), op)); }
int main(int argc, const char *argv[]) { int i; int *mem = malloc(1100000); capture_stdio(); for (i = 0;; ++i) { int32_t t0[2], t1[2]; char *msg; int n; gp_get_usertime(t0); switch (i) { case 0: iadd(0, n = 10000000, &msg); break; case 1: imul(1, n = 1000000, &msg); break; case 2: idiv(1, n = 1000000, &msg); break; case 3: fadd(3.14, n = 10000000, &msg); break; case 4: fmul(1.0000001, n = 10000000, &msg); break; case 5: fdiv(1.0000001, n = 1000000, &msg); break; case 6: fconv(12345, n = 10000000, &msg); break; case 7: mfast(mem, n = 10000000, &msg); break; case 8: mslow(mem, n = 1000000, &msg); break; default: free(mem); exit(0); } gp_get_usertime(t1); fprintf(stdout, "Time for %9d %s = %g ms\n", n, msg, (t1[0] - t0[0]) * 1000.0 + (t1[1] - t0[1]) / 1000000.0); fflush(stdout); } }
ompi_fortran_real4_t shmem_real4_fetch_f(FORTRAN_POINTER_T target, MPI_Fint *pe) { ompi_fortran_real4_t out_value = 0; oshmem_op_t* op = oshmem_op_sum_freal4; int value = 0; MCA_ATOMIC_CALL(fadd(FPTR_2_VOID_PTR(target), (void *)&out_value, (const void *)&value, sizeof(out_value), OMPI_FINT_2_INT(*pe), op)); return out_value; }
int main(int argc, char* argv[]) { printf("easy test!\n"); int t; int a = 4; int b = 5; int c = add(a, b); printf("%d + %d = %d\n", a, b, c); float x = 5.5; float y = .6; float z = fadd(x, y); printf("%f + %f = %f\n", x, y, z); return 0; }
void fasinh(_MIPD_ flash x,flash y) { /* calculate y=asinh(x) */ #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif copy(x,y); if (mr_mip->ERNUM || size(y)==0) return; MR_IN(66) fmul(_MIPP_ y,y,mr_mip->w11); fincr(_MIPP_ mr_mip->w11,1,1,mr_mip->w11); froot(_MIPP_ mr_mip->w11,2,mr_mip->w11); fadd(_MIPP_ y,mr_mip->w11,y); flog(_MIPP_ y,y); MR_OUT }
void facosh(_MIPD_ flash x,flash y) { /* calculate y=acosh(x) */ #ifndef MR_GENERIC_MT miracl *mr_mip=get_mip(); #endif copy(x,y); if (mr_mip->ERNUM) return; MR_IN(62) fmul(_MIPP_ y,y,mr_mip->w11); fincr(_MIPP_ mr_mip->w11,(-1),1,mr_mip->w11); froot(_MIPP_ mr_mip->w11,2,mr_mip->w11); fadd(_MIPP_ y,mr_mip->w11,y); flog(_MIPP_ y,y); MR_OUT }
/** Adds two matrices. * Returns materr(2) if the two matrices can't * be added, materr(1) if the initialization * didn't go right. */ matrix MatrixAdd(matrix m1, matrix m2) { if (!isValidOp(m1,m2,'a')) { return materr(2); } matrix mx = initialize(m1.rows, m1.columns); if (mx.mx == NULL) { return materr(1); } for(int row = 0; row < mx.rows; row++) for(int col = 0; col < mx.columns; col++) mx.mx[row][col] = fadd(m1.mx[row][col], m2.mx[row][col]); return mx; }
/** Multiplies m1 by m2. * Returns materr(2) if the two matrices can't * be multiplied, materr(1) if the initialization * didn't go right. */ matrix MatrixMul(matrix m1, matrix m2) { if (!isValidOp(m1,m2,'m')) { return materr(2); } matrix mx = initialize(m1.rows, m2.columns); if (mx.mx == NULL) { return materr(1); } for(int row = 0; row < mx.rows; row++) { for(int col = 0; col < mx.columns; col++) { for(int i = 0; i < m1.columns; i++) { mx.mx[row][col] = fadd(mx.mx[row][col], fmul(m1.mx[row][i], m2.mx[i][col])); } } } return mx; }
char * all_tests (void) { fesetround (FE_TOWARDZERO); srand((unsigned)time(NULL)); union uint32_f a, b, c; for (int i = 0; i < 2000000 ; i++) { char aa[33],bb[33],cc[33]; a.i = (uint32_t)( (rand () << 2) + rand ()); b.i = (uint32_t)( (rand () << 2) + rand ()); if (fpclassify (a.f) != FP_NORMAL || fpclassify (b.f) != FP_NORMAL) continue; tests_run++; c.i = fadd (a.i, b.i); if (fpclassify (c.f) != FP_NORMAL || fpclassify (a.f*b.f) != FP_NORMAL) continue; for (int t = 0; t < 32;++t) { aa[31 - t] = a.i & (1 << t) ? '1' : '0'; bb[31 - t] = b.i & (1 << t) ? '1' : '0'; cc[31 - t] = c.i & (1 << t) ? '1' : '0'; } aa[32] = '\0'; bb[32] = '\0'; cc[32] = '\0'; // 非正規化数とかはやらない if (isnormal (a.f) && isnormal (b.f)) { if (!isnan (c.f)) printf ("%s\t%s\t%s\n",aa,bb,cc); } } return NULL; }
static void do_emu(struct info * info) { unsigned short code; temp_real tmp; char * address; if (I387.cwd & I387.swd & 0x3f) I387.swd |= 0x8000; else I387.swd &= 0x7fff; ORIG_EIP = EIP; /* 0x0007 means user code space */ if (CS != 0x000F) { printk("math_emulate: %04x:%08x\n\r",CS,EIP); panic("Math emulation needed in kernel"); } code = get_fs_word((unsigned short *) EIP); bswapw(code); code &= 0x7ff; I387.fip = EIP; *(unsigned short *) &I387.fcs = CS; *(1+(unsigned short *) &I387.fcs) = code; EIP += 2; switch (code) { case 0x1d0: /* fnop */ return; case 0x1d1: case 0x1d2: case 0x1d3: case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7: math_abort(info,1<<(SIGILL-1)); case 0x1e0: ST(0).exponent ^= 0x8000; return; case 0x1e1: ST(0).exponent &= 0x7fff; return; case 0x1e2: case 0x1e3: math_abort(info,1<<(SIGILL-1)); case 0x1e4: ftst(PST(0)); return; case 0x1e5: printk("fxam not implemented\n\r"); math_abort(info,1<<(SIGILL-1)); case 0x1e6: case 0x1e7: math_abort(info,1<<(SIGILL-1)); case 0x1e8: fpush(); ST(0) = CONST1; return; case 0x1e9: fpush(); ST(0) = CONSTL2T; return; case 0x1ea: fpush(); ST(0) = CONSTL2E; return; case 0x1eb: fpush(); ST(0) = CONSTPI; return; case 0x1ec: fpush(); ST(0) = CONSTLG2; return; case 0x1ed: fpush(); ST(0) = CONSTLN2; return; case 0x1ee: fpush(); ST(0) = CONSTZ; return; case 0x1ef: math_abort(info,1<<(SIGILL-1)); case 0x1f0: case 0x1f1: case 0x1f2: case 0x1f3: case 0x1f4: case 0x1f5: case 0x1f6: case 0x1f7: case 0x1f8: case 0x1f9: case 0x1fa: case 0x1fb: case 0x1fc: case 0x1fd: case 0x1fe: case 0x1ff: printk("%04x fxxx not implemented\n\r",code + 0xc800); math_abort(info,1<<(SIGILL-1)); case 0x2e9: fucom(PST(1),PST(0)); fpop(); fpop(); return; case 0x3d0: case 0x3d1: return; case 0x3e2: I387.swd &= 0x7f00; return; case 0x3e3: I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; return; case 0x3e4: return; case 0x6d9: fcom(PST(1),PST(0)); fpop(); fpop(); return; case 0x7e0: *(short *) &EAX = I387.swd; return; } switch (code >> 3) { case 0x18: fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x19: fmul(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1a: fcom(PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1b: fcom(PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); fpop(); return; case 0x1c: real_to_real(&ST(code & 7),&tmp); tmp.exponent ^= 0x8000; fadd(PST(0),&tmp,&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1d: ST(0).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1e: fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1f: fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x38: fpush(); ST(0) = ST((code & 7)+1); return; case 0x39: fxchg(&ST(0),&ST(code & 7)); return; case 0x3b: ST(code & 7) = ST(0); fpop(); return; case 0x98: fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x99: fmul(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x9a: fcom(PST(code & 7),PST(0)); return; case 0x9b: fcom(PST(code & 7),PST(0)); fpop(); return; case 0x9c: ST(code & 7).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x9d: real_to_real(&ST(0),&tmp); tmp.exponent ^= 0x8000; fadd(PST(code & 7),&tmp,&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x9e: fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x9f: fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0xb8: printk("ffree not implemented\n\r"); math_abort(info,1<<(SIGILL-1)); case 0xb9: fxchg(&ST(0),&ST(code & 7)); return; case 0xba: ST(code & 7) = ST(0); return; case 0xbb: ST(code & 7) = ST(0); fpop(); return; case 0xbc: fucom(PST(code & 7),PST(0)); return; case 0xbd: fucom(PST(code & 7),PST(0)); fpop(); return; case 0xd8: fadd(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xd9: fmul(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xda: fcom(PST(code & 7),PST(0)); fpop(); return; case 0xdc: ST(code & 7).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xdd: real_to_real(&ST(0),&tmp); tmp.exponent ^= 0x8000; fadd(PST(code & 7),&tmp,&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xde: fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xdf: fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xf8: printk("ffree not implemented\n\r"); math_abort(info,1<<(SIGILL-1)); fpop(); return; case 0xf9: fxchg(&ST(0),&ST(code & 7)); return; case 0xfa: case 0xfb: ST(code & 7) = ST(0); fpop(); return; } switch ((code>>3) & 0xe7) { case 0x22: put_short_real(PST(0),info,code); return; case 0x23: put_short_real(PST(0),info,code); fpop(); return; case 0x24: address = ea(info,code); for (code = 0 ; code < 7 ; code++) { ((long *) & I387)[code] = get_fs_long((unsigned long *) address); address += 4; } return; case 0x25: address = ea(info,code); *(unsigned short *) &I387.cwd = get_fs_word((unsigned short *) address); return; case 0x26: address = ea(info,code); verify_area(address,28); for (code = 0 ; code < 7 ; code++) { put_fs_long( ((long *) & I387)[code], (unsigned long *) address); address += 4; } return; case 0x27: address = ea(info,code); verify_area(address,2); put_fs_word(I387.cwd,(short *) address); return; case 0x62: put_long_int(PST(0),info,code); return; case 0x63: put_long_int(PST(0),info,code); fpop(); return; case 0x65: fpush(); get_temp_real(&tmp,info,code); real_to_real(&tmp,&ST(0)); return; case 0x67: put_temp_real(PST(0),info,code); fpop(); return; case 0xa2: put_long_real(PST(0),info,code); return; case 0xa3: put_long_real(PST(0),info,code); fpop(); return; case 0xa4: address = ea(info,code); for (code = 0 ; code < 27 ; code++) { ((long *) & I387)[code] = get_fs_long((unsigned long *) address); address += 4; } return; case 0xa6: address = ea(info,code); verify_area(address,108); for (code = 0 ; code < 27 ; code++) { put_fs_long( ((long *) & I387)[code], (unsigned long *) address); address += 4; } I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; return; case 0xa7: address = ea(info,code); verify_area(address,2); put_fs_word(I387.swd,(short *) address); return; case 0xe2: put_short_int(PST(0),info,code); return; case 0xe3: put_short_int(PST(0),info,code); fpop(); return; case 0xe4: fpush(); get_BCD(&tmp,info,code); real_to_real(&tmp,&ST(0)); return; case 0xe5: fpush(); get_longlong_int(&tmp,info,code); real_to_real(&tmp,&ST(0)); return; case 0xe6: put_BCD(PST(0),info,code); fpop(); return; case 0xe7: put_longlong_int(PST(0),info,code); fpop(); return; } switch (code >> 9) { case 0: get_short_real(&tmp,info,code); break; case 1: get_long_int(&tmp,info,code); break; case 2: get_long_real(&tmp,info,code); break; case 4: get_short_int(&tmp,info,code); } switch ((code>>3) & 0x27) { case 0: fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 1: fmul(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 2: fcom(&tmp,PST(0)); return; case 3: fcom(&tmp,PST(0)); fpop(); return; case 4: tmp.exponent ^= 0x8000; fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 5: ST(0).exponent ^= 0x8000; fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 6: fdiv(PST(0),&tmp,&tmp); real_to_real(&tmp,&ST(0)); return; case 7: fdiv(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; } if ((code & 0x138) == 0x100) { fpush(); real_to_real(&tmp,&ST(0)); return; } printk("Unknown math-insns: %04x:%08x %04x\n\r",CS,EIP,code); math_abort(info,1<<(SIGFPE-1)); }
BOOL gauss(flash A[][50],flash b[],int n) { /* solve Ax=b using Gaussian elimination * * solution x returned in b */ int i,j,k,m; BOOL ok; flash w,s; w=mirvar(0); s=mirvar(0); ok=TRUE; for (i=0;i<n;i++) copy(b[i],A[i][n]); for (i=0;i<n;i++) { /* Gaussian elimination */ m=i; for (j=i+1;j<n;j++) { absol(A[j][i],w); absol(A[m][i],s); if (fcomp(w,s)>0) m=j; } if (m!=i) for (k=i;k<=n;k++) { copy(A[i][k],w); copy(A[m][k],A[i][k]); copy(w,A[m][k]); } if (size(A[i][i])==0) { ok=FALSE; break; } for (j=i+1;j<n;j++) { fdiv(A[j][i],A[i][i],s); for (k=n;k>=i;k--) { fmul(s,A[i][k],w); fsub(A[j][k],w,A[j][k]); } } } if (ok) for (j=n-1;j>=0;j--) { /* Backward substitution */ zero(s); for (k=j+1;k<n;k++) { fmul(A[j][k],b[k],w); fadd(s,w,s); } fsub(A[j][n],s,w); if (size(A[j][j])==0) { ok=FALSE; break; } fdiv(w,A[j][j],b[j]); } mirkill(s); mirkill(w); return ok; }
uint32_t fsub(uint32_t a, uint32_t b) { return fadd(a, fneg(b)); }
int encode_op(char *opcode, char *op_data) { int rd,rs,rt,imm,funct,shaft,target; char tmp[256]; const char *fi = "%s %d"; const char *fg = "%s %%g%d"; const char *ff = "%s %%f%d"; const char *fl = "%s %s"; const char *fgi = "%s %%g%d, %d"; const char *fgl = "%s %%g%d, %s"; const char *fgg = "%s %%g%d, %%g%d"; const char *fggl = "%s %%g%d, %%g%d, %s"; const char *fggi = "%s %%g%d, %%g%d, %d"; const char *fggg = "%s %%g%d, %%g%d, %%g%d"; const char *fff = "%s %%f%d, %%f%d"; const char *fgf = "%s %%g%d, %%f%d"; const char *ffg = "%s %%f%d, %%g%d"; const char *fffl = "%s %%f%d, %%f%d, %s"; const char *ffff = "%s %%f%d, %%f%d, %%f%d"; const char *ffgi = "%s %%f%d, %%g%d, %d"; const char *ffgg = "%s %%f%d, %%g%d, %%g%d"; char lname[256]; shaft = funct = target = 0; if(strcmp(opcode, "mvhi") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return mvhi(rs,0,imm); } if(strcmp(opcode, "mvlo") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return mvlo(rs,0,imm); } if(strcmp(opcode, "add") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return add(rs,rt,rd,0); } if(strcmp(opcode, "nor") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return nor(rs,rt,rd,0); } if(strcmp(opcode, "sub") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return sub(rs,rt,rd,0); } if(strcmp(opcode, "mul") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return mul(rs,rt,rd,0); } if(strcmp(opcode, "addi") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return addi(rs,rt,imm); } if(strcmp(opcode, "subi") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return subi(rs,rt,imm); } if(strcmp(opcode, "muli") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return muli(rs,rt,imm); } if(strcmp(opcode, "input") == 0){ if(sscanf(op_data, fg, tmp, &rd) == 2) return input(0,0,rd,0); } if(strcmp(opcode, "inputw") == 0){ if(sscanf(op_data, fg, tmp, &rd) == 2) return inputw(0,0,rd,0); } if(strcmp(opcode, "inputf") == 0){ if(sscanf(op_data, ff, tmp, &rd) == 2) return inputf(0,0,rd,0); } if(strcmp(opcode, "output") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return output(rs,0,0,0); } if(strcmp(opcode, "outputw") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return outputw(rs,0,0,0); } if(strcmp(opcode, "outputf") == 0){ if(sscanf(op_data, ff, tmp, &rs) == 2) return outputf(rs,0,0,0); } if(strcmp(opcode, "and") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return _and(rs,rt,rd,0); } if(strcmp(opcode, "or") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return _or(rs,rt,rd,0); } if(strcmp(opcode, "sll") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return sll(rs,rt,rd,0); } if(strcmp(opcode, "srl") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return srl(rs,rt,rd,0); } if(strcmp(opcode, "slli") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return slli(rs,rt,imm); } if(strcmp(opcode, "srli") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return srli(rs,rt,imm); } if(strcmp(opcode, "b") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return b(rs,0,0,0); } if(strcmp(opcode, "jmp") == 0){ if(sscanf(op_data, fl, tmp, lname) == 2) { strcpy(label_name[label_cnt],lname); return jmp(label_cnt++); } } if(strcmp(opcode, "jeq") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jeq(rs,rt,label_cnt++); } } if(strcmp(opcode, "jne") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jne(rs,rt,label_cnt++); } } if(strcmp(opcode, "jlt") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jlt(rs,rt,label_cnt++); } } if(strcmp(opcode, "jle") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jle(rs,rt,label_cnt++); } } if(strcmp(opcode, "call") == 0){ if(sscanf(op_data, fl, tmp, lname) == 2) { strcpy(label_name[label_cnt],lname); return call(label_cnt++); } } if(strcmp(opcode, "callR") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return callr(rs,0,0,0); } if(strcmp(opcode, "return") == 0){ return _return(0); } if(strcmp(opcode, "ld") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return ld(rs,rt,rd,0); } if(strcmp(opcode, "ldi") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return ldi(rs,rt,imm); } if(strcmp(opcode, "ldlr") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return ldlr(rs,0,imm); } if(strcmp(opcode, "fld") == 0){ if(sscanf(op_data, ffgg, tmp, &rd, &rs,&rt) == 4) return fld(rs,rt,rd,0); } if(strcmp(opcode, "st") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return st(rs,rt,rd,0); } if(strcmp(opcode, "sti") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return sti(rs,rt,imm); } if(strcmp(opcode, "stlr") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return stlr(rs,0,imm); } if(strcmp(opcode, "fst") == 0){ if(sscanf(op_data, ffgg, tmp, &rd, &rs,&rt) == 4) return fst(rs,rt,rd,0); } if(strcmp(opcode, "fadd") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fadd(rs,rt,rd,0); } if(strcmp(opcode, "fsub") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fsub(rs,rt,rd,0); } if(strcmp(opcode, "fmul") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fmul(rs,rt,rd,0); } if(strcmp(opcode, "fdiv") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fdiv(rs,rt,rd,0); } if(strcmp(opcode, "fsqrt") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return fsqrt(rs,0,rd,0); } if(strcmp(opcode, "fabs") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return _fabs(rs,0,rd,0); } if(strcmp(opcode, "fmov") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return fmov(rs,0,rd,0); } if(strcmp(opcode, "fneg") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return fneg(rs,0,rd,0); } if(strcmp(opcode, "fldi") == 0){ if(sscanf(op_data, ffgi, tmp, &rt, &rs, &imm) == 4) return fldi(rs,rt,imm); } if(strcmp(opcode, "fsti") == 0){ if(sscanf(op_data, ffgi, tmp, &rt, &rs, &imm) == 4) return fsti(rs,rt,imm); } if(strcmp(opcode, "fjeq") == 0){ if(sscanf(op_data, fffl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return fjeq(rs,rt,label_cnt++); } } if(strcmp(opcode, "fjlt") == 0){ if(sscanf(op_data, fffl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return fjlt(rs,rt,label_cnt++); } } if(strcmp(opcode, "halt") == 0){ return halt(0,0,0,0); } if(strcmp(opcode, "setL") == 0){ if(sscanf(op_data, fgl, tmp, &rd, lname) == 3) { strcpy(label_name[label_cnt],lname); return setl(0,rd,label_cnt++); } } if(strcmp(opcode, "padd") == 0){ if(sscanf(op_data, fgi, tmp, &rt, &imm) == 3) { return padd(0,rt,imm); } } if(strcmp(opcode, "link") == 0){ if(sscanf(op_data, fi, tmp, &imm) == 2) { return link(0,0,imm); } } if(strcmp(opcode, "movlr") == 0){ return movlr(0,0,0,0); } if(strcmp(opcode, "btmplr") == 0){ return btmplr(0,0,0,0); } /* if(strcmp(opcode, "padd") == 0){ if(sscanf(op_data, fgg, tmp, &rd, &rt) == 3) { return padd(0,rt,d,0); } } */ return -1; }
void ANCFBeamBE2D::EvalF2(Vector& f, double t) { Body2D::EvalF2(f, t); TMStartTimer(22); // do the computation /*ConstVector<ANCFBeamBE2DmaxDOF> fadd(2*NS()); // temporary storage vector ConstVector<ANCFBeamBE2DmaxDOF> delta_eps(2*NS()), delta_kappa(2*NS()); double EI = GetBeamEIy(); double EA = GetBeamEA(); for (IntegrationPointsIterator ip(integrationRuleStiffness); !ip.IsEnd(); ++ip) { double x = ip.Point2D().X(); double eps = GetEpsAxial(x); double kappa = GetKappa(x); GetDeltaEpsAxial(x, delta_eps); GetDeltaKappa(x, delta_kappa); fadd += ((EA*eps)*delta_eps + (EI*kappa)*delta_kappa) * (ip.Weight() * lx*0.5); } f -= fadd;*/ ConstVector<ANCFBeamBE2DmaxDOF> fadd(2*NS()); // temporary storage vector ConstVector<ANCFBeamBE2DmaxDOF> delta_eps(2*NS()), delta_kappa(2*NS()); double EI = GetBeamEIy(); double EA = GetBeamEA(); for (IntegrationPointsIterator ip(integrationRuleStiffness); !ip.IsEnd(); ++ip) { double x = ip.Point2D().X(); //Vector2D rx = GetPosx2D(x); //Vector2D rxx = GetPosxx2D(x); Vector2D rx, rxx; for (int i = 1; i <= NS(); i++) { //double sx = ip.GetVectorData(1)->Get(i) * 2./lx; //double sxx = ip.GetVectorData(2)->Get(i) * 4./(lx*lx); double sx = GetS0x(x, i) * 2./GetLx(); double sxx = GetS0xx(x, i) * 4./(GetLx()*GetLx()); double d1 = q0(2*i-1) + XG(2*i-1); double d2 = q0(2*i ) + XG(2*i ); rx(1) += sx * d1; rx(2) += sx * d2; rxx(1) += sxx * d1; rxx(2) += sxx * d2; } double rxn2 = rx.Norm2(); double eps = rx.Norm() - 1.0; double kappa = (rx.Cross(rxx))/rxn2; double d = 1./rx.Norm(); double kdux = -2.*rx(1)*kappa / rxn2 + rxx(2) / rxn2; double kduxx = -rx(2) / rxn2; double kdwx = -2.*rx(2)*kappa / rxn2 - rxx(1) / rxn2; double kdwxx = rx(1) / rxn2; for (int j = 1; j <= NS(); j++) { double sx = GetS0x(x, j) * 2./GetLx(); double sxx = GetS0xx(x, j) * 4./(GetLx()*GetLx()); //double sx = ip.GetVectorData(1)->Get(j) * 2./lx; //double sxx = ip.GetVectorData(2)->Get(j) * 4./(lx*lx); delta_eps(2*j-1) = d * rx(1) * sx; delta_eps(2*j ) = d * rx(2) * sx; delta_kappa(2*j-1) = (kdux * sx + kduxx * sxx); delta_kappa(2*j ) = (kdwx * sx + kdwxx * sxx); } fadd += ((EA*eps)*delta_eps + (EI*kappa)*delta_kappa) * (ip.Weight() * GetLx()*0.5); } f -= fadd; TMStopTimer(22); };
STATIC unsigned fsub(unsigned fa, unsigned fb) { return fadd(fa, fneg(fb)); }
float fsub(float in1, float in2) { return fadd(in1,(in2*-1)); }
int main() { float_b f1,f2,f3,f4; int i = 0; int c1 = 0; int c2 = 0; int c3 = 0; int c4 = 0; srand(time(NULL)); while(i < 1000000) { //正規化数ランダム f1.ieee.sign = rand()%2; f1.ieee.exp = rand()%254+1; f1.ieee.fraction = rand()%8388608; f2.ieee.sign = rand()%2; f2.ieee.exp = rand()%254+1; f2.ieee.fraction = rand()%8388608; f3.f = f1.f + f2.f; f4.f = fadd(f1.f,f2.f); if (f3.f != f4.f && (f3.ieee.exp != 0 || f4.ieee.exp != 0) && (f3.ieee.exp != 255 || f4.ieee.exp != 255)) { printf("%f+%f=%f\n",f1.f,f2.f,f3.f); print_bit(f3); print_bit(f4); } else { c1++; } f3.f = f1.f * f2.f; f4.f = fmul(f1.f,f2.f); if (f3.f != f4.f && (f3.ieee.exp != 0 || f4.ieee.exp != 0) && (f3.ieee.exp != 255 || (f4.ieee.exp != 0 && f4.ieee.exp != 255))) { printf("%f*%f=%f\n",f1.f,f2.f,f3.f); print_bit(f3); print_bit(f4); } else { c2++; } f3.f = f1.f / f2.f; f4.f = fdiv(f1.f,f2.f); if (f3.f != f4.f && ((f3.ieee.exp != 0 && f3.ieee.exp != 255) || (f4.ieee.exp != 0 && f4.ieee.exp != 255))) { printf("%f/%f=%f\n",f1.f,f2.f,f3.f); print_bit(f3); print_bit(f4); } else { c3++; } f1.ieee.sign = 0; f3.f = sqrtf(f1.f); f4.f = sqrt_m(f1.f); if (f3.f != f4.f) { printf("sqrt(%f)=%f\n",f1.f,f3.f); print_bit(f3); print_bit(f4); } else { c4++; } i++; } printf("fadd:%d fmul:%d fdiv:%d sqrt:%d\n",c1,c2,c3,c4); i = 0; c1 = 0; c2 = 0; c3 = 0; c4 = 0; while(i < 1000000) { //0.0に対する計算 f1.ieee.sign = rand()%2; f1.ieee.exp = (rand()%254+1)*(i%2); f1.ieee.fraction = rand()%8388608; f2.ieee.sign = rand()%2; f2.ieee.exp = (rand()%254+1)*((i+1)%2); f2.ieee.fraction = rand()%8388608; if (i%2 == 1) f3.f = f1.f; else f3.f = f2.f; f4.f = fadd(f1.f,f2.f); if (f3.f != f4.f) { printf("%f+%f=%f\n",f1.f,f2.f,f3.f); print_bit(f3); print_bit(f4); } else { c1++; } f3.ieee.sign = (f1.ieee.sign + f2.ieee.sign)%2; f3.ieee.exp = 0; f3.ieee.fraction = f1.ieee.fraction; f4.f = fmul(f1.f,f2.f); if (f3.f != f4.f) { printf("%f*%f=%f\n",f1.f,f2.f,f3.f); print_bit(f3); print_bit(f4); } else { c2++; } if (i%2 == 1) { f3.ieee.sign = f1.ieee.sign + f2.ieee.sign; f3.ieee.exp = 255; f3.ieee.fraction = f1.ieee.fraction; } else { f3.f = 0.0 / f2.f; } f4.f = fdiv(f1.f,f2.f); if ((f3.ieee.sign != f4.ieee.sign || f3.ieee.exp != f4.ieee.exp || f3.ieee.fraction != f4.ieee.fraction) && (i%2 == 1 || (f3.ieee.exp != 0 && f3.ieee.exp != 255) || (f4.ieee.exp != 0 && f4.ieee.exp != 255))) { printf("%f/%f=%f\n",f1.f,f2.f,f3.f); print_bit(f3); print_bit(f4); } else { c3++; } f1.ieee.sign = 0; if (i%2 == 1) f3.f = sqrtf(f1.f); else f3.f = f1.f; f4.f = sqrt_m(f1.f); if (f3.f != f4.f) { printf("sqrt(%f)=%f\n",f1.f,f3.f); print_bit(f3); print_bit(f4); } else { c4++; } i++; } printf("コーナーケース\n"); printf("0.0(とみなされる数)の演算 fadd:%d fmul:%d fdiv:%d sqrt:%d\n",c1,c2,c3,c4); i = 0; c1 = 0; c2 = 0; c3 = 0; c4 = 0; while(i < 1000000) { f1.ieee.sign = rand()%2; f1.ieee.exp = (rand()%254+1); f1.ieee.fraction = rand()%8388608; f2.ieee.sign = rand()%2; f2.ieee.exp = f1.ieee.exp + (rand()%3-1); f2.ieee.fraction = rand()%8388608; if (f2.ieee.exp == 255) f2.ieee.exp = 254; if (f2.ieee.exp == 0) f2.ieee.exp = 1; f3.f = f1.f + f2.f; f4.f = fadd(f1.f,f2.f); if (f3.f != f4.f && (f3.ieee.exp != 0 || f4.ieee.exp != 0) && (f3.ieee.exp != 255 || f4.ieee.exp != 255)) { print_bit(f1); print_bit(f2); printf("%f+%f=%f\n",f1.f,f2.f,f3.f); print_bit(f3); print_bit(f4); } else { c1++; } f2.f = f1.f; f2.ieee.sign = f1.ieee.sign + 1; f3.f = f1.f + f2.f; f4.f = fadd(f1.f,f2.f); if (f3.f != f4.f && (f3.ieee.exp != 0 || f4.ieee.exp != 0) && (f3.ieee.exp != 255 || f4.ieee.exp != 255)) { printf("%f+%f=%f\n",f1.f,f2.f,f3.f); print_bit(f3); print_bit(f4); } else { c2++; } i++; } printf("指数の差が高々1 fadd:%d\n",c1); printf("絶対値が等しく符号が逆 fadd:%d\n",c2); return 0; }
static BOOL act(int p,int q) { /* act on selected key */ int k,n,c; aprint(PRESSED,4+5*p,6+3*q,keys[q][p]); switch(p+7*q) { case 0: if (degrees) fmul(x,radeg,x); if (hyp) fsinh(x,x); else fsin(x,x); newx=TRUE; break; case 1: if (degrees) fmul(x,radeg,x); if (hyp) fcosh(x,x); else fcos(x,x); newx=TRUE; break; case 2: if (degrees) fmul(x,radeg,x); if (hyp) ftanh(x,x); else ftan(x,x); newx=TRUE; break; case 3: if (lgbase>0) { n=size(x); if (abs(n)<MR_TOOBIG) { convert(lgbase,x); if (n<0) frecip(x,x); fpower(x,abs(n),x); newx=TRUE; break; } if (lgbase==2) fmul(x,loge2,x); if (lgbase==10) fmul(x,loge10,x); } fexp(x,x); newx=TRUE; break; case 4: mip->RPOINT=!mip->RPOINT; newx=TRUE; break; case 5: clrall(); newx=TRUE; break; case 6: return TRUE; case 7: if (hyp) fasinh(x,x); else fasin(x,x); if (degrees) fdiv(x,radeg,x); newx=TRUE; break; case 8: if (hyp) facosh(x,x); else facos(x,x); if (degrees) fdiv(x,radeg,x); newx=TRUE; break; case 9: if (hyp) fatanh(x,x); else fatan(x,x); if (degrees) fdiv(x,radeg,x); newx=TRUE; break; case 10: flog(x,x); if (lgbase==2) fdiv(x,loge2,x); if (lgbase==10) fdiv(x,loge10,x); newx=TRUE; break; case 11: newx=TRUE; k=3; forever { aprint(INVER,2+stptr[k],2,settings[k][option[k]]); curser(2+stptr[k],2); c=arrow(gethit()); if (c==1) { if (option[k]==nops[k]) option[k]=0; else option[k]+=1; continue; } aprint(STATCOL,2+stptr[k],2,settings[k][option[k]]); if (c==0 || c==2) break; if (c==4 && k>0) k--; if (c==3 && k<3) k++; } setopts(); break; case 12: chekit(7); break; case 13: result=FALSE; if (ipt==0) break; ipt--; mybuff[ipt]='\0'; if (ipt==0) clr(); just(mybuff); cinstr(x,mybuff); newx=TRUE; break; case 14: if (!next('7')) putchar(BELL); break; case 15: if (!next('8')) putchar(BELL); break; case 16: if (!next('9')) putchar(BELL); break; case 17: chekit(6); break; case 18: chekit(5); break; case 19: chekit(4); break; case 20: copy(m,x); newx=TRUE; break; case 21: if (!next('4')) putchar(BELL); break; case 22: if (!next('5')) putchar(BELL); break; case 23: if (!next('6')) putchar(BELL); break; case 24: fmul(x,x,x); newx=TRUE; break; case 25: froot(x,2,x); newx=TRUE; break; case 26: chekit(3); break; case 27: brkt=0; chekit(0); flag=OFF; fadd(m,x,m); newx=TRUE; break; case 28: if (!next('1')) putchar(BELL); break; case 29: if (!next('2')) putchar(BELL); break; case 30: if (!next('3')) putchar(BELL); break; case 31: frecip(x,x); newx=TRUE; break; case 32: fpi(x); newx=TRUE; break; case 33: chekit(2); break; case 34: negify(x,x); newx=TRUE; break; case 35: if (!next('0')) putchar(BELL); break; case 36: if (!next('/')) putchar(BELL); break; case 37: if (!next('.')) putchar(BELL); break; case 38: if (ipt>0) { putchar(BELL); result=FALSE; } else { zero(x); brkt+=1; newx=TRUE; } break; case 39: if (brkt>0) { chekit(0); brkt-=1; } else { putchar(BELL); result=FALSE; } break; case 40: chekit(1); break; case 41: brkt=0; equals(0); flag=OFF; break; } return FALSE; }
static int math_emulate(struct trapframe * info) { unsigned short code; temp_real tmp; char * address; u_long oldeip; /* ever used fp? */ if ((((struct pcb *)curproc->p_addr)->pcb_flags & FP_SOFTFP) == 0) { ((struct pcb *)curproc->p_addr)->pcb_flags |= FP_SOFTFP; I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; } if (I387.cwd & I387.swd & 0x3f) I387.swd |= 0x8000; else I387.swd &= 0x7fff; oldeip = info->tf_eip; /* 0x001f means user code space */ if ((u_short)info->tf_cs != 0x001F) { printf("math_emulate: %04x:%08lx\n", (u_short)info->tf_cs, oldeip); panic("?Math emulation needed in kernel?"); } code = get_fs_word((unsigned short *) oldeip); bswapw(code); code &= 0x7ff; I387.fip = oldeip; *(unsigned short *) &I387.fcs = (u_short) info->tf_cs; *(1+(unsigned short *) &I387.fcs) = code; info->tf_eip += 2; switch (code) { case 0x1d0: /* fnop */ return(0); case 0x1d1: case 0x1d2: case 0x1d3: /* fst to 32-bit mem */ case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7: math_abort(info,SIGILL); case 0x1e0: /* fchs */ ST(0).exponent ^= 0x8000; return(0); case 0x1e1: /* fabs */ ST(0).exponent &= 0x7fff; return(0); case 0x1e2: case 0x1e3: math_abort(info,SIGILL); case 0x1e4: /* ftst */ ftst(PST(0)); return(0); case 0x1e5: /* fxam */ printf("fxam not implemented\n"); math_abort(info,SIGILL); case 0x1e6: case 0x1e7: /* fldenv */ math_abort(info,SIGILL); case 0x1e8: /* fld1 */ fpush(); ST(0) = CONST1; return(0); case 0x1e9: /* fld2t */ fpush(); ST(0) = CONSTL2T; return(0); case 0x1ea: /* fld2e */ fpush(); ST(0) = CONSTL2E; return(0); case 0x1eb: /* fldpi */ fpush(); ST(0) = CONSTPI; return(0); case 0x1ec: /* fldlg2 */ fpush(); ST(0) = CONSTLG2; return(0); case 0x1ed: /* fldln2 */ fpush(); ST(0) = CONSTLN2; return(0); case 0x1ee: /* fldz */ fpush(); ST(0) = CONSTZ; return(0); case 0x1ef: math_abort(info,SIGILL); case 0x1f0: /* f2xm1 */ case 0x1f1: /* fyl2x */ case 0x1f2: /* fptan */ case 0x1f3: /* fpatan */ case 0x1f4: /* fxtract */ case 0x1f5: /* fprem1 */ case 0x1f6: /* fdecstp */ case 0x1f7: /* fincstp */ case 0x1f8: /* fprem */ case 0x1f9: /* fyl2xp1 */ case 0x1fa: /* fsqrt */ case 0x1fb: /* fsincos */ case 0x1fe: /* fsin */ case 0x1ff: /* fcos */ uprintf( "math_emulate: instruction %04x not implemented\n", code + 0xd800); math_abort(info,SIGILL); case 0x1fc: /* frndint */ frndint(PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1fd: /* fscale */ /* incomplete and totally inadequate -wfj */ Fscale(PST(0), PST(1), &tmp); real_to_real(&tmp,&ST(0)); return(0); /* 19 Sep 92*/ case 0x2e9: /* ????? */ /* if this should be a fucomp ST(0),ST(1) , it must be a 0x3e9 ATS */ fucom(PST(1),PST(0)); fpop(); fpop(); return(0); case 0x3d0: case 0x3d1: /* fist ?? */ return(0); case 0x3e2: /* fclex */ I387.swd &= 0x7f00; return(0); case 0x3e3: /* fninit */ I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; return(0); case 0x3e4: return(0); case 0x6d9: /* fcompp */ fcom(PST(1),PST(0)); fpop(); fpop(); return(0); case 0x7e0: /* fstsw ax */ *(short *) &info->tf_eax = I387.swd; return(0); } switch (code >> 3) { case 0x18: /* fadd */ fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x19: /* fmul */ fmul(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1a: /* fcom */ fcom(PST(code & 7),PST(0)); return(0); case 0x1b: /* fcomp */ fcom(PST(code & 7),PST(0)); fpop(); return(0); case 0x1c: /* fsubr */ real_to_real(&ST(code & 7),&tmp); tmp.exponent ^= 0x8000; fadd(PST(0),&tmp,&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1d: /* fsub */ ST(0).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1e: /* fdivr */ fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1f: /* fdiv */ fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x38: /* fld */ fpush(); ST(0) = ST((code & 7)+1); /* why plus 1 ????? ATS */ return(0); case 0x39: /* fxch */ fxchg(&ST(0),&ST(code & 7)); return(0); case 0x3b: /* ??? ??? wrong ???? ATS */ ST(code & 7) = ST(0); fpop(); return(0); case 0x98: /* fadd */ fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x99: /* fmul */ fmul(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x9a: /* ???? , my manual don't list a direction bit for fcom , ??? ATS */ fcom(PST(code & 7),PST(0)); return(0); case 0x9b: /* same as above , ATS */ fcom(PST(code & 7),PST(0)); fpop(); return(0); case 0x9c: /* fsubr */ ST(code & 7).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x9d: /* fsub */ real_to_real(&ST(0),&tmp); tmp.exponent ^= 0x8000; fadd(PST(code & 7),&tmp,&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x9e: /* fdivr */ fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x9f: /* fdiv */ fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0xb8: /* ffree */ printf("ffree not implemented\n"); math_abort(info,SIGILL); case 0xb9: /* fstp ???? where is the pop ? ATS */ fxchg(&ST(0),&ST(code & 7)); return(0); case 0xba: /* fst */ ST(code & 7) = ST(0); return(0); case 0xbb: /* ????? encoding of fstp to mem ? ATS */ ST(code & 7) = ST(0); fpop(); return(0); case 0xbc: /* fucom */ fucom(PST(code & 7),PST(0)); return(0); case 0xbd: /* fucomp */ fucom(PST(code & 7),PST(0)); fpop(); return(0); case 0xd8: /* faddp */ fadd(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xd9: /* fmulp */ fmul(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xda: /* ??? encoding of ficom with 16 bit mem ? ATS */ fcom(PST(code & 7),PST(0)); fpop(); return(0); case 0xdc: /* fsubrp */ ST(code & 7).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xdd: /* fsubp */ real_to_real(&ST(0),&tmp); tmp.exponent ^= 0x8000; fadd(PST(code & 7),&tmp,&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xde: /* fdivrp */ fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xdf: /* fdivp */ fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xf8: /* fild 16-bit mem ???? ATS */ printf("ffree not implemented\n"); math_abort(info,SIGILL); fpop(); return(0); case 0xf9: /* ????? ATS */ fxchg(&ST(0),&ST(code & 7)); return(0); case 0xfa: /* fist 16-bit mem ? ATS */ case 0xfb: /* fistp 16-bit mem ? ATS */ ST(code & 7) = ST(0); fpop(); return(0); } switch ((code>>3) & 0xe7) { case 0x22: put_short_real(PST(0),info,code); return(0); case 0x23: put_short_real(PST(0),info,code); fpop(); return(0); case 0x24: address = ea(info,code); for (code = 0 ; code < 7 ; code++) { ((long *) & I387)[code] = get_fs_long((unsigned long *) address); address += 4; } return(0); case 0x25: address = ea(info,code); *(unsigned short *) &I387.cwd = get_fs_word((unsigned short *) address); return(0); case 0x26: address = ea(info,code); /*verify_area(address,28);*/ for (code = 0 ; code < 7 ; code++) { put_fs_long( ((long *) & I387)[code], (unsigned long *) address); address += 4; } return(0); case 0x27: address = ea(info,code); /*verify_area(address,2);*/ put_fs_word(I387.cwd,(short *) address); return(0); case 0x62: put_long_int(PST(0),info,code); return(0); case 0x63: put_long_int(PST(0),info,code); fpop(); return(0); case 0x65: fpush(); get_temp_real(&tmp,info,code); real_to_real(&tmp,&ST(0)); return(0); case 0x67: put_temp_real(PST(0),info,code); fpop(); return(0); case 0xa2: put_long_real(PST(0),info,code); return(0); case 0xa3: put_long_real(PST(0),info,code); fpop(); return(0); case 0xa4: address = ea(info,code); for (code = 0 ; code < 27 ; code++) { ((long *) & I387)[code] = get_fs_long((unsigned long *) address); address += 4; } return(0); case 0xa6: address = ea(info,code); /*verify_area(address,108);*/ for (code = 0 ; code < 27 ; code++) { put_fs_long( ((long *) & I387)[code], (unsigned long *) address); address += 4; } I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; return(0); case 0xa7: address = ea(info,code); /*verify_area(address,2);*/ put_fs_word(I387.swd,(short *) address); return(0); case 0xe2: put_short_int(PST(0),info,code); return(0); case 0xe3: put_short_int(PST(0),info,code); fpop(); return(0); case 0xe4: fpush(); get_BCD(&tmp,info,code); real_to_real(&tmp,&ST(0)); return(0); case 0xe5: fpush(); get_longlong_int(&tmp,info,code); real_to_real(&tmp,&ST(0)); return(0); case 0xe6: put_BCD(PST(0),info,code); fpop(); return(0); case 0xe7: put_longlong_int(PST(0),info,code); fpop(); return(0); } switch (code >> 9) { case 0: get_short_real(&tmp,info,code); break; case 1: get_long_int(&tmp,info,code); break; case 2: get_long_real(&tmp,info,code); break; case 4: get_short_int(&tmp,info,code); } switch ((code>>3) & 0x27) { case 0: fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 1: fmul(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 2: fcom(&tmp,PST(0)); return(0); case 3: fcom(&tmp,PST(0)); fpop(); return(0); case 4: tmp.exponent ^= 0x8000; fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 5: ST(0).exponent ^= 0x8000; fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 6: fdiv(PST(0),&tmp,&tmp); real_to_real(&tmp,&ST(0)); return(0); case 7: fdiv(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); } if ((code & 0x138) == 0x100) { fpush(); real_to_real(&tmp,&ST(0)); return(0); } printf("Unknown math-insns: %04x:%08x %04x\n",(u_short)info->tf_cs, info->tf_eip,code); math_abort(info,SIGFPE); }
static void equals(int no) { /* perform binary operation */ BOOL pop; newx=FALSE; pop=TRUE; while (pop) { if (prec(no)>prop[sp]) { /* if higher precedence, keep this one pending */ if (sp==top) { mip->ERNUM=(-1); result=FALSE; newx=TRUE; } else sp++; return; } newx=TRUE; if (flag && op[sp]!=3 && op[sp]!=0) swap(); switch (op[sp]) { case 7: fdiv(x,y[sp],t); ftrunc(t,t,t); fmul(t,y[sp],t); fsub(x,t,x); break; case 6: fpowf(x,y[sp],x); break; case 5: frecip(y[sp],t); fpowf(x,t,x); break; case 4: fdiv(x,y[sp],x); break; case 3: fmul(x,y[sp],x); break; case 2: fsub(x,y[sp],x); break; case 1: fadd(x,y[sp],x); break; case 0: break; } if (sp>0 && (prec(no)<=prop[sp-1])) sp--; else pop=FALSE; } }