15 for(i = 0; i < 8; i++)
20 fpatransfer(u32int instr)
37 Rn = P->R + ((instr >> 16) & 15);
38 Fd = P->F + ((instr >> 12) & 7);
41 off = (instr & 255) * 4;
47 targ = vaddr(addr, 8, &seg);
48 switch(instr & (fT0 | fT1 | fL)) {
49 case 0: *(float *) targ = *Fd; break;
50 case fL: *Fd = *(float *) targ; break;
51 case fT0: *(double *) targ = *Fd; break;
52 case fT0 | fL: *Fd = *(double *) targ; break;
53 default: invalid(instr);
63 fpasecop(u32int instr)
66 case 8: return 0.0; break;
67 case 9: return 1.0; break;
68 case 10: return 2.0; break;
69 case 11: return 3.0; break;
70 case 12: return 4.0; break;
71 case 13: return 5.0; break;
72 case 14: return 0.5; break;
73 case 15: return 10.0; break;
75 return P->F[instr & 7];
79 fpaoperation(u32int instr)
81 long double *Fn, *Fd, op, op2, res;
84 Fn = P->F + ((instr >> 16) & 7);
85 Fd = P->F + ((instr >> 12) & 7);
86 op2 = fpasecop(instr);
88 prec = ((instr >> 7) & 1) | ((instr >> 18) & 2);
89 opc = ((instr >> 20) & 15) | ((instr >> 11) & 16);
91 case 0: res = op + op2; break;
92 case 1: res = op * op2; break;
93 case 2: res = op - op2; break;
94 case 3: res = op2 - op; break;
95 case 4: res = op / op2; break;
96 case 5: res = op2 / op; break;
97 case 16: res = op2; break;
98 case 17: res = - op2; break;
99 case 18: res = fabs(op2); break;
100 case 19: res = (vlong) op2; break;
101 case 20: res = sqrt(op2); break;
102 default: sysfatal("unimplemented FPA operation %#x @ %8ux", opc, P->R[15] - 4);
106 case 0: *Fd = (float) res; break;
107 case 1: *Fd = (double) res; break;
108 case 2: *Fd = res; break;
109 default: invalid(instr);
114 fparegtransfer(u32int instr)
118 long double *Fn, op, op2;
120 Rd = P->R + ((instr >> 12) & 15);
121 Fn = P->F + ((instr >> 16) & 7);
122 op = fpasecop(instr);
123 if(Rd == P->R + 15) {
125 switch((instr >> 21) & 7) {
127 case 5: op = - op; break;
128 default: invalid(instr);
131 P->CPSR = (P->CPSR & ~FLAGS) | flN;
133 P->CPSR = (P->CPSR & ~FLAGS) | flC;
137 P->CPSR = (P->CPSR & ~FLAGS) | flV;
142 switch((instr >> 20) & 15) {
143 case 0: *Fn = *(long *) Rd; break;
144 case 1: tmp = op; *Rd = tmp; break;
145 case 2: P->FPSR = *Rd; break;
146 case 3: *Rd = P->FPSR; break;
147 default: invalid(instr);