xref: /netbsd/external/gpl3/gdb/dist/sim/v850/simops.c (revision 66e63ce3)
1*66e63ce3Schristos #include "sim-main.h"
2*66e63ce3Schristos #include "v850_sim.h"
3*66e63ce3Schristos #include "simops.h"
4*66e63ce3Schristos 
5*66e63ce3Schristos #include <sys/types.h>
6*66e63ce3Schristos 
7*66e63ce3Schristos #ifdef HAVE_UTIME_H
8*66e63ce3Schristos #include <utime.h>
9*66e63ce3Schristos #endif
10*66e63ce3Schristos 
11*66e63ce3Schristos #ifdef HAVE_TIME_H
12*66e63ce3Schristos #include <time.h>
13*66e63ce3Schristos #endif
14*66e63ce3Schristos 
15*66e63ce3Schristos #ifdef HAVE_UNISTD_H
16*66e63ce3Schristos #include <unistd.h>
17*66e63ce3Schristos #endif
18*66e63ce3Schristos 
19*66e63ce3Schristos #ifdef HAVE_STRING_H
20*66e63ce3Schristos #include <string.h>
21*66e63ce3Schristos #else
22*66e63ce3Schristos #ifdef HAVE_STRINGS_H
23*66e63ce3Schristos #include <strings.h>
24*66e63ce3Schristos #endif
25*66e63ce3Schristos #endif
26*66e63ce3Schristos 
27*66e63ce3Schristos #include "targ-vals.h"
28*66e63ce3Schristos 
29*66e63ce3Schristos #include "libiberty.h"
30*66e63ce3Schristos 
31*66e63ce3Schristos #include <errno.h>
32*66e63ce3Schristos #if !defined(__GO32__) && !defined(_WIN32)
33*66e63ce3Schristos #include <sys/stat.h>
34*66e63ce3Schristos #include <sys/times.h>
35*66e63ce3Schristos #include <sys/time.h>
36*66e63ce3Schristos #endif
37*66e63ce3Schristos 
38*66e63ce3Schristos /* This is an array of the bit positions of registers r20 .. r31 in
39*66e63ce3Schristos    that order in a prepare/dispose instruction.  */
40*66e63ce3Schristos int type1_regs[12] = { 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 0, 21 };
41*66e63ce3Schristos /* This is an array of the bit positions of registers r16 .. r31 in
42*66e63ce3Schristos    that order in a push/pop instruction.  */
43*66e63ce3Schristos int type2_regs[16] = { 3, 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
44*66e63ce3Schristos /* This is an array of the bit positions of registers r1 .. r15 in
45*66e63ce3Schristos    that order in a push/pop instruction.  */
46*66e63ce3Schristos int type3_regs[15] = { 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
47*66e63ce3Schristos 
48*66e63ce3Schristos #ifdef DEBUG
49*66e63ce3Schristos #ifndef SIZE_INSTRUCTION
50*66e63ce3Schristos #define SIZE_INSTRUCTION 18
51*66e63ce3Schristos #endif
52*66e63ce3Schristos 
53*66e63ce3Schristos #ifndef SIZE_VALUES
54*66e63ce3Schristos #define SIZE_VALUES 11
55*66e63ce3Schristos #endif
56*66e63ce3Schristos 
57*66e63ce3Schristos 
58*66e63ce3Schristos unsigned32 trace_values[3];
59*66e63ce3Schristos int trace_num_values;
60*66e63ce3Schristos unsigned32 trace_pc;
61*66e63ce3Schristos const char *trace_name;
62*66e63ce3Schristos int trace_module;
63*66e63ce3Schristos 
64*66e63ce3Schristos 
65*66e63ce3Schristos void
66*66e63ce3Schristos trace_input (name, type, size)
67*66e63ce3Schristos      char *name;
68*66e63ce3Schristos      enum op_types type;
69*66e63ce3Schristos      int size;
70*66e63ce3Schristos {
71*66e63ce3Schristos 
72*66e63ce3Schristos   if (!TRACE_ALU_P (STATE_CPU (simulator, 0)))
73*66e63ce3Schristos     return;
74*66e63ce3Schristos 
75*66e63ce3Schristos   trace_pc = PC;
76*66e63ce3Schristos   trace_name = name;
77*66e63ce3Schristos   trace_module = TRACE_ALU_IDX;
78*66e63ce3Schristos 
79*66e63ce3Schristos   switch (type)
80*66e63ce3Schristos     {
81*66e63ce3Schristos     default:
82*66e63ce3Schristos     case OP_UNKNOWN:
83*66e63ce3Schristos     case OP_NONE:
84*66e63ce3Schristos     case OP_TRAP:
85*66e63ce3Schristos       trace_num_values = 0;
86*66e63ce3Schristos       break;
87*66e63ce3Schristos 
88*66e63ce3Schristos     case OP_REG:
89*66e63ce3Schristos     case OP_REG_REG_MOVE:
90*66e63ce3Schristos       trace_values[0] = State.regs[OP[0]];
91*66e63ce3Schristos       trace_num_values = 1;
92*66e63ce3Schristos       break;
93*66e63ce3Schristos 
94*66e63ce3Schristos     case OP_BIT_CHANGE:
95*66e63ce3Schristos     case OP_REG_REG:
96*66e63ce3Schristos     case OP_REG_REG_CMP:
97*66e63ce3Schristos       trace_values[0] = State.regs[OP[1]];
98*66e63ce3Schristos       trace_values[1] = State.regs[OP[0]];
99*66e63ce3Schristos       trace_num_values = 2;
100*66e63ce3Schristos       break;
101*66e63ce3Schristos 
102*66e63ce3Schristos     case OP_IMM_REG:
103*66e63ce3Schristos     case OP_IMM_REG_CMP:
104*66e63ce3Schristos       trace_values[0] = SEXT5 (OP[0]);
105*66e63ce3Schristos       trace_values[1] = OP[1];
106*66e63ce3Schristos       trace_num_values = 2;
107*66e63ce3Schristos       break;
108*66e63ce3Schristos 
109*66e63ce3Schristos     case OP_IMM_REG_MOVE:
110*66e63ce3Schristos       trace_values[0] = SEXT5 (OP[0]);
111*66e63ce3Schristos       trace_num_values = 1;
112*66e63ce3Schristos       break;
113*66e63ce3Schristos 
114*66e63ce3Schristos     case OP_COND_BR:
115*66e63ce3Schristos       trace_values[0] = State.pc;
116*66e63ce3Schristos       trace_values[1] = SEXT9 (OP[0]);
117*66e63ce3Schristos       trace_values[2] = PSW;
118*66e63ce3Schristos       trace_num_values = 3;
119*66e63ce3Schristos       break;
120*66e63ce3Schristos 
121*66e63ce3Schristos     case OP_LOAD16:
122*66e63ce3Schristos       trace_values[0] = OP[1] * size;
123*66e63ce3Schristos       trace_values[1] = State.regs[30];
124*66e63ce3Schristos       trace_num_values = 2;
125*66e63ce3Schristos       break;
126*66e63ce3Schristos 
127*66e63ce3Schristos     case OP_STORE16:
128*66e63ce3Schristos       trace_values[0] = State.regs[OP[0]];
129*66e63ce3Schristos       trace_values[1] = OP[1] * size;
130*66e63ce3Schristos       trace_values[2] = State.regs[30];
131*66e63ce3Schristos       trace_num_values = 3;
132*66e63ce3Schristos       break;
133*66e63ce3Schristos 
134*66e63ce3Schristos     case OP_LOAD32:
135*66e63ce3Schristos       trace_values[0] = EXTEND16 (OP[2]);
136*66e63ce3Schristos       trace_values[1] = State.regs[OP[0]];
137*66e63ce3Schristos       trace_num_values = 2;
138*66e63ce3Schristos       break;
139*66e63ce3Schristos 
140*66e63ce3Schristos     case OP_STORE32:
141*66e63ce3Schristos       trace_values[0] = State.regs[OP[1]];
142*66e63ce3Schristos       trace_values[1] = EXTEND16 (OP[2]);
143*66e63ce3Schristos       trace_values[2] = State.regs[OP[0]];
144*66e63ce3Schristos       trace_num_values = 3;
145*66e63ce3Schristos       break;
146*66e63ce3Schristos 
147*66e63ce3Schristos     case OP_JUMP:
148*66e63ce3Schristos       trace_values[0] = SEXT22 (OP[0]);
149*66e63ce3Schristos       trace_values[1] = State.pc;
150*66e63ce3Schristos       trace_num_values = 2;
151*66e63ce3Schristos       break;
152*66e63ce3Schristos 
153*66e63ce3Schristos     case OP_IMM_REG_REG:
154*66e63ce3Schristos       trace_values[0] = EXTEND16 (OP[0]) << size;
155*66e63ce3Schristos       trace_values[1] = State.regs[OP[1]];
156*66e63ce3Schristos       trace_num_values = 2;
157*66e63ce3Schristos       break;
158*66e63ce3Schristos 
159*66e63ce3Schristos     case OP_IMM16_REG_REG:
160*66e63ce3Schristos       trace_values[0] = EXTEND16 (OP[2]) << size;
161*66e63ce3Schristos       trace_values[1] = State.regs[OP[1]];
162*66e63ce3Schristos       trace_num_values = 2;
163*66e63ce3Schristos       break;
164*66e63ce3Schristos 
165*66e63ce3Schristos     case OP_UIMM_REG_REG:
166*66e63ce3Schristos       trace_values[0] = (OP[0] & 0xffff) << size;
167*66e63ce3Schristos       trace_values[1] = State.regs[OP[1]];
168*66e63ce3Schristos       trace_num_values = 2;
169*66e63ce3Schristos       break;
170*66e63ce3Schristos 
171*66e63ce3Schristos     case OP_UIMM16_REG_REG:
172*66e63ce3Schristos       trace_values[0] = (OP[2]) << size;
173*66e63ce3Schristos       trace_values[1] = State.regs[OP[1]];
174*66e63ce3Schristos       trace_num_values = 2;
175*66e63ce3Schristos       break;
176*66e63ce3Schristos 
177*66e63ce3Schristos     case OP_BIT:
178*66e63ce3Schristos       trace_num_values = 0;
179*66e63ce3Schristos       break;
180*66e63ce3Schristos 
181*66e63ce3Schristos     case OP_EX1:
182*66e63ce3Schristos       trace_values[0] = PSW;
183*66e63ce3Schristos       trace_num_values = 1;
184*66e63ce3Schristos       break;
185*66e63ce3Schristos 
186*66e63ce3Schristos     case OP_EX2:
187*66e63ce3Schristos       trace_num_values = 0;
188*66e63ce3Schristos       break;
189*66e63ce3Schristos 
190*66e63ce3Schristos     case OP_LDSR:
191*66e63ce3Schristos       trace_values[0] = State.regs[OP[0]];
192*66e63ce3Schristos       trace_num_values = 1;
193*66e63ce3Schristos       break;
194*66e63ce3Schristos 
195*66e63ce3Schristos     case OP_STSR:
196*66e63ce3Schristos       trace_values[0] = State.sregs[OP[1]];
197*66e63ce3Schristos       trace_num_values = 1;
198*66e63ce3Schristos     }
199*66e63ce3Schristos 
200*66e63ce3Schristos }
201*66e63ce3Schristos 
202*66e63ce3Schristos void
203*66e63ce3Schristos trace_result (int has_result, unsigned32 result)
204*66e63ce3Schristos {
205*66e63ce3Schristos   char buf[1000];
206*66e63ce3Schristos   char *chp;
207*66e63ce3Schristos 
208*66e63ce3Schristos   buf[0] = '\0';
209*66e63ce3Schristos   chp = buf;
210*66e63ce3Schristos 
211*66e63ce3Schristos   /* write out the values saved during the trace_input call */
212*66e63ce3Schristos   {
213*66e63ce3Schristos     int i;
214*66e63ce3Schristos     for (i = 0; i < trace_num_values; i++)
215*66e63ce3Schristos       {
216*66e63ce3Schristos 	sprintf (chp, "%*s0x%.8lx", SIZE_VALUES - 10, "",
217*66e63ce3Schristos 		 (long) trace_values[i]);
218*66e63ce3Schristos 	chp = strchr (chp, '\0');
219*66e63ce3Schristos       }
220*66e63ce3Schristos     while (i++ < 3)
221*66e63ce3Schristos       {
222*66e63ce3Schristos 	sprintf (chp, "%*s", SIZE_VALUES, "");
223*66e63ce3Schristos 	chp = strchr (chp, '\0');
224*66e63ce3Schristos       }
225*66e63ce3Schristos   }
226*66e63ce3Schristos 
227*66e63ce3Schristos   /* append any result to the end of the buffer */
228*66e63ce3Schristos   if (has_result)
229*66e63ce3Schristos     sprintf (chp, " :: 0x%.8lx", (unsigned long)result);
230*66e63ce3Schristos 
231*66e63ce3Schristos   trace_generic (simulator, STATE_CPU (simulator, 0), trace_module, buf);
232*66e63ce3Schristos }
233*66e63ce3Schristos 
234*66e63ce3Schristos void
235*66e63ce3Schristos trace_output (result)
236*66e63ce3Schristos      enum op_types result;
237*66e63ce3Schristos {
238*66e63ce3Schristos   if (!TRACE_ALU_P (STATE_CPU (simulator, 0)))
239*66e63ce3Schristos     return;
240*66e63ce3Schristos 
241*66e63ce3Schristos   switch (result)
242*66e63ce3Schristos     {
243*66e63ce3Schristos     default:
244*66e63ce3Schristos     case OP_UNKNOWN:
245*66e63ce3Schristos     case OP_NONE:
246*66e63ce3Schristos     case OP_TRAP:
247*66e63ce3Schristos     case OP_REG:
248*66e63ce3Schristos     case OP_REG_REG_CMP:
249*66e63ce3Schristos     case OP_IMM_REG_CMP:
250*66e63ce3Schristos     case OP_COND_BR:
251*66e63ce3Schristos     case OP_STORE16:
252*66e63ce3Schristos     case OP_STORE32:
253*66e63ce3Schristos     case OP_BIT:
254*66e63ce3Schristos     case OP_EX2:
255*66e63ce3Schristos       trace_result (0, 0);
256*66e63ce3Schristos       break;
257*66e63ce3Schristos 
258*66e63ce3Schristos     case OP_LOAD16:
259*66e63ce3Schristos     case OP_STSR:
260*66e63ce3Schristos       trace_result (1, State.regs[OP[0]]);
261*66e63ce3Schristos       break;
262*66e63ce3Schristos 
263*66e63ce3Schristos     case OP_REG_REG:
264*66e63ce3Schristos     case OP_REG_REG_MOVE:
265*66e63ce3Schristos     case OP_IMM_REG:
266*66e63ce3Schristos     case OP_IMM_REG_MOVE:
267*66e63ce3Schristos     case OP_LOAD32:
268*66e63ce3Schristos     case OP_EX1:
269*66e63ce3Schristos       trace_result (1, State.regs[OP[1]]);
270*66e63ce3Schristos       break;
271*66e63ce3Schristos 
272*66e63ce3Schristos     case OP_IMM_REG_REG:
273*66e63ce3Schristos     case OP_UIMM_REG_REG:
274*66e63ce3Schristos     case OP_IMM16_REG_REG:
275*66e63ce3Schristos     case OP_UIMM16_REG_REG:
276*66e63ce3Schristos       trace_result (1, State.regs[OP[1]]);
277*66e63ce3Schristos       break;
278*66e63ce3Schristos 
279*66e63ce3Schristos     case OP_JUMP:
280*66e63ce3Schristos       if (OP[1] != 0)
281*66e63ce3Schristos 	trace_result (1, State.regs[OP[1]]);
282*66e63ce3Schristos       else
283*66e63ce3Schristos 	trace_result (0, 0);
284*66e63ce3Schristos       break;
285*66e63ce3Schristos 
286*66e63ce3Schristos     case OP_LDSR:
287*66e63ce3Schristos       trace_result (1, State.sregs[OP[1]]);
288*66e63ce3Schristos       break;
289*66e63ce3Schristos     }
290*66e63ce3Schristos }
291*66e63ce3Schristos #endif
292*66e63ce3Schristos 
293*66e63ce3Schristos 
294*66e63ce3Schristos /* Returns 1 if the specific condition is met, returns 0 otherwise.  */
295*66e63ce3Schristos int
296*66e63ce3Schristos condition_met (unsigned code)
297*66e63ce3Schristos {
298*66e63ce3Schristos   unsigned int psw = PSW;
299*66e63ce3Schristos 
300*66e63ce3Schristos   switch (code & 0xf)
301*66e63ce3Schristos     {
302*66e63ce3Schristos       case 0x0: return ((psw & PSW_OV) != 0);
303*66e63ce3Schristos       case 0x1:	return ((psw & PSW_CY) != 0);
304*66e63ce3Schristos       case 0x2:	return ((psw & PSW_Z) != 0);
305*66e63ce3Schristos       case 0x3:	return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0);
306*66e63ce3Schristos       case 0x4:	return ((psw & PSW_S) != 0);
307*66e63ce3Schristos     /*case 0x5:	return 1;*/
308*66e63ce3Schristos       case 0x6: return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0);
309*66e63ce3Schristos       case 0x7:	return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) != 0);
310*66e63ce3Schristos       case 0x8:	return ((psw & PSW_OV) == 0);
311*66e63ce3Schristos       case 0x9:	return ((psw & PSW_CY) == 0);
312*66e63ce3Schristos       case 0xa:	return ((psw & PSW_Z) == 0);
313*66e63ce3Schristos       case 0xb:	return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0);
314*66e63ce3Schristos       case 0xc:	return ((psw & PSW_S) == 0);
315*66e63ce3Schristos       case 0xd:	return ((psw & PSW_SAT) != 0);
316*66e63ce3Schristos       case 0xe:	return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0);
317*66e63ce3Schristos       case 0xf:	return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) == 0);
318*66e63ce3Schristos     }
319*66e63ce3Schristos 
320*66e63ce3Schristos   return 1;
321*66e63ce3Schristos }
322*66e63ce3Schristos 
323*66e63ce3Schristos static unsigned long
324*66e63ce3Schristos Add32 (unsigned long a1, unsigned long a2, int * carry)
325*66e63ce3Schristos {
326*66e63ce3Schristos   unsigned long result = (a1 + a2);
327*66e63ce3Schristos 
328*66e63ce3Schristos   * carry = (result < a1);
329*66e63ce3Schristos 
330*66e63ce3Schristos   return result;
331*66e63ce3Schristos }
332*66e63ce3Schristos 
333*66e63ce3Schristos static void
334*66e63ce3Schristos Multiply64 (int sign, unsigned long op0)
335*66e63ce3Schristos {
336*66e63ce3Schristos   unsigned long op1;
337*66e63ce3Schristos   unsigned long lo;
338*66e63ce3Schristos   unsigned long mid1;
339*66e63ce3Schristos   unsigned long mid2;
340*66e63ce3Schristos   unsigned long hi;
341*66e63ce3Schristos   unsigned long RdLo;
342*66e63ce3Schristos   unsigned long RdHi;
343*66e63ce3Schristos   int           carry;
344*66e63ce3Schristos 
345*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
346*66e63ce3Schristos 
347*66e63ce3Schristos   if (sign)
348*66e63ce3Schristos     {
349*66e63ce3Schristos       /* Compute sign of result and adjust operands if necessary.  */
350*66e63ce3Schristos 
351*66e63ce3Schristos       sign = (op0 ^ op1) & 0x80000000;
352*66e63ce3Schristos 
353*66e63ce3Schristos       if (((signed long) op0) < 0)
354*66e63ce3Schristos 	op0 = - op0;
355*66e63ce3Schristos 
356*66e63ce3Schristos       if (((signed long) op1) < 0)
357*66e63ce3Schristos 	op1 = - op1;
358*66e63ce3Schristos     }
359*66e63ce3Schristos 
360*66e63ce3Schristos   /* We can split the 32x32 into four 16x16 operations. This ensures
361*66e63ce3Schristos      that we do not lose precision on 32bit only hosts: */
362*66e63ce3Schristos   lo   = ( (op0        & 0xFFFF) *  (op1        & 0xFFFF));
363*66e63ce3Schristos   mid1 = ( (op0        & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
364*66e63ce3Schristos   mid2 = (((op0 >> 16) & 0xFFFF) *  (op1        & 0xFFFF));
365*66e63ce3Schristos   hi   = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
366*66e63ce3Schristos 
367*66e63ce3Schristos   /* We now need to add all of these results together, taking care
368*66e63ce3Schristos      to propogate the carries from the additions: */
369*66e63ce3Schristos   RdLo = Add32 (lo, (mid1 << 16), & carry);
370*66e63ce3Schristos   RdHi = carry;
371*66e63ce3Schristos   RdLo = Add32 (RdLo, (mid2 << 16), & carry);
372*66e63ce3Schristos   RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
373*66e63ce3Schristos 
374*66e63ce3Schristos   if (sign)
375*66e63ce3Schristos     {
376*66e63ce3Schristos       /* Negate result if necessary.  */
377*66e63ce3Schristos 
378*66e63ce3Schristos       RdLo = ~ RdLo;
379*66e63ce3Schristos       RdHi = ~ RdHi;
380*66e63ce3Schristos       if (RdLo == 0xFFFFFFFF)
381*66e63ce3Schristos 	{
382*66e63ce3Schristos 	  RdLo = 0;
383*66e63ce3Schristos 	  RdHi += 1;
384*66e63ce3Schristos 	}
385*66e63ce3Schristos       else
386*66e63ce3Schristos 	RdLo += 1;
387*66e63ce3Schristos     }
388*66e63ce3Schristos 
389*66e63ce3Schristos   /* Don't store into register 0.  */
390*66e63ce3Schristos   if (OP[1])
391*66e63ce3Schristos     State.regs[ OP[1]       ] = RdLo;
392*66e63ce3Schristos   if (OP[2] >> 11)
393*66e63ce3Schristos     State.regs[ OP[2] >> 11 ] = RdHi;
394*66e63ce3Schristos 
395*66e63ce3Schristos   return;
396*66e63ce3Schristos }
397*66e63ce3Schristos 
398*66e63ce3Schristos 
399*66e63ce3Schristos /* Read a null terminated string from memory, return in a buffer */
400*66e63ce3Schristos static char *
401*66e63ce3Schristos fetch_str (sd, addr)
402*66e63ce3Schristos      SIM_DESC sd;
403*66e63ce3Schristos      address_word addr;
404*66e63ce3Schristos {
405*66e63ce3Schristos   char *buf;
406*66e63ce3Schristos   int nr = 0;
407*66e63ce3Schristos   while (sim_core_read_1 (STATE_CPU (sd, 0),
408*66e63ce3Schristos 			  PC, read_map, addr + nr) != 0)
409*66e63ce3Schristos     nr++;
410*66e63ce3Schristos   buf = NZALLOC (char, nr + 1);
411*66e63ce3Schristos   sim_read (simulator, addr, buf, nr);
412*66e63ce3Schristos   return buf;
413*66e63ce3Schristos }
414*66e63ce3Schristos 
415*66e63ce3Schristos /* Read a null terminated argument vector from memory, return in a
416*66e63ce3Schristos    buffer */
417*66e63ce3Schristos static char **
418*66e63ce3Schristos fetch_argv (sd, addr)
419*66e63ce3Schristos      SIM_DESC sd;
420*66e63ce3Schristos      address_word addr;
421*66e63ce3Schristos {
422*66e63ce3Schristos   int max_nr = 64;
423*66e63ce3Schristos   int nr = 0;
424*66e63ce3Schristos   char **buf = xmalloc (max_nr * sizeof (char*));
425*66e63ce3Schristos   while (1)
426*66e63ce3Schristos     {
427*66e63ce3Schristos       unsigned32 a = sim_core_read_4 (STATE_CPU (sd, 0),
428*66e63ce3Schristos 				      PC, read_map, addr + nr * 4);
429*66e63ce3Schristos       if (a == 0) break;
430*66e63ce3Schristos       buf[nr] = fetch_str (sd, a);
431*66e63ce3Schristos       nr ++;
432*66e63ce3Schristos       if (nr == max_nr - 1)
433*66e63ce3Schristos 	{
434*66e63ce3Schristos 	  max_nr += 50;
435*66e63ce3Schristos 	  buf = xrealloc (buf, max_nr * sizeof (char*));
436*66e63ce3Schristos 	}
437*66e63ce3Schristos     }
438*66e63ce3Schristos   buf[nr] = 0;
439*66e63ce3Schristos   return buf;
440*66e63ce3Schristos }
441*66e63ce3Schristos 
442*66e63ce3Schristos 
443*66e63ce3Schristos /* sst.b */
444*66e63ce3Schristos int
445*66e63ce3Schristos OP_380 ()
446*66e63ce3Schristos {
447*66e63ce3Schristos   trace_input ("sst.b", OP_STORE16, 1);
448*66e63ce3Schristos 
449*66e63ce3Schristos   store_mem (State.regs[30] + (OP[3] & 0x7f), 1, State.regs[ OP[1] ]);
450*66e63ce3Schristos 
451*66e63ce3Schristos   trace_output (OP_STORE16);
452*66e63ce3Schristos 
453*66e63ce3Schristos   return 2;
454*66e63ce3Schristos }
455*66e63ce3Schristos 
456*66e63ce3Schristos /* sst.h */
457*66e63ce3Schristos int
458*66e63ce3Schristos OP_480 ()
459*66e63ce3Schristos {
460*66e63ce3Schristos   trace_input ("sst.h", OP_STORE16, 2);
461*66e63ce3Schristos 
462*66e63ce3Schristos   store_mem (State.regs[30] + ((OP[3] & 0x7f) << 1), 2, State.regs[ OP[1] ]);
463*66e63ce3Schristos 
464*66e63ce3Schristos   trace_output (OP_STORE16);
465*66e63ce3Schristos 
466*66e63ce3Schristos   return 2;
467*66e63ce3Schristos }
468*66e63ce3Schristos 
469*66e63ce3Schristos /* sst.w */
470*66e63ce3Schristos int
471*66e63ce3Schristos OP_501 ()
472*66e63ce3Schristos {
473*66e63ce3Schristos   trace_input ("sst.w", OP_STORE16, 4);
474*66e63ce3Schristos 
475*66e63ce3Schristos   store_mem (State.regs[30] + ((OP[3] & 0x7e) << 1), 4, State.regs[ OP[1] ]);
476*66e63ce3Schristos 
477*66e63ce3Schristos   trace_output (OP_STORE16);
478*66e63ce3Schristos 
479*66e63ce3Schristos   return 2;
480*66e63ce3Schristos }
481*66e63ce3Schristos 
482*66e63ce3Schristos /* ld.b */
483*66e63ce3Schristos int
484*66e63ce3Schristos OP_700 ()
485*66e63ce3Schristos {
486*66e63ce3Schristos   int adr;
487*66e63ce3Schristos 
488*66e63ce3Schristos   trace_input ("ld.b", OP_LOAD32, 1);
489*66e63ce3Schristos 
490*66e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]);
491*66e63ce3Schristos 
492*66e63ce3Schristos   State.regs[ OP[1] ] = EXTEND8 (load_mem (adr, 1));
493*66e63ce3Schristos 
494*66e63ce3Schristos   trace_output (OP_LOAD32);
495*66e63ce3Schristos 
496*66e63ce3Schristos   return 4;
497*66e63ce3Schristos }
498*66e63ce3Schristos 
499*66e63ce3Schristos /* ld.h */
500*66e63ce3Schristos int
501*66e63ce3Schristos OP_720 ()
502*66e63ce3Schristos {
503*66e63ce3Schristos   int adr;
504*66e63ce3Schristos 
505*66e63ce3Schristos   trace_input ("ld.h", OP_LOAD32, 2);
506*66e63ce3Schristos 
507*66e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]);
508*66e63ce3Schristos   adr &= ~0x1;
509*66e63ce3Schristos 
510*66e63ce3Schristos   State.regs[ OP[1] ] = EXTEND16 (load_mem (adr, 2));
511*66e63ce3Schristos 
512*66e63ce3Schristos   trace_output (OP_LOAD32);
513*66e63ce3Schristos 
514*66e63ce3Schristos   return 4;
515*66e63ce3Schristos }
516*66e63ce3Schristos 
517*66e63ce3Schristos /* ld.w */
518*66e63ce3Schristos int
519*66e63ce3Schristos OP_10720 ()
520*66e63ce3Schristos {
521*66e63ce3Schristos   int adr;
522*66e63ce3Schristos 
523*66e63ce3Schristos   trace_input ("ld.w", OP_LOAD32, 4);
524*66e63ce3Schristos 
525*66e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1);
526*66e63ce3Schristos   adr &= ~0x3;
527*66e63ce3Schristos 
528*66e63ce3Schristos   State.regs[ OP[1] ] = load_mem (adr, 4);
529*66e63ce3Schristos 
530*66e63ce3Schristos   trace_output (OP_LOAD32);
531*66e63ce3Schristos 
532*66e63ce3Schristos   return 4;
533*66e63ce3Schristos }
534*66e63ce3Schristos 
535*66e63ce3Schristos /* st.b */
536*66e63ce3Schristos int
537*66e63ce3Schristos OP_740 ()
538*66e63ce3Schristos {
539*66e63ce3Schristos   trace_input ("st.b", OP_STORE32, 1);
540*66e63ce3Schristos 
541*66e63ce3Schristos   store_mem (State.regs[ OP[0] ] + EXTEND16 (OP[2]), 1, State.regs[ OP[1] ]);
542*66e63ce3Schristos 
543*66e63ce3Schristos   trace_output (OP_STORE32);
544*66e63ce3Schristos 
545*66e63ce3Schristos   return 4;
546*66e63ce3Schristos }
547*66e63ce3Schristos 
548*66e63ce3Schristos /* st.h */
549*66e63ce3Schristos int
550*66e63ce3Schristos OP_760 ()
551*66e63ce3Schristos {
552*66e63ce3Schristos   int adr;
553*66e63ce3Schristos 
554*66e63ce3Schristos   trace_input ("st.h", OP_STORE32, 2);
555*66e63ce3Schristos 
556*66e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]);
557*66e63ce3Schristos   adr &= ~1;
558*66e63ce3Schristos 
559*66e63ce3Schristos   store_mem (adr, 2, State.regs[ OP[1] ]);
560*66e63ce3Schristos 
561*66e63ce3Schristos   trace_output (OP_STORE32);
562*66e63ce3Schristos 
563*66e63ce3Schristos   return 4;
564*66e63ce3Schristos }
565*66e63ce3Schristos 
566*66e63ce3Schristos /* st.w */
567*66e63ce3Schristos int
568*66e63ce3Schristos OP_10760 ()
569*66e63ce3Schristos {
570*66e63ce3Schristos   int adr;
571*66e63ce3Schristos 
572*66e63ce3Schristos   trace_input ("st.w", OP_STORE32, 4);
573*66e63ce3Schristos 
574*66e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1);
575*66e63ce3Schristos   adr &= ~3;
576*66e63ce3Schristos 
577*66e63ce3Schristos   store_mem (adr, 4, State.regs[ OP[1] ]);
578*66e63ce3Schristos 
579*66e63ce3Schristos   trace_output (OP_STORE32);
580*66e63ce3Schristos 
581*66e63ce3Schristos   return 4;
582*66e63ce3Schristos }
583*66e63ce3Schristos 
584*66e63ce3Schristos /* add reg, reg */
585*66e63ce3Schristos int
586*66e63ce3Schristos OP_1C0 ()
587*66e63ce3Schristos {
588*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
589*66e63ce3Schristos 
590*66e63ce3Schristos   trace_input ("add", OP_REG_REG, 0);
591*66e63ce3Schristos 
592*66e63ce3Schristos   /* Compute the result.  */
593*66e63ce3Schristos 
594*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
595*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
596*66e63ce3Schristos 
597*66e63ce3Schristos   result = op0 + op1;
598*66e63ce3Schristos 
599*66e63ce3Schristos   /* Compute the condition codes.  */
600*66e63ce3Schristos   z = (result == 0);
601*66e63ce3Schristos   s = (result & 0x80000000);
602*66e63ce3Schristos   cy = (result < op0 || result < op1);
603*66e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
604*66e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
605*66e63ce3Schristos 
606*66e63ce3Schristos   /* Store the result and condition codes.  */
607*66e63ce3Schristos   State.regs[OP[1]] = result;
608*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
609*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
610*66e63ce3Schristos 		     | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
611*66e63ce3Schristos   trace_output (OP_REG_REG);
612*66e63ce3Schristos 
613*66e63ce3Schristos   return 2;
614*66e63ce3Schristos }
615*66e63ce3Schristos 
616*66e63ce3Schristos /* add sign_extend(imm5), reg */
617*66e63ce3Schristos int
618*66e63ce3Schristos OP_240 ()
619*66e63ce3Schristos {
620*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
621*66e63ce3Schristos   int temp;
622*66e63ce3Schristos 
623*66e63ce3Schristos   trace_input ("add", OP_IMM_REG, 0);
624*66e63ce3Schristos 
625*66e63ce3Schristos   /* Compute the result.  */
626*66e63ce3Schristos   temp = SEXT5 (OP[0]);
627*66e63ce3Schristos   op0 = temp;
628*66e63ce3Schristos   op1 = State.regs[OP[1]];
629*66e63ce3Schristos   result = op0 + op1;
630*66e63ce3Schristos 
631*66e63ce3Schristos   /* Compute the condition codes.  */
632*66e63ce3Schristos   z = (result == 0);
633*66e63ce3Schristos   s = (result & 0x80000000);
634*66e63ce3Schristos   cy = (result < op0 || result < op1);
635*66e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
636*66e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
637*66e63ce3Schristos 
638*66e63ce3Schristos   /* Store the result and condition codes.  */
639*66e63ce3Schristos   State.regs[OP[1]] = result;
640*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
641*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
642*66e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
643*66e63ce3Schristos   trace_output (OP_IMM_REG);
644*66e63ce3Schristos 
645*66e63ce3Schristos   return 2;
646*66e63ce3Schristos }
647*66e63ce3Schristos 
648*66e63ce3Schristos /* addi sign_extend(imm16), reg, reg */
649*66e63ce3Schristos int
650*66e63ce3Schristos OP_600 ()
651*66e63ce3Schristos {
652*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
653*66e63ce3Schristos 
654*66e63ce3Schristos   trace_input ("addi", OP_IMM16_REG_REG, 0);
655*66e63ce3Schristos 
656*66e63ce3Schristos   /* Compute the result.  */
657*66e63ce3Schristos 
658*66e63ce3Schristos   op0 = EXTEND16 (OP[2]);
659*66e63ce3Schristos   op1 = State.regs[ OP[0] ];
660*66e63ce3Schristos   result = op0 + op1;
661*66e63ce3Schristos 
662*66e63ce3Schristos   /* Compute the condition codes.  */
663*66e63ce3Schristos   z = (result == 0);
664*66e63ce3Schristos   s = (result & 0x80000000);
665*66e63ce3Schristos   cy = (result < op0 || result < op1);
666*66e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
667*66e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
668*66e63ce3Schristos 
669*66e63ce3Schristos   /* Store the result and condition codes.  */
670*66e63ce3Schristos   State.regs[OP[1]] = result;
671*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
672*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
673*66e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
674*66e63ce3Schristos   trace_output (OP_IMM16_REG_REG);
675*66e63ce3Schristos 
676*66e63ce3Schristos   return 4;
677*66e63ce3Schristos }
678*66e63ce3Schristos 
679*66e63ce3Schristos /* sub reg1, reg2 */
680*66e63ce3Schristos int
681*66e63ce3Schristos OP_1A0 ()
682*66e63ce3Schristos {
683*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
684*66e63ce3Schristos 
685*66e63ce3Schristos   trace_input ("sub", OP_REG_REG, 0);
686*66e63ce3Schristos   /* Compute the result.  */
687*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
688*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
689*66e63ce3Schristos   result = op1 - op0;
690*66e63ce3Schristos 
691*66e63ce3Schristos   /* Compute the condition codes.  */
692*66e63ce3Schristos   z = (result == 0);
693*66e63ce3Schristos   s = (result & 0x80000000);
694*66e63ce3Schristos   cy = (op1 < op0);
695*66e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
696*66e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
697*66e63ce3Schristos 
698*66e63ce3Schristos   /* Store the result and condition codes.  */
699*66e63ce3Schristos   State.regs[OP[1]] = result;
700*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
701*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
702*66e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
703*66e63ce3Schristos   trace_output (OP_REG_REG);
704*66e63ce3Schristos 
705*66e63ce3Schristos   return 2;
706*66e63ce3Schristos }
707*66e63ce3Schristos 
708*66e63ce3Schristos /* subr reg1, reg2 */
709*66e63ce3Schristos int
710*66e63ce3Schristos OP_180 ()
711*66e63ce3Schristos {
712*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
713*66e63ce3Schristos 
714*66e63ce3Schristos   trace_input ("subr", OP_REG_REG, 0);
715*66e63ce3Schristos   /* Compute the result.  */
716*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
717*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
718*66e63ce3Schristos   result = op0 - op1;
719*66e63ce3Schristos 
720*66e63ce3Schristos   /* Compute the condition codes.  */
721*66e63ce3Schristos   z = (result == 0);
722*66e63ce3Schristos   s = (result & 0x80000000);
723*66e63ce3Schristos   cy = (op0 < op1);
724*66e63ce3Schristos   ov = ((op0 & 0x80000000) != (op1 & 0x80000000)
725*66e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
726*66e63ce3Schristos 
727*66e63ce3Schristos   /* Store the result and condition codes.  */
728*66e63ce3Schristos   State.regs[OP[1]] = result;
729*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
730*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
731*66e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
732*66e63ce3Schristos   trace_output (OP_REG_REG);
733*66e63ce3Schristos 
734*66e63ce3Schristos   return 2;
735*66e63ce3Schristos }
736*66e63ce3Schristos 
737*66e63ce3Schristos /* sxh reg1 */
738*66e63ce3Schristos int
739*66e63ce3Schristos OP_E0 ()
740*66e63ce3Schristos {
741*66e63ce3Schristos   trace_input ("mulh", OP_REG_REG, 0);
742*66e63ce3Schristos 
743*66e63ce3Schristos   State.regs[ OP[1] ] = (EXTEND16 (State.regs[ OP[1] ]) * EXTEND16 (State.regs[ OP[0] ]));
744*66e63ce3Schristos 
745*66e63ce3Schristos   trace_output (OP_REG_REG);
746*66e63ce3Schristos 
747*66e63ce3Schristos   return 2;
748*66e63ce3Schristos }
749*66e63ce3Schristos 
750*66e63ce3Schristos /* mulh sign_extend(imm5), reg2 */
751*66e63ce3Schristos int
752*66e63ce3Schristos OP_2E0 ()
753*66e63ce3Schristos {
754*66e63ce3Schristos   trace_input ("mulh", OP_IMM_REG, 0);
755*66e63ce3Schristos 
756*66e63ce3Schristos   State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[1] ]) * SEXT5 (OP[0]);
757*66e63ce3Schristos 
758*66e63ce3Schristos   trace_output (OP_IMM_REG);
759*66e63ce3Schristos 
760*66e63ce3Schristos   return 2;
761*66e63ce3Schristos }
762*66e63ce3Schristos 
763*66e63ce3Schristos /* mulhi imm16, reg1, reg2 */
764*66e63ce3Schristos int
765*66e63ce3Schristos OP_6E0 ()
766*66e63ce3Schristos {
767*66e63ce3Schristos   trace_input ("mulhi", OP_IMM16_REG_REG, 0);
768*66e63ce3Schristos 
769*66e63ce3Schristos   State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[0] ]) * EXTEND16 (OP[2]);
770*66e63ce3Schristos 
771*66e63ce3Schristos   trace_output (OP_IMM16_REG_REG);
772*66e63ce3Schristos 
773*66e63ce3Schristos   return 4;
774*66e63ce3Schristos }
775*66e63ce3Schristos 
776*66e63ce3Schristos /* cmp reg, reg */
777*66e63ce3Schristos int
778*66e63ce3Schristos OP_1E0 ()
779*66e63ce3Schristos {
780*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
781*66e63ce3Schristos 
782*66e63ce3Schristos   trace_input ("cmp", OP_REG_REG_CMP, 0);
783*66e63ce3Schristos   /* Compute the result.  */
784*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
785*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
786*66e63ce3Schristos   result = op1 - op0;
787*66e63ce3Schristos 
788*66e63ce3Schristos   /* Compute the condition codes.  */
789*66e63ce3Schristos   z = (result == 0);
790*66e63ce3Schristos   s = (result & 0x80000000);
791*66e63ce3Schristos   cy = (op1 < op0);
792*66e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
793*66e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
794*66e63ce3Schristos 
795*66e63ce3Schristos   /* Set condition codes.  */
796*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
797*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
798*66e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
799*66e63ce3Schristos   trace_output (OP_REG_REG_CMP);
800*66e63ce3Schristos 
801*66e63ce3Schristos   return 2;
802*66e63ce3Schristos }
803*66e63ce3Schristos 
804*66e63ce3Schristos /* cmp sign_extend(imm5), reg */
805*66e63ce3Schristos int
806*66e63ce3Schristos OP_260 ()
807*66e63ce3Schristos {
808*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
809*66e63ce3Schristos   int temp;
810*66e63ce3Schristos 
811*66e63ce3Schristos   /* Compute the result.  */
812*66e63ce3Schristos   trace_input ("cmp", OP_IMM_REG_CMP, 0);
813*66e63ce3Schristos   temp = SEXT5 (OP[0]);
814*66e63ce3Schristos   op0 = temp;
815*66e63ce3Schristos   op1 = State.regs[OP[1]];
816*66e63ce3Schristos   result = op1 - op0;
817*66e63ce3Schristos 
818*66e63ce3Schristos   /* Compute the condition codes.  */
819*66e63ce3Schristos   z = (result == 0);
820*66e63ce3Schristos   s = (result & 0x80000000);
821*66e63ce3Schristos   cy = (op1 < op0);
822*66e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
823*66e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
824*66e63ce3Schristos 
825*66e63ce3Schristos   /* Set condition codes.  */
826*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
827*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
828*66e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
829*66e63ce3Schristos   trace_output (OP_IMM_REG_CMP);
830*66e63ce3Schristos 
831*66e63ce3Schristos   return 2;
832*66e63ce3Schristos }
833*66e63ce3Schristos 
834*66e63ce3Schristos /* setf cccc,reg2 */
835*66e63ce3Schristos int
836*66e63ce3Schristos OP_7E0 ()
837*66e63ce3Schristos {
838*66e63ce3Schristos   trace_input ("setf", OP_EX1, 0);
839*66e63ce3Schristos 
840*66e63ce3Schristos   State.regs[ OP[1] ] = condition_met (OP[0]);
841*66e63ce3Schristos 
842*66e63ce3Schristos   trace_output (OP_EX1);
843*66e63ce3Schristos 
844*66e63ce3Schristos   return 4;
845*66e63ce3Schristos }
846*66e63ce3Schristos 
847*66e63ce3Schristos /* satadd reg,reg */
848*66e63ce3Schristos int
849*66e63ce3Schristos OP_C0 ()
850*66e63ce3Schristos {
851*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
852*66e63ce3Schristos 
853*66e63ce3Schristos   trace_input ("satadd", OP_REG_REG, 0);
854*66e63ce3Schristos   /* Compute the result.  */
855*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
856*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
857*66e63ce3Schristos   result = op0 + op1;
858*66e63ce3Schristos 
859*66e63ce3Schristos   /* Compute the condition codes.  */
860*66e63ce3Schristos   z = (result == 0);
861*66e63ce3Schristos   s = (result & 0x80000000);
862*66e63ce3Schristos   cy = (result < op0 || result < op1);
863*66e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
864*66e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
865*66e63ce3Schristos   sat = ov;
866*66e63ce3Schristos 
867*66e63ce3Schristos   /* Handle saturated results.  */
868*66e63ce3Schristos   if (sat && s)
869*66e63ce3Schristos     {
870*66e63ce3Schristos       /* An overflow that results in a negative result implies that we
871*66e63ce3Schristos 	 became too positive.  */
872*66e63ce3Schristos       result = 0x7fffffff;
873*66e63ce3Schristos       s = 0;
874*66e63ce3Schristos     }
875*66e63ce3Schristos   else if (sat)
876*66e63ce3Schristos     {
877*66e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
878*66e63ce3Schristos       result = 0x80000000;
879*66e63ce3Schristos       s = 1;
880*66e63ce3Schristos       z = 0;
881*66e63ce3Schristos     }
882*66e63ce3Schristos 
883*66e63ce3Schristos   /* Store the result and condition codes.  */
884*66e63ce3Schristos   State.regs[OP[1]] = result;
885*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
886*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
887*66e63ce3Schristos 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
888*66e63ce3Schristos 	  | (sat ? PSW_SAT : 0));
889*66e63ce3Schristos 
890*66e63ce3Schristos   trace_output (OP_REG_REG);
891*66e63ce3Schristos 
892*66e63ce3Schristos   return 2;
893*66e63ce3Schristos }
894*66e63ce3Schristos 
895*66e63ce3Schristos /* satadd sign_extend(imm5), reg */
896*66e63ce3Schristos int
897*66e63ce3Schristos OP_220 ()
898*66e63ce3Schristos {
899*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
900*66e63ce3Schristos 
901*66e63ce3Schristos   int temp;
902*66e63ce3Schristos 
903*66e63ce3Schristos   trace_input ("satadd", OP_IMM_REG, 0);
904*66e63ce3Schristos 
905*66e63ce3Schristos   /* Compute the result.  */
906*66e63ce3Schristos   temp = SEXT5 (OP[0]);
907*66e63ce3Schristos   op0 = temp;
908*66e63ce3Schristos   op1 = State.regs[OP[1]];
909*66e63ce3Schristos   result = op0 + op1;
910*66e63ce3Schristos 
911*66e63ce3Schristos   /* Compute the condition codes.  */
912*66e63ce3Schristos   z = (result == 0);
913*66e63ce3Schristos   s = (result & 0x80000000);
914*66e63ce3Schristos   cy = (result < op0 || result < op1);
915*66e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
916*66e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
917*66e63ce3Schristos   sat = ov;
918*66e63ce3Schristos 
919*66e63ce3Schristos   /* Handle saturated results.  */
920*66e63ce3Schristos   if (sat && s)
921*66e63ce3Schristos     {
922*66e63ce3Schristos       /* An overflow that results in a negative result implies that we
923*66e63ce3Schristos 	 became too positive.  */
924*66e63ce3Schristos       result = 0x7fffffff;
925*66e63ce3Schristos       s = 0;
926*66e63ce3Schristos     }
927*66e63ce3Schristos   else if (sat)
928*66e63ce3Schristos     {
929*66e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
930*66e63ce3Schristos       result = 0x80000000;
931*66e63ce3Schristos       s = 1;
932*66e63ce3Schristos       z = 0;
933*66e63ce3Schristos     }
934*66e63ce3Schristos 
935*66e63ce3Schristos   /* Store the result and condition codes.  */
936*66e63ce3Schristos   State.regs[OP[1]] = result;
937*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
938*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
939*66e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
940*66e63ce3Schristos 		| (sat ? PSW_SAT : 0));
941*66e63ce3Schristos   trace_output (OP_IMM_REG);
942*66e63ce3Schristos 
943*66e63ce3Schristos   return 2;
944*66e63ce3Schristos }
945*66e63ce3Schristos 
946*66e63ce3Schristos /* satsub reg1, reg2 */
947*66e63ce3Schristos int
948*66e63ce3Schristos OP_A0 ()
949*66e63ce3Schristos {
950*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
951*66e63ce3Schristos 
952*66e63ce3Schristos   trace_input ("satsub", OP_REG_REG, 0);
953*66e63ce3Schristos 
954*66e63ce3Schristos   /* Compute the result.  */
955*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
956*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
957*66e63ce3Schristos   result = op1 - op0;
958*66e63ce3Schristos 
959*66e63ce3Schristos   /* Compute the condition codes.  */
960*66e63ce3Schristos   z = (result == 0);
961*66e63ce3Schristos   s = (result & 0x80000000);
962*66e63ce3Schristos   cy = (op1 < op0);
963*66e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
964*66e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
965*66e63ce3Schristos   sat = ov;
966*66e63ce3Schristos 
967*66e63ce3Schristos   /* Handle saturated results.  */
968*66e63ce3Schristos   if (sat && s)
969*66e63ce3Schristos     {
970*66e63ce3Schristos       /* An overflow that results in a negative result implies that we
971*66e63ce3Schristos 	 became too positive.  */
972*66e63ce3Schristos       result = 0x7fffffff;
973*66e63ce3Schristos       s = 0;
974*66e63ce3Schristos     }
975*66e63ce3Schristos   else if (sat)
976*66e63ce3Schristos     {
977*66e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
978*66e63ce3Schristos       result = 0x80000000;
979*66e63ce3Schristos       s = 1;
980*66e63ce3Schristos       z = 0;
981*66e63ce3Schristos     }
982*66e63ce3Schristos 
983*66e63ce3Schristos   /* Store the result and condition codes.  */
984*66e63ce3Schristos   State.regs[OP[1]] = result;
985*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
986*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
987*66e63ce3Schristos 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
988*66e63ce3Schristos 	  | (sat ? PSW_SAT : 0));
989*66e63ce3Schristos 
990*66e63ce3Schristos   trace_output (OP_REG_REG);
991*66e63ce3Schristos   return 2;
992*66e63ce3Schristos }
993*66e63ce3Schristos 
994*66e63ce3Schristos /* satsubi sign_extend(imm16), reg */
995*66e63ce3Schristos int
996*66e63ce3Schristos OP_660 ()
997*66e63ce3Schristos {
998*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
999*66e63ce3Schristos   int temp;
1000*66e63ce3Schristos 
1001*66e63ce3Schristos   trace_input ("satsubi", OP_IMM_REG, 0);
1002*66e63ce3Schristos 
1003*66e63ce3Schristos   /* Compute the result.  */
1004*66e63ce3Schristos   temp = EXTEND16 (OP[2]);
1005*66e63ce3Schristos   op0 = temp;
1006*66e63ce3Schristos   op1 = State.regs[ OP[0] ];
1007*66e63ce3Schristos   result = op1 - op0;
1008*66e63ce3Schristos 
1009*66e63ce3Schristos   /* Compute the condition codes.  */
1010*66e63ce3Schristos   z = (result == 0);
1011*66e63ce3Schristos   s = (result & 0x80000000);
1012*66e63ce3Schristos   cy = (op1 < op0);
1013*66e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
1014*66e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
1015*66e63ce3Schristos   sat = ov;
1016*66e63ce3Schristos 
1017*66e63ce3Schristos   /* Handle saturated results.  */
1018*66e63ce3Schristos   if (sat && s)
1019*66e63ce3Schristos     {
1020*66e63ce3Schristos       /* An overflow that results in a negative result implies that we
1021*66e63ce3Schristos 	 became too positive.  */
1022*66e63ce3Schristos       result = 0x7fffffff;
1023*66e63ce3Schristos       s = 0;
1024*66e63ce3Schristos     }
1025*66e63ce3Schristos   else if (sat)
1026*66e63ce3Schristos     {
1027*66e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
1028*66e63ce3Schristos       result = 0x80000000;
1029*66e63ce3Schristos       s = 1;
1030*66e63ce3Schristos       z = 0;
1031*66e63ce3Schristos     }
1032*66e63ce3Schristos 
1033*66e63ce3Schristos   /* Store the result and condition codes.  */
1034*66e63ce3Schristos   State.regs[OP[1]] = result;
1035*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1036*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1037*66e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
1038*66e63ce3Schristos 		| (sat ? PSW_SAT : 0));
1039*66e63ce3Schristos 
1040*66e63ce3Schristos   trace_output (OP_IMM_REG);
1041*66e63ce3Schristos 
1042*66e63ce3Schristos   return 4;
1043*66e63ce3Schristos }
1044*66e63ce3Schristos 
1045*66e63ce3Schristos /* satsubr reg,reg */
1046*66e63ce3Schristos int
1047*66e63ce3Schristos OP_80 ()
1048*66e63ce3Schristos {
1049*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
1050*66e63ce3Schristos 
1051*66e63ce3Schristos   trace_input ("satsubr", OP_REG_REG, 0);
1052*66e63ce3Schristos 
1053*66e63ce3Schristos   /* Compute the result.  */
1054*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1055*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1056*66e63ce3Schristos   result = op0 - op1;
1057*66e63ce3Schristos 
1058*66e63ce3Schristos   /* Compute the condition codes.  */
1059*66e63ce3Schristos   z = (result == 0);
1060*66e63ce3Schristos   s = (result & 0x80000000);
1061*66e63ce3Schristos   cy = (op0 < op1);
1062*66e63ce3Schristos   ov = ((op0 & 0x80000000) != (op1 & 0x80000000)
1063*66e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
1064*66e63ce3Schristos   sat = ov;
1065*66e63ce3Schristos 
1066*66e63ce3Schristos   /* Handle saturated results.  */
1067*66e63ce3Schristos   if (sat && s)
1068*66e63ce3Schristos     {
1069*66e63ce3Schristos       /* An overflow that results in a negative result implies that we
1070*66e63ce3Schristos 	 became too positive.  */
1071*66e63ce3Schristos       result = 0x7fffffff;
1072*66e63ce3Schristos       s = 0;
1073*66e63ce3Schristos     }
1074*66e63ce3Schristos   else if (sat)
1075*66e63ce3Schristos     {
1076*66e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
1077*66e63ce3Schristos       result = 0x80000000;
1078*66e63ce3Schristos       s = 1;
1079*66e63ce3Schristos       z = 0;
1080*66e63ce3Schristos     }
1081*66e63ce3Schristos 
1082*66e63ce3Schristos   /* Store the result and condition codes.  */
1083*66e63ce3Schristos   State.regs[OP[1]] = result;
1084*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1085*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1086*66e63ce3Schristos 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
1087*66e63ce3Schristos 	  | (sat ? PSW_SAT : 0));
1088*66e63ce3Schristos 
1089*66e63ce3Schristos   trace_output (OP_REG_REG);
1090*66e63ce3Schristos 
1091*66e63ce3Schristos   return 2;
1092*66e63ce3Schristos }
1093*66e63ce3Schristos 
1094*66e63ce3Schristos /* tst reg,reg */
1095*66e63ce3Schristos int
1096*66e63ce3Schristos OP_160 ()
1097*66e63ce3Schristos {
1098*66e63ce3Schristos   unsigned int op0, op1, result, z, s;
1099*66e63ce3Schristos 
1100*66e63ce3Schristos   trace_input ("tst", OP_REG_REG_CMP, 0);
1101*66e63ce3Schristos 
1102*66e63ce3Schristos   /* Compute the result.  */
1103*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1104*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1105*66e63ce3Schristos   result = op0 & op1;
1106*66e63ce3Schristos 
1107*66e63ce3Schristos   /* Compute the condition codes.  */
1108*66e63ce3Schristos   z = (result == 0);
1109*66e63ce3Schristos   s = (result & 0x80000000);
1110*66e63ce3Schristos 
1111*66e63ce3Schristos   /* Store the condition codes.  */
1112*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1113*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
1114*66e63ce3Schristos   trace_output (OP_REG_REG_CMP);
1115*66e63ce3Schristos 
1116*66e63ce3Schristos   return 2;
1117*66e63ce3Schristos }
1118*66e63ce3Schristos 
1119*66e63ce3Schristos /* mov sign_extend(imm5), reg */
1120*66e63ce3Schristos int
1121*66e63ce3Schristos OP_200 ()
1122*66e63ce3Schristos {
1123*66e63ce3Schristos   int value = SEXT5 (OP[0]);
1124*66e63ce3Schristos 
1125*66e63ce3Schristos   trace_input ("mov", OP_IMM_REG_MOVE, 0);
1126*66e63ce3Schristos 
1127*66e63ce3Schristos   State.regs[ OP[1] ] = value;
1128*66e63ce3Schristos 
1129*66e63ce3Schristos   trace_output (OP_IMM_REG_MOVE);
1130*66e63ce3Schristos 
1131*66e63ce3Schristos   return 2;
1132*66e63ce3Schristos }
1133*66e63ce3Schristos 
1134*66e63ce3Schristos /* movhi imm16, reg, reg */
1135*66e63ce3Schristos int
1136*66e63ce3Schristos OP_640 ()
1137*66e63ce3Schristos {
1138*66e63ce3Schristos   trace_input ("movhi", OP_UIMM16_REG_REG, 16);
1139*66e63ce3Schristos 
1140*66e63ce3Schristos   State.regs[ OP[1] ] = State.regs[ OP[0] ] + (OP[2] << 16);
1141*66e63ce3Schristos 
1142*66e63ce3Schristos   trace_output (OP_UIMM16_REG_REG);
1143*66e63ce3Schristos 
1144*66e63ce3Schristos   return 4;
1145*66e63ce3Schristos }
1146*66e63ce3Schristos 
1147*66e63ce3Schristos /* sar zero_extend(imm5),reg1 */
1148*66e63ce3Schristos int
1149*66e63ce3Schristos OP_2A0 ()
1150*66e63ce3Schristos {
1151*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
1152*66e63ce3Schristos 
1153*66e63ce3Schristos   trace_input ("sar", OP_IMM_REG, 0);
1154*66e63ce3Schristos   op0 = OP[0];
1155*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1156*66e63ce3Schristos   result = (signed)op1 >> op0;
1157*66e63ce3Schristos 
1158*66e63ce3Schristos   /* Compute the condition codes.  */
1159*66e63ce3Schristos   z = (result == 0);
1160*66e63ce3Schristos   s = (result & 0x80000000);
1161*66e63ce3Schristos   cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
1162*66e63ce3Schristos 
1163*66e63ce3Schristos   /* Store the result and condition codes.  */
1164*66e63ce3Schristos   State.regs[ OP[1] ] = result;
1165*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1166*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1167*66e63ce3Schristos 		| (cy ? PSW_CY : 0));
1168*66e63ce3Schristos   trace_output (OP_IMM_REG);
1169*66e63ce3Schristos 
1170*66e63ce3Schristos   return 2;
1171*66e63ce3Schristos }
1172*66e63ce3Schristos 
1173*66e63ce3Schristos /* sar reg1, reg2 */
1174*66e63ce3Schristos int
1175*66e63ce3Schristos OP_A007E0 ()
1176*66e63ce3Schristos {
1177*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
1178*66e63ce3Schristos 
1179*66e63ce3Schristos   trace_input ("sar", OP_REG_REG, 0);
1180*66e63ce3Schristos 
1181*66e63ce3Schristos   op0 = State.regs[ OP[0] ] & 0x1f;
1182*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1183*66e63ce3Schristos   result = (signed)op1 >> op0;
1184*66e63ce3Schristos 
1185*66e63ce3Schristos   /* Compute the condition codes.  */
1186*66e63ce3Schristos   z = (result == 0);
1187*66e63ce3Schristos   s = (result & 0x80000000);
1188*66e63ce3Schristos   cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
1189*66e63ce3Schristos 
1190*66e63ce3Schristos   /* Store the result and condition codes.  */
1191*66e63ce3Schristos   State.regs[OP[1]] = result;
1192*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1193*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1194*66e63ce3Schristos 		| (cy ? PSW_CY : 0));
1195*66e63ce3Schristos   trace_output (OP_REG_REG);
1196*66e63ce3Schristos 
1197*66e63ce3Schristos   return 4;
1198*66e63ce3Schristos }
1199*66e63ce3Schristos 
1200*66e63ce3Schristos /* shl zero_extend(imm5),reg1 */
1201*66e63ce3Schristos int
1202*66e63ce3Schristos OP_2C0 ()
1203*66e63ce3Schristos {
1204*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
1205*66e63ce3Schristos 
1206*66e63ce3Schristos   trace_input ("shl", OP_IMM_REG, 0);
1207*66e63ce3Schristos   op0 = OP[0];
1208*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1209*66e63ce3Schristos   result = op1 << op0;
1210*66e63ce3Schristos 
1211*66e63ce3Schristos   /* Compute the condition codes.  */
1212*66e63ce3Schristos   z = (result == 0);
1213*66e63ce3Schristos   s = (result & 0x80000000);
1214*66e63ce3Schristos   cy = op0 ? (op1 & (1 << (32 - op0))) : 0;
1215*66e63ce3Schristos 
1216*66e63ce3Schristos   /* Store the result and condition codes.  */
1217*66e63ce3Schristos   State.regs[OP[1]] = result;
1218*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1219*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1220*66e63ce3Schristos 		| (cy ? PSW_CY : 0));
1221*66e63ce3Schristos   trace_output (OP_IMM_REG);
1222*66e63ce3Schristos 
1223*66e63ce3Schristos   return 2;
1224*66e63ce3Schristos }
1225*66e63ce3Schristos 
1226*66e63ce3Schristos /* shl reg1, reg2 */
1227*66e63ce3Schristos int
1228*66e63ce3Schristos OP_C007E0 ()
1229*66e63ce3Schristos {
1230*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
1231*66e63ce3Schristos 
1232*66e63ce3Schristos   trace_input ("shl", OP_REG_REG, 0);
1233*66e63ce3Schristos   op0 = State.regs[ OP[0] ] & 0x1f;
1234*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1235*66e63ce3Schristos   result = op1 << op0;
1236*66e63ce3Schristos 
1237*66e63ce3Schristos   /* Compute the condition codes.  */
1238*66e63ce3Schristos   z = (result == 0);
1239*66e63ce3Schristos   s = (result & 0x80000000);
1240*66e63ce3Schristos   cy = op0 ? (op1 & (1 << (32 - op0))) : 0;
1241*66e63ce3Schristos 
1242*66e63ce3Schristos   /* Store the result and condition codes.  */
1243*66e63ce3Schristos   State.regs[OP[1]] = result;
1244*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1245*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1246*66e63ce3Schristos 		| (cy ? PSW_CY : 0));
1247*66e63ce3Schristos   trace_output (OP_REG_REG);
1248*66e63ce3Schristos 
1249*66e63ce3Schristos   return 4;
1250*66e63ce3Schristos }
1251*66e63ce3Schristos 
1252*66e63ce3Schristos /* shr zero_extend(imm5),reg1 */
1253*66e63ce3Schristos int
1254*66e63ce3Schristos OP_280 ()
1255*66e63ce3Schristos {
1256*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
1257*66e63ce3Schristos 
1258*66e63ce3Schristos   trace_input ("shr", OP_IMM_REG, 0);
1259*66e63ce3Schristos   op0 = OP[0];
1260*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1261*66e63ce3Schristos   result = op1 >> op0;
1262*66e63ce3Schristos 
1263*66e63ce3Schristos   /* Compute the condition codes.  */
1264*66e63ce3Schristos   z = (result == 0);
1265*66e63ce3Schristos   s = (result & 0x80000000);
1266*66e63ce3Schristos   cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
1267*66e63ce3Schristos 
1268*66e63ce3Schristos   /* Store the result and condition codes.  */
1269*66e63ce3Schristos   State.regs[OP[1]] = result;
1270*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1271*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1272*66e63ce3Schristos 		| (cy ? PSW_CY : 0));
1273*66e63ce3Schristos   trace_output (OP_IMM_REG);
1274*66e63ce3Schristos 
1275*66e63ce3Schristos   return 2;
1276*66e63ce3Schristos }
1277*66e63ce3Schristos 
1278*66e63ce3Schristos /* shr reg1, reg2 */
1279*66e63ce3Schristos int
1280*66e63ce3Schristos OP_8007E0 ()
1281*66e63ce3Schristos {
1282*66e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
1283*66e63ce3Schristos 
1284*66e63ce3Schristos   trace_input ("shr", OP_REG_REG, 0);
1285*66e63ce3Schristos   op0 = State.regs[ OP[0] ] & 0x1f;
1286*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1287*66e63ce3Schristos   result = op1 >> op0;
1288*66e63ce3Schristos 
1289*66e63ce3Schristos   /* Compute the condition codes.  */
1290*66e63ce3Schristos   z = (result == 0);
1291*66e63ce3Schristos   s = (result & 0x80000000);
1292*66e63ce3Schristos   cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
1293*66e63ce3Schristos 
1294*66e63ce3Schristos   /* Store the result and condition codes.  */
1295*66e63ce3Schristos   State.regs[OP[1]] = result;
1296*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1297*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1298*66e63ce3Schristos 		| (cy ? PSW_CY : 0));
1299*66e63ce3Schristos   trace_output (OP_REG_REG);
1300*66e63ce3Schristos 
1301*66e63ce3Schristos   return 4;
1302*66e63ce3Schristos }
1303*66e63ce3Schristos 
1304*66e63ce3Schristos /* or reg, reg */
1305*66e63ce3Schristos int
1306*66e63ce3Schristos OP_100 ()
1307*66e63ce3Schristos {
1308*66e63ce3Schristos   unsigned int op0, op1, result, z, s;
1309*66e63ce3Schristos 
1310*66e63ce3Schristos   trace_input ("or", OP_REG_REG, 0);
1311*66e63ce3Schristos 
1312*66e63ce3Schristos   /* Compute the result.  */
1313*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1314*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1315*66e63ce3Schristos   result = op0 | op1;
1316*66e63ce3Schristos 
1317*66e63ce3Schristos   /* Compute the condition codes.  */
1318*66e63ce3Schristos   z = (result == 0);
1319*66e63ce3Schristos   s = (result & 0x80000000);
1320*66e63ce3Schristos 
1321*66e63ce3Schristos   /* Store the result and condition codes.  */
1322*66e63ce3Schristos   State.regs[OP[1]] = result;
1323*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1324*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
1325*66e63ce3Schristos   trace_output (OP_REG_REG);
1326*66e63ce3Schristos 
1327*66e63ce3Schristos   return 2;
1328*66e63ce3Schristos }
1329*66e63ce3Schristos 
1330*66e63ce3Schristos /* ori zero_extend(imm16), reg, reg */
1331*66e63ce3Schristos int
1332*66e63ce3Schristos OP_680 ()
1333*66e63ce3Schristos {
1334*66e63ce3Schristos   unsigned int op0, op1, result, z, s;
1335*66e63ce3Schristos 
1336*66e63ce3Schristos   trace_input ("ori", OP_UIMM16_REG_REG, 0);
1337*66e63ce3Schristos   op0 = OP[2];
1338*66e63ce3Schristos   op1 = State.regs[ OP[0] ];
1339*66e63ce3Schristos   result = op0 | op1;
1340*66e63ce3Schristos 
1341*66e63ce3Schristos   /* Compute the condition codes.  */
1342*66e63ce3Schristos   z = (result == 0);
1343*66e63ce3Schristos   s = (result & 0x80000000);
1344*66e63ce3Schristos 
1345*66e63ce3Schristos   /* Store the result and condition codes.  */
1346*66e63ce3Schristos   State.regs[OP[1]] = result;
1347*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1348*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
1349*66e63ce3Schristos   trace_output (OP_UIMM16_REG_REG);
1350*66e63ce3Schristos 
1351*66e63ce3Schristos   return 4;
1352*66e63ce3Schristos }
1353*66e63ce3Schristos 
1354*66e63ce3Schristos /* and reg, reg */
1355*66e63ce3Schristos int
1356*66e63ce3Schristos OP_140 ()
1357*66e63ce3Schristos {
1358*66e63ce3Schristos   unsigned int op0, op1, result, z, s;
1359*66e63ce3Schristos 
1360*66e63ce3Schristos   trace_input ("and", OP_REG_REG, 0);
1361*66e63ce3Schristos 
1362*66e63ce3Schristos   /* Compute the result.  */
1363*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1364*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1365*66e63ce3Schristos   result = op0 & op1;
1366*66e63ce3Schristos 
1367*66e63ce3Schristos   /* Compute the condition codes.  */
1368*66e63ce3Schristos   z = (result == 0);
1369*66e63ce3Schristos   s = (result & 0x80000000);
1370*66e63ce3Schristos 
1371*66e63ce3Schristos   /* Store the result and condition codes.  */
1372*66e63ce3Schristos   State.regs[OP[1]] = result;
1373*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1374*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
1375*66e63ce3Schristos   trace_output (OP_REG_REG);
1376*66e63ce3Schristos 
1377*66e63ce3Schristos   return 2;
1378*66e63ce3Schristos }
1379*66e63ce3Schristos 
1380*66e63ce3Schristos /* andi zero_extend(imm16), reg, reg */
1381*66e63ce3Schristos int
1382*66e63ce3Schristos OP_6C0 ()
1383*66e63ce3Schristos {
1384*66e63ce3Schristos   unsigned int result, z;
1385*66e63ce3Schristos 
1386*66e63ce3Schristos   trace_input ("andi", OP_UIMM16_REG_REG, 0);
1387*66e63ce3Schristos 
1388*66e63ce3Schristos   result = OP[2] & State.regs[ OP[0] ];
1389*66e63ce3Schristos 
1390*66e63ce3Schristos   /* Compute the condition codes.  */
1391*66e63ce3Schristos   z = (result == 0);
1392*66e63ce3Schristos 
1393*66e63ce3Schristos   /* Store the result and condition codes.  */
1394*66e63ce3Schristos   State.regs[ OP[1] ] = result;
1395*66e63ce3Schristos 
1396*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1397*66e63ce3Schristos   PSW |= (z ? PSW_Z : 0);
1398*66e63ce3Schristos 
1399*66e63ce3Schristos   trace_output (OP_UIMM16_REG_REG);
1400*66e63ce3Schristos 
1401*66e63ce3Schristos   return 4;
1402*66e63ce3Schristos }
1403*66e63ce3Schristos 
1404*66e63ce3Schristos /* xor reg, reg */
1405*66e63ce3Schristos int
1406*66e63ce3Schristos OP_120 ()
1407*66e63ce3Schristos {
1408*66e63ce3Schristos   unsigned int op0, op1, result, z, s;
1409*66e63ce3Schristos 
1410*66e63ce3Schristos   trace_input ("xor", OP_REG_REG, 0);
1411*66e63ce3Schristos 
1412*66e63ce3Schristos   /* Compute the result.  */
1413*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1414*66e63ce3Schristos   op1 = State.regs[ OP[1] ];
1415*66e63ce3Schristos   result = op0 ^ op1;
1416*66e63ce3Schristos 
1417*66e63ce3Schristos   /* Compute the condition codes.  */
1418*66e63ce3Schristos   z = (result == 0);
1419*66e63ce3Schristos   s = (result & 0x80000000);
1420*66e63ce3Schristos 
1421*66e63ce3Schristos   /* Store the result and condition codes.  */
1422*66e63ce3Schristos   State.regs[OP[1]] = result;
1423*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1424*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
1425*66e63ce3Schristos   trace_output (OP_REG_REG);
1426*66e63ce3Schristos 
1427*66e63ce3Schristos   return 2;
1428*66e63ce3Schristos }
1429*66e63ce3Schristos 
1430*66e63ce3Schristos /* xori zero_extend(imm16), reg, reg */
1431*66e63ce3Schristos int
1432*66e63ce3Schristos OP_6A0 ()
1433*66e63ce3Schristos {
1434*66e63ce3Schristos   unsigned int op0, op1, result, z, s;
1435*66e63ce3Schristos 
1436*66e63ce3Schristos   trace_input ("xori", OP_UIMM16_REG_REG, 0);
1437*66e63ce3Schristos   op0 = OP[2];
1438*66e63ce3Schristos   op1 = State.regs[ OP[0] ];
1439*66e63ce3Schristos   result = op0 ^ op1;
1440*66e63ce3Schristos 
1441*66e63ce3Schristos   /* Compute the condition codes.  */
1442*66e63ce3Schristos   z = (result == 0);
1443*66e63ce3Schristos   s = (result & 0x80000000);
1444*66e63ce3Schristos 
1445*66e63ce3Schristos   /* Store the result and condition codes.  */
1446*66e63ce3Schristos   State.regs[OP[1]] = result;
1447*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1448*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
1449*66e63ce3Schristos   trace_output (OP_UIMM16_REG_REG);
1450*66e63ce3Schristos 
1451*66e63ce3Schristos   return 4;
1452*66e63ce3Schristos }
1453*66e63ce3Schristos 
1454*66e63ce3Schristos /* not reg1, reg2 */
1455*66e63ce3Schristos int
1456*66e63ce3Schristos OP_20 ()
1457*66e63ce3Schristos {
1458*66e63ce3Schristos   unsigned int op0, result, z, s;
1459*66e63ce3Schristos 
1460*66e63ce3Schristos   trace_input ("not", OP_REG_REG_MOVE, 0);
1461*66e63ce3Schristos   /* Compute the result.  */
1462*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1463*66e63ce3Schristos   result = ~op0;
1464*66e63ce3Schristos 
1465*66e63ce3Schristos   /* Compute the condition codes.  */
1466*66e63ce3Schristos   z = (result == 0);
1467*66e63ce3Schristos   s = (result & 0x80000000);
1468*66e63ce3Schristos 
1469*66e63ce3Schristos   /* Store the result and condition codes.  */
1470*66e63ce3Schristos   State.regs[OP[1]] = result;
1471*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1472*66e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
1473*66e63ce3Schristos   trace_output (OP_REG_REG_MOVE);
1474*66e63ce3Schristos 
1475*66e63ce3Schristos   return 2;
1476*66e63ce3Schristos }
1477*66e63ce3Schristos 
1478*66e63ce3Schristos /* set1 */
1479*66e63ce3Schristos int
1480*66e63ce3Schristos OP_7C0 ()
1481*66e63ce3Schristos {
1482*66e63ce3Schristos   unsigned int op0, op1, op2;
1483*66e63ce3Schristos   int temp;
1484*66e63ce3Schristos 
1485*66e63ce3Schristos   trace_input ("set1", OP_BIT, 0);
1486*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1487*66e63ce3Schristos   op1 = OP[1] & 0x7;
1488*66e63ce3Schristos   temp = EXTEND16 (OP[2]);
1489*66e63ce3Schristos   op2 = temp;
1490*66e63ce3Schristos   temp = load_mem (op0 + op2, 1);
1491*66e63ce3Schristos   PSW &= ~PSW_Z;
1492*66e63ce3Schristos   if ((temp & (1 << op1)) == 0)
1493*66e63ce3Schristos     PSW |= PSW_Z;
1494*66e63ce3Schristos   temp |= (1 << op1);
1495*66e63ce3Schristos   store_mem (op0 + op2, 1, temp);
1496*66e63ce3Schristos   trace_output (OP_BIT);
1497*66e63ce3Schristos 
1498*66e63ce3Schristos   return 4;
1499*66e63ce3Schristos }
1500*66e63ce3Schristos 
1501*66e63ce3Schristos /* not1 */
1502*66e63ce3Schristos int
1503*66e63ce3Schristos OP_47C0 ()
1504*66e63ce3Schristos {
1505*66e63ce3Schristos   unsigned int op0, op1, op2;
1506*66e63ce3Schristos   int temp;
1507*66e63ce3Schristos 
1508*66e63ce3Schristos   trace_input ("not1", OP_BIT, 0);
1509*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1510*66e63ce3Schristos   op1 = OP[1] & 0x7;
1511*66e63ce3Schristos   temp = EXTEND16 (OP[2]);
1512*66e63ce3Schristos   op2 = temp;
1513*66e63ce3Schristos   temp = load_mem (op0 + op2, 1);
1514*66e63ce3Schristos   PSW &= ~PSW_Z;
1515*66e63ce3Schristos   if ((temp & (1 << op1)) == 0)
1516*66e63ce3Schristos     PSW |= PSW_Z;
1517*66e63ce3Schristos   temp ^= (1 << op1);
1518*66e63ce3Schristos   store_mem (op0 + op2, 1, temp);
1519*66e63ce3Schristos   trace_output (OP_BIT);
1520*66e63ce3Schristos 
1521*66e63ce3Schristos   return 4;
1522*66e63ce3Schristos }
1523*66e63ce3Schristos 
1524*66e63ce3Schristos /* clr1 */
1525*66e63ce3Schristos int
1526*66e63ce3Schristos OP_87C0 ()
1527*66e63ce3Schristos {
1528*66e63ce3Schristos   unsigned int op0, op1, op2;
1529*66e63ce3Schristos   int temp;
1530*66e63ce3Schristos 
1531*66e63ce3Schristos   trace_input ("clr1", OP_BIT, 0);
1532*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1533*66e63ce3Schristos   op1 = OP[1] & 0x7;
1534*66e63ce3Schristos   temp = EXTEND16 (OP[2]);
1535*66e63ce3Schristos   op2 = temp;
1536*66e63ce3Schristos   temp = load_mem (op0 + op2, 1);
1537*66e63ce3Schristos   PSW &= ~PSW_Z;
1538*66e63ce3Schristos   if ((temp & (1 << op1)) == 0)
1539*66e63ce3Schristos     PSW |= PSW_Z;
1540*66e63ce3Schristos   temp &= ~(1 << op1);
1541*66e63ce3Schristos   store_mem (op0 + op2, 1, temp);
1542*66e63ce3Schristos   trace_output (OP_BIT);
1543*66e63ce3Schristos 
1544*66e63ce3Schristos   return 4;
1545*66e63ce3Schristos }
1546*66e63ce3Schristos 
1547*66e63ce3Schristos /* tst1 */
1548*66e63ce3Schristos int
1549*66e63ce3Schristos OP_C7C0 ()
1550*66e63ce3Schristos {
1551*66e63ce3Schristos   unsigned int op0, op1, op2;
1552*66e63ce3Schristos   int temp;
1553*66e63ce3Schristos 
1554*66e63ce3Schristos   trace_input ("tst1", OP_BIT, 0);
1555*66e63ce3Schristos   op0 = State.regs[ OP[0] ];
1556*66e63ce3Schristos   op1 = OP[1] & 0x7;
1557*66e63ce3Schristos   temp = EXTEND16 (OP[2]);
1558*66e63ce3Schristos   op2 = temp;
1559*66e63ce3Schristos   temp = load_mem (op0 + op2, 1);
1560*66e63ce3Schristos   PSW &= ~PSW_Z;
1561*66e63ce3Schristos   if ((temp & (1 << op1)) == 0)
1562*66e63ce3Schristos     PSW |= PSW_Z;
1563*66e63ce3Schristos   trace_output (OP_BIT);
1564*66e63ce3Schristos 
1565*66e63ce3Schristos   return 4;
1566*66e63ce3Schristos }
1567*66e63ce3Schristos 
1568*66e63ce3Schristos /* di */
1569*66e63ce3Schristos int
1570*66e63ce3Schristos OP_16007E0 ()
1571*66e63ce3Schristos {
1572*66e63ce3Schristos   trace_input ("di", OP_NONE, 0);
1573*66e63ce3Schristos   PSW |= PSW_ID;
1574*66e63ce3Schristos   trace_output (OP_NONE);
1575*66e63ce3Schristos 
1576*66e63ce3Schristos   return 4;
1577*66e63ce3Schristos }
1578*66e63ce3Schristos 
1579*66e63ce3Schristos /* ei */
1580*66e63ce3Schristos int
1581*66e63ce3Schristos OP_16087E0 ()
1582*66e63ce3Schristos {
1583*66e63ce3Schristos   trace_input ("ei", OP_NONE, 0);
1584*66e63ce3Schristos   PSW &= ~PSW_ID;
1585*66e63ce3Schristos   trace_output (OP_NONE);
1586*66e63ce3Schristos 
1587*66e63ce3Schristos   return 4;
1588*66e63ce3Schristos }
1589*66e63ce3Schristos 
1590*66e63ce3Schristos /* halt */
1591*66e63ce3Schristos int
1592*66e63ce3Schristos OP_12007E0 ()
1593*66e63ce3Schristos {
1594*66e63ce3Schristos   trace_input ("halt", OP_NONE, 0);
1595*66e63ce3Schristos   /* FIXME this should put processor into a mode where NMI still handled */
1596*66e63ce3Schristos   trace_output (OP_NONE);
1597*66e63ce3Schristos   sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
1598*66e63ce3Schristos 		   sim_stopped, SIM_SIGTRAP);
1599*66e63ce3Schristos   return 0;
1600*66e63ce3Schristos }
1601*66e63ce3Schristos 
1602*66e63ce3Schristos /* trap */
1603*66e63ce3Schristos int
1604*66e63ce3Schristos OP_10007E0 ()
1605*66e63ce3Schristos {
1606*66e63ce3Schristos   trace_input ("trap", OP_TRAP, 0);
1607*66e63ce3Schristos   trace_output (OP_TRAP);
1608*66e63ce3Schristos 
1609*66e63ce3Schristos   /* Trap 31 is used for simulating OS I/O functions */
1610*66e63ce3Schristos 
1611*66e63ce3Schristos   if (OP[0] == 31)
1612*66e63ce3Schristos     {
1613*66e63ce3Schristos       int save_errno = errno;
1614*66e63ce3Schristos       errno = 0;
1615*66e63ce3Schristos 
1616*66e63ce3Schristos /* Registers passed to trap 0 */
1617*66e63ce3Schristos 
1618*66e63ce3Schristos #define FUNC   State.regs[6]	/* function number, return value */
1619*66e63ce3Schristos #define PARM1  State.regs[7]	/* optional parm 1 */
1620*66e63ce3Schristos #define PARM2  State.regs[8]	/* optional parm 2 */
1621*66e63ce3Schristos #define PARM3  State.regs[9]	/* optional parm 3 */
1622*66e63ce3Schristos 
1623*66e63ce3Schristos /* Registers set by trap 0 */
1624*66e63ce3Schristos 
1625*66e63ce3Schristos #define RETVAL State.regs[10]	/* return value */
1626*66e63ce3Schristos #define RETERR State.regs[11]	/* return error code */
1627*66e63ce3Schristos 
1628*66e63ce3Schristos /* Turn a pointer in a register into a pointer into real memory. */
1629*66e63ce3Schristos 
1630*66e63ce3Schristos #define MEMPTR(x) (map (x))
1631*66e63ce3Schristos 
1632*66e63ce3Schristos       RETERR = 0;
1633*66e63ce3Schristos 
1634*66e63ce3Schristos       switch (FUNC)
1635*66e63ce3Schristos 	{
1636*66e63ce3Schristos 
1637*66e63ce3Schristos #ifdef HAVE_FORK
1638*66e63ce3Schristos #ifdef TARGET_SYS_fork
1639*66e63ce3Schristos 	case TARGET_SYS_fork:
1640*66e63ce3Schristos 	  RETVAL = fork ();
1641*66e63ce3Schristos 	  RETERR = errno;
1642*66e63ce3Schristos 	  break;
1643*66e63ce3Schristos #endif
1644*66e63ce3Schristos #endif
1645*66e63ce3Schristos 
1646*66e63ce3Schristos #ifdef HAVE_EXECVE
1647*66e63ce3Schristos #ifdef TARGET_SYS_execv
1648*66e63ce3Schristos 	case TARGET_SYS_execve:
1649*66e63ce3Schristos 	  {
1650*66e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
1651*66e63ce3Schristos 	    char **argv = fetch_argv (simulator, PARM2);
1652*66e63ce3Schristos 	    char **envp = fetch_argv (simulator, PARM3);
1653*66e63ce3Schristos 	    RETVAL = execve (path, argv, envp);
1654*66e63ce3Schristos 	    free (path);
1655*66e63ce3Schristos 	    freeargv (argv);
1656*66e63ce3Schristos 	    freeargv (envp);
1657*66e63ce3Schristos 	    RETERR = errno;
1658*66e63ce3Schristos 	    break;
1659*66e63ce3Schristos 	  }
1660*66e63ce3Schristos #endif
1661*66e63ce3Schristos #endif
1662*66e63ce3Schristos 
1663*66e63ce3Schristos #if HAVE_EXECV
1664*66e63ce3Schristos #ifdef TARGET_SYS_execv
1665*66e63ce3Schristos 	case TARGET_SYS_execv:
1666*66e63ce3Schristos 	  {
1667*66e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
1668*66e63ce3Schristos 	    char **argv = fetch_argv (simulator, PARM2);
1669*66e63ce3Schristos 	    RETVAL = execv (path, argv);
1670*66e63ce3Schristos 	    free (path);
1671*66e63ce3Schristos 	    freeargv (argv);
1672*66e63ce3Schristos 	    RETERR = errno;
1673*66e63ce3Schristos 	    break;
1674*66e63ce3Schristos 	  }
1675*66e63ce3Schristos #endif
1676*66e63ce3Schristos #endif
1677*66e63ce3Schristos 
1678*66e63ce3Schristos #if 0
1679*66e63ce3Schristos #ifdef TARGET_SYS_pipe
1680*66e63ce3Schristos 	case TARGET_SYS_pipe:
1681*66e63ce3Schristos 	  {
1682*66e63ce3Schristos 	    reg_t buf;
1683*66e63ce3Schristos 	    int host_fd[2];
1684*66e63ce3Schristos 
1685*66e63ce3Schristos 	    buf = PARM1;
1686*66e63ce3Schristos 	    RETVAL = pipe (host_fd);
1687*66e63ce3Schristos 	    SW (buf, host_fd[0]);
1688*66e63ce3Schristos 	    buf += sizeof(uint16);
1689*66e63ce3Schristos 	    SW (buf, host_fd[1]);
1690*66e63ce3Schristos 	    RETERR = errno;
1691*66e63ce3Schristos 	  }
1692*66e63ce3Schristos 	  break;
1693*66e63ce3Schristos #endif
1694*66e63ce3Schristos #endif
1695*66e63ce3Schristos 
1696*66e63ce3Schristos #if 0
1697*66e63ce3Schristos #ifdef TARGET_SYS_wait
1698*66e63ce3Schristos 	case TARGET_SYS_wait:
1699*66e63ce3Schristos 	  {
1700*66e63ce3Schristos 	    int status;
1701*66e63ce3Schristos 
1702*66e63ce3Schristos 	    RETVAL = wait (&status);
1703*66e63ce3Schristos 	    SW (PARM1, status);
1704*66e63ce3Schristos 	    RETERR = errno;
1705*66e63ce3Schristos 	  }
1706*66e63ce3Schristos 	  break;
1707*66e63ce3Schristos #endif
1708*66e63ce3Schristos #endif
1709*66e63ce3Schristos 
1710*66e63ce3Schristos #ifdef TARGET_SYS_read
1711*66e63ce3Schristos 	case TARGET_SYS_read:
1712*66e63ce3Schristos 	  {
1713*66e63ce3Schristos 	    char *buf = zalloc (PARM3);
1714*66e63ce3Schristos 	    RETVAL = sim_io_read (simulator, PARM1, buf, PARM3);
1715*66e63ce3Schristos 	    sim_write (simulator, PARM2, buf, PARM3);
1716*66e63ce3Schristos 	    free (buf);
1717*66e63ce3Schristos 	    if ((int) RETVAL < 0)
1718*66e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
1719*66e63ce3Schristos 	    break;
1720*66e63ce3Schristos 	  }
1721*66e63ce3Schristos #endif
1722*66e63ce3Schristos 
1723*66e63ce3Schristos #ifdef TARGET_SYS_write
1724*66e63ce3Schristos 	case TARGET_SYS_write:
1725*66e63ce3Schristos 	  {
1726*66e63ce3Schristos 	    char *buf = zalloc (PARM3);
1727*66e63ce3Schristos 	    sim_read (simulator, PARM2, buf, PARM3);
1728*66e63ce3Schristos 	    if (PARM1 == 1)
1729*66e63ce3Schristos 	      RETVAL = sim_io_write_stdout (simulator, buf, PARM3);
1730*66e63ce3Schristos 	    else
1731*66e63ce3Schristos 	      RETVAL = sim_io_write (simulator, PARM1, buf, PARM3);
1732*66e63ce3Schristos 	    free (buf);
1733*66e63ce3Schristos 	    if ((int) RETVAL < 0)
1734*66e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
1735*66e63ce3Schristos 	    break;
1736*66e63ce3Schristos 	  }
1737*66e63ce3Schristos #endif
1738*66e63ce3Schristos 
1739*66e63ce3Schristos #ifdef TARGET_SYS_lseek
1740*66e63ce3Schristos 	case TARGET_SYS_lseek:
1741*66e63ce3Schristos 	  RETVAL = sim_io_lseek (simulator, PARM1, PARM2, PARM3);
1742*66e63ce3Schristos 	  if ((int) RETVAL < 0)
1743*66e63ce3Schristos 	    RETERR = sim_io_get_errno (simulator);
1744*66e63ce3Schristos 	  break;
1745*66e63ce3Schristos #endif
1746*66e63ce3Schristos 
1747*66e63ce3Schristos #ifdef TARGET_SYS_close
1748*66e63ce3Schristos 	case TARGET_SYS_close:
1749*66e63ce3Schristos 	  RETVAL = sim_io_close (simulator, PARM1);
1750*66e63ce3Schristos 	  if ((int) RETVAL < 0)
1751*66e63ce3Schristos 	    RETERR = sim_io_get_errno (simulator);
1752*66e63ce3Schristos 	  break;
1753*66e63ce3Schristos #endif
1754*66e63ce3Schristos 
1755*66e63ce3Schristos #ifdef TARGET_SYS_open
1756*66e63ce3Schristos 	case TARGET_SYS_open:
1757*66e63ce3Schristos 	  {
1758*66e63ce3Schristos 	    char *buf = fetch_str (simulator, PARM1);
1759*66e63ce3Schristos 	    RETVAL = sim_io_open (simulator, buf, PARM2);
1760*66e63ce3Schristos 	    free (buf);
1761*66e63ce3Schristos 	    if ((int) RETVAL < 0)
1762*66e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
1763*66e63ce3Schristos 	    break;
1764*66e63ce3Schristos 	  }
1765*66e63ce3Schristos #endif
1766*66e63ce3Schristos 
1767*66e63ce3Schristos #ifdef TARGET_SYS_exit
1768*66e63ce3Schristos 	case TARGET_SYS_exit:
1769*66e63ce3Schristos 	  if ((PARM1 & 0xffff0000) == 0xdead0000 && (PARM1 & 0xffff) != 0)
1770*66e63ce3Schristos 	    /* get signal encoded by kill */
1771*66e63ce3Schristos 	    sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
1772*66e63ce3Schristos 			     sim_signalled, PARM1 & 0xffff);
1773*66e63ce3Schristos 	  else if (PARM1 == 0xdead)
1774*66e63ce3Schristos 	    /* old libraries */
1775*66e63ce3Schristos 	    sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
1776*66e63ce3Schristos 			     sim_stopped, SIM_SIGABRT);
1777*66e63ce3Schristos 	  else
1778*66e63ce3Schristos 	    /* PARM1 has exit status */
1779*66e63ce3Schristos 	    sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
1780*66e63ce3Schristos 			     sim_exited, PARM1);
1781*66e63ce3Schristos 	  break;
1782*66e63ce3Schristos #endif
1783*66e63ce3Schristos 
1784*66e63ce3Schristos #ifdef TARGET_SYS_stat
1785*66e63ce3Schristos 	case TARGET_SYS_stat:	/* added at hmsi */
1786*66e63ce3Schristos 	  /* stat system call */
1787*66e63ce3Schristos 	  {
1788*66e63ce3Schristos 	    struct stat host_stat;
1789*66e63ce3Schristos 	    reg_t buf;
1790*66e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
1791*66e63ce3Schristos 
1792*66e63ce3Schristos 	    RETVAL = sim_io_stat (simulator, path, &host_stat);
1793*66e63ce3Schristos 
1794*66e63ce3Schristos 	    free (path);
1795*66e63ce3Schristos 	    buf = PARM2;
1796*66e63ce3Schristos 
1797*66e63ce3Schristos 	    /* Just wild-assed guesses.  */
1798*66e63ce3Schristos 	    store_mem (buf, 2, host_stat.st_dev);
1799*66e63ce3Schristos 	    store_mem (buf + 2, 2, host_stat.st_ino);
1800*66e63ce3Schristos 	    store_mem (buf + 4, 4, host_stat.st_mode);
1801*66e63ce3Schristos 	    store_mem (buf + 8, 2, host_stat.st_nlink);
1802*66e63ce3Schristos 	    store_mem (buf + 10, 2, host_stat.st_uid);
1803*66e63ce3Schristos 	    store_mem (buf + 12, 2, host_stat.st_gid);
1804*66e63ce3Schristos 	    store_mem (buf + 14, 2, host_stat.st_rdev);
1805*66e63ce3Schristos 	    store_mem (buf + 16, 4, host_stat.st_size);
1806*66e63ce3Schristos 	    store_mem (buf + 20, 4, host_stat.st_atime);
1807*66e63ce3Schristos 	    store_mem (buf + 28, 4, host_stat.st_mtime);
1808*66e63ce3Schristos 	    store_mem (buf + 36, 4, host_stat.st_ctime);
1809*66e63ce3Schristos 
1810*66e63ce3Schristos 	    if ((int) RETVAL < 0)
1811*66e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
1812*66e63ce3Schristos 	  }
1813*66e63ce3Schristos 	  break;
1814*66e63ce3Schristos #endif
1815*66e63ce3Schristos 
1816*66e63ce3Schristos #ifdef TARGET_SYS_fstat
1817*66e63ce3Schristos 	case TARGET_SYS_fstat:
1818*66e63ce3Schristos 	  /* fstat system call */
1819*66e63ce3Schristos 	  {
1820*66e63ce3Schristos 	    struct stat host_stat;
1821*66e63ce3Schristos 	    reg_t buf;
1822*66e63ce3Schristos 
1823*66e63ce3Schristos 	    RETVAL = sim_io_fstat (simulator, PARM1, &host_stat);
1824*66e63ce3Schristos 
1825*66e63ce3Schristos 	    buf = PARM2;
1826*66e63ce3Schristos 
1827*66e63ce3Schristos 	    /* Just wild-assed guesses.  */
1828*66e63ce3Schristos 	    store_mem (buf, 2, host_stat.st_dev);
1829*66e63ce3Schristos 	    store_mem (buf + 2, 2, host_stat.st_ino);
1830*66e63ce3Schristos 	    store_mem (buf + 4, 4, host_stat.st_mode);
1831*66e63ce3Schristos 	    store_mem (buf + 8, 2, host_stat.st_nlink);
1832*66e63ce3Schristos 	    store_mem (buf + 10, 2, host_stat.st_uid);
1833*66e63ce3Schristos 	    store_mem (buf + 12, 2, host_stat.st_gid);
1834*66e63ce3Schristos 	    store_mem (buf + 14, 2, host_stat.st_rdev);
1835*66e63ce3Schristos 	    store_mem (buf + 16, 4, host_stat.st_size);
1836*66e63ce3Schristos 	    store_mem (buf + 20, 4, host_stat.st_atime);
1837*66e63ce3Schristos 	    store_mem (buf + 28, 4, host_stat.st_mtime);
1838*66e63ce3Schristos 	    store_mem (buf + 36, 4, host_stat.st_ctime);
1839*66e63ce3Schristos 
1840*66e63ce3Schristos 	    if ((int) RETVAL < 0)
1841*66e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
1842*66e63ce3Schristos 	  }
1843*66e63ce3Schristos 	  break;
1844*66e63ce3Schristos #endif
1845*66e63ce3Schristos 
1846*66e63ce3Schristos #ifdef TARGET_SYS_rename
1847*66e63ce3Schristos 	case TARGET_SYS_rename:
1848*66e63ce3Schristos 	  {
1849*66e63ce3Schristos 	    char *oldpath = fetch_str (simulator, PARM1);
1850*66e63ce3Schristos 	    char *newpath = fetch_str (simulator, PARM2);
1851*66e63ce3Schristos 	    RETVAL = sim_io_rename (simulator, oldpath, newpath);
1852*66e63ce3Schristos 	    free (oldpath);
1853*66e63ce3Schristos 	    free (newpath);
1854*66e63ce3Schristos 	    if ((int) RETVAL < 0)
1855*66e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
1856*66e63ce3Schristos 	  }
1857*66e63ce3Schristos 	  break;
1858*66e63ce3Schristos #endif
1859*66e63ce3Schristos 
1860*66e63ce3Schristos #ifdef TARGET_SYS_unlink
1861*66e63ce3Schristos 	case TARGET_SYS_unlink:
1862*66e63ce3Schristos 	  {
1863*66e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
1864*66e63ce3Schristos 	    RETVAL = sim_io_unlink (simulator, path);
1865*66e63ce3Schristos 	    free (path);
1866*66e63ce3Schristos 	    if ((int) RETVAL < 0)
1867*66e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
1868*66e63ce3Schristos 	  }
1869*66e63ce3Schristos 	  break;
1870*66e63ce3Schristos #endif
1871*66e63ce3Schristos 
1872*66e63ce3Schristos #ifdef HAVE_CHOWN
1873*66e63ce3Schristos #ifdef TARGET_SYS_chown
1874*66e63ce3Schristos 	case TARGET_SYS_chown:
1875*66e63ce3Schristos 	  {
1876*66e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
1877*66e63ce3Schristos 	    RETVAL = chown (path, PARM2, PARM3);
1878*66e63ce3Schristos 	    free (path);
1879*66e63ce3Schristos 	    RETERR = errno;
1880*66e63ce3Schristos 	  }
1881*66e63ce3Schristos 	  break;
1882*66e63ce3Schristos #endif
1883*66e63ce3Schristos #endif
1884*66e63ce3Schristos 
1885*66e63ce3Schristos #if HAVE_CHMOD
1886*66e63ce3Schristos #ifdef TARGET_SYS_chmod
1887*66e63ce3Schristos 	case TARGET_SYS_chmod:
1888*66e63ce3Schristos 	  {
1889*66e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
1890*66e63ce3Schristos 	    RETVAL = chmod (path, PARM2);
1891*66e63ce3Schristos 	    free (path);
1892*66e63ce3Schristos 	    RETERR = errno;
1893*66e63ce3Schristos 	  }
1894*66e63ce3Schristos 	  break;
1895*66e63ce3Schristos #endif
1896*66e63ce3Schristos #endif
1897*66e63ce3Schristos 
1898*66e63ce3Schristos #ifdef TARGET_SYS_time
1899*66e63ce3Schristos #if HAVE_TIME
1900*66e63ce3Schristos 	case TARGET_SYS_time:
1901*66e63ce3Schristos 	  {
1902*66e63ce3Schristos 	    time_t now;
1903*66e63ce3Schristos 	    RETVAL = time (&now);
1904*66e63ce3Schristos 	    store_mem (PARM1, 4, now);
1905*66e63ce3Schristos 	    RETERR = errno;
1906*66e63ce3Schristos 	  }
1907*66e63ce3Schristos 	  break;
1908*66e63ce3Schristos #endif
1909*66e63ce3Schristos #endif
1910*66e63ce3Schristos 
1911*66e63ce3Schristos #if !defined(__GO32__) && !defined(_WIN32)
1912*66e63ce3Schristos #ifdef TARGET_SYS_times
1913*66e63ce3Schristos 	case TARGET_SYS_times:
1914*66e63ce3Schristos 	  {
1915*66e63ce3Schristos 	    struct tms tms;
1916*66e63ce3Schristos 	    RETVAL = times (&tms);
1917*66e63ce3Schristos 	    store_mem (PARM1, 4, tms.tms_utime);
1918*66e63ce3Schristos 	    store_mem (PARM1 + 4, 4, tms.tms_stime);
1919*66e63ce3Schristos 	    store_mem (PARM1 + 8, 4, tms.tms_cutime);
1920*66e63ce3Schristos 	    store_mem (PARM1 + 12, 4, tms.tms_cstime);
1921*66e63ce3Schristos 	    reterr = errno;
1922*66e63ce3Schristos 	    break;
1923*66e63ce3Schristos 	  }
1924*66e63ce3Schristos #endif
1925*66e63ce3Schristos #endif
1926*66e63ce3Schristos 
1927*66e63ce3Schristos #ifdef TARGET_SYS_gettimeofday
1928*66e63ce3Schristos #if !defined(__GO32__) && !defined(_WIN32)
1929*66e63ce3Schristos 	case TARGET_SYS_gettimeofday:
1930*66e63ce3Schristos 	  {
1931*66e63ce3Schristos 	    struct timeval t;
1932*66e63ce3Schristos 	    struct timezone tz;
1933*66e63ce3Schristos 	    RETVAL = gettimeofday (&t, &tz);
1934*66e63ce3Schristos 	    store_mem (PARM1, 4, t.tv_sec);
1935*66e63ce3Schristos 	    store_mem (PARM1 + 4, 4, t.tv_usec);
1936*66e63ce3Schristos 	    store_mem (PARM2, 4, tz.tz_minuteswest);
1937*66e63ce3Schristos 	    store_mem (PARM2 + 4, 4, tz.tz_dsttime);
1938*66e63ce3Schristos 	    RETERR = errno;
1939*66e63ce3Schristos 	    break;
1940*66e63ce3Schristos 	  }
1941*66e63ce3Schristos #endif
1942*66e63ce3Schristos #endif
1943*66e63ce3Schristos 
1944*66e63ce3Schristos #ifdef TARGET_SYS_utime
1945*66e63ce3Schristos #if HAVE_UTIME
1946*66e63ce3Schristos 	case TARGET_SYS_utime:
1947*66e63ce3Schristos 	  {
1948*66e63ce3Schristos 	    /* Cast the second argument to void *, to avoid type mismatch
1949*66e63ce3Schristos 	       if a prototype is present.  */
1950*66e63ce3Schristos 	    sim_io_error (simulator, "Utime not supported");
1951*66e63ce3Schristos 	    /* RETVAL = utime (path, (void *) MEMPTR (PARM2)); */
1952*66e63ce3Schristos 	  }
1953*66e63ce3Schristos 	  break;
1954*66e63ce3Schristos #endif
1955*66e63ce3Schristos #endif
1956*66e63ce3Schristos 
1957*66e63ce3Schristos 	default:
1958*66e63ce3Schristos 	  abort ();
1959*66e63ce3Schristos 	}
1960*66e63ce3Schristos       errno = save_errno;
1961*66e63ce3Schristos 
1962*66e63ce3Schristos       return 4;
1963*66e63ce3Schristos     }
1964*66e63ce3Schristos   else
1965*66e63ce3Schristos     {				/* Trap 0 -> 30 */
1966*66e63ce3Schristos       EIPC = PC + 4;
1967*66e63ce3Schristos       EIPSW = PSW;
1968*66e63ce3Schristos       /* Mask out EICC */
1969*66e63ce3Schristos       ECR &= 0xffff0000;
1970*66e63ce3Schristos       ECR |= 0x40 + OP[0];
1971*66e63ce3Schristos       /* Flag that we are now doing exception processing.  */
1972*66e63ce3Schristos       PSW |= PSW_EP | PSW_ID;
1973*66e63ce3Schristos       PC = (OP[0] < 0x10) ? 0x40 : 0x50;
1974*66e63ce3Schristos 
1975*66e63ce3Schristos       return 0;
1976*66e63ce3Schristos     }
1977*66e63ce3Schristos }
1978*66e63ce3Schristos 
1979*66e63ce3Schristos /* tst1 reg2, [reg1] */
1980*66e63ce3Schristos int
1981*66e63ce3Schristos OP_E607E0 (void)
1982*66e63ce3Schristos {
1983*66e63ce3Schristos   int temp;
1984*66e63ce3Schristos 
1985*66e63ce3Schristos   trace_input ("tst1", OP_BIT, 1);
1986*66e63ce3Schristos 
1987*66e63ce3Schristos   temp = load_mem (State.regs[ OP[0] ], 1);
1988*66e63ce3Schristos 
1989*66e63ce3Schristos   PSW &= ~PSW_Z;
1990*66e63ce3Schristos   if ((temp & (1 << (State.regs[ OP[1] ] & 0x7))) == 0)
1991*66e63ce3Schristos     PSW |= PSW_Z;
1992*66e63ce3Schristos 
1993*66e63ce3Schristos   trace_output (OP_BIT);
1994*66e63ce3Schristos 
1995*66e63ce3Schristos   return 4;
1996*66e63ce3Schristos }
1997*66e63ce3Schristos 
1998*66e63ce3Schristos /* mulu reg1, reg2, reg3 */
1999*66e63ce3Schristos int
2000*66e63ce3Schristos OP_22207E0 (void)
2001*66e63ce3Schristos {
2002*66e63ce3Schristos   trace_input ("mulu", OP_REG_REG_REG, 0);
2003*66e63ce3Schristos 
2004*66e63ce3Schristos   Multiply64 (0, State.regs[ OP[0] ]);
2005*66e63ce3Schristos 
2006*66e63ce3Schristos   trace_output (OP_REG_REG_REG);
2007*66e63ce3Schristos 
2008*66e63ce3Schristos   return 4;
2009*66e63ce3Schristos }
2010*66e63ce3Schristos 
2011*66e63ce3Schristos #define BIT_CHANGE_OP( name, binop )		\
2012*66e63ce3Schristos   unsigned int bit;				\
2013*66e63ce3Schristos   unsigned int temp;				\
2014*66e63ce3Schristos   						\
2015*66e63ce3Schristos   trace_input (name, OP_BIT_CHANGE, 0);		\
2016*66e63ce3Schristos   						\
2017*66e63ce3Schristos   bit  = 1 << (State.regs[ OP[1] ] & 0x7);	\
2018*66e63ce3Schristos   temp = load_mem (State.regs[ OP[0] ], 1);	\
2019*66e63ce3Schristos 						\
2020*66e63ce3Schristos   PSW &= ~PSW_Z;				\
2021*66e63ce3Schristos   if ((temp & bit) == 0)			\
2022*66e63ce3Schristos     PSW |= PSW_Z;				\
2023*66e63ce3Schristos   temp binop bit;				\
2024*66e63ce3Schristos   						\
2025*66e63ce3Schristos   store_mem (State.regs[ OP[0] ], 1, temp);	\
2026*66e63ce3Schristos 	     					\
2027*66e63ce3Schristos   trace_output (OP_BIT_CHANGE);			\
2028*66e63ce3Schristos 	     					\
2029*66e63ce3Schristos   return 4;
2030*66e63ce3Schristos 
2031*66e63ce3Schristos /* clr1 reg2, [reg1] */
2032*66e63ce3Schristos int
2033*66e63ce3Schristos OP_E407E0 (void)
2034*66e63ce3Schristos {
2035*66e63ce3Schristos   BIT_CHANGE_OP ("clr1", &= ~ );
2036*66e63ce3Schristos }
2037*66e63ce3Schristos 
2038*66e63ce3Schristos /* not1 reg2, [reg1] */
2039*66e63ce3Schristos int
2040*66e63ce3Schristos OP_E207E0 (void)
2041*66e63ce3Schristos {
2042*66e63ce3Schristos   BIT_CHANGE_OP ("not1", ^= );
2043*66e63ce3Schristos }
2044*66e63ce3Schristos 
2045*66e63ce3Schristos /* set1 */
2046*66e63ce3Schristos int
2047*66e63ce3Schristos OP_E007E0 (void)
2048*66e63ce3Schristos {
2049*66e63ce3Schristos   BIT_CHANGE_OP ("set1", |= );
2050*66e63ce3Schristos }
2051*66e63ce3Schristos 
2052*66e63ce3Schristos /* sasf */
2053*66e63ce3Schristos int
2054*66e63ce3Schristos OP_20007E0 (void)
2055*66e63ce3Schristos {
2056*66e63ce3Schristos   trace_input ("sasf", OP_EX1, 0);
2057*66e63ce3Schristos 
2058*66e63ce3Schristos   State.regs[ OP[1] ] = (State.regs[ OP[1] ] << 1) | condition_met (OP[0]);
2059*66e63ce3Schristos 
2060*66e63ce3Schristos   trace_output (OP_EX1);
2061*66e63ce3Schristos 
2062*66e63ce3Schristos   return 4;
2063*66e63ce3Schristos }
2064*66e63ce3Schristos 
2065*66e63ce3Schristos /* This function is courtesy of Sugimoto at NEC, via Seow Tan
2066*66e63ce3Schristos    (Soew_Tan@el.nec.com) */
2067*66e63ce3Schristos void
2068*66e63ce3Schristos divun
2069*66e63ce3Schristos (
2070*66e63ce3Schristos   unsigned int       N,
2071*66e63ce3Schristos   unsigned long int  als,
2072*66e63ce3Schristos   unsigned long int  sfi,
2073*66e63ce3Schristos   unsigned32 /*unsigned long int*/ *  quotient_ptr,
2074*66e63ce3Schristos   unsigned32 /*unsigned long int*/ *  remainder_ptr,
2075*66e63ce3Schristos   int *          overflow_ptr
2076*66e63ce3Schristos )
2077*66e63ce3Schristos {
2078*66e63ce3Schristos   unsigned long   ald = sfi >> (N - 1);
2079*66e63ce3Schristos   unsigned long   alo = als;
2080*66e63ce3Schristos   unsigned int    Q   = 1;
2081*66e63ce3Schristos   unsigned int    C;
2082*66e63ce3Schristos   unsigned int    S   = 0;
2083*66e63ce3Schristos   unsigned int    i;
2084*66e63ce3Schristos   unsigned int    R1  = 1;
2085*66e63ce3Schristos   unsigned int    DBZ = (als == 0) ? 1 : 0;
2086*66e63ce3Schristos   unsigned long   alt = Q ? ~als : als;
2087*66e63ce3Schristos 
2088*66e63ce3Schristos   /* 1st Loop */
2089*66e63ce3Schristos   alo = ald + alt + Q;
2090*66e63ce3Schristos   C   = (((alt >> 31) & (ald >> 31))
2091*66e63ce3Schristos 	 | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
2092*66e63ce3Schristos   C   = C ^ Q;
2093*66e63ce3Schristos   Q   = ~(C ^ S) & 1;
2094*66e63ce3Schristos   R1  = (alo == 0) ? 0 : (R1 & Q);
2095*66e63ce3Schristos   if ((S ^ (alo>>31)) && !C)
2096*66e63ce3Schristos     {
2097*66e63ce3Schristos       DBZ = 1;
2098*66e63ce3Schristos     }
2099*66e63ce3Schristos   S   = alo >> 31;
2100*66e63ce3Schristos   sfi = (sfi << (32-N+1)) | Q;
2101*66e63ce3Schristos   ald = (alo << 1) | (sfi >> 31);
2102*66e63ce3Schristos 
2103*66e63ce3Schristos   /* 2nd - N-1th Loop */
2104*66e63ce3Schristos   for (i = 2; i < N; i++)
2105*66e63ce3Schristos     {
2106*66e63ce3Schristos       alt = Q ? ~als : als;
2107*66e63ce3Schristos       alo = ald + alt + Q;
2108*66e63ce3Schristos       C   = (((alt >> 31) & (ald >> 31))
2109*66e63ce3Schristos 	     | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
2110*66e63ce3Schristos       C   = C ^ Q;
2111*66e63ce3Schristos       Q   = ~(C ^ S) & 1;
2112*66e63ce3Schristos       R1  = (alo == 0) ? 0 : (R1 & Q);
2113*66e63ce3Schristos       if ((S ^ (alo>>31)) && !C && !DBZ)
2114*66e63ce3Schristos 	{
2115*66e63ce3Schristos 	  DBZ = 1;
2116*66e63ce3Schristos 	}
2117*66e63ce3Schristos       S   = alo >> 31;
2118*66e63ce3Schristos       sfi = (sfi << 1) | Q;
2119*66e63ce3Schristos       ald = (alo << 1) | (sfi >> 31);
2120*66e63ce3Schristos     }
2121*66e63ce3Schristos 
2122*66e63ce3Schristos   /* Nth Loop */
2123*66e63ce3Schristos   alt = Q ? ~als : als;
2124*66e63ce3Schristos   alo = ald + alt + Q;
2125*66e63ce3Schristos   C   = (((alt >> 31) & (ald >> 31))
2126*66e63ce3Schristos 	 | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
2127*66e63ce3Schristos   C   = C ^ Q;
2128*66e63ce3Schristos   Q   = ~(C ^ S) & 1;
2129*66e63ce3Schristos   R1  = (alo == 0) ? 0 : (R1 & Q);
2130*66e63ce3Schristos   if ((S ^ (alo>>31)) && !C)
2131*66e63ce3Schristos     {
2132*66e63ce3Schristos       DBZ = 1;
2133*66e63ce3Schristos     }
2134*66e63ce3Schristos 
2135*66e63ce3Schristos   * quotient_ptr  = (sfi << 1) | Q;
2136*66e63ce3Schristos   * remainder_ptr = Q ? alo : (alo + als);
2137*66e63ce3Schristos   * overflow_ptr  = DBZ | R1;
2138*66e63ce3Schristos }
2139*66e63ce3Schristos 
2140*66e63ce3Schristos /* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
2141*66e63ce3Schristos void
2142*66e63ce3Schristos divn
2143*66e63ce3Schristos (
2144*66e63ce3Schristos   unsigned int       N,
2145*66e63ce3Schristos   unsigned long int  als,
2146*66e63ce3Schristos   unsigned long int  sfi,
2147*66e63ce3Schristos   signed32 /*signed long int*/ *  quotient_ptr,
2148*66e63ce3Schristos   signed32 /*signed long int*/ *  remainder_ptr,
2149*66e63ce3Schristos   int *          overflow_ptr
2150*66e63ce3Schristos )
2151*66e63ce3Schristos {
2152*66e63ce3Schristos   unsigned long	  ald = (signed long) sfi >> (N - 1);
2153*66e63ce3Schristos   unsigned long   alo = als;
2154*66e63ce3Schristos   unsigned int    SS  = als >> 31;
2155*66e63ce3Schristos   unsigned int	  SD  = sfi >> 31;
2156*66e63ce3Schristos   unsigned int    R1  = 1;
2157*66e63ce3Schristos   unsigned int    OV;
2158*66e63ce3Schristos   unsigned int    DBZ = als == 0 ? 1 : 0;
2159*66e63ce3Schristos   unsigned int    Q   = ~(SS ^ SD) & 1;
2160*66e63ce3Schristos   unsigned int    C;
2161*66e63ce3Schristos   unsigned int    S;
2162*66e63ce3Schristos   unsigned int    i;
2163*66e63ce3Schristos   unsigned long   alt = Q ? ~als : als;
2164*66e63ce3Schristos 
2165*66e63ce3Schristos 
2166*66e63ce3Schristos   /* 1st Loop */
2167*66e63ce3Schristos 
2168*66e63ce3Schristos   alo = ald + alt + Q;
2169*66e63ce3Schristos   C   = (((alt >> 31) & (ald >> 31))
2170*66e63ce3Schristos 	 | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
2171*66e63ce3Schristos   Q   = C ^ SS;
2172*66e63ce3Schristos   R1  = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
2173*66e63ce3Schristos   S   = alo >> 31;
2174*66e63ce3Schristos   sfi = (sfi << (32-N+1)) | Q;
2175*66e63ce3Schristos   ald = (alo << 1) | (sfi >> 31);
2176*66e63ce3Schristos   if ((alo >> 31) ^ (ald >> 31))
2177*66e63ce3Schristos     {
2178*66e63ce3Schristos       DBZ = 1;
2179*66e63ce3Schristos     }
2180*66e63ce3Schristos 
2181*66e63ce3Schristos   /* 2nd - N-1th Loop */
2182*66e63ce3Schristos 
2183*66e63ce3Schristos   for (i = 2; i < N; i++)
2184*66e63ce3Schristos     {
2185*66e63ce3Schristos       alt = Q ? ~als : als;
2186*66e63ce3Schristos       alo = ald + alt + Q;
2187*66e63ce3Schristos       C   = (((alt >> 31) & (ald >> 31))
2188*66e63ce3Schristos 	     | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
2189*66e63ce3Schristos       Q   = C ^ SS;
2190*66e63ce3Schristos       R1  = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
2191*66e63ce3Schristos       S   = alo >> 31;
2192*66e63ce3Schristos       sfi = (sfi << 1) | Q;
2193*66e63ce3Schristos       ald = (alo << 1) | (sfi >> 31);
2194*66e63ce3Schristos       if ((alo >> 31) ^ (ald >> 31))
2195*66e63ce3Schristos 	{
2196*66e63ce3Schristos 	  DBZ = 1;
2197*66e63ce3Schristos 	}
2198*66e63ce3Schristos     }
2199*66e63ce3Schristos 
2200*66e63ce3Schristos   /* Nth Loop */
2201*66e63ce3Schristos   alt = Q ? ~als : als;
2202*66e63ce3Schristos   alo = ald + alt + Q;
2203*66e63ce3Schristos   C   = (((alt >> 31) & (ald >> 31))
2204*66e63ce3Schristos 	 | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
2205*66e63ce3Schristos   Q   = C ^ SS;
2206*66e63ce3Schristos   R1  = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
2207*66e63ce3Schristos   sfi = (sfi << (32-N+1));
2208*66e63ce3Schristos   ald = alo;
2209*66e63ce3Schristos 
2210*66e63ce3Schristos   /* End */
2211*66e63ce3Schristos   if (alo != 0)
2212*66e63ce3Schristos     {
2213*66e63ce3Schristos       alt = Q ? ~als : als;
2214*66e63ce3Schristos       alo = ald + alt + Q;
2215*66e63ce3Schristos     }
2216*66e63ce3Schristos   R1  = R1 & ((~alo >> 31) ^ SD);
2217*66e63ce3Schristos   if ((alo != 0) && ((Q ^ (SS ^ SD)) ^ R1)) alo = ald;
2218*66e63ce3Schristos   if (N != 32)
2219*66e63ce3Schristos     ald = sfi = (long) ((sfi >> 1) | (SS ^ SD) << 31) >> (32-N-1) | Q;
2220*66e63ce3Schristos   else
2221*66e63ce3Schristos     ald = sfi = sfi | Q;
2222*66e63ce3Schristos 
2223*66e63ce3Schristos   OV = DBZ | ((alo == 0) ? 0 : R1);
2224*66e63ce3Schristos 
2225*66e63ce3Schristos   * remainder_ptr = alo;
2226*66e63ce3Schristos 
2227*66e63ce3Schristos   /* Adj */
2228*66e63ce3Schristos   if (((alo != 0) && ((SS ^ SD) ^ R1))
2229*66e63ce3Schristos       || ((alo == 0) && (SS ^ R1)))
2230*66e63ce3Schristos     alo = ald + 1;
2231*66e63ce3Schristos   else
2232*66e63ce3Schristos     alo = ald;
2233*66e63ce3Schristos 
2234*66e63ce3Schristos   OV  = (DBZ | R1) ? OV : ((alo >> 31) & (~ald >> 31));
2235*66e63ce3Schristos 
2236*66e63ce3Schristos   * quotient_ptr  = alo;
2237*66e63ce3Schristos   * overflow_ptr  = OV;
2238*66e63ce3Schristos }
2239*66e63ce3Schristos 
2240*66e63ce3Schristos /* sdivun imm5, reg1, reg2, reg3 */
2241*66e63ce3Schristos int
2242*66e63ce3Schristos OP_1C207E0 (void)
2243*66e63ce3Schristos {
2244*66e63ce3Schristos   unsigned32 /*unsigned long int*/  quotient;
2245*66e63ce3Schristos   unsigned32 /*unsigned long int*/  remainder;
2246*66e63ce3Schristos   unsigned long int  divide_by;
2247*66e63ce3Schristos   unsigned long int  divide_this;
2248*66e63ce3Schristos   int            overflow = 0;
2249*66e63ce3Schristos   unsigned int       imm5;
2250*66e63ce3Schristos 
2251*66e63ce3Schristos   trace_input ("sdivun", OP_IMM_REG_REG_REG, 0);
2252*66e63ce3Schristos 
2253*66e63ce3Schristos   imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2254*66e63ce3Schristos 
2255*66e63ce3Schristos   divide_by   = State.regs[ OP[0] ];
2256*66e63ce3Schristos   divide_this = State.regs[ OP[1] ] << imm5;
2257*66e63ce3Schristos 
2258*66e63ce3Schristos   divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
2259*66e63ce3Schristos 
2260*66e63ce3Schristos   State.regs[ OP[1]       ] = quotient;
2261*66e63ce3Schristos   State.regs[ OP[2] >> 11 ] = remainder;
2262*66e63ce3Schristos 
2263*66e63ce3Schristos   /* Set condition codes.  */
2264*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2265*66e63ce3Schristos 
2266*66e63ce3Schristos   if (overflow)      PSW |= PSW_OV;
2267*66e63ce3Schristos   if (quotient == 0) PSW |= PSW_Z;
2268*66e63ce3Schristos   if (quotient & 0x80000000) PSW |= PSW_S;
2269*66e63ce3Schristos 
2270*66e63ce3Schristos   trace_output (OP_IMM_REG_REG_REG);
2271*66e63ce3Schristos 
2272*66e63ce3Schristos   return 4;
2273*66e63ce3Schristos }
2274*66e63ce3Schristos 
2275*66e63ce3Schristos /* sdivn imm5, reg1, reg2, reg3 */
2276*66e63ce3Schristos int
2277*66e63ce3Schristos OP_1C007E0 (void)
2278*66e63ce3Schristos {
2279*66e63ce3Schristos   signed32 /*signed long int*/  quotient;
2280*66e63ce3Schristos   signed32 /*signed long int*/  remainder;
2281*66e63ce3Schristos   signed long int  divide_by;
2282*66e63ce3Schristos   signed long int  divide_this;
2283*66e63ce3Schristos   int          overflow = 0;
2284*66e63ce3Schristos   unsigned int     imm5;
2285*66e63ce3Schristos 
2286*66e63ce3Schristos   trace_input ("sdivn", OP_IMM_REG_REG_REG, 0);
2287*66e63ce3Schristos 
2288*66e63ce3Schristos   imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2289*66e63ce3Schristos 
2290*66e63ce3Schristos   divide_by   = (signed32) State.regs[ OP[0] ];
2291*66e63ce3Schristos   divide_this = (signed32) (State.regs[ OP[1] ] << imm5);
2292*66e63ce3Schristos 
2293*66e63ce3Schristos   divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
2294*66e63ce3Schristos 
2295*66e63ce3Schristos   State.regs[ OP[1]       ] = quotient;
2296*66e63ce3Schristos   State.regs[ OP[2] >> 11 ] = remainder;
2297*66e63ce3Schristos 
2298*66e63ce3Schristos   /* Set condition codes.  */
2299*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2300*66e63ce3Schristos 
2301*66e63ce3Schristos   if (overflow)      PSW |= PSW_OV;
2302*66e63ce3Schristos   if (quotient == 0) PSW |= PSW_Z;
2303*66e63ce3Schristos   if (quotient <  0) PSW |= PSW_S;
2304*66e63ce3Schristos 
2305*66e63ce3Schristos   trace_output (OP_IMM_REG_REG_REG);
2306*66e63ce3Schristos 
2307*66e63ce3Schristos   return 4;
2308*66e63ce3Schristos }
2309*66e63ce3Schristos 
2310*66e63ce3Schristos /* sdivhun imm5, reg1, reg2, reg3 */
2311*66e63ce3Schristos int
2312*66e63ce3Schristos OP_18207E0 (void)
2313*66e63ce3Schristos {
2314*66e63ce3Schristos   unsigned32 /*unsigned long int*/  quotient;
2315*66e63ce3Schristos   unsigned32 /*unsigned long int*/  remainder;
2316*66e63ce3Schristos   unsigned long int  divide_by;
2317*66e63ce3Schristos   unsigned long int  divide_this;
2318*66e63ce3Schristos   int            overflow = 0;
2319*66e63ce3Schristos   unsigned int       imm5;
2320*66e63ce3Schristos 
2321*66e63ce3Schristos   trace_input ("sdivhun", OP_IMM_REG_REG_REG, 0);
2322*66e63ce3Schristos 
2323*66e63ce3Schristos   imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2324*66e63ce3Schristos 
2325*66e63ce3Schristos   divide_by   = State.regs[ OP[0] ] & 0xffff;
2326*66e63ce3Schristos   divide_this = State.regs[ OP[1] ] << imm5;
2327*66e63ce3Schristos 
2328*66e63ce3Schristos   divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
2329*66e63ce3Schristos 
2330*66e63ce3Schristos   State.regs[ OP[1]       ] = quotient;
2331*66e63ce3Schristos   State.regs[ OP[2] >> 11 ] = remainder;
2332*66e63ce3Schristos 
2333*66e63ce3Schristos   /* Set condition codes.  */
2334*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2335*66e63ce3Schristos 
2336*66e63ce3Schristos   if (overflow)      PSW |= PSW_OV;
2337*66e63ce3Schristos   if (quotient == 0) PSW |= PSW_Z;
2338*66e63ce3Schristos   if (quotient & 0x80000000) PSW |= PSW_S;
2339*66e63ce3Schristos 
2340*66e63ce3Schristos   trace_output (OP_IMM_REG_REG_REG);
2341*66e63ce3Schristos 
2342*66e63ce3Schristos   return 4;
2343*66e63ce3Schristos }
2344*66e63ce3Schristos 
2345*66e63ce3Schristos /* sdivhn imm5, reg1, reg2, reg3 */
2346*66e63ce3Schristos int
2347*66e63ce3Schristos OP_18007E0 (void)
2348*66e63ce3Schristos {
2349*66e63ce3Schristos   signed32 /*signed long int*/  quotient;
2350*66e63ce3Schristos   signed32 /*signed long int*/  remainder;
2351*66e63ce3Schristos   signed long int  divide_by;
2352*66e63ce3Schristos   signed long int  divide_this;
2353*66e63ce3Schristos   int          overflow = 0;
2354*66e63ce3Schristos   unsigned int     imm5;
2355*66e63ce3Schristos 
2356*66e63ce3Schristos   trace_input ("sdivhn", OP_IMM_REG_REG_REG, 0);
2357*66e63ce3Schristos 
2358*66e63ce3Schristos   imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2359*66e63ce3Schristos 
2360*66e63ce3Schristos   divide_by   = EXTEND16 (State.regs[ OP[0] ]);
2361*66e63ce3Schristos   divide_this = (signed32) (State.regs[ OP[1] ] << imm5);
2362*66e63ce3Schristos 
2363*66e63ce3Schristos   divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
2364*66e63ce3Schristos 
2365*66e63ce3Schristos   State.regs[ OP[1]       ] = quotient;
2366*66e63ce3Schristos   State.regs[ OP[2] >> 11 ] = remainder;
2367*66e63ce3Schristos 
2368*66e63ce3Schristos   /* Set condition codes.  */
2369*66e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2370*66e63ce3Schristos 
2371*66e63ce3Schristos   if (overflow)      PSW |= PSW_OV;
2372*66e63ce3Schristos   if (quotient == 0) PSW |= PSW_Z;
2373*66e63ce3Schristos   if (quotient <  0) PSW |= PSW_S;
2374*66e63ce3Schristos 
2375*66e63ce3Schristos   trace_output (OP_IMM_REG_REG_REG);
2376*66e63ce3Schristos 
2377*66e63ce3Schristos   return 4;
2378*66e63ce3Schristos }
2379*66e63ce3Schristos 
2380*66e63ce3Schristos /* divu  reg1, reg2, reg3 */
2381*66e63ce3Schristos int
2382*66e63ce3Schristos OP_2C207E0 (void)
2383*66e63ce3Schristos {
2384*66e63ce3Schristos   unsigned long int quotient;
2385*66e63ce3Schristos   unsigned long int remainder;
2386*66e63ce3Schristos   unsigned long int divide_by;
2387*66e63ce3Schristos   unsigned long int divide_this;
2388*66e63ce3Schristos   int           overflow = 0;
2389*66e63ce3Schristos 
2390*66e63ce3Schristos   trace_input ("divu", OP_REG_REG_REG, 0);
2391*66e63ce3Schristos 
2392*66e63ce3Schristos   /* Compute the result.  */
2393*66e63ce3Schristos 
2394*66e63ce3Schristos   divide_by   = State.regs[ OP[0] ];
2395*66e63ce3Schristos   divide_this = State.regs[ OP[1] ];
2396*66e63ce3Schristos 
2397*66e63ce3Schristos   if (divide_by == 0)
2398*66e63ce3Schristos     {
2399*66e63ce3Schristos       PSW |= PSW_OV;
2400*66e63ce3Schristos     }
2401*66e63ce3Schristos   else
2402*66e63ce3Schristos     {
2403*66e63ce3Schristos       State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
2404*66e63ce3Schristos       State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
2405*66e63ce3Schristos 
2406*66e63ce3Schristos       /* Set condition codes.  */
2407*66e63ce3Schristos       PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2408*66e63ce3Schristos 
2409*66e63ce3Schristos       if (overflow)      PSW |= PSW_OV;
2410*66e63ce3Schristos       if (quotient == 0) PSW |= PSW_Z;
2411*66e63ce3Schristos       if (quotient & 0x80000000) PSW |= PSW_S;
2412*66e63ce3Schristos     }
2413*66e63ce3Schristos 
2414*66e63ce3Schristos   trace_output (OP_REG_REG_REG);
2415*66e63ce3Schristos 
2416*66e63ce3Schristos   return 4;
2417*66e63ce3Schristos }
2418*66e63ce3Schristos 
2419*66e63ce3Schristos /* div  reg1, reg2, reg3 */
2420*66e63ce3Schristos int
2421*66e63ce3Schristos OP_2C007E0 (void)
2422*66e63ce3Schristos {
2423*66e63ce3Schristos   signed long int quotient;
2424*66e63ce3Schristos   signed long int remainder;
2425*66e63ce3Schristos   signed long int divide_by;
2426*66e63ce3Schristos   signed long int divide_this;
2427*66e63ce3Schristos 
2428*66e63ce3Schristos   trace_input ("div", OP_REG_REG_REG, 0);
2429*66e63ce3Schristos 
2430*66e63ce3Schristos   /* Compute the result.  */
2431*66e63ce3Schristos 
2432*66e63ce3Schristos   divide_by   = (signed32) State.regs[ OP[0] ];
2433*66e63ce3Schristos   divide_this = State.regs[ OP[1] ];
2434*66e63ce3Schristos 
2435*66e63ce3Schristos   if (divide_by == 0)
2436*66e63ce3Schristos     {
2437*66e63ce3Schristos       PSW |= PSW_OV;
2438*66e63ce3Schristos     }
2439*66e63ce3Schristos   else if (divide_by == -1 && divide_this == (1L << 31))
2440*66e63ce3Schristos     {
2441*66e63ce3Schristos       PSW &= ~PSW_Z;
2442*66e63ce3Schristos       PSW |= PSW_OV | PSW_S;
2443*66e63ce3Schristos       State.regs[ OP[1] ] = (1 << 31);
2444*66e63ce3Schristos       State.regs[ OP[2] >> 11 ] = 0;
2445*66e63ce3Schristos     }
2446*66e63ce3Schristos   else
2447*66e63ce3Schristos     {
2448*66e63ce3Schristos       divide_this = (signed32) divide_this;
2449*66e63ce3Schristos       State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
2450*66e63ce3Schristos       State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
2451*66e63ce3Schristos 
2452*66e63ce3Schristos       /* Set condition codes.  */
2453*66e63ce3Schristos       PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2454*66e63ce3Schristos 
2455*66e63ce3Schristos       if (quotient == 0) PSW |= PSW_Z;
2456*66e63ce3Schristos       if (quotient <  0) PSW |= PSW_S;
2457*66e63ce3Schristos     }
2458*66e63ce3Schristos 
2459*66e63ce3Schristos   trace_output (OP_REG_REG_REG);
2460*66e63ce3Schristos 
2461*66e63ce3Schristos   return 4;
2462*66e63ce3Schristos }
2463*66e63ce3Schristos 
2464*66e63ce3Schristos /* divhu  reg1, reg2, reg3 */
2465*66e63ce3Schristos int
2466*66e63ce3Schristos OP_28207E0 (void)
2467*66e63ce3Schristos {
2468*66e63ce3Schristos   unsigned long int quotient;
2469*66e63ce3Schristos   unsigned long int remainder;
2470*66e63ce3Schristos   unsigned long int divide_by;
2471*66e63ce3Schristos   unsigned long int divide_this;
2472*66e63ce3Schristos   int           overflow = 0;
2473*66e63ce3Schristos 
2474*66e63ce3Schristos   trace_input ("divhu", OP_REG_REG_REG, 0);
2475*66e63ce3Schristos 
2476*66e63ce3Schristos   /* Compute the result.  */
2477*66e63ce3Schristos 
2478*66e63ce3Schristos   divide_by   = State.regs[ OP[0] ] & 0xffff;
2479*66e63ce3Schristos   divide_this = State.regs[ OP[1] ];
2480*66e63ce3Schristos 
2481*66e63ce3Schristos   if (divide_by == 0)
2482*66e63ce3Schristos     {
2483*66e63ce3Schristos       PSW |= PSW_OV;
2484*66e63ce3Schristos     }
2485*66e63ce3Schristos   else
2486*66e63ce3Schristos     {
2487*66e63ce3Schristos       State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
2488*66e63ce3Schristos       State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
2489*66e63ce3Schristos 
2490*66e63ce3Schristos       /* Set condition codes.  */
2491*66e63ce3Schristos       PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2492*66e63ce3Schristos 
2493*66e63ce3Schristos       if (overflow)      PSW |= PSW_OV;
2494*66e63ce3Schristos       if (quotient == 0) PSW |= PSW_Z;
2495*66e63ce3Schristos       if (quotient & 0x80000000) PSW |= PSW_S;
2496*66e63ce3Schristos     }
2497*66e63ce3Schristos 
2498*66e63ce3Schristos   trace_output (OP_REG_REG_REG);
2499*66e63ce3Schristos 
2500*66e63ce3Schristos   return 4;
2501*66e63ce3Schristos }
2502*66e63ce3Schristos 
2503*66e63ce3Schristos /* divh  reg1, reg2, reg3 */
2504*66e63ce3Schristos int
2505*66e63ce3Schristos OP_28007E0 (void)
2506*66e63ce3Schristos {
2507*66e63ce3Schristos   signed long int quotient;
2508*66e63ce3Schristos   signed long int remainder;
2509*66e63ce3Schristos   signed long int divide_by;
2510*66e63ce3Schristos   signed long int divide_this;
2511*66e63ce3Schristos   int         overflow = 0;
2512*66e63ce3Schristos 
2513*66e63ce3Schristos   trace_input ("divh", OP_REG_REG_REG, 0);
2514*66e63ce3Schristos 
2515*66e63ce3Schristos   /* Compute the result.  */
2516*66e63ce3Schristos 
2517*66e63ce3Schristos   divide_by  = EXTEND16 (State.regs[ OP[0] ]);
2518*66e63ce3Schristos   divide_this = State.regs[ OP[1] ];
2519*66e63ce3Schristos 
2520*66e63ce3Schristos   if (divide_by == 0)
2521*66e63ce3Schristos     {
2522*66e63ce3Schristos       PSW |= PSW_OV;
2523*66e63ce3Schristos     }
2524*66e63ce3Schristos   else if (divide_by == -1 && divide_this == (1L << 31))
2525*66e63ce3Schristos     {
2526*66e63ce3Schristos       PSW &= ~PSW_Z;
2527*66e63ce3Schristos       PSW |= PSW_OV | PSW_S;
2528*66e63ce3Schristos       State.regs[ OP[1] ] = (1 << 31);
2529*66e63ce3Schristos       State.regs[ OP[2] >> 11 ] = 0;
2530*66e63ce3Schristos     }
2531*66e63ce3Schristos   else
2532*66e63ce3Schristos     {
2533*66e63ce3Schristos       divide_this = (signed32) divide_this;
2534*66e63ce3Schristos       State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
2535*66e63ce3Schristos       State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
2536*66e63ce3Schristos 
2537*66e63ce3Schristos       /* Set condition codes.  */
2538*66e63ce3Schristos       PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2539*66e63ce3Schristos 
2540*66e63ce3Schristos       if (quotient == 0) PSW |= PSW_Z;
2541*66e63ce3Schristos       if (quotient <  0) PSW |= PSW_S;
2542*66e63ce3Schristos     }
2543*66e63ce3Schristos 
2544*66e63ce3Schristos   trace_output (OP_REG_REG_REG);
2545*66e63ce3Schristos 
2546*66e63ce3Schristos   return 4;
2547*66e63ce3Schristos }
2548*66e63ce3Schristos 
2549*66e63ce3Schristos /* mulu imm9, reg2, reg3 */
2550*66e63ce3Schristos int
2551*66e63ce3Schristos OP_24207E0 (void)
2552*66e63ce3Schristos {
2553*66e63ce3Schristos   trace_input ("mulu", OP_IMM_REG_REG, 0);
2554*66e63ce3Schristos 
2555*66e63ce3Schristos   Multiply64 (0, (OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0));
2556*66e63ce3Schristos 
2557*66e63ce3Schristos   trace_output (OP_IMM_REG_REG);
2558*66e63ce3Schristos 
2559*66e63ce3Schristos   return 4;
2560*66e63ce3Schristos }
2561*66e63ce3Schristos 
2562*66e63ce3Schristos /* mul imm9, reg2, reg3 */
2563*66e63ce3Schristos int
2564*66e63ce3Schristos OP_24007E0 (void)
2565*66e63ce3Schristos {
2566*66e63ce3Schristos   trace_input ("mul", OP_IMM_REG_REG, 0);
2567*66e63ce3Schristos 
2568*66e63ce3Schristos   Multiply64 (1, SEXT9 ((OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0)));
2569*66e63ce3Schristos 
2570*66e63ce3Schristos   trace_output (OP_IMM_REG_REG);
2571*66e63ce3Schristos 
2572*66e63ce3Schristos   return 4;
2573*66e63ce3Schristos }
2574*66e63ce3Schristos 
2575*66e63ce3Schristos /* ld.hu */
2576*66e63ce3Schristos int
2577*66e63ce3Schristos OP_107E0 (void)
2578*66e63ce3Schristos {
2579*66e63ce3Schristos   int adr;
2580*66e63ce3Schristos 
2581*66e63ce3Schristos   trace_input ("ld.hu", OP_LOAD32, 2);
2582*66e63ce3Schristos 
2583*66e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1);
2584*66e63ce3Schristos   adr &= ~0x1;
2585*66e63ce3Schristos 
2586*66e63ce3Schristos   State.regs[ OP[1] ] = load_mem (adr, 2);
2587*66e63ce3Schristos 
2588*66e63ce3Schristos   trace_output (OP_LOAD32);
2589*66e63ce3Schristos 
2590*66e63ce3Schristos   return 4;
2591*66e63ce3Schristos }
2592*66e63ce3Schristos 
2593*66e63ce3Schristos 
2594*66e63ce3Schristos /* ld.bu */
2595*66e63ce3Schristos int
2596*66e63ce3Schristos OP_10780 (void)
2597*66e63ce3Schristos {
2598*66e63ce3Schristos   int adr;
2599*66e63ce3Schristos 
2600*66e63ce3Schristos   trace_input ("ld.bu", OP_LOAD32, 1);
2601*66e63ce3Schristos 
2602*66e63ce3Schristos   adr = (State.regs[ OP[0] ]
2603*66e63ce3Schristos 	 + (EXTEND16 (OP[2] & ~1) | ((OP[3] >> 5) & 1)));
2604*66e63ce3Schristos 
2605*66e63ce3Schristos   State.regs[ OP[1] ] = load_mem (adr, 1);
2606*66e63ce3Schristos 
2607*66e63ce3Schristos   trace_output (OP_LOAD32);
2608*66e63ce3Schristos 
2609*66e63ce3Schristos   return 4;
2610*66e63ce3Schristos }
2611*66e63ce3Schristos 
2612*66e63ce3Schristos /* prepare list12, imm5, imm32 */
2613*66e63ce3Schristos int
2614*66e63ce3Schristos OP_1B0780 (void)
2615*66e63ce3Schristos {
2616*66e63ce3Schristos   int  i;
2617*66e63ce3Schristos 
2618*66e63ce3Schristos   trace_input ("prepare", OP_PUSHPOP1, 0);
2619*66e63ce3Schristos 
2620*66e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
2621*66e63ce3Schristos   for (i = 0; i < 12; i++)
2622*66e63ce3Schristos     if ((OP[3] & (1 << type1_regs[ i ])))
2623*66e63ce3Schristos       {
2624*66e63ce3Schristos 	SP -= 4;
2625*66e63ce3Schristos 	store_mem (SP, 4, State.regs[ 20 + i ]);
2626*66e63ce3Schristos       }
2627*66e63ce3Schristos 
2628*66e63ce3Schristos   SP -= (OP[3] & 0x3e) << 1;
2629*66e63ce3Schristos 
2630*66e63ce3Schristos   EP = load_mem (PC + 4, 4);
2631*66e63ce3Schristos 
2632*66e63ce3Schristos   trace_output (OP_PUSHPOP1);
2633*66e63ce3Schristos 
2634*66e63ce3Schristos   return 8;
2635*66e63ce3Schristos }
2636*66e63ce3Schristos 
2637*66e63ce3Schristos /* prepare list12, imm5, imm16-32 */
2638*66e63ce3Schristos int
2639*66e63ce3Schristos OP_130780 (void)
2640*66e63ce3Schristos {
2641*66e63ce3Schristos   int  i;
2642*66e63ce3Schristos 
2643*66e63ce3Schristos   trace_input ("prepare", OP_PUSHPOP1, 0);
2644*66e63ce3Schristos 
2645*66e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
2646*66e63ce3Schristos   for (i = 0; i < 12; i++)
2647*66e63ce3Schristos     if ((OP[3] & (1 << type1_regs[ i ])))
2648*66e63ce3Schristos       {
2649*66e63ce3Schristos 	SP -= 4;
2650*66e63ce3Schristos 	store_mem (SP, 4, State.regs[ 20 + i ]);
2651*66e63ce3Schristos       }
2652*66e63ce3Schristos 
2653*66e63ce3Schristos   SP -= (OP[3] & 0x3e) << 1;
2654*66e63ce3Schristos 
2655*66e63ce3Schristos   EP = load_mem (PC + 4, 2) << 16;
2656*66e63ce3Schristos 
2657*66e63ce3Schristos   trace_output (OP_PUSHPOP1);
2658*66e63ce3Schristos 
2659*66e63ce3Schristos   return 6;
2660*66e63ce3Schristos }
2661*66e63ce3Schristos 
2662*66e63ce3Schristos /* prepare list12, imm5, imm16 */
2663*66e63ce3Schristos int
2664*66e63ce3Schristos OP_B0780 (void)
2665*66e63ce3Schristos {
2666*66e63ce3Schristos   int  i;
2667*66e63ce3Schristos 
2668*66e63ce3Schristos   trace_input ("prepare", OP_PUSHPOP1, 0);
2669*66e63ce3Schristos 
2670*66e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
2671*66e63ce3Schristos   for (i = 0; i < 12; i++)
2672*66e63ce3Schristos     if ((OP[3] & (1 << type1_regs[ i ])))
2673*66e63ce3Schristos       {
2674*66e63ce3Schristos 	SP -= 4;
2675*66e63ce3Schristos 	store_mem (SP, 4, State.regs[ 20 + i ]);
2676*66e63ce3Schristos       }
2677*66e63ce3Schristos 
2678*66e63ce3Schristos   SP -= (OP[3] & 0x3e) << 1;
2679*66e63ce3Schristos 
2680*66e63ce3Schristos   EP = EXTEND16 (load_mem (PC + 4, 2));
2681*66e63ce3Schristos 
2682*66e63ce3Schristos   trace_output (OP_PUSHPOP1);
2683*66e63ce3Schristos 
2684*66e63ce3Schristos   return 6;
2685*66e63ce3Schristos }
2686*66e63ce3Schristos 
2687*66e63ce3Schristos /* prepare list12, imm5, sp */
2688*66e63ce3Schristos int
2689*66e63ce3Schristos OP_30780 (void)
2690*66e63ce3Schristos {
2691*66e63ce3Schristos   int  i;
2692*66e63ce3Schristos 
2693*66e63ce3Schristos   trace_input ("prepare", OP_PUSHPOP1, 0);
2694*66e63ce3Schristos 
2695*66e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
2696*66e63ce3Schristos   for (i = 0; i < 12; i++)
2697*66e63ce3Schristos     if ((OP[3] & (1 << type1_regs[ i ])))
2698*66e63ce3Schristos       {
2699*66e63ce3Schristos 	SP -= 4;
2700*66e63ce3Schristos 	store_mem (SP, 4, State.regs[ 20 + i ]);
2701*66e63ce3Schristos       }
2702*66e63ce3Schristos 
2703*66e63ce3Schristos   SP -= (OP[3] & 0x3e) << 1;
2704*66e63ce3Schristos 
2705*66e63ce3Schristos   EP = SP;
2706*66e63ce3Schristos 
2707*66e63ce3Schristos   trace_output (OP_PUSHPOP1);
2708*66e63ce3Schristos 
2709*66e63ce3Schristos   return 4;
2710*66e63ce3Schristos }
2711*66e63ce3Schristos 
2712*66e63ce3Schristos /* mul reg1, reg2, reg3 */
2713*66e63ce3Schristos int
2714*66e63ce3Schristos OP_22007E0 (void)
2715*66e63ce3Schristos {
2716*66e63ce3Schristos   trace_input ("mul", OP_REG_REG_REG, 0);
2717*66e63ce3Schristos 
2718*66e63ce3Schristos   Multiply64 (1, State.regs[ OP[0] ]);
2719*66e63ce3Schristos 
2720*66e63ce3Schristos   trace_output (OP_REG_REG_REG);
2721*66e63ce3Schristos 
2722*66e63ce3Schristos   return 4;
2723*66e63ce3Schristos }
2724*66e63ce3Schristos 
2725*66e63ce3Schristos /* popmh list18 */
2726*66e63ce3Schristos int
2727*66e63ce3Schristos OP_307F0 (void)
2728*66e63ce3Schristos {
2729*66e63ce3Schristos   int i;
2730*66e63ce3Schristos 
2731*66e63ce3Schristos   trace_input ("popmh", OP_PUSHPOP2, 0);
2732*66e63ce3Schristos 
2733*66e63ce3Schristos   if (OP[3] & (1 << 19))
2734*66e63ce3Schristos     {
2735*66e63ce3Schristos       if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
2736*66e63ce3Schristos 	{
2737*66e63ce3Schristos 	  FEPSW = load_mem ( SP      & ~ 3, 4);
2738*66e63ce3Schristos 	  FEPC  = load_mem ((SP + 4) & ~ 3, 4);
2739*66e63ce3Schristos 	}
2740*66e63ce3Schristos       else
2741*66e63ce3Schristos 	{
2742*66e63ce3Schristos 	  EIPSW = load_mem ( SP      & ~ 3, 4);
2743*66e63ce3Schristos 	  EIPC  = load_mem ((SP + 4) & ~ 3, 4);
2744*66e63ce3Schristos 	}
2745*66e63ce3Schristos 
2746*66e63ce3Schristos       SP += 8;
2747*66e63ce3Schristos     }
2748*66e63ce3Schristos 
2749*66e63ce3Schristos   /* Load the registers with lower number registers being retrieved from higher addresses.  */
2750*66e63ce3Schristos   for (i = 16; i--;)
2751*66e63ce3Schristos     if ((OP[3] & (1 << type2_regs[ i ])))
2752*66e63ce3Schristos       {
2753*66e63ce3Schristos 	State.regs[ i + 16 ] = load_mem (SP & ~ 3, 4);
2754*66e63ce3Schristos 	SP += 4;
2755*66e63ce3Schristos       }
2756*66e63ce3Schristos 
2757*66e63ce3Schristos   trace_output (OP_PUSHPOP2);
2758*66e63ce3Schristos 
2759*66e63ce3Schristos   return 4;
2760*66e63ce3Schristos }
2761*66e63ce3Schristos 
2762*66e63ce3Schristos /* popml lsit18 */
2763*66e63ce3Schristos int
2764*66e63ce3Schristos OP_107F0 (void)
2765*66e63ce3Schristos {
2766*66e63ce3Schristos   int i;
2767*66e63ce3Schristos 
2768*66e63ce3Schristos   trace_input ("popml", OP_PUSHPOP3, 0);
2769*66e63ce3Schristos 
2770*66e63ce3Schristos   if (OP[3] & (1 << 19))
2771*66e63ce3Schristos     {
2772*66e63ce3Schristos       if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
2773*66e63ce3Schristos 	{
2774*66e63ce3Schristos 	  FEPSW = load_mem ( SP      & ~ 3, 4);
2775*66e63ce3Schristos 	  FEPC =  load_mem ((SP + 4) & ~ 3, 4);
2776*66e63ce3Schristos 	}
2777*66e63ce3Schristos       else
2778*66e63ce3Schristos 	{
2779*66e63ce3Schristos 	  EIPSW = load_mem ( SP      & ~ 3, 4);
2780*66e63ce3Schristos 	  EIPC  = load_mem ((SP + 4) & ~ 3, 4);
2781*66e63ce3Schristos 	}
2782*66e63ce3Schristos 
2783*66e63ce3Schristos       SP += 8;
2784*66e63ce3Schristos     }
2785*66e63ce3Schristos 
2786*66e63ce3Schristos   if (OP[3] & (1 << 3))
2787*66e63ce3Schristos     {
2788*66e63ce3Schristos       PSW = load_mem (SP & ~ 3, 4);
2789*66e63ce3Schristos       SP += 4;
2790*66e63ce3Schristos     }
2791*66e63ce3Schristos 
2792*66e63ce3Schristos   /* Load the registers with lower number registers being retrieved from higher addresses.  */
2793*66e63ce3Schristos   for (i = 15; i--;)
2794*66e63ce3Schristos     if ((OP[3] & (1 << type3_regs[ i ])))
2795*66e63ce3Schristos       {
2796*66e63ce3Schristos 	State.regs[ i + 1 ] = load_mem (SP & ~ 3, 4);
2797*66e63ce3Schristos 	SP += 4;
2798*66e63ce3Schristos       }
2799*66e63ce3Schristos 
2800*66e63ce3Schristos   trace_output (OP_PUSHPOP2);
2801*66e63ce3Schristos 
2802*66e63ce3Schristos   return 4;
2803*66e63ce3Schristos }
2804*66e63ce3Schristos 
2805*66e63ce3Schristos /* pushmh list18 */
2806*66e63ce3Schristos int
2807*66e63ce3Schristos OP_307E0 (void)
2808*66e63ce3Schristos {
2809*66e63ce3Schristos   int i;
2810*66e63ce3Schristos 
2811*66e63ce3Schristos   trace_input ("pushmh", OP_PUSHPOP2, 0);
2812*66e63ce3Schristos 
2813*66e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
2814*66e63ce3Schristos   for (i = 0; i < 16; i++)
2815*66e63ce3Schristos     if ((OP[3] & (1 << type2_regs[ i ])))
2816*66e63ce3Schristos       {
2817*66e63ce3Schristos 	SP -= 4;
2818*66e63ce3Schristos 	store_mem (SP & ~ 3, 4, State.regs[ i + 16 ]);
2819*66e63ce3Schristos       }
2820*66e63ce3Schristos 
2821*66e63ce3Schristos   if (OP[3] & (1 << 19))
2822*66e63ce3Schristos     {
2823*66e63ce3Schristos       SP -= 8;
2824*66e63ce3Schristos 
2825*66e63ce3Schristos       if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
2826*66e63ce3Schristos 	{
2827*66e63ce3Schristos 	  store_mem ((SP + 4) & ~ 3, 4, FEPC);
2828*66e63ce3Schristos 	  store_mem ( SP      & ~ 3, 4, FEPSW);
2829*66e63ce3Schristos 	}
2830*66e63ce3Schristos       else
2831*66e63ce3Schristos 	{
2832*66e63ce3Schristos 	  store_mem ((SP + 4) & ~ 3, 4, EIPC);
2833*66e63ce3Schristos 	  store_mem ( SP      & ~ 3, 4, EIPSW);
2834*66e63ce3Schristos 	}
2835*66e63ce3Schristos     }
2836*66e63ce3Schristos 
2837*66e63ce3Schristos   trace_output (OP_PUSHPOP2);
2838*66e63ce3Schristos 
2839*66e63ce3Schristos   return 4;
2840*66e63ce3Schristos }
2841*66e63ce3Schristos 
2842