📄 fpa_recompute.c
字号:
case 16: extended_precision(); result = reg_3_op + (reg_2_op * mem_op); break; case 17: extended_precision(); result = reg_3_op - (reg_2_op * mem_op); break; case 18: extended_precision(); result = (reg_2_op * mem_op) - reg_3_op; break; case 19: extended_precision(); result = reg_3_op * (reg_2_op + mem_op); break; case 20: extended_precision(); result = reg_3_op * (reg_2_op - mem_op); break; case 21: extended_precision(); result = reg_3_op * (mem_op - reg_2_op); break; case 22: extended_precision(); result = mem_op + (reg_2_op * reg_3_op); break; case 23: extended_precision(); result = mem_op - (reg_2_op * reg_3_op); break; case 24: extended_precision(); result = (reg_2_op * reg_3_op) - mem_op; break; case 25: extended_precision(); result = mem_op * (reg_2_op + reg_3_op); break; case 26: extended_precision(); result = mem_op * (reg_3_op - reg_2_op); break; case 28: /* complex addition */ complex2.d = reg_2_op; complex3.d = mem_op; complex1.f[0] = complex2.f[0]+complex3.f[0]; complex1.f[1] = complex2.f[1]+complex3.f[1]; result = complex1.d; break; case 29: /* complex subtraction */ complex2.d = reg_2_op; complex3.d = mem_op; complex1.f[0] = complex2.f[0]-complex3.f[0]; complex1.f[1] = complex2.f[1]-complex3.f[1]; result = complex1.d; break; case 30: /* complex multiplication */ extended_precision(); complex2.d = reg_2_op; complex3.d = mem_op; complex1.f[0] = complex2.f[0]*complex3.f[0]-complex2.f[1]*complex3.f[1]; complex1.f[1] = complex2.f[0]*complex3.f[1]+complex2.f[1]*complex3.f[0]; result = complex1.d; break; case 31: /* complex division */ extended_precision(); complex2.d = reg_2_op; complex3.d = mem_op; if (complex3.f[1] == 0) { /* Special case division by real. */ complex1.f[0]=complex2.f[0]/complex3.f[0]; complex1.f[1]=complex2.f[1]/complex3.f[0]; } else { /* General case. */ register double denominator = complex3.f[0] * complex3.f[0] + complex3.f[1] * complex3.f[1] ; complex1.f[0] = (complex2.f[0]*complex3.f[0]+complex2.f[1]*complex3.f[1])/denominator; complex1.f[1] = (complex2.f[1]*complex3.f[0]-complex2.f[0]*complex3.f[1])/denominator; } result = complex1.d; break; default: found = 0; } if (found) { if (prec) write_double(reg_1, result); else write_single(reg_1, result); }pastwrite: if (!found) fprintf(stderr, "\n Invalid result from failed FPA extended format instruction:\n operand %X reg_2 %g reg_3 %g \n", mem_op, reg_2_op, reg_3_op); return (found);}STATIC intextended_single(a1, a2) struct fpa_access *a1, *a2;/* Procedure to recompute extended single format instructions. */{ int found, opcode; struct fpa_access ac1, ac2; short reg_2, reg_3; double reg_2_op, reg_3_op, mem_op, mem_2_op; union singlekluge sk; ac1 = *a1; ac2 = *a2; reg_2 = ac1.kluge.kis.reg1; reg_2_op = read_single(reg_2); reg_3 = ac2.kluge.kis.op & 0xf; reg_3_op = read_single(reg_3); sk.i[0] = ac1.data; mem_op = sk.x; sk.i[0] = ac2.data; mem_2_op = sk.x; found = extended_semantics(ac1.kluge.kis.op & 0x1f, ac2.kluge.kis.reg1, ac1.kluge.kis.prec, mem_op, mem_2_op, reg_2_op, reg_3_op); return (found);}STATIC intextended_double(a1, a2) struct fpa_access *a1, *a2;/* Procedure to recompute extended double format instructions. */{ int found, opcode; struct fpa_access ac1, ac2; short reg_2, reg_3; double reg_2_op, reg_3_op, mem_op; union doublekluge dk; ac1 = *a1; ac2 = *a2; reg_2 = ac1.kluge.kis.reg1; reg_2_op = read_double(reg_2); reg_3 = ac2.kluge.kis.op & 0xf; reg_3_op = read_double(reg_3); dk.i[0] = ac1.data; dk.i[1] = ac2.data; mem_op = dk.x; found = extended_semantics(ac1.kluge.kis.op & 0x1f, ac2.kluge.kis.reg1, ac1.kluge.kis.prec, mem_op, 0.0, reg_2_op, reg_3_op); return (found);}STATIC intdirect_semantics(opcode, prec, data, pc) int opcode, prec, data;{ int found; double reg_2_op, reg_3_op, result; union singlekluge sk; found = 1; if (prec) { /* double */ reg_2_op = read_2_double(data); reg_3_op = read_3_double(data); } else { /* single */ reg_2_op = read_2_single(data); reg_3_op = read_3_single(data); } if ((opcode % 2) == 1) switch (opcode >> 4) { /* multiplier */ case 0: result = (reg_2_op) * (reg_3_op); break; case 1: result = fabs(reg_2_op) * (reg_3_op); break; case 2: result = (reg_2_op) * fabs(reg_3_op); break; case 3: result = fabs(reg_2_op) * fabs(reg_3_op); break; case 4: result = -(reg_2_op) * (reg_3_op); break; case 5: result = -fabs(reg_2_op) * (reg_3_op); break; case 6: result = -(reg_2_op) * fabs(reg_3_op); break; case 7: result = -fabs(reg_2_op) * fabs(reg_3_op); break; } else switch (opcode >> 1) { /* alu */ case 0: result = reg_2_op - reg_3_op; break; case 1: result = fabs(reg_2_op - reg_3_op); break; case 2: result = fabs(reg_2_op) - fabs(reg_3_op); break; case 3: result = reg_2_op / reg_3_op; break; case 4: result = -reg_2_op; break; case 8: result = reg_2_op + reg_3_op; break; case 9: result = fabs(reg_2_op + reg_3_op); break; case 10: result = fabs(reg_2_op) + fabs(reg_3_op); break; case 12: result = reg_2_op; break; case 14: result = fabs(reg_2_op); break; case 16: fpa_compare(reg_2_op, reg_3_op, pc); goto pastwrite; case 18: fpa_compare(fabs(reg_2_op), fabs(reg_3_op), pc); goto pastwrite; case 20: fpa_compare(reg_2_op, 0.0, pc); goto pastwrite; case 28: result = fpa_tolong(reg_2_op); write_long(data & 0x1f, result); goto pastwrite; case 29: sk.x = (float) read_2_single(data); result = sk.i[0]; break; case 30: if (prec) { /* double result */ reg_2_op = read_2_single(data); } else {/* single result */ reg_2_op = read_2_double(data); } result = (float) reg_2_op; break; default: found = 0; break; } if (found) { if (prec) write_double(data & 0x1f, result); else write_single(data & 0x1f, result); }pastwrite: if (!found) fprintf(stderr, "\n Invalid result from failed FPA direct format instruction:\n data %X reg_2 %g reg_3 %g \n", data, reg_2_op, reg_3_op); return (found);}STATIC intdirect_single(a1, pc) struct fpa_access *a1; unsigned short *pc;/* Procedure to recompute direct single format instructions. */{ return (direct_double(a1, pc));}STATIC intdirect_double(a1, pc) struct fpa_access *a1; unsigned short *pc;/* Procedure to recompute direct double format instructions. */{ int found, opcode, prec; struct fpa_access ac1; long data; ac1 = *a1; opcode = (ac1.kluge.kint >> 3) & 0x3f; prec = ac1.kluge.kis.prec; data = ac1.data; found = direct_semantics(opcode, prec, data, pc); return (found);}STATIC intcommand_semantics(opcode, prec, data) int opcode, prec, data;{ complexunion complex1, complex2, complex3; double reg_2_op, reg_3_op, reg_4_op, result; double r2_op[4], r3_op[4]; int found, rmax, ddata, i; double d1, d2; pdoublekluge pdk; found = 1; if (prec) { /* double */ reg_2_op = read_2_double(data); reg_3_op = read_3_double(data); reg_4_op = read_4_double(data); } else { /* single */ reg_2_op = read_2_single(data); reg_3_op = read_3_single(data); reg_4_op = read_4_single(data); } switch (opcode) { case 0: case 1: case 3: case 4: case 5: case 6: case 7: extended_precision(); result = fpa_transcendental(opcode, reg_2_op); break; case 8: /* sqrt */ result = fpa_transcendental(opcode, reg_2_op); break; case 9: /* hypot */ extended_precision(); pdk.pd[0] = (double *)®_3_op; pdk.pd[1] = (double *)®_2_op; result = fpa_transcendental(9, pdk.d); break; case 10: /* complex negation */ complex3.d = reg_2_op; complex1.f[0] = -complex3.f[0]; complex1.f[1] = -complex3.f[1]; result = complex1.d; break; case 11: /* complex absolute value */ extended_precision(); complex3.d = reg_2_op; d1=complex3.f[0]; d2=complex3.f[1]; pdk.pd[0] = (double *)&d1; pdk.pd[1] = (double *)&d2; result = (double) (float) fpa_transcendental(9, pdk.d); write_single(data & 0x1f, result); goto pastwrite; break; case 12: /* complex addition */ complex2.d = reg_2_op; complex3.d = reg_3_op; complex1.f[0] = complex2.f[0]+complex3.f[0]; complex1.f[1] = complex2.f[1]+complex3.f[1]; result = complex1.d; break; case 13: /* complex subtraction */ complex2.d = reg_2_op; complex3.d = reg_3_op; complex1.f[0] = complex2.f[0]-complex3.f[0]; complex1.f[1] = complex2.f[1]-complex3.f[1]; result = complex1.d; break; case 14: /* complex multiplication */ extended_precision(); complex2.d = reg_2_op; complex3.d = reg_3_op; complex1.f[0] = complex2.f[0]*complex3.f[0]-complex2.f[1]*complex3.f[1]; complex1.f[1] = complex2.f[0]*complex3.f[1]+complex2.f[1]*complex3.f[0]; result = complex1.d; break; case 15: /* complex division */ extended_precision(); complex2.d = reg_2_op; complex3.d = reg_3_op; if (complex3.f[1] == 0) { /* Special case division by real. */ complex1.f[0]=complex2.f[0]/complex3.f[0]; complex1.f[1]=complex2.f[1]/complex3.f[0]; } else { /* General case. */ register double denominator = complex3.f[0] * complex3.f[0] + complex3.f[1] * complex3.f[1] ; complex1.f[0] = (complex2.f[0]*complex3.f[0]+complex2.f[1]*complex3.f[1])/denominator; complex1.f[1] = (complex2.f[1]*complex3.f[0]-complex2.f[0]*complex3.f[1])/denominator; } result = complex1.d; break; case 48: /* sincos */ extended_precision(); result = fpa_transcendental(1, reg_2_op); /* cos */ if (prec) write_double((data >> 26) & 0x1f, result); else write_single((data >> 26) & 0x1f, result); result = fpa_transcendental(0, reg_2_op); /* sin */ break; case 17: extended_precision(); result = reg_3_op + (reg_2_op * reg_4_op); break; case 18: extended_precision(); result = reg_3_op - (reg_2_op * reg_4_op); break; case 19: extended_precision(); result = (reg_2_op * reg_4_op) - reg_3_op; break; case 20: extended_precision(); result = reg_3_op * (reg_2_op + reg_4_op); break; case 21: extended_precision(); result = reg_3_op * (reg_2_op - reg_4_op); break; case 22: extended_precision(); result = reg_3_op * (reg_4_op - reg_2_op); break; case 23: rmax = 1; goto vector; case 24: rmax = 2; goto vector; case 25: rmax = 3;vector: extended_precision(); r2_op[0] = reg_2_op; r3_op[0] = reg_3_op; ddata = data; for (i = 1; i <= rmax; i++) { ddata = data + 0x10040; /* increment reg_2 and reg_3 */ if (prec) { /* double */ r2_op[i] = read_2_double(ddata); r3_op[i] = read_3_double(ddata); } else {/* single */ r2_op[i] = read_2_single(ddata); r3_op[i] = read_3_single(ddata); } } switch (rmax) { /* write out in extenso to get maximum * benefit from extended precision evaluation */ case 1: result = r2_op[0] * r3_op[0] + r2_op[1] * r3_op[1]; break; case 2: result = r2_op[0] * r3_op[0] + r2_op[1] * r3_op[1] + r2_op[2] * r3_op[2]; break; case 3: result = r2_op[0] * r3_op[0] + r2_op[1] * r3_op[1] + r2_op[2] * r3_op[2] + r2_op[3] * r3_op[3]; break; } break; default: found = 0; break; } if (found) { if (prec) write_double(data & 0x1f, result); else write_single(data & 0x1f, result); }pastwrite: if (!found) fprintf(stderr, "\n Invalid result from failed FPA command format instruction:\n data %X reg_2 %g reg_3 %g \n", data, reg_2_op, reg_3_op); return (found);}STATIC intcommand_single(a1) struct fpa_access *a1;/* Procedure to recompute command single format instructions. */{ return (command_double(a1));}STATIC intcommand_double(a1) struct fpa_access *a1;/* Procedure to recompute command double format instructions. */{ int found, opcode, prec; struct fpa_access ac1; long data; ac1 = *a1; opcode = (ac1.kluge.kint >> 3) & 0x3f; prec = ac1.kluge.kis.prec; data = ac1.data; found = command_semantics(opcode, prec, data); return (found);}#ifdef F68881intfpa_81comp(x, pc)#endif#ifdef FSOFT int fpa_softcomp(x, pc)#endif struct fpa_inst *x; unsigned short *pc;/* Procedure to recompute an FPA instruction. */{ struct fpa_access *ap, ap0, ap1; int i, opcode, found; ap0 = x->a[0]; ap1 = x->a[1]; opcode = ap0.kluge.kis.op; if (opcode >= 0x20) { /* extended */ if (ap0.kluge.kis.prec == 1) found = extended_double(&ap0, &ap1); else found = extended_single(&ap0, &ap1); } else if (opcode >= 0x14) { /* direct */ if (ap0.kluge.kis.prec == 1) found = direct_double(&ap0, pc); else found = direct_single(&ap0, pc); } else if (opcode >= 0x10) { /* command */ if (ap0.kluge.kis.prec == 1) found = command_double(&ap0); else found = command_single(&ap0); } else { if (ap0.kluge.kis.prec == 1) found = short_double(&ap0, &ap1, pc); else found = short_single(&ap0, pc); } if (!found) for (i = 0; i < 2;) { ap = (struct fpa_access *) & (x->a[i++]); if (ap->kluge.kis.valid == 0) { fprintf(stderr, " access %1d op %2x reg %2d prec %1d data %8X \n", i, ap->kluge.kis.op, ap->kluge.kis.reg1, ap->kluge.kis.prec, ap->data); } } return (found);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -