xref: /netbsd/external/gpl3/gdb/dist/sim/v850/simops.c (revision c03b94e9)
166e63ce3Schristos #include "sim-main.h"
266e63ce3Schristos #include "v850_sim.h"
366e63ce3Schristos #include "simops.h"
466e63ce3Schristos 
566e63ce3Schristos #include <sys/types.h>
666e63ce3Schristos 
766e63ce3Schristos #ifdef HAVE_UTIME_H
866e63ce3Schristos #include <utime.h>
966e63ce3Schristos #endif
1066e63ce3Schristos 
1166e63ce3Schristos #ifdef HAVE_TIME_H
1266e63ce3Schristos #include <time.h>
1366e63ce3Schristos #endif
1466e63ce3Schristos 
1566e63ce3Schristos #ifdef HAVE_UNISTD_H
1666e63ce3Schristos #include <unistd.h>
1766e63ce3Schristos #endif
1866e63ce3Schristos 
1966e63ce3Schristos #ifdef HAVE_STRING_H
2066e63ce3Schristos #include <string.h>
2166e63ce3Schristos #else
2266e63ce3Schristos #ifdef HAVE_STRINGS_H
2366e63ce3Schristos #include <strings.h>
2466e63ce3Schristos #endif
2566e63ce3Schristos #endif
2666e63ce3Schristos 
2766e63ce3Schristos #include "targ-vals.h"
2866e63ce3Schristos 
2966e63ce3Schristos #include "libiberty.h"
3066e63ce3Schristos 
3166e63ce3Schristos #include <errno.h>
3266e63ce3Schristos #if !defined(__GO32__) && !defined(_WIN32)
3366e63ce3Schristos #include <sys/stat.h>
3466e63ce3Schristos #include <sys/times.h>
3566e63ce3Schristos #include <sys/time.h>
3666e63ce3Schristos #endif
3766e63ce3Schristos 
3866e63ce3Schristos /* This is an array of the bit positions of registers r20 .. r31 in
3966e63ce3Schristos    that order in a prepare/dispose instruction.  */
4066e63ce3Schristos int type1_regs[12] = { 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 0, 21 };
4166e63ce3Schristos /* This is an array of the bit positions of registers r16 .. r31 in
4266e63ce3Schristos    that order in a push/pop instruction.  */
4366e63ce3Schristos int type2_regs[16] = { 3, 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
4466e63ce3Schristos /* This is an array of the bit positions of registers r1 .. r15 in
4566e63ce3Schristos    that order in a push/pop instruction.  */
4666e63ce3Schristos int type3_regs[15] = { 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
4766e63ce3Schristos 
4866e63ce3Schristos #ifdef DEBUG
4966e63ce3Schristos #ifndef SIZE_INSTRUCTION
5066e63ce3Schristos #define SIZE_INSTRUCTION 18
5166e63ce3Schristos #endif
5266e63ce3Schristos 
5366e63ce3Schristos #ifndef SIZE_VALUES
5466e63ce3Schristos #define SIZE_VALUES 11
5566e63ce3Schristos #endif
5666e63ce3Schristos 
5766e63ce3Schristos 
5866e63ce3Schristos unsigned32   trace_values[3];
5966e63ce3Schristos int          trace_num_values;
6066e63ce3Schristos unsigned32   trace_pc;
6166e63ce3Schristos const char * trace_name;
6266e63ce3Schristos int          trace_module;
6366e63ce3Schristos 
6466e63ce3Schristos 
6566e63ce3Schristos void
trace_input(char * name,enum op_types type,int size)66ed6a76a9Schristos trace_input (char *name, enum op_types type, int size)
6766e63ce3Schristos {
6866e63ce3Schristos   if (!TRACE_ALU_P (STATE_CPU (simulator, 0)))
6966e63ce3Schristos     return;
7066e63ce3Schristos 
7166e63ce3Schristos   trace_pc = PC;
7266e63ce3Schristos   trace_name = name;
7366e63ce3Schristos   trace_module = TRACE_ALU_IDX;
7466e63ce3Schristos 
7566e63ce3Schristos   switch (type)
7666e63ce3Schristos     {
7766e63ce3Schristos     default:
7866e63ce3Schristos     case OP_UNKNOWN:
7966e63ce3Schristos     case OP_NONE:
8066e63ce3Schristos     case OP_TRAP:
8166e63ce3Schristos       trace_num_values = 0;
8266e63ce3Schristos       break;
8366e63ce3Schristos 
8466e63ce3Schristos     case OP_REG:
8566e63ce3Schristos     case OP_REG_REG_MOVE:
8666e63ce3Schristos       trace_values[0] = State.regs[OP[0]];
8766e63ce3Schristos       trace_num_values = 1;
8866e63ce3Schristos       break;
8966e63ce3Schristos 
9066e63ce3Schristos     case OP_BIT_CHANGE:
9166e63ce3Schristos     case OP_REG_REG:
9266e63ce3Schristos     case OP_REG_REG_CMP:
9366e63ce3Schristos       trace_values[0] = State.regs[OP[1]];
9466e63ce3Schristos       trace_values[1] = State.regs[OP[0]];
9566e63ce3Schristos       trace_num_values = 2;
9666e63ce3Schristos       break;
9766e63ce3Schristos 
9866e63ce3Schristos     case OP_IMM_REG:
9966e63ce3Schristos     case OP_IMM_REG_CMP:
10066e63ce3Schristos       trace_values[0] = SEXT5 (OP[0]);
10166e63ce3Schristos       trace_values[1] = OP[1];
10266e63ce3Schristos       trace_num_values = 2;
10366e63ce3Schristos       break;
10466e63ce3Schristos 
10566e63ce3Schristos     case OP_IMM_REG_MOVE:
10666e63ce3Schristos       trace_values[0] = SEXT5 (OP[0]);
10766e63ce3Schristos       trace_num_values = 1;
10866e63ce3Schristos       break;
10966e63ce3Schristos 
11066e63ce3Schristos     case OP_COND_BR:
11166e63ce3Schristos       trace_values[0] = State.pc;
11266e63ce3Schristos       trace_values[1] = SEXT9 (OP[0]);
11366e63ce3Schristos       trace_values[2] = PSW;
11466e63ce3Schristos       trace_num_values = 3;
11566e63ce3Schristos       break;
11666e63ce3Schristos 
11766e63ce3Schristos     case OP_LOAD16:
11866e63ce3Schristos       trace_values[0] = OP[1] * size;
11966e63ce3Schristos       trace_values[1] = State.regs[30];
12066e63ce3Schristos       trace_num_values = 2;
12166e63ce3Schristos       break;
12266e63ce3Schristos 
12366e63ce3Schristos     case OP_STORE16:
12466e63ce3Schristos       trace_values[0] = State.regs[OP[0]];
12566e63ce3Schristos       trace_values[1] = OP[1] * size;
12666e63ce3Schristos       trace_values[2] = State.regs[30];
12766e63ce3Schristos       trace_num_values = 3;
12866e63ce3Schristos       break;
12966e63ce3Schristos 
13066e63ce3Schristos     case OP_LOAD32:
13166e63ce3Schristos       trace_values[0] = EXTEND16 (OP[2]);
13266e63ce3Schristos       trace_values[1] = State.regs[OP[0]];
13366e63ce3Schristos       trace_num_values = 2;
13466e63ce3Schristos       break;
13566e63ce3Schristos 
13666e63ce3Schristos     case OP_STORE32:
13766e63ce3Schristos       trace_values[0] = State.regs[OP[1]];
13866e63ce3Schristos       trace_values[1] = EXTEND16 (OP[2]);
13966e63ce3Schristos       trace_values[2] = State.regs[OP[0]];
14066e63ce3Schristos       trace_num_values = 3;
14166e63ce3Schristos       break;
14266e63ce3Schristos 
14366e63ce3Schristos     case OP_JUMP:
14466e63ce3Schristos       trace_values[0] = SEXT22 (OP[0]);
14566e63ce3Schristos       trace_values[1] = State.pc;
14666e63ce3Schristos       trace_num_values = 2;
14766e63ce3Schristos       break;
14866e63ce3Schristos 
14966e63ce3Schristos     case OP_IMM_REG_REG:
15066e63ce3Schristos       trace_values[0] = EXTEND16 (OP[0]) << size;
15166e63ce3Schristos       trace_values[1] = State.regs[OP[1]];
15266e63ce3Schristos       trace_num_values = 2;
15366e63ce3Schristos       break;
15466e63ce3Schristos 
15566e63ce3Schristos     case OP_IMM16_REG_REG:
15666e63ce3Schristos       trace_values[0] = EXTEND16 (OP[2]) << size;
15766e63ce3Schristos       trace_values[1] = State.regs[OP[1]];
15866e63ce3Schristos       trace_num_values = 2;
15966e63ce3Schristos       break;
16066e63ce3Schristos 
16166e63ce3Schristos     case OP_UIMM_REG_REG:
16266e63ce3Schristos       trace_values[0] = (OP[0] & 0xffff) << size;
16366e63ce3Schristos       trace_values[1] = State.regs[OP[1]];
16466e63ce3Schristos       trace_num_values = 2;
16566e63ce3Schristos       break;
16666e63ce3Schristos 
16766e63ce3Schristos     case OP_UIMM16_REG_REG:
16866e63ce3Schristos       trace_values[0] = (OP[2]) << size;
16966e63ce3Schristos       trace_values[1] = State.regs[OP[1]];
17066e63ce3Schristos       trace_num_values = 2;
17166e63ce3Schristos       break;
17266e63ce3Schristos 
17366e63ce3Schristos     case OP_BIT:
17466e63ce3Schristos       trace_num_values = 0;
17566e63ce3Schristos       break;
17666e63ce3Schristos 
17766e63ce3Schristos     case OP_EX1:
17866e63ce3Schristos       trace_values[0] = PSW;
17966e63ce3Schristos       trace_num_values = 1;
18066e63ce3Schristos       break;
18166e63ce3Schristos 
18266e63ce3Schristos     case OP_EX2:
18366e63ce3Schristos       trace_num_values = 0;
18466e63ce3Schristos       break;
18566e63ce3Schristos 
18666e63ce3Schristos     case OP_LDSR:
18766e63ce3Schristos       trace_values[0] = State.regs[OP[0]];
18866e63ce3Schristos       trace_num_values = 1;
18966e63ce3Schristos       break;
19066e63ce3Schristos 
19166e63ce3Schristos     case OP_STSR:
19266e63ce3Schristos       trace_values[0] = State.sregs[OP[1]];
19366e63ce3Schristos       trace_num_values = 1;
19466e63ce3Schristos     }
19566e63ce3Schristos 
19666e63ce3Schristos }
19766e63ce3Schristos 
19866e63ce3Schristos void
trace_result(int has_result,unsigned32 result)19966e63ce3Schristos trace_result (int has_result, unsigned32 result)
20066e63ce3Schristos {
20166e63ce3Schristos   char buf[1000];
20266e63ce3Schristos   char *chp;
20366e63ce3Schristos 
20466e63ce3Schristos   buf[0] = '\0';
20566e63ce3Schristos   chp = buf;
20666e63ce3Schristos 
20766e63ce3Schristos   /* write out the values saved during the trace_input call */
20866e63ce3Schristos   {
20966e63ce3Schristos     int i;
21066e63ce3Schristos     for (i = 0; i < trace_num_values; i++)
21166e63ce3Schristos       {
21266e63ce3Schristos 	sprintf (chp, "%*s0x%.8lx", SIZE_VALUES - 10, "",
21366e63ce3Schristos 		 (long) trace_values[i]);
21466e63ce3Schristos 	chp = strchr (chp, '\0');
21566e63ce3Schristos       }
21666e63ce3Schristos     while (i++ < 3)
21766e63ce3Schristos       {
21866e63ce3Schristos 	sprintf (chp, "%*s", SIZE_VALUES, "");
21966e63ce3Schristos 	chp = strchr (chp, '\0');
22066e63ce3Schristos       }
22166e63ce3Schristos   }
22266e63ce3Schristos 
22366e63ce3Schristos   /* append any result to the end of the buffer */
22466e63ce3Schristos   if (has_result)
22566e63ce3Schristos     sprintf (chp, " :: 0x%.8lx", (unsigned long) result);
22666e63ce3Schristos 
227ed6a76a9Schristos   trace_generic (simulator, STATE_CPU (simulator, 0), trace_module, "%s", buf);
22866e63ce3Schristos }
22966e63ce3Schristos 
23066e63ce3Schristos void
trace_output(enum op_types result)231ed6a76a9Schristos trace_output (enum op_types result)
23266e63ce3Schristos {
23366e63ce3Schristos   if (!TRACE_ALU_P (STATE_CPU (simulator, 0)))
23466e63ce3Schristos     return;
23566e63ce3Schristos 
23666e63ce3Schristos   switch (result)
23766e63ce3Schristos     {
23866e63ce3Schristos     default:
23966e63ce3Schristos     case OP_UNKNOWN:
24066e63ce3Schristos     case OP_NONE:
24166e63ce3Schristos     case OP_TRAP:
24266e63ce3Schristos     case OP_REG:
24366e63ce3Schristos     case OP_REG_REG_CMP:
24466e63ce3Schristos     case OP_IMM_REG_CMP:
24566e63ce3Schristos     case OP_COND_BR:
24666e63ce3Schristos     case OP_STORE16:
24766e63ce3Schristos     case OP_STORE32:
24866e63ce3Schristos     case OP_BIT:
24966e63ce3Schristos     case OP_EX2:
25066e63ce3Schristos       trace_result (0, 0);
25166e63ce3Schristos       break;
25266e63ce3Schristos 
25366e63ce3Schristos     case OP_LOAD16:
25466e63ce3Schristos     case OP_STSR:
25566e63ce3Schristos       trace_result (1, State.regs[OP[0]]);
25666e63ce3Schristos       break;
25766e63ce3Schristos 
25866e63ce3Schristos     case OP_REG_REG:
25966e63ce3Schristos     case OP_REG_REG_MOVE:
26066e63ce3Schristos     case OP_IMM_REG:
26166e63ce3Schristos     case OP_IMM_REG_MOVE:
26266e63ce3Schristos     case OP_LOAD32:
26366e63ce3Schristos     case OP_EX1:
26466e63ce3Schristos       trace_result (1, State.regs[OP[1]]);
26566e63ce3Schristos       break;
26666e63ce3Schristos 
26766e63ce3Schristos     case OP_IMM_REG_REG:
26866e63ce3Schristos     case OP_UIMM_REG_REG:
26966e63ce3Schristos     case OP_IMM16_REG_REG:
27066e63ce3Schristos     case OP_UIMM16_REG_REG:
27166e63ce3Schristos       trace_result (1, State.regs[OP[1]]);
27266e63ce3Schristos       break;
27366e63ce3Schristos 
27466e63ce3Schristos     case OP_JUMP:
27566e63ce3Schristos       if (OP[1] != 0)
27666e63ce3Schristos 	trace_result (1, State.regs[OP[1]]);
27766e63ce3Schristos       else
27866e63ce3Schristos 	trace_result (0, 0);
27966e63ce3Schristos       break;
28066e63ce3Schristos 
28166e63ce3Schristos     case OP_LDSR:
28266e63ce3Schristos       trace_result (1, State.sregs[OP[1]]);
28366e63ce3Schristos       break;
28466e63ce3Schristos     }
28566e63ce3Schristos }
28666e63ce3Schristos #endif
28766e63ce3Schristos 
28866e63ce3Schristos 
28966e63ce3Schristos /* Returns 1 if the specific condition is met, returns 0 otherwise.  */
29066e63ce3Schristos int
condition_met(unsigned code)29166e63ce3Schristos condition_met (unsigned code)
29266e63ce3Schristos {
29366e63ce3Schristos   unsigned int psw = PSW;
29466e63ce3Schristos 
29566e63ce3Schristos   switch (code & 0xf)
29666e63ce3Schristos     {
29766e63ce3Schristos       case 0x0: return ((psw & PSW_OV) != 0);
29866e63ce3Schristos       case 0x1:	return ((psw & PSW_CY) != 0);
29966e63ce3Schristos       case 0x2:	return ((psw & PSW_Z) != 0);
30066e63ce3Schristos       case 0x3:	return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0);
30166e63ce3Schristos       case 0x4:	return ((psw & PSW_S) != 0);
30266e63ce3Schristos     /*case 0x5:	return 1;*/
30366e63ce3Schristos       case 0x6: return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0);
30466e63ce3Schristos       case 0x7:	return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) != 0);
30566e63ce3Schristos       case 0x8:	return ((psw & PSW_OV) == 0);
30666e63ce3Schristos       case 0x9:	return ((psw & PSW_CY) == 0);
30766e63ce3Schristos       case 0xa:	return ((psw & PSW_Z) == 0);
30866e63ce3Schristos       case 0xb:	return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0);
30966e63ce3Schristos       case 0xc:	return ((psw & PSW_S) == 0);
31066e63ce3Schristos       case 0xd:	return ((psw & PSW_SAT) != 0);
31166e63ce3Schristos       case 0xe:	return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0);
31266e63ce3Schristos       case 0xf:	return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) == 0);
31366e63ce3Schristos     }
31466e63ce3Schristos 
31566e63ce3Schristos   return 1;
31666e63ce3Schristos }
31766e63ce3Schristos 
31848596154Schristos unsigned long
Add32(unsigned long a1,unsigned long a2,int * carry)31966e63ce3Schristos Add32 (unsigned long a1, unsigned long a2, int * carry)
32066e63ce3Schristos {
32166e63ce3Schristos   unsigned long result = (a1 + a2);
32266e63ce3Schristos 
32366e63ce3Schristos   * carry = (result < a1);
32466e63ce3Schristos 
32566e63ce3Schristos   return result;
32666e63ce3Schristos }
32766e63ce3Schristos 
32866e63ce3Schristos static void
Multiply64(int sign,unsigned long op0)32966e63ce3Schristos Multiply64 (int sign, unsigned long op0)
33066e63ce3Schristos {
33166e63ce3Schristos   unsigned long op1;
33266e63ce3Schristos   unsigned long lo;
33366e63ce3Schristos   unsigned long mid1;
33466e63ce3Schristos   unsigned long mid2;
33566e63ce3Schristos   unsigned long hi;
33666e63ce3Schristos   unsigned long RdLo;
33766e63ce3Schristos   unsigned long RdHi;
33866e63ce3Schristos   int           carry;
33966e63ce3Schristos 
34066e63ce3Schristos   op1 = State.regs[ OP[1] ];
34166e63ce3Schristos 
34266e63ce3Schristos   if (sign)
34366e63ce3Schristos     {
34466e63ce3Schristos       /* Compute sign of result and adjust operands if necessary.  */
34566e63ce3Schristos 
34666e63ce3Schristos       sign = (op0 ^ op1) & 0x80000000;
34766e63ce3Schristos 
34866e63ce3Schristos       if (((signed long) op0) < 0)
34966e63ce3Schristos 	op0 = - op0;
35066e63ce3Schristos 
35166e63ce3Schristos       if (((signed long) op1) < 0)
35266e63ce3Schristos 	op1 = - op1;
35366e63ce3Schristos     }
35466e63ce3Schristos 
35566e63ce3Schristos   /* We can split the 32x32 into four 16x16 operations. This ensures
35666e63ce3Schristos      that we do not lose precision on 32bit only hosts: */
35766e63ce3Schristos   lo   = ( (op0        & 0xFFFF) *  (op1        & 0xFFFF));
35866e63ce3Schristos   mid1 = ( (op0        & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
35966e63ce3Schristos   mid2 = (((op0 >> 16) & 0xFFFF) *  (op1        & 0xFFFF));
36066e63ce3Schristos   hi   = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
36166e63ce3Schristos 
36266e63ce3Schristos   /* We now need to add all of these results together, taking care
36366e63ce3Schristos      to propogate the carries from the additions: */
36466e63ce3Schristos   RdLo = Add32 (lo, (mid1 << 16), & carry);
36566e63ce3Schristos   RdHi = carry;
36666e63ce3Schristos   RdLo = Add32 (RdLo, (mid2 << 16), & carry);
36766e63ce3Schristos   RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
36866e63ce3Schristos 
36966e63ce3Schristos   if (sign)
37066e63ce3Schristos     {
37166e63ce3Schristos       /* Negate result if necessary.  */
37266e63ce3Schristos 
37366e63ce3Schristos       RdLo = ~ RdLo;
37466e63ce3Schristos       RdHi = ~ RdHi;
37566e63ce3Schristos       if (RdLo == 0xFFFFFFFF)
37666e63ce3Schristos 	{
37766e63ce3Schristos 	  RdLo = 0;
37866e63ce3Schristos 	  RdHi += 1;
37966e63ce3Schristos 	}
38066e63ce3Schristos       else
38166e63ce3Schristos 	RdLo += 1;
38266e63ce3Schristos     }
38366e63ce3Schristos 
38466e63ce3Schristos   /* Don't store into register 0.  */
38566e63ce3Schristos   if (OP[1])
38666e63ce3Schristos     State.regs[ OP[1]       ] = RdLo;
38766e63ce3Schristos   if (OP[2] >> 11)
38866e63ce3Schristos     State.regs[ OP[2] >> 11 ] = RdHi;
38966e63ce3Schristos 
39066e63ce3Schristos   return;
39166e63ce3Schristos }
39266e63ce3Schristos 
39366e63ce3Schristos 
394ed6a76a9Schristos /* Read a null terminated string from memory, return in a buffer.  */
395ed6a76a9Schristos 
39666e63ce3Schristos static char *
fetch_str(SIM_DESC sd,address_word addr)397ed6a76a9Schristos fetch_str (SIM_DESC sd, address_word addr)
39866e63ce3Schristos {
39966e63ce3Schristos   char *buf;
40066e63ce3Schristos   int nr = 0;
401ed6a76a9Schristos 
40266e63ce3Schristos   while (sim_core_read_1 (STATE_CPU (sd, 0),
40366e63ce3Schristos 			  PC, read_map, addr + nr) != 0)
40466e63ce3Schristos     nr++;
405ed6a76a9Schristos 
40666e63ce3Schristos   buf = NZALLOC (char, nr + 1);
407ed6a76a9Schristos   sim_read (simulator, addr, (unsigned char *) buf, nr);
408ed6a76a9Schristos 
40966e63ce3Schristos   return buf;
41066e63ce3Schristos }
41166e63ce3Schristos 
41266e63ce3Schristos /* Read a null terminated argument vector from memory, return in a
413ed6a76a9Schristos    buffer.  */
414ed6a76a9Schristos 
41566e63ce3Schristos static char **
fetch_argv(SIM_DESC sd,address_word addr)416ed6a76a9Schristos fetch_argv (SIM_DESC sd, address_word addr)
41766e63ce3Schristos {
41866e63ce3Schristos   int max_nr = 64;
41966e63ce3Schristos   int nr = 0;
42066e63ce3Schristos   char **buf = xmalloc (max_nr * sizeof (char*));
421ed6a76a9Schristos 
42266e63ce3Schristos   while (1)
42366e63ce3Schristos     {
42466e63ce3Schristos       unsigned32 a = sim_core_read_4 (STATE_CPU (sd, 0),
42566e63ce3Schristos 				      PC, read_map, addr + nr * 4);
42666e63ce3Schristos       if (a == 0) break;
42766e63ce3Schristos       buf[nr] = fetch_str (sd, a);
42866e63ce3Schristos       nr ++;
42966e63ce3Schristos       if (nr == max_nr - 1)
43066e63ce3Schristos 	{
43166e63ce3Schristos 	  max_nr += 50;
43266e63ce3Schristos 	  buf = xrealloc (buf, max_nr * sizeof (char*));
43366e63ce3Schristos 	}
43466e63ce3Schristos     }
43566e63ce3Schristos   buf[nr] = 0;
43666e63ce3Schristos   return buf;
43766e63ce3Schristos }
43866e63ce3Schristos 
43966e63ce3Schristos 
44066e63ce3Schristos /* sst.b */
44166e63ce3Schristos int
OP_380(void)442ed6a76a9Schristos OP_380 (void)
44366e63ce3Schristos {
44466e63ce3Schristos   trace_input ("sst.b", OP_STORE16, 1);
44566e63ce3Schristos 
44666e63ce3Schristos   store_mem (State.regs[30] + (OP[3] & 0x7f), 1, State.regs[ OP[1] ]);
44766e63ce3Schristos 
44866e63ce3Schristos   trace_output (OP_STORE16);
44966e63ce3Schristos 
45066e63ce3Schristos   return 2;
45166e63ce3Schristos }
45266e63ce3Schristos 
45366e63ce3Schristos /* sst.h */
45466e63ce3Schristos int
OP_480(void)455ed6a76a9Schristos OP_480 (void)
45666e63ce3Schristos {
45766e63ce3Schristos   trace_input ("sst.h", OP_STORE16, 2);
45866e63ce3Schristos 
45966e63ce3Schristos   store_mem (State.regs[30] + ((OP[3] & 0x7f) << 1), 2, State.regs[ OP[1] ]);
46066e63ce3Schristos 
46166e63ce3Schristos   trace_output (OP_STORE16);
46266e63ce3Schristos 
46366e63ce3Schristos   return 2;
46466e63ce3Schristos }
46566e63ce3Schristos 
46666e63ce3Schristos /* sst.w */
46766e63ce3Schristos int
OP_501(void)468ed6a76a9Schristos OP_501 (void)
46966e63ce3Schristos {
47066e63ce3Schristos   trace_input ("sst.w", OP_STORE16, 4);
47166e63ce3Schristos 
47266e63ce3Schristos   store_mem (State.regs[30] + ((OP[3] & 0x7e) << 1), 4, State.regs[ OP[1] ]);
47366e63ce3Schristos 
47466e63ce3Schristos   trace_output (OP_STORE16);
47566e63ce3Schristos 
47666e63ce3Schristos   return 2;
47766e63ce3Schristos }
47866e63ce3Schristos 
47966e63ce3Schristos /* ld.b */
48066e63ce3Schristos int
OP_700(void)481ed6a76a9Schristos OP_700 (void)
48266e63ce3Schristos {
48366e63ce3Schristos   int adr;
48466e63ce3Schristos 
48566e63ce3Schristos   trace_input ("ld.b", OP_LOAD32, 1);
48666e63ce3Schristos 
48766e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]);
48866e63ce3Schristos 
48966e63ce3Schristos   State.regs[ OP[1] ] = EXTEND8 (load_mem (adr, 1));
49066e63ce3Schristos 
49166e63ce3Schristos   trace_output (OP_LOAD32);
49266e63ce3Schristos 
49366e63ce3Schristos   return 4;
49466e63ce3Schristos }
49566e63ce3Schristos 
49666e63ce3Schristos /* ld.h */
49766e63ce3Schristos int
OP_720(void)498ed6a76a9Schristos OP_720 (void)
49966e63ce3Schristos {
50066e63ce3Schristos   int adr;
50166e63ce3Schristos 
50266e63ce3Schristos   trace_input ("ld.h", OP_LOAD32, 2);
50366e63ce3Schristos 
50466e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]);
50566e63ce3Schristos   adr &= ~0x1;
50666e63ce3Schristos 
50766e63ce3Schristos   State.regs[ OP[1] ] = EXTEND16 (load_mem (adr, 2));
50866e63ce3Schristos 
50966e63ce3Schristos   trace_output (OP_LOAD32);
51066e63ce3Schristos 
51166e63ce3Schristos   return 4;
51266e63ce3Schristos }
51366e63ce3Schristos 
51466e63ce3Schristos /* ld.w */
51566e63ce3Schristos int
OP_10720(void)516ed6a76a9Schristos OP_10720 (void)
51766e63ce3Schristos {
51866e63ce3Schristos   int adr;
51966e63ce3Schristos 
52066e63ce3Schristos   trace_input ("ld.w", OP_LOAD32, 4);
52166e63ce3Schristos 
52266e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1);
52366e63ce3Schristos   adr &= ~0x3;
52466e63ce3Schristos 
52566e63ce3Schristos   State.regs[ OP[1] ] = load_mem (adr, 4);
52666e63ce3Schristos 
52766e63ce3Schristos   trace_output (OP_LOAD32);
52866e63ce3Schristos 
52966e63ce3Schristos   return 4;
53066e63ce3Schristos }
53166e63ce3Schristos 
53266e63ce3Schristos /* st.b */
53366e63ce3Schristos int
OP_740(void)534ed6a76a9Schristos OP_740 (void)
53566e63ce3Schristos {
53666e63ce3Schristos   trace_input ("st.b", OP_STORE32, 1);
53766e63ce3Schristos 
53866e63ce3Schristos   store_mem (State.regs[ OP[0] ] + EXTEND16 (OP[2]), 1, State.regs[ OP[1] ]);
53966e63ce3Schristos 
54066e63ce3Schristos   trace_output (OP_STORE32);
54166e63ce3Schristos 
54266e63ce3Schristos   return 4;
54366e63ce3Schristos }
54466e63ce3Schristos 
54566e63ce3Schristos /* st.h */
54666e63ce3Schristos int
OP_760(void)547ed6a76a9Schristos OP_760 (void)
54866e63ce3Schristos {
54966e63ce3Schristos   int adr;
55066e63ce3Schristos 
55166e63ce3Schristos   trace_input ("st.h", OP_STORE32, 2);
55266e63ce3Schristos 
55366e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]);
55466e63ce3Schristos   adr &= ~1;
55566e63ce3Schristos 
55666e63ce3Schristos   store_mem (adr, 2, State.regs[ OP[1] ]);
55766e63ce3Schristos 
55866e63ce3Schristos   trace_output (OP_STORE32);
55966e63ce3Schristos 
56066e63ce3Schristos   return 4;
56166e63ce3Schristos }
56266e63ce3Schristos 
56366e63ce3Schristos /* st.w */
56466e63ce3Schristos int
OP_10760(void)565ed6a76a9Schristos OP_10760 (void)
56666e63ce3Schristos {
56766e63ce3Schristos   int adr;
56866e63ce3Schristos 
56966e63ce3Schristos   trace_input ("st.w", OP_STORE32, 4);
57066e63ce3Schristos 
57166e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1);
57266e63ce3Schristos   adr &= ~3;
57366e63ce3Schristos 
57466e63ce3Schristos   store_mem (adr, 4, State.regs[ OP[1] ]);
57566e63ce3Schristos 
57666e63ce3Schristos   trace_output (OP_STORE32);
57766e63ce3Schristos 
57866e63ce3Schristos   return 4;
57966e63ce3Schristos }
58066e63ce3Schristos 
58166e63ce3Schristos /* add reg, reg */
58266e63ce3Schristos int
OP_1C0(void)583ed6a76a9Schristos OP_1C0 (void)
58466e63ce3Schristos {
58566e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
58666e63ce3Schristos 
58766e63ce3Schristos   trace_input ("add", OP_REG_REG, 0);
58866e63ce3Schristos 
58966e63ce3Schristos   /* Compute the result.  */
59066e63ce3Schristos 
59166e63ce3Schristos   op0 = State.regs[ OP[0] ];
59266e63ce3Schristos   op1 = State.regs[ OP[1] ];
59366e63ce3Schristos 
59466e63ce3Schristos   result = op0 + op1;
59566e63ce3Schristos 
59666e63ce3Schristos   /* Compute the condition codes.  */
59766e63ce3Schristos   z = (result == 0);
59866e63ce3Schristos   s = (result & 0x80000000);
59966e63ce3Schristos   cy = (result < op0 || result < op1);
60066e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
60166e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
60266e63ce3Schristos 
60366e63ce3Schristos   /* Store the result and condition codes.  */
60466e63ce3Schristos   State.regs[OP[1]] = result;
60566e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
60666e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
60766e63ce3Schristos 		     | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
60866e63ce3Schristos   trace_output (OP_REG_REG);
60966e63ce3Schristos 
61066e63ce3Schristos   return 2;
61166e63ce3Schristos }
61266e63ce3Schristos 
61366e63ce3Schristos /* add sign_extend(imm5), reg */
61466e63ce3Schristos int
OP_240(void)615ed6a76a9Schristos OP_240 (void)
61666e63ce3Schristos {
61766e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
61866e63ce3Schristos   int temp;
61966e63ce3Schristos 
62066e63ce3Schristos   trace_input ("add", OP_IMM_REG, 0);
62166e63ce3Schristos 
62266e63ce3Schristos   /* Compute the result.  */
62366e63ce3Schristos   temp = SEXT5 (OP[0]);
62466e63ce3Schristos   op0 = temp;
62566e63ce3Schristos   op1 = State.regs[OP[1]];
62666e63ce3Schristos   result = op0 + op1;
62766e63ce3Schristos 
62866e63ce3Schristos   /* Compute the condition codes.  */
62966e63ce3Schristos   z = (result == 0);
63066e63ce3Schristos   s = (result & 0x80000000);
63166e63ce3Schristos   cy = (result < op0 || result < op1);
63266e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
63366e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
63466e63ce3Schristos 
63566e63ce3Schristos   /* Store the result and condition codes.  */
63666e63ce3Schristos   State.regs[OP[1]] = result;
63766e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
63866e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
63966e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
64066e63ce3Schristos   trace_output (OP_IMM_REG);
64166e63ce3Schristos 
64266e63ce3Schristos   return 2;
64366e63ce3Schristos }
64466e63ce3Schristos 
64566e63ce3Schristos /* addi sign_extend(imm16), reg, reg */
64666e63ce3Schristos int
OP_600(void)647ed6a76a9Schristos OP_600 (void)
64866e63ce3Schristos {
64966e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
65066e63ce3Schristos 
65166e63ce3Schristos   trace_input ("addi", OP_IMM16_REG_REG, 0);
65266e63ce3Schristos 
65366e63ce3Schristos   /* Compute the result.  */
65466e63ce3Schristos 
65566e63ce3Schristos   op0 = EXTEND16 (OP[2]);
65666e63ce3Schristos   op1 = State.regs[ OP[0] ];
65766e63ce3Schristos   result = op0 + op1;
65866e63ce3Schristos 
65966e63ce3Schristos   /* Compute the condition codes.  */
66066e63ce3Schristos   z = (result == 0);
66166e63ce3Schristos   s = (result & 0x80000000);
66266e63ce3Schristos   cy = (result < op0 || result < op1);
66366e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
66466e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
66566e63ce3Schristos 
66666e63ce3Schristos   /* Store the result and condition codes.  */
66766e63ce3Schristos   State.regs[OP[1]] = result;
66866e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
66966e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
67066e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
67166e63ce3Schristos   trace_output (OP_IMM16_REG_REG);
67266e63ce3Schristos 
67366e63ce3Schristos   return 4;
67466e63ce3Schristos }
67566e63ce3Schristos 
67666e63ce3Schristos /* sub reg1, reg2 */
67766e63ce3Schristos int
OP_1A0(void)678ed6a76a9Schristos OP_1A0 (void)
67966e63ce3Schristos {
68066e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
68166e63ce3Schristos 
68266e63ce3Schristos   trace_input ("sub", OP_REG_REG, 0);
68366e63ce3Schristos   /* Compute the result.  */
68466e63ce3Schristos   op0 = State.regs[ OP[0] ];
68566e63ce3Schristos   op1 = State.regs[ OP[1] ];
68666e63ce3Schristos   result = op1 - op0;
68766e63ce3Schristos 
68866e63ce3Schristos   /* Compute the condition codes.  */
68966e63ce3Schristos   z = (result == 0);
69066e63ce3Schristos   s = (result & 0x80000000);
69166e63ce3Schristos   cy = (op1 < op0);
69266e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
69366e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
69466e63ce3Schristos 
69566e63ce3Schristos   /* Store the result and condition codes.  */
69666e63ce3Schristos   State.regs[OP[1]] = result;
69766e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
69866e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
69966e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
70066e63ce3Schristos   trace_output (OP_REG_REG);
70166e63ce3Schristos 
70266e63ce3Schristos   return 2;
70366e63ce3Schristos }
70466e63ce3Schristos 
70566e63ce3Schristos /* subr reg1, reg2 */
70666e63ce3Schristos int
OP_180(void)707ed6a76a9Schristos OP_180 (void)
70866e63ce3Schristos {
70966e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
71066e63ce3Schristos 
71166e63ce3Schristos   trace_input ("subr", OP_REG_REG, 0);
71266e63ce3Schristos   /* Compute the result.  */
71366e63ce3Schristos   op0 = State.regs[ OP[0] ];
71466e63ce3Schristos   op1 = State.regs[ OP[1] ];
71566e63ce3Schristos   result = op0 - op1;
71666e63ce3Schristos 
71766e63ce3Schristos   /* Compute the condition codes.  */
71866e63ce3Schristos   z = (result == 0);
71966e63ce3Schristos   s = (result & 0x80000000);
72066e63ce3Schristos   cy = (op0 < op1);
72166e63ce3Schristos   ov = ((op0 & 0x80000000) != (op1 & 0x80000000)
72266e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
72366e63ce3Schristos 
72466e63ce3Schristos   /* Store the result and condition codes.  */
72566e63ce3Schristos   State.regs[OP[1]] = result;
72666e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
72766e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
72866e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
72966e63ce3Schristos   trace_output (OP_REG_REG);
73066e63ce3Schristos 
73166e63ce3Schristos   return 2;
73266e63ce3Schristos }
73366e63ce3Schristos 
73466e63ce3Schristos /* sxh reg1 */
73566e63ce3Schristos int
OP_E0(void)736ed6a76a9Schristos OP_E0 (void)
73766e63ce3Schristos {
73866e63ce3Schristos   trace_input ("mulh", OP_REG_REG, 0);
73966e63ce3Schristos 
74066e63ce3Schristos   State.regs[ OP[1] ] = (EXTEND16 (State.regs[ OP[1] ]) * EXTEND16 (State.regs[ OP[0] ]));
74166e63ce3Schristos 
74266e63ce3Schristos   trace_output (OP_REG_REG);
74366e63ce3Schristos 
74466e63ce3Schristos   return 2;
74566e63ce3Schristos }
74666e63ce3Schristos 
74766e63ce3Schristos /* mulh sign_extend(imm5), reg2 */
74866e63ce3Schristos int
OP_2E0(void)749ed6a76a9Schristos OP_2E0 (void)
75066e63ce3Schristos {
75166e63ce3Schristos   trace_input ("mulh", OP_IMM_REG, 0);
75266e63ce3Schristos 
75366e63ce3Schristos   State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[1] ]) * SEXT5 (OP[0]);
75466e63ce3Schristos 
75566e63ce3Schristos   trace_output (OP_IMM_REG);
75666e63ce3Schristos 
75766e63ce3Schristos   return 2;
75866e63ce3Schristos }
75966e63ce3Schristos 
76066e63ce3Schristos /* mulhi imm16, reg1, reg2 */
76166e63ce3Schristos int
OP_6E0(void)762ed6a76a9Schristos OP_6E0 (void)
76366e63ce3Schristos {
76466e63ce3Schristos   trace_input ("mulhi", OP_IMM16_REG_REG, 0);
76566e63ce3Schristos 
76666e63ce3Schristos   State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[0] ]) * EXTEND16 (OP[2]);
76766e63ce3Schristos 
76866e63ce3Schristos   trace_output (OP_IMM16_REG_REG);
76966e63ce3Schristos 
77066e63ce3Schristos   return 4;
77166e63ce3Schristos }
77266e63ce3Schristos 
77366e63ce3Schristos /* cmp reg, reg */
77466e63ce3Schristos int
OP_1E0(void)775ed6a76a9Schristos OP_1E0 (void)
77666e63ce3Schristos {
77766e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
77866e63ce3Schristos 
77966e63ce3Schristos   trace_input ("cmp", OP_REG_REG_CMP, 0);
78066e63ce3Schristos   /* Compute the result.  */
78166e63ce3Schristos   op0 = State.regs[ OP[0] ];
78266e63ce3Schristos   op1 = State.regs[ OP[1] ];
78366e63ce3Schristos   result = op1 - op0;
78466e63ce3Schristos 
78566e63ce3Schristos   /* Compute the condition codes.  */
78666e63ce3Schristos   z = (result == 0);
78766e63ce3Schristos   s = (result & 0x80000000);
78866e63ce3Schristos   cy = (op1 < op0);
78966e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
79066e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
79166e63ce3Schristos 
79266e63ce3Schristos   /* Set condition codes.  */
79366e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
79466e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
79566e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
79666e63ce3Schristos   trace_output (OP_REG_REG_CMP);
79766e63ce3Schristos 
79866e63ce3Schristos   return 2;
79966e63ce3Schristos }
80066e63ce3Schristos 
80166e63ce3Schristos /* cmp sign_extend(imm5), reg */
80266e63ce3Schristos int
OP_260(void)803ed6a76a9Schristos OP_260 (void)
80466e63ce3Schristos {
80566e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov;
80666e63ce3Schristos   int temp;
80766e63ce3Schristos 
80866e63ce3Schristos   /* Compute the result.  */
80966e63ce3Schristos   trace_input ("cmp", OP_IMM_REG_CMP, 0);
81066e63ce3Schristos   temp = SEXT5 (OP[0]);
81166e63ce3Schristos   op0 = temp;
81266e63ce3Schristos   op1 = State.regs[OP[1]];
81366e63ce3Schristos   result = op1 - op0;
81466e63ce3Schristos 
81566e63ce3Schristos   /* Compute the condition codes.  */
81666e63ce3Schristos   z = (result == 0);
81766e63ce3Schristos   s = (result & 0x80000000);
81866e63ce3Schristos   cy = (op1 < op0);
81966e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
82066e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
82166e63ce3Schristos 
82266e63ce3Schristos   /* Set condition codes.  */
82366e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
82466e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
82566e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
82666e63ce3Schristos   trace_output (OP_IMM_REG_CMP);
82766e63ce3Schristos 
82866e63ce3Schristos   return 2;
82966e63ce3Schristos }
83066e63ce3Schristos 
83166e63ce3Schristos /* setf cccc,reg2 */
83266e63ce3Schristos int
OP_7E0(void)833ed6a76a9Schristos OP_7E0 (void)
83466e63ce3Schristos {
83566e63ce3Schristos   trace_input ("setf", OP_EX1, 0);
83666e63ce3Schristos 
83766e63ce3Schristos   State.regs[ OP[1] ] = condition_met (OP[0]);
83866e63ce3Schristos 
83966e63ce3Schristos   trace_output (OP_EX1);
84066e63ce3Schristos 
84166e63ce3Schristos   return 4;
84266e63ce3Schristos }
84366e63ce3Schristos 
84466e63ce3Schristos /* satadd reg,reg */
84566e63ce3Schristos int
OP_C0(void)846ed6a76a9Schristos OP_C0 (void)
84766e63ce3Schristos {
84866e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
84966e63ce3Schristos 
85066e63ce3Schristos   trace_input ("satadd", OP_REG_REG, 0);
85166e63ce3Schristos   /* Compute the result.  */
85266e63ce3Schristos   op0 = State.regs[ OP[0] ];
85366e63ce3Schristos   op1 = State.regs[ OP[1] ];
85466e63ce3Schristos   result = op0 + op1;
85566e63ce3Schristos 
85666e63ce3Schristos   /* Compute the condition codes.  */
85766e63ce3Schristos   z = (result == 0);
85866e63ce3Schristos   s = (result & 0x80000000);
85966e63ce3Schristos   cy = (result < op0 || result < op1);
86066e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
86166e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
86266e63ce3Schristos   sat = ov;
86366e63ce3Schristos 
86466e63ce3Schristos   /* Handle saturated results.  */
86566e63ce3Schristos   if (sat && s)
86666e63ce3Schristos     {
86766e63ce3Schristos       /* An overflow that results in a negative result implies that we
86866e63ce3Schristos 	 became too positive.  */
86966e63ce3Schristos       result = 0x7fffffff;
87066e63ce3Schristos       s = 0;
87166e63ce3Schristos     }
87266e63ce3Schristos   else if (sat)
87366e63ce3Schristos     {
87466e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
87566e63ce3Schristos       result = 0x80000000;
87666e63ce3Schristos       s = 1;
87766e63ce3Schristos       z = 0;
87866e63ce3Schristos     }
87966e63ce3Schristos 
88066e63ce3Schristos   /* Store the result and condition codes.  */
88166e63ce3Schristos   State.regs[OP[1]] = result;
88266e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
88366e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
88466e63ce3Schristos 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
88566e63ce3Schristos 	  | (sat ? PSW_SAT : 0));
88666e63ce3Schristos 
88766e63ce3Schristos   trace_output (OP_REG_REG);
88866e63ce3Schristos 
88966e63ce3Schristos   return 2;
89066e63ce3Schristos }
89166e63ce3Schristos 
89266e63ce3Schristos /* satadd sign_extend(imm5), reg */
89366e63ce3Schristos int
OP_220(void)894ed6a76a9Schristos OP_220 (void)
89566e63ce3Schristos {
89666e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
89766e63ce3Schristos 
89866e63ce3Schristos   int temp;
89966e63ce3Schristos 
90066e63ce3Schristos   trace_input ("satadd", OP_IMM_REG, 0);
90166e63ce3Schristos 
90266e63ce3Schristos   /* Compute the result.  */
90366e63ce3Schristos   temp = SEXT5 (OP[0]);
90466e63ce3Schristos   op0 = temp;
90566e63ce3Schristos   op1 = State.regs[OP[1]];
90666e63ce3Schristos   result = op0 + op1;
90766e63ce3Schristos 
90866e63ce3Schristos   /* Compute the condition codes.  */
90966e63ce3Schristos   z = (result == 0);
91066e63ce3Schristos   s = (result & 0x80000000);
91166e63ce3Schristos   cy = (result < op0 || result < op1);
91266e63ce3Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
91366e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
91466e63ce3Schristos   sat = ov;
91566e63ce3Schristos 
91666e63ce3Schristos   /* Handle saturated results.  */
91766e63ce3Schristos   if (sat && s)
91866e63ce3Schristos     {
91966e63ce3Schristos       /* An overflow that results in a negative result implies that we
92066e63ce3Schristos 	 became too positive.  */
92166e63ce3Schristos       result = 0x7fffffff;
92266e63ce3Schristos       s = 0;
92366e63ce3Schristos     }
92466e63ce3Schristos   else if (sat)
92566e63ce3Schristos     {
92666e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
92766e63ce3Schristos       result = 0x80000000;
92866e63ce3Schristos       s = 1;
92966e63ce3Schristos       z = 0;
93066e63ce3Schristos     }
93166e63ce3Schristos 
93266e63ce3Schristos   /* Store the result and condition codes.  */
93366e63ce3Schristos   State.regs[OP[1]] = result;
93466e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
93566e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
93666e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
93766e63ce3Schristos 		| (sat ? PSW_SAT : 0));
93866e63ce3Schristos   trace_output (OP_IMM_REG);
93966e63ce3Schristos 
94066e63ce3Schristos   return 2;
94166e63ce3Schristos }
94266e63ce3Schristos 
94366e63ce3Schristos /* satsub reg1, reg2 */
94466e63ce3Schristos int
OP_A0(void)945ed6a76a9Schristos OP_A0 (void)
94666e63ce3Schristos {
94766e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
94866e63ce3Schristos 
94966e63ce3Schristos   trace_input ("satsub", OP_REG_REG, 0);
95066e63ce3Schristos 
95166e63ce3Schristos   /* Compute the result.  */
95266e63ce3Schristos   op0 = State.regs[ OP[0] ];
95366e63ce3Schristos   op1 = State.regs[ OP[1] ];
95466e63ce3Schristos   result = op1 - op0;
95566e63ce3Schristos 
95666e63ce3Schristos   /* Compute the condition codes.  */
95766e63ce3Schristos   z = (result == 0);
95866e63ce3Schristos   s = (result & 0x80000000);
95966e63ce3Schristos   cy = (op1 < op0);
96066e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
96166e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
96266e63ce3Schristos   sat = ov;
96366e63ce3Schristos 
96466e63ce3Schristos   /* Handle saturated results.  */
96566e63ce3Schristos   if (sat && s)
96666e63ce3Schristos     {
96766e63ce3Schristos       /* An overflow that results in a negative result implies that we
96866e63ce3Schristos 	 became too positive.  */
96966e63ce3Schristos       result = 0x7fffffff;
97066e63ce3Schristos       s = 0;
97166e63ce3Schristos     }
97266e63ce3Schristos   else if (sat)
97366e63ce3Schristos     {
97466e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
97566e63ce3Schristos       result = 0x80000000;
97666e63ce3Schristos       s = 1;
97766e63ce3Schristos       z = 0;
97866e63ce3Schristos     }
97966e63ce3Schristos 
98066e63ce3Schristos   /* Store the result and condition codes.  */
98166e63ce3Schristos   State.regs[OP[1]] = result;
98266e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
98366e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
98466e63ce3Schristos 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
98566e63ce3Schristos 	  | (sat ? PSW_SAT : 0));
98666e63ce3Schristos 
98766e63ce3Schristos   trace_output (OP_REG_REG);
98866e63ce3Schristos   return 2;
98966e63ce3Schristos }
99066e63ce3Schristos 
99166e63ce3Schristos /* satsubi sign_extend(imm16), reg */
99266e63ce3Schristos int
OP_660(void)993ed6a76a9Schristos OP_660 (void)
99466e63ce3Schristos {
99566e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
99666e63ce3Schristos   int temp;
99766e63ce3Schristos 
99866e63ce3Schristos   trace_input ("satsubi", OP_IMM_REG, 0);
99966e63ce3Schristos 
100066e63ce3Schristos   /* Compute the result.  */
100166e63ce3Schristos   temp = EXTEND16 (OP[2]);
100266e63ce3Schristos   op0 = temp;
100366e63ce3Schristos   op1 = State.regs[ OP[0] ];
100466e63ce3Schristos   result = op1 - op0;
100566e63ce3Schristos 
100666e63ce3Schristos   /* Compute the condition codes.  */
100766e63ce3Schristos   z = (result == 0);
100866e63ce3Schristos   s = (result & 0x80000000);
100966e63ce3Schristos   cy = (op1 < op0);
101066e63ce3Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
101166e63ce3Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
101266e63ce3Schristos   sat = ov;
101366e63ce3Schristos 
101466e63ce3Schristos   /* Handle saturated results.  */
101566e63ce3Schristos   if (sat && s)
101666e63ce3Schristos     {
101766e63ce3Schristos       /* An overflow that results in a negative result implies that we
101866e63ce3Schristos 	 became too positive.  */
101966e63ce3Schristos       result = 0x7fffffff;
102066e63ce3Schristos       s = 0;
102166e63ce3Schristos     }
102266e63ce3Schristos   else if (sat)
102366e63ce3Schristos     {
102466e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
102566e63ce3Schristos       result = 0x80000000;
102666e63ce3Schristos       s = 1;
102766e63ce3Schristos       z = 0;
102866e63ce3Schristos     }
102966e63ce3Schristos 
103066e63ce3Schristos   /* Store the result and condition codes.  */
103166e63ce3Schristos   State.regs[OP[1]] = result;
103266e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
103366e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
103466e63ce3Schristos 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
103566e63ce3Schristos 		| (sat ? PSW_SAT : 0));
103666e63ce3Schristos 
103766e63ce3Schristos   trace_output (OP_IMM_REG);
103866e63ce3Schristos 
103966e63ce3Schristos   return 4;
104066e63ce3Schristos }
104166e63ce3Schristos 
104266e63ce3Schristos /* satsubr reg,reg */
104366e63ce3Schristos int
OP_80(void)1044ed6a76a9Schristos OP_80 (void)
104566e63ce3Schristos {
104666e63ce3Schristos   unsigned int op0, op1, result, z, s, cy, ov, sat;
104766e63ce3Schristos 
104866e63ce3Schristos   trace_input ("satsubr", OP_REG_REG, 0);
104966e63ce3Schristos 
105066e63ce3Schristos   /* Compute the result.  */
105166e63ce3Schristos   op0 = State.regs[ OP[0] ];
105266e63ce3Schristos   op1 = State.regs[ OP[1] ];
105366e63ce3Schristos   result = op0 - op1;
105466e63ce3Schristos 
105566e63ce3Schristos   /* Compute the condition codes.  */
105666e63ce3Schristos   z = (result == 0);
105766e63ce3Schristos   s = (result & 0x80000000);
105866e63ce3Schristos   cy = (op0 < op1);
105966e63ce3Schristos   ov = ((op0 & 0x80000000) != (op1 & 0x80000000)
106066e63ce3Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
106166e63ce3Schristos   sat = ov;
106266e63ce3Schristos 
106366e63ce3Schristos   /* Handle saturated results.  */
106466e63ce3Schristos   if (sat && s)
106566e63ce3Schristos     {
106666e63ce3Schristos       /* An overflow that results in a negative result implies that we
106766e63ce3Schristos 	 became too positive.  */
106866e63ce3Schristos       result = 0x7fffffff;
106966e63ce3Schristos       s = 0;
107066e63ce3Schristos     }
107166e63ce3Schristos   else if (sat)
107266e63ce3Schristos     {
107366e63ce3Schristos       /* Any other overflow must have thus been too negative.  */
107466e63ce3Schristos       result = 0x80000000;
107566e63ce3Schristos       s = 1;
107666e63ce3Schristos       z = 0;
107766e63ce3Schristos     }
107866e63ce3Schristos 
107966e63ce3Schristos   /* Store the result and condition codes.  */
108066e63ce3Schristos   State.regs[OP[1]] = result;
108166e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
108266e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
108366e63ce3Schristos 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
108466e63ce3Schristos 	  | (sat ? PSW_SAT : 0));
108566e63ce3Schristos 
108666e63ce3Schristos   trace_output (OP_REG_REG);
108766e63ce3Schristos 
108866e63ce3Schristos   return 2;
108966e63ce3Schristos }
109066e63ce3Schristos 
109166e63ce3Schristos /* tst reg,reg */
109266e63ce3Schristos int
OP_160(void)1093ed6a76a9Schristos OP_160 (void)
109466e63ce3Schristos {
109566e63ce3Schristos   unsigned int op0, op1, result, z, s;
109666e63ce3Schristos 
109766e63ce3Schristos   trace_input ("tst", OP_REG_REG_CMP, 0);
109866e63ce3Schristos 
109966e63ce3Schristos   /* Compute the result.  */
110066e63ce3Schristos   op0 = State.regs[ OP[0] ];
110166e63ce3Schristos   op1 = State.regs[ OP[1] ];
110266e63ce3Schristos   result = op0 & op1;
110366e63ce3Schristos 
110466e63ce3Schristos   /* Compute the condition codes.  */
110566e63ce3Schristos   z = (result == 0);
110666e63ce3Schristos   s = (result & 0x80000000);
110766e63ce3Schristos 
110866e63ce3Schristos   /* Store the condition codes.  */
110966e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
111066e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
111166e63ce3Schristos   trace_output (OP_REG_REG_CMP);
111266e63ce3Schristos 
111366e63ce3Schristos   return 2;
111466e63ce3Schristos }
111566e63ce3Schristos 
111666e63ce3Schristos /* mov sign_extend(imm5), reg */
111766e63ce3Schristos int
OP_200(void)1118ed6a76a9Schristos OP_200 (void)
111966e63ce3Schristos {
112066e63ce3Schristos   int value = SEXT5 (OP[0]);
112166e63ce3Schristos 
112266e63ce3Schristos   trace_input ("mov", OP_IMM_REG_MOVE, 0);
112366e63ce3Schristos 
112466e63ce3Schristos   State.regs[ OP[1] ] = value;
112566e63ce3Schristos 
112666e63ce3Schristos   trace_output (OP_IMM_REG_MOVE);
112766e63ce3Schristos 
112866e63ce3Schristos   return 2;
112966e63ce3Schristos }
113066e63ce3Schristos 
113166e63ce3Schristos /* movhi imm16, reg, reg */
113266e63ce3Schristos int
OP_640(void)1133ed6a76a9Schristos OP_640 (void)
113466e63ce3Schristos {
113566e63ce3Schristos   trace_input ("movhi", OP_UIMM16_REG_REG, 16);
113666e63ce3Schristos 
113766e63ce3Schristos   State.regs[ OP[1] ] = State.regs[ OP[0] ] + (OP[2] << 16);
113866e63ce3Schristos 
113966e63ce3Schristos   trace_output (OP_UIMM16_REG_REG);
114066e63ce3Schristos 
114166e63ce3Schristos   return 4;
114266e63ce3Schristos }
114366e63ce3Schristos 
114466e63ce3Schristos /* sar zero_extend(imm5),reg1 */
114566e63ce3Schristos int
OP_2A0(void)1146ed6a76a9Schristos OP_2A0 (void)
114766e63ce3Schristos {
114866e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
114966e63ce3Schristos 
115066e63ce3Schristos   trace_input ("sar", OP_IMM_REG, 0);
115166e63ce3Schristos   op0 = OP[0];
115266e63ce3Schristos   op1 = State.regs[ OP[1] ];
115366e63ce3Schristos   result = (signed)op1 >> op0;
115466e63ce3Schristos 
115566e63ce3Schristos   /* Compute the condition codes.  */
115666e63ce3Schristos   z = (result == 0);
115766e63ce3Schristos   s = (result & 0x80000000);
115866e63ce3Schristos   cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
115966e63ce3Schristos 
116066e63ce3Schristos   /* Store the result and condition codes.  */
116166e63ce3Schristos   State.regs[ OP[1] ] = result;
116266e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
116366e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
116466e63ce3Schristos 		| (cy ? PSW_CY : 0));
116566e63ce3Schristos   trace_output (OP_IMM_REG);
116666e63ce3Schristos 
116766e63ce3Schristos   return 2;
116866e63ce3Schristos }
116966e63ce3Schristos 
117066e63ce3Schristos /* sar reg1, reg2 */
117166e63ce3Schristos int
OP_A007E0(void)1172ed6a76a9Schristos OP_A007E0 (void)
117366e63ce3Schristos {
117466e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
117566e63ce3Schristos 
117666e63ce3Schristos   trace_input ("sar", OP_REG_REG, 0);
117766e63ce3Schristos 
117866e63ce3Schristos   op0 = State.regs[ OP[0] ] & 0x1f;
117966e63ce3Schristos   op1 = State.regs[ OP[1] ];
118066e63ce3Schristos   result = (signed)op1 >> op0;
118166e63ce3Schristos 
118266e63ce3Schristos   /* Compute the condition codes.  */
118366e63ce3Schristos   z = (result == 0);
118466e63ce3Schristos   s = (result & 0x80000000);
118566e63ce3Schristos   cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
118666e63ce3Schristos 
118766e63ce3Schristos   /* Store the result and condition codes.  */
118866e63ce3Schristos   State.regs[OP[1]] = result;
118966e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
119066e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
119166e63ce3Schristos 		| (cy ? PSW_CY : 0));
119266e63ce3Schristos   trace_output (OP_REG_REG);
119366e63ce3Schristos 
119466e63ce3Schristos   return 4;
119566e63ce3Schristos }
119666e63ce3Schristos 
119766e63ce3Schristos /* shl zero_extend(imm5),reg1 */
119866e63ce3Schristos int
OP_2C0(void)1199ed6a76a9Schristos OP_2C0 (void)
120066e63ce3Schristos {
120166e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
120266e63ce3Schristos 
120366e63ce3Schristos   trace_input ("shl", OP_IMM_REG, 0);
120466e63ce3Schristos   op0 = OP[0];
120566e63ce3Schristos   op1 = State.regs[ OP[1] ];
120666e63ce3Schristos   result = op1 << op0;
120766e63ce3Schristos 
120866e63ce3Schristos   /* Compute the condition codes.  */
120966e63ce3Schristos   z = (result == 0);
121066e63ce3Schristos   s = (result & 0x80000000);
121166e63ce3Schristos   cy = op0 ? (op1 & (1 << (32 - op0))) : 0;
121266e63ce3Schristos 
121366e63ce3Schristos   /* Store the result and condition codes.  */
121466e63ce3Schristos   State.regs[OP[1]] = result;
121566e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
121666e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
121766e63ce3Schristos 		| (cy ? PSW_CY : 0));
121866e63ce3Schristos   trace_output (OP_IMM_REG);
121966e63ce3Schristos 
122066e63ce3Schristos   return 2;
122166e63ce3Schristos }
122266e63ce3Schristos 
122366e63ce3Schristos /* shl reg1, reg2 */
122466e63ce3Schristos int
OP_C007E0(void)1225ed6a76a9Schristos OP_C007E0 (void)
122666e63ce3Schristos {
122766e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
122866e63ce3Schristos 
122966e63ce3Schristos   trace_input ("shl", OP_REG_REG, 0);
123066e63ce3Schristos   op0 = State.regs[ OP[0] ] & 0x1f;
123166e63ce3Schristos   op1 = State.regs[ OP[1] ];
123266e63ce3Schristos   result = op1 << op0;
123366e63ce3Schristos 
123466e63ce3Schristos   /* Compute the condition codes.  */
123566e63ce3Schristos   z = (result == 0);
123666e63ce3Schristos   s = (result & 0x80000000);
123766e63ce3Schristos   cy = op0 ? (op1 & (1 << (32 - op0))) : 0;
123866e63ce3Schristos 
123966e63ce3Schristos   /* Store the result and condition codes.  */
124066e63ce3Schristos   State.regs[OP[1]] = result;
124166e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
124266e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
124366e63ce3Schristos 		| (cy ? PSW_CY : 0));
124466e63ce3Schristos   trace_output (OP_REG_REG);
124566e63ce3Schristos 
124666e63ce3Schristos   return 4;
124766e63ce3Schristos }
124866e63ce3Schristos 
124966e63ce3Schristos /* shr zero_extend(imm5),reg1 */
125066e63ce3Schristos int
OP_280(void)1251ed6a76a9Schristos OP_280 (void)
125266e63ce3Schristos {
125366e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
125466e63ce3Schristos 
125566e63ce3Schristos   trace_input ("shr", OP_IMM_REG, 0);
125666e63ce3Schristos   op0 = OP[0];
125766e63ce3Schristos   op1 = State.regs[ OP[1] ];
125866e63ce3Schristos   result = op1 >> op0;
125966e63ce3Schristos 
126066e63ce3Schristos   /* Compute the condition codes.  */
126166e63ce3Schristos   z = (result == 0);
126266e63ce3Schristos   s = (result & 0x80000000);
126366e63ce3Schristos   cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
126466e63ce3Schristos 
126566e63ce3Schristos   /* Store the result and condition codes.  */
126666e63ce3Schristos   State.regs[OP[1]] = result;
126766e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
126866e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
126966e63ce3Schristos 		| (cy ? PSW_CY : 0));
127066e63ce3Schristos   trace_output (OP_IMM_REG);
127166e63ce3Schristos 
127266e63ce3Schristos   return 2;
127366e63ce3Schristos }
127466e63ce3Schristos 
127566e63ce3Schristos /* shr reg1, reg2 */
127666e63ce3Schristos int
OP_8007E0(void)1277ed6a76a9Schristos OP_8007E0 (void)
127866e63ce3Schristos {
127966e63ce3Schristos   unsigned int op0, op1, result, z, s, cy;
128066e63ce3Schristos 
128166e63ce3Schristos   trace_input ("shr", OP_REG_REG, 0);
128266e63ce3Schristos   op0 = State.regs[ OP[0] ] & 0x1f;
128366e63ce3Schristos   op1 = State.regs[ OP[1] ];
128466e63ce3Schristos   result = op1 >> op0;
128566e63ce3Schristos 
128666e63ce3Schristos   /* Compute the condition codes.  */
128766e63ce3Schristos   z = (result == 0);
128866e63ce3Schristos   s = (result & 0x80000000);
128966e63ce3Schristos   cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
129066e63ce3Schristos 
129166e63ce3Schristos   /* Store the result and condition codes.  */
129266e63ce3Schristos   State.regs[OP[1]] = result;
129366e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
129466e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
129566e63ce3Schristos 		| (cy ? PSW_CY : 0));
129666e63ce3Schristos   trace_output (OP_REG_REG);
129766e63ce3Schristos 
129866e63ce3Schristos   return 4;
129966e63ce3Schristos }
130066e63ce3Schristos 
130166e63ce3Schristos /* or reg, reg */
130266e63ce3Schristos int
OP_100(void)1303ed6a76a9Schristos OP_100 (void)
130466e63ce3Schristos {
130566e63ce3Schristos   unsigned int op0, op1, result, z, s;
130666e63ce3Schristos 
130766e63ce3Schristos   trace_input ("or", OP_REG_REG, 0);
130866e63ce3Schristos 
130966e63ce3Schristos   /* Compute the result.  */
131066e63ce3Schristos   op0 = State.regs[ OP[0] ];
131166e63ce3Schristos   op1 = State.regs[ OP[1] ];
131266e63ce3Schristos   result = op0 | op1;
131366e63ce3Schristos 
131466e63ce3Schristos   /* Compute the condition codes.  */
131566e63ce3Schristos   z = (result == 0);
131666e63ce3Schristos   s = (result & 0x80000000);
131766e63ce3Schristos 
131866e63ce3Schristos   /* Store the result and condition codes.  */
131966e63ce3Schristos   State.regs[OP[1]] = result;
132066e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
132166e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
132266e63ce3Schristos   trace_output (OP_REG_REG);
132366e63ce3Schristos 
132466e63ce3Schristos   return 2;
132566e63ce3Schristos }
132666e63ce3Schristos 
132766e63ce3Schristos /* ori zero_extend(imm16), reg, reg */
132866e63ce3Schristos int
OP_680(void)1329ed6a76a9Schristos OP_680 (void)
133066e63ce3Schristos {
133166e63ce3Schristos   unsigned int op0, op1, result, z, s;
133266e63ce3Schristos 
133366e63ce3Schristos   trace_input ("ori", OP_UIMM16_REG_REG, 0);
133466e63ce3Schristos   op0 = OP[2];
133566e63ce3Schristos   op1 = State.regs[ OP[0] ];
133666e63ce3Schristos   result = op0 | op1;
133766e63ce3Schristos 
133866e63ce3Schristos   /* Compute the condition codes.  */
133966e63ce3Schristos   z = (result == 0);
134066e63ce3Schristos   s = (result & 0x80000000);
134166e63ce3Schristos 
134266e63ce3Schristos   /* Store the result and condition codes.  */
134366e63ce3Schristos   State.regs[OP[1]] = result;
134466e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
134566e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
134666e63ce3Schristos   trace_output (OP_UIMM16_REG_REG);
134766e63ce3Schristos 
134866e63ce3Schristos   return 4;
134966e63ce3Schristos }
135066e63ce3Schristos 
135166e63ce3Schristos /* and reg, reg */
135266e63ce3Schristos int
OP_140(void)1353ed6a76a9Schristos OP_140 (void)
135466e63ce3Schristos {
135566e63ce3Schristos   unsigned int op0, op1, result, z, s;
135666e63ce3Schristos 
135766e63ce3Schristos   trace_input ("and", OP_REG_REG, 0);
135866e63ce3Schristos 
135966e63ce3Schristos   /* Compute the result.  */
136066e63ce3Schristos   op0 = State.regs[ OP[0] ];
136166e63ce3Schristos   op1 = State.regs[ OP[1] ];
136266e63ce3Schristos   result = op0 & op1;
136366e63ce3Schristos 
136466e63ce3Schristos   /* Compute the condition codes.  */
136566e63ce3Schristos   z = (result == 0);
136666e63ce3Schristos   s = (result & 0x80000000);
136766e63ce3Schristos 
136866e63ce3Schristos   /* Store the result and condition codes.  */
136966e63ce3Schristos   State.regs[OP[1]] = result;
137066e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
137166e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
137266e63ce3Schristos   trace_output (OP_REG_REG);
137366e63ce3Schristos 
137466e63ce3Schristos   return 2;
137566e63ce3Schristos }
137666e63ce3Schristos 
137766e63ce3Schristos /* andi zero_extend(imm16), reg, reg */
137866e63ce3Schristos int
OP_6C0(void)1379ed6a76a9Schristos OP_6C0 (void)
138066e63ce3Schristos {
138166e63ce3Schristos   unsigned int result, z;
138266e63ce3Schristos 
138366e63ce3Schristos   trace_input ("andi", OP_UIMM16_REG_REG, 0);
138466e63ce3Schristos 
138566e63ce3Schristos   result = OP[2] & State.regs[ OP[0] ];
138666e63ce3Schristos 
138766e63ce3Schristos   /* Compute the condition codes.  */
138866e63ce3Schristos   z = (result == 0);
138966e63ce3Schristos 
139066e63ce3Schristos   /* Store the result and condition codes.  */
139166e63ce3Schristos   State.regs[ OP[1] ] = result;
139266e63ce3Schristos 
139366e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
139466e63ce3Schristos   PSW |= (z ? PSW_Z : 0);
139566e63ce3Schristos 
139666e63ce3Schristos   trace_output (OP_UIMM16_REG_REG);
139766e63ce3Schristos 
139866e63ce3Schristos   return 4;
139966e63ce3Schristos }
140066e63ce3Schristos 
140166e63ce3Schristos /* xor reg, reg */
140266e63ce3Schristos int
OP_120(void)1403ed6a76a9Schristos OP_120 (void)
140466e63ce3Schristos {
140566e63ce3Schristos   unsigned int op0, op1, result, z, s;
140666e63ce3Schristos 
140766e63ce3Schristos   trace_input ("xor", OP_REG_REG, 0);
140866e63ce3Schristos 
140966e63ce3Schristos   /* Compute the result.  */
141066e63ce3Schristos   op0 = State.regs[ OP[0] ];
141166e63ce3Schristos   op1 = State.regs[ OP[1] ];
141266e63ce3Schristos   result = op0 ^ op1;
141366e63ce3Schristos 
141466e63ce3Schristos   /* Compute the condition codes.  */
141566e63ce3Schristos   z = (result == 0);
141666e63ce3Schristos   s = (result & 0x80000000);
141766e63ce3Schristos 
141866e63ce3Schristos   /* Store the result and condition codes.  */
141966e63ce3Schristos   State.regs[OP[1]] = result;
142066e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
142166e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
142266e63ce3Schristos   trace_output (OP_REG_REG);
142366e63ce3Schristos 
142466e63ce3Schristos   return 2;
142566e63ce3Schristos }
142666e63ce3Schristos 
142766e63ce3Schristos /* xori zero_extend(imm16), reg, reg */
142866e63ce3Schristos int
OP_6A0(void)1429ed6a76a9Schristos OP_6A0 (void)
143066e63ce3Schristos {
143166e63ce3Schristos   unsigned int op0, op1, result, z, s;
143266e63ce3Schristos 
143366e63ce3Schristos   trace_input ("xori", OP_UIMM16_REG_REG, 0);
143466e63ce3Schristos   op0 = OP[2];
143566e63ce3Schristos   op1 = State.regs[ OP[0] ];
143666e63ce3Schristos   result = op0 ^ op1;
143766e63ce3Schristos 
143866e63ce3Schristos   /* Compute the condition codes.  */
143966e63ce3Schristos   z = (result == 0);
144066e63ce3Schristos   s = (result & 0x80000000);
144166e63ce3Schristos 
144266e63ce3Schristos   /* Store the result and condition codes.  */
144366e63ce3Schristos   State.regs[OP[1]] = result;
144466e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
144566e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
144666e63ce3Schristos   trace_output (OP_UIMM16_REG_REG);
144766e63ce3Schristos 
144866e63ce3Schristos   return 4;
144966e63ce3Schristos }
145066e63ce3Schristos 
145166e63ce3Schristos /* not reg1, reg2 */
145266e63ce3Schristos int
OP_20(void)1453ed6a76a9Schristos OP_20 (void)
145466e63ce3Schristos {
145566e63ce3Schristos   unsigned int op0, result, z, s;
145666e63ce3Schristos 
145766e63ce3Schristos   trace_input ("not", OP_REG_REG_MOVE, 0);
145866e63ce3Schristos   /* Compute the result.  */
145966e63ce3Schristos   op0 = State.regs[ OP[0] ];
146066e63ce3Schristos   result = ~op0;
146166e63ce3Schristos 
146266e63ce3Schristos   /* Compute the condition codes.  */
146366e63ce3Schristos   z = (result == 0);
146466e63ce3Schristos   s = (result & 0x80000000);
146566e63ce3Schristos 
146666e63ce3Schristos   /* Store the result and condition codes.  */
146766e63ce3Schristos   State.regs[OP[1]] = result;
146866e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
146966e63ce3Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
147066e63ce3Schristos   trace_output (OP_REG_REG_MOVE);
147166e63ce3Schristos 
147266e63ce3Schristos   return 2;
147366e63ce3Schristos }
147466e63ce3Schristos 
147566e63ce3Schristos /* set1 */
147666e63ce3Schristos int
OP_7C0(void)1477ed6a76a9Schristos OP_7C0 (void)
147866e63ce3Schristos {
147966e63ce3Schristos   unsigned int op0, op1, op2;
148066e63ce3Schristos   int temp;
148166e63ce3Schristos 
148266e63ce3Schristos   trace_input ("set1", OP_BIT, 0);
148366e63ce3Schristos   op0 = State.regs[ OP[0] ];
148466e63ce3Schristos   op1 = OP[1] & 0x7;
148566e63ce3Schristos   temp = EXTEND16 (OP[2]);
148666e63ce3Schristos   op2 = temp;
148766e63ce3Schristos   temp = load_mem (op0 + op2, 1);
148866e63ce3Schristos   PSW &= ~PSW_Z;
148966e63ce3Schristos   if ((temp & (1 << op1)) == 0)
149066e63ce3Schristos     PSW |= PSW_Z;
149166e63ce3Schristos   temp |= (1 << op1);
149266e63ce3Schristos   store_mem (op0 + op2, 1, temp);
149366e63ce3Schristos   trace_output (OP_BIT);
149466e63ce3Schristos 
149566e63ce3Schristos   return 4;
149666e63ce3Schristos }
149766e63ce3Schristos 
149866e63ce3Schristos /* not1 */
149966e63ce3Schristos int
OP_47C0(void)1500ed6a76a9Schristos OP_47C0 (void)
150166e63ce3Schristos {
150266e63ce3Schristos   unsigned int op0, op1, op2;
150366e63ce3Schristos   int temp;
150466e63ce3Schristos 
150566e63ce3Schristos   trace_input ("not1", OP_BIT, 0);
150666e63ce3Schristos   op0 = State.regs[ OP[0] ];
150766e63ce3Schristos   op1 = OP[1] & 0x7;
150866e63ce3Schristos   temp = EXTEND16 (OP[2]);
150966e63ce3Schristos   op2 = temp;
151066e63ce3Schristos   temp = load_mem (op0 + op2, 1);
151166e63ce3Schristos   PSW &= ~PSW_Z;
151266e63ce3Schristos   if ((temp & (1 << op1)) == 0)
151366e63ce3Schristos     PSW |= PSW_Z;
151466e63ce3Schristos   temp ^= (1 << op1);
151566e63ce3Schristos   store_mem (op0 + op2, 1, temp);
151666e63ce3Schristos   trace_output (OP_BIT);
151766e63ce3Schristos 
151866e63ce3Schristos   return 4;
151966e63ce3Schristos }
152066e63ce3Schristos 
152166e63ce3Schristos /* clr1 */
152266e63ce3Schristos int
OP_87C0(void)1523ed6a76a9Schristos OP_87C0 (void)
152466e63ce3Schristos {
152566e63ce3Schristos   unsigned int op0, op1, op2;
152666e63ce3Schristos   int temp;
152766e63ce3Schristos 
152866e63ce3Schristos   trace_input ("clr1", OP_BIT, 0);
152966e63ce3Schristos   op0 = State.regs[ OP[0] ];
153066e63ce3Schristos   op1 = OP[1] & 0x7;
153166e63ce3Schristos   temp = EXTEND16 (OP[2]);
153266e63ce3Schristos   op2 = temp;
153366e63ce3Schristos   temp = load_mem (op0 + op2, 1);
153466e63ce3Schristos   PSW &= ~PSW_Z;
153566e63ce3Schristos   if ((temp & (1 << op1)) == 0)
153666e63ce3Schristos     PSW |= PSW_Z;
153766e63ce3Schristos   temp &= ~(1 << op1);
153866e63ce3Schristos   store_mem (op0 + op2, 1, temp);
153966e63ce3Schristos   trace_output (OP_BIT);
154066e63ce3Schristos 
154166e63ce3Schristos   return 4;
154266e63ce3Schristos }
154366e63ce3Schristos 
154466e63ce3Schristos /* tst1 */
154566e63ce3Schristos int
OP_C7C0(void)1546ed6a76a9Schristos OP_C7C0 (void)
154766e63ce3Schristos {
154866e63ce3Schristos   unsigned int op0, op1, op2;
154966e63ce3Schristos   int temp;
155066e63ce3Schristos 
155166e63ce3Schristos   trace_input ("tst1", OP_BIT, 0);
155266e63ce3Schristos   op0 = State.regs[ OP[0] ];
155366e63ce3Schristos   op1 = OP[1] & 0x7;
155466e63ce3Schristos   temp = EXTEND16 (OP[2]);
155566e63ce3Schristos   op2 = temp;
155666e63ce3Schristos   temp = load_mem (op0 + op2, 1);
155766e63ce3Schristos   PSW &= ~PSW_Z;
155866e63ce3Schristos   if ((temp & (1 << op1)) == 0)
155966e63ce3Schristos     PSW |= PSW_Z;
156066e63ce3Schristos   trace_output (OP_BIT);
156166e63ce3Schristos 
156266e63ce3Schristos   return 4;
156366e63ce3Schristos }
156466e63ce3Schristos 
156566e63ce3Schristos /* di */
156666e63ce3Schristos int
OP_16007E0(void)1567ed6a76a9Schristos OP_16007E0 (void)
156866e63ce3Schristos {
156966e63ce3Schristos   trace_input ("di", OP_NONE, 0);
157066e63ce3Schristos   PSW |= PSW_ID;
157166e63ce3Schristos   trace_output (OP_NONE);
157266e63ce3Schristos 
157366e63ce3Schristos   return 4;
157466e63ce3Schristos }
157566e63ce3Schristos 
157666e63ce3Schristos /* ei */
157766e63ce3Schristos int
OP_16087E0(void)1578ed6a76a9Schristos OP_16087E0 (void)
157966e63ce3Schristos {
158066e63ce3Schristos   trace_input ("ei", OP_NONE, 0);
158166e63ce3Schristos   PSW &= ~PSW_ID;
158266e63ce3Schristos   trace_output (OP_NONE);
158366e63ce3Schristos 
158466e63ce3Schristos   return 4;
158566e63ce3Schristos }
158666e63ce3Schristos 
158766e63ce3Schristos /* halt */
158866e63ce3Schristos int
OP_12007E0(void)1589ed6a76a9Schristos OP_12007E0 (void)
159066e63ce3Schristos {
159166e63ce3Schristos   trace_input ("halt", OP_NONE, 0);
159266e63ce3Schristos   /* FIXME this should put processor into a mode where NMI still handled */
159366e63ce3Schristos   trace_output (OP_NONE);
159466e63ce3Schristos   sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
159566e63ce3Schristos 		   sim_stopped, SIM_SIGTRAP);
159666e63ce3Schristos   return 0;
159766e63ce3Schristos }
159866e63ce3Schristos 
159966e63ce3Schristos /* trap */
160066e63ce3Schristos int
OP_10007E0(void)1601ed6a76a9Schristos OP_10007E0 (void)
160266e63ce3Schristos {
160366e63ce3Schristos   trace_input ("trap", OP_TRAP, 0);
160466e63ce3Schristos   trace_output (OP_TRAP);
160566e63ce3Schristos 
160666e63ce3Schristos   /* Trap 31 is used for simulating OS I/O functions */
160766e63ce3Schristos 
160866e63ce3Schristos   if (OP[0] == 31)
160966e63ce3Schristos     {
161066e63ce3Schristos       int save_errno = errno;
161166e63ce3Schristos       errno = 0;
161266e63ce3Schristos 
161366e63ce3Schristos /* Registers passed to trap 0 */
161466e63ce3Schristos 
161566e63ce3Schristos #define FUNC   State.regs[6]	/* function number, return value */
161666e63ce3Schristos #define PARM1  State.regs[7]	/* optional parm 1 */
161766e63ce3Schristos #define PARM2  State.regs[8]	/* optional parm 2 */
161866e63ce3Schristos #define PARM3  State.regs[9]	/* optional parm 3 */
161966e63ce3Schristos 
162066e63ce3Schristos /* Registers set by trap 0 */
162166e63ce3Schristos 
162266e63ce3Schristos #define RETVAL State.regs[10]	/* return value */
162366e63ce3Schristos #define RETERR State.regs[11]	/* return error code */
162466e63ce3Schristos 
162566e63ce3Schristos /* Turn a pointer in a register into a pointer into real memory. */
162666e63ce3Schristos 
162766e63ce3Schristos #define MEMPTR(x) (map (x))
162866e63ce3Schristos 
162966e63ce3Schristos       RETERR = 0;
163066e63ce3Schristos 
163166e63ce3Schristos       switch (FUNC)
163266e63ce3Schristos 	{
163366e63ce3Schristos 
163466e63ce3Schristos #ifdef HAVE_FORK
163566e63ce3Schristos #ifdef TARGET_SYS_fork
163666e63ce3Schristos 	case TARGET_SYS_fork:
163766e63ce3Schristos 	  RETVAL = fork ();
163866e63ce3Schristos 	  RETERR = errno;
163966e63ce3Schristos 	  break;
164066e63ce3Schristos #endif
164166e63ce3Schristos #endif
164266e63ce3Schristos 
164366e63ce3Schristos #ifdef HAVE_EXECVE
164466e63ce3Schristos #ifdef TARGET_SYS_execv
164566e63ce3Schristos 	case TARGET_SYS_execve:
164666e63ce3Schristos 	  {
164766e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
164866e63ce3Schristos 	    char **argv = fetch_argv (simulator, PARM2);
164966e63ce3Schristos 	    char **envp = fetch_argv (simulator, PARM3);
165066e63ce3Schristos 	    RETVAL = execve (path, argv, envp);
165166e63ce3Schristos 	    free (path);
165266e63ce3Schristos 	    freeargv (argv);
165366e63ce3Schristos 	    freeargv (envp);
165466e63ce3Schristos 	    RETERR = errno;
165566e63ce3Schristos 	    break;
165666e63ce3Schristos 	  }
165766e63ce3Schristos #endif
165866e63ce3Schristos #endif
165966e63ce3Schristos 
166066e63ce3Schristos #if HAVE_EXECV
166166e63ce3Schristos #ifdef TARGET_SYS_execv
166266e63ce3Schristos 	case TARGET_SYS_execv:
166366e63ce3Schristos 	  {
166466e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
166566e63ce3Schristos 	    char **argv = fetch_argv (simulator, PARM2);
166666e63ce3Schristos 	    RETVAL = execv (path, argv);
166766e63ce3Schristos 	    free (path);
166866e63ce3Schristos 	    freeargv (argv);
166966e63ce3Schristos 	    RETERR = errno;
167066e63ce3Schristos 	    break;
167166e63ce3Schristos 	  }
167266e63ce3Schristos #endif
167366e63ce3Schristos #endif
167466e63ce3Schristos 
167566e63ce3Schristos #if 0
167666e63ce3Schristos #ifdef TARGET_SYS_pipe
167766e63ce3Schristos 	case TARGET_SYS_pipe:
167866e63ce3Schristos 	  {
167966e63ce3Schristos 	    reg_t buf;
168066e63ce3Schristos 	    int host_fd[2];
168166e63ce3Schristos 
168266e63ce3Schristos 	    buf = PARM1;
168366e63ce3Schristos 	    RETVAL = pipe (host_fd);
168466e63ce3Schristos 	    SW (buf, host_fd[0]);
168566e63ce3Schristos 	    buf += sizeof (uint16);
168666e63ce3Schristos 	    SW (buf, host_fd[1]);
168766e63ce3Schristos 	    RETERR = errno;
168866e63ce3Schristos 	  }
168966e63ce3Schristos 	  break;
169066e63ce3Schristos #endif
169166e63ce3Schristos #endif
169266e63ce3Schristos 
169366e63ce3Schristos #if 0
169466e63ce3Schristos #ifdef TARGET_SYS_wait
169566e63ce3Schristos 	case TARGET_SYS_wait:
169666e63ce3Schristos 	  {
169766e63ce3Schristos 	    int status;
169866e63ce3Schristos 
169966e63ce3Schristos 	    RETVAL = wait (&status);
170066e63ce3Schristos 	    SW (PARM1, status);
170166e63ce3Schristos 	    RETERR = errno;
170266e63ce3Schristos 	  }
170366e63ce3Schristos 	  break;
170466e63ce3Schristos #endif
170566e63ce3Schristos #endif
170666e63ce3Schristos 
170766e63ce3Schristos #ifdef TARGET_SYS_read
170866e63ce3Schristos 	case TARGET_SYS_read:
170966e63ce3Schristos 	  {
171066e63ce3Schristos 	    char *buf = zalloc (PARM3);
171166e63ce3Schristos 	    RETVAL = sim_io_read (simulator, PARM1, buf, PARM3);
1712ed6a76a9Schristos 	    sim_write (simulator, PARM2, (unsigned char *) buf, PARM3);
171366e63ce3Schristos 	    free (buf);
171466e63ce3Schristos 	    if ((int) RETVAL < 0)
171566e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
171666e63ce3Schristos 	    break;
171766e63ce3Schristos 	  }
171866e63ce3Schristos #endif
171966e63ce3Schristos 
172066e63ce3Schristos #ifdef TARGET_SYS_write
172166e63ce3Schristos 	case TARGET_SYS_write:
172266e63ce3Schristos 	  {
172366e63ce3Schristos 	    char *buf = zalloc (PARM3);
1724ed6a76a9Schristos 	    sim_read (simulator, PARM2, (unsigned char *) buf, PARM3);
172566e63ce3Schristos 	    if (PARM1 == 1)
172666e63ce3Schristos 	      RETVAL = sim_io_write_stdout (simulator, buf, PARM3);
172766e63ce3Schristos 	    else
172866e63ce3Schristos 	      RETVAL = sim_io_write (simulator, PARM1, buf, PARM3);
172966e63ce3Schristos 	    free (buf);
173066e63ce3Schristos 	    if ((int) RETVAL < 0)
173166e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
173266e63ce3Schristos 	    break;
173366e63ce3Schristos 	  }
173466e63ce3Schristos #endif
173566e63ce3Schristos 
173666e63ce3Schristos #ifdef TARGET_SYS_lseek
173766e63ce3Schristos 	case TARGET_SYS_lseek:
173866e63ce3Schristos 	  RETVAL = sim_io_lseek (simulator, PARM1, PARM2, PARM3);
173966e63ce3Schristos 	  if ((int) RETVAL < 0)
174066e63ce3Schristos 	    RETERR = sim_io_get_errno (simulator);
174166e63ce3Schristos 	  break;
174266e63ce3Schristos #endif
174366e63ce3Schristos 
174466e63ce3Schristos #ifdef TARGET_SYS_close
174566e63ce3Schristos 	case TARGET_SYS_close:
174666e63ce3Schristos 	  RETVAL = sim_io_close (simulator, PARM1);
174766e63ce3Schristos 	  if ((int) RETVAL < 0)
174866e63ce3Schristos 	    RETERR = sim_io_get_errno (simulator);
174966e63ce3Schristos 	  break;
175066e63ce3Schristos #endif
175166e63ce3Schristos 
175266e63ce3Schristos #ifdef TARGET_SYS_open
175366e63ce3Schristos 	case TARGET_SYS_open:
175466e63ce3Schristos 	  {
175566e63ce3Schristos 	    char *buf = fetch_str (simulator, PARM1);
175666e63ce3Schristos 	    RETVAL = sim_io_open (simulator, buf, PARM2);
175766e63ce3Schristos 	    free (buf);
175866e63ce3Schristos 	    if ((int) RETVAL < 0)
175966e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
176066e63ce3Schristos 	    break;
176166e63ce3Schristos 	  }
176266e63ce3Schristos #endif
176366e63ce3Schristos 
176466e63ce3Schristos #ifdef TARGET_SYS_exit
176566e63ce3Schristos 	case TARGET_SYS_exit:
176666e63ce3Schristos 	  if ((PARM1 & 0xffff0000) == 0xdead0000 && (PARM1 & 0xffff) != 0)
176766e63ce3Schristos 	    /* get signal encoded by kill */
176866e63ce3Schristos 	    sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
176966e63ce3Schristos 			     sim_signalled, PARM1 & 0xffff);
177066e63ce3Schristos 	  else if (PARM1 == 0xdead)
177166e63ce3Schristos 	    /* old libraries */
177266e63ce3Schristos 	    sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
177366e63ce3Schristos 			     sim_stopped, SIM_SIGABRT);
177466e63ce3Schristos 	  else
177566e63ce3Schristos 	    /* PARM1 has exit status */
177666e63ce3Schristos 	    sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
177766e63ce3Schristos 			     sim_exited, PARM1);
177866e63ce3Schristos 	  break;
177966e63ce3Schristos #endif
178066e63ce3Schristos 
178166e63ce3Schristos #ifdef TARGET_SYS_stat
178266e63ce3Schristos 	case TARGET_SYS_stat:	/* added at hmsi */
178366e63ce3Schristos 	  /* stat system call */
178466e63ce3Schristos 	  {
178566e63ce3Schristos 	    struct stat host_stat;
178666e63ce3Schristos 	    reg_t buf;
178766e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
178866e63ce3Schristos 
178966e63ce3Schristos 	    RETVAL = sim_io_stat (simulator, path, &host_stat);
179066e63ce3Schristos 
179166e63ce3Schristos 	    free (path);
179266e63ce3Schristos 	    buf = PARM2;
179366e63ce3Schristos 
179466e63ce3Schristos 	    /* Just wild-assed guesses.  */
179566e63ce3Schristos 	    store_mem (buf, 2, host_stat.st_dev);
179666e63ce3Schristos 	    store_mem (buf + 2, 2, host_stat.st_ino);
179766e63ce3Schristos 	    store_mem (buf + 4, 4, host_stat.st_mode);
179866e63ce3Schristos 	    store_mem (buf + 8, 2, host_stat.st_nlink);
179966e63ce3Schristos 	    store_mem (buf + 10, 2, host_stat.st_uid);
180066e63ce3Schristos 	    store_mem (buf + 12, 2, host_stat.st_gid);
180166e63ce3Schristos 	    store_mem (buf + 14, 2, host_stat.st_rdev);
180266e63ce3Schristos 	    store_mem (buf + 16, 4, host_stat.st_size);
180366e63ce3Schristos 	    store_mem (buf + 20, 4, host_stat.st_atime);
180466e63ce3Schristos 	    store_mem (buf + 28, 4, host_stat.st_mtime);
180566e63ce3Schristos 	    store_mem (buf + 36, 4, host_stat.st_ctime);
180666e63ce3Schristos 
180766e63ce3Schristos 	    if ((int) RETVAL < 0)
180866e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
180966e63ce3Schristos 	  }
181066e63ce3Schristos 	  break;
181166e63ce3Schristos #endif
181266e63ce3Schristos 
181366e63ce3Schristos #ifdef TARGET_SYS_fstat
181466e63ce3Schristos 	case TARGET_SYS_fstat:
181566e63ce3Schristos 	  /* fstat system call */
181666e63ce3Schristos 	  {
181766e63ce3Schristos 	    struct stat host_stat;
181866e63ce3Schristos 	    reg_t buf;
181966e63ce3Schristos 
182066e63ce3Schristos 	    RETVAL = sim_io_fstat (simulator, PARM1, &host_stat);
182166e63ce3Schristos 
182266e63ce3Schristos 	    buf = PARM2;
182366e63ce3Schristos 
182466e63ce3Schristos 	    /* Just wild-assed guesses.  */
182566e63ce3Schristos 	    store_mem (buf, 2, host_stat.st_dev);
182666e63ce3Schristos 	    store_mem (buf + 2, 2, host_stat.st_ino);
182766e63ce3Schristos 	    store_mem (buf + 4, 4, host_stat.st_mode);
182866e63ce3Schristos 	    store_mem (buf + 8, 2, host_stat.st_nlink);
182966e63ce3Schristos 	    store_mem (buf + 10, 2, host_stat.st_uid);
183066e63ce3Schristos 	    store_mem (buf + 12, 2, host_stat.st_gid);
183166e63ce3Schristos 	    store_mem (buf + 14, 2, host_stat.st_rdev);
183266e63ce3Schristos 	    store_mem (buf + 16, 4, host_stat.st_size);
183366e63ce3Schristos 	    store_mem (buf + 20, 4, host_stat.st_atime);
183466e63ce3Schristos 	    store_mem (buf + 28, 4, host_stat.st_mtime);
183566e63ce3Schristos 	    store_mem (buf + 36, 4, host_stat.st_ctime);
183666e63ce3Schristos 
183766e63ce3Schristos 	    if ((int) RETVAL < 0)
183866e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
183966e63ce3Schristos 	  }
184066e63ce3Schristos 	  break;
184166e63ce3Schristos #endif
184266e63ce3Schristos 
184366e63ce3Schristos #ifdef TARGET_SYS_rename
184466e63ce3Schristos 	case TARGET_SYS_rename:
184566e63ce3Schristos 	  {
184666e63ce3Schristos 	    char *oldpath = fetch_str (simulator, PARM1);
184766e63ce3Schristos 	    char *newpath = fetch_str (simulator, PARM2);
184866e63ce3Schristos 	    RETVAL = sim_io_rename (simulator, oldpath, newpath);
184966e63ce3Schristos 	    free (oldpath);
185066e63ce3Schristos 	    free (newpath);
185166e63ce3Schristos 	    if ((int) RETVAL < 0)
185266e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
185366e63ce3Schristos 	  }
185466e63ce3Schristos 	  break;
185566e63ce3Schristos #endif
185666e63ce3Schristos 
185766e63ce3Schristos #ifdef TARGET_SYS_unlink
185866e63ce3Schristos 	case TARGET_SYS_unlink:
185966e63ce3Schristos 	  {
186066e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
186166e63ce3Schristos 	    RETVAL = sim_io_unlink (simulator, path);
186266e63ce3Schristos 	    free (path);
186366e63ce3Schristos 	    if ((int) RETVAL < 0)
186466e63ce3Schristos 	      RETERR = sim_io_get_errno (simulator);
186566e63ce3Schristos 	  }
186666e63ce3Schristos 	  break;
186766e63ce3Schristos #endif
186866e63ce3Schristos 
186966e63ce3Schristos #ifdef HAVE_CHOWN
187066e63ce3Schristos #ifdef TARGET_SYS_chown
187166e63ce3Schristos 	case TARGET_SYS_chown:
187266e63ce3Schristos 	  {
187366e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
187466e63ce3Schristos 	    RETVAL = chown (path, PARM2, PARM3);
187566e63ce3Schristos 	    free (path);
187666e63ce3Schristos 	    RETERR = errno;
187766e63ce3Schristos 	  }
187866e63ce3Schristos 	  break;
187966e63ce3Schristos #endif
188066e63ce3Schristos #endif
188166e63ce3Schristos 
188266e63ce3Schristos #if HAVE_CHMOD
188366e63ce3Schristos #ifdef TARGET_SYS_chmod
188466e63ce3Schristos 	case TARGET_SYS_chmod:
188566e63ce3Schristos 	  {
188666e63ce3Schristos 	    char *path = fetch_str (simulator, PARM1);
188766e63ce3Schristos 	    RETVAL = chmod (path, PARM2);
188866e63ce3Schristos 	    free (path);
188966e63ce3Schristos 	    RETERR = errno;
189066e63ce3Schristos 	  }
189166e63ce3Schristos 	  break;
189266e63ce3Schristos #endif
189366e63ce3Schristos #endif
189466e63ce3Schristos 
189566e63ce3Schristos #ifdef TARGET_SYS_time
189666e63ce3Schristos #if HAVE_TIME
189766e63ce3Schristos 	case TARGET_SYS_time:
189866e63ce3Schristos 	  {
189966e63ce3Schristos 	    time_t now;
190066e63ce3Schristos 	    RETVAL = time (&now);
190166e63ce3Schristos 	    store_mem (PARM1, 4, now);
190266e63ce3Schristos 	    RETERR = errno;
190366e63ce3Schristos 	  }
190466e63ce3Schristos 	  break;
190566e63ce3Schristos #endif
190666e63ce3Schristos #endif
190766e63ce3Schristos 
190866e63ce3Schristos #if !defined(__GO32__) && !defined(_WIN32)
190966e63ce3Schristos #ifdef TARGET_SYS_times
191066e63ce3Schristos 	case TARGET_SYS_times:
191166e63ce3Schristos 	  {
191266e63ce3Schristos 	    struct tms tms;
191366e63ce3Schristos 	    RETVAL = times (&tms);
191466e63ce3Schristos 	    store_mem (PARM1, 4, tms.tms_utime);
191566e63ce3Schristos 	    store_mem (PARM1 + 4, 4, tms.tms_stime);
191666e63ce3Schristos 	    store_mem (PARM1 + 8, 4, tms.tms_cutime);
191766e63ce3Schristos 	    store_mem (PARM1 + 12, 4, tms.tms_cstime);
191866e63ce3Schristos 	    reterr = errno;
191966e63ce3Schristos 	    break;
192066e63ce3Schristos 	  }
192166e63ce3Schristos #endif
192266e63ce3Schristos #endif
192366e63ce3Schristos 
192466e63ce3Schristos #ifdef TARGET_SYS_gettimeofday
192566e63ce3Schristos #if !defined(__GO32__) && !defined(_WIN32)
192666e63ce3Schristos 	case TARGET_SYS_gettimeofday:
192766e63ce3Schristos 	  {
192866e63ce3Schristos 	    struct timeval t;
192966e63ce3Schristos 	    struct timezone tz;
193066e63ce3Schristos 	    RETVAL = gettimeofday (&t, &tz);
193166e63ce3Schristos 	    store_mem (PARM1, 4, t.tv_sec);
193266e63ce3Schristos 	    store_mem (PARM1 + 4, 4, t.tv_usec);
193366e63ce3Schristos 	    store_mem (PARM2, 4, tz.tz_minuteswest);
193466e63ce3Schristos 	    store_mem (PARM2 + 4, 4, tz.tz_dsttime);
193566e63ce3Schristos 	    RETERR = errno;
193666e63ce3Schristos 	    break;
193766e63ce3Schristos 	  }
193866e63ce3Schristos #endif
193966e63ce3Schristos #endif
194066e63ce3Schristos 
194166e63ce3Schristos #ifdef TARGET_SYS_utime
194266e63ce3Schristos #if HAVE_UTIME
194366e63ce3Schristos 	case TARGET_SYS_utime:
194466e63ce3Schristos 	  {
194566e63ce3Schristos 	    /* Cast the second argument to void *, to avoid type mismatch
194666e63ce3Schristos 	       if a prototype is present.  */
194766e63ce3Schristos 	    sim_io_error (simulator, "Utime not supported");
194866e63ce3Schristos 	    /* RETVAL = utime (path, (void *) MEMPTR (PARM2)); */
194966e63ce3Schristos 	  }
195066e63ce3Schristos 	  break;
195166e63ce3Schristos #endif
195266e63ce3Schristos #endif
195366e63ce3Schristos 
195466e63ce3Schristos 	default:
195566e63ce3Schristos 	  abort ();
195666e63ce3Schristos 	}
195766e63ce3Schristos       errno = save_errno;
195866e63ce3Schristos 
195966e63ce3Schristos       return 4;
196066e63ce3Schristos     }
196166e63ce3Schristos   else
196266e63ce3Schristos     {				/* Trap 0 -> 30 */
196366e63ce3Schristos       EIPC = PC + 4;
196466e63ce3Schristos       EIPSW = PSW;
196566e63ce3Schristos       /* Mask out EICC */
196666e63ce3Schristos       ECR &= 0xffff0000;
196766e63ce3Schristos       ECR |= 0x40 + OP[0];
196866e63ce3Schristos       /* Flag that we are now doing exception processing.  */
196966e63ce3Schristos       PSW |= PSW_EP | PSW_ID;
197066e63ce3Schristos       PC = (OP[0] < 0x10) ? 0x40 : 0x50;
197166e63ce3Schristos 
197266e63ce3Schristos       return 0;
197366e63ce3Schristos     }
197466e63ce3Schristos }
197566e63ce3Schristos 
197666e63ce3Schristos /* tst1 reg2, [reg1] */
197766e63ce3Schristos int
OP_E607E0(void)197866e63ce3Schristos OP_E607E0 (void)
197966e63ce3Schristos {
198066e63ce3Schristos   int temp;
198166e63ce3Schristos 
198266e63ce3Schristos   trace_input ("tst1", OP_BIT, 1);
198366e63ce3Schristos 
198466e63ce3Schristos   temp = load_mem (State.regs[ OP[0] ], 1);
198566e63ce3Schristos 
198666e63ce3Schristos   PSW &= ~PSW_Z;
198766e63ce3Schristos   if ((temp & (1 << (State.regs[ OP[1] ] & 0x7))) == 0)
198866e63ce3Schristos     PSW |= PSW_Z;
198966e63ce3Schristos 
199066e63ce3Schristos   trace_output (OP_BIT);
199166e63ce3Schristos 
199266e63ce3Schristos   return 4;
199366e63ce3Schristos }
199466e63ce3Schristos 
199566e63ce3Schristos /* mulu reg1, reg2, reg3 */
199666e63ce3Schristos int
OP_22207E0(void)199766e63ce3Schristos OP_22207E0 (void)
199866e63ce3Schristos {
199966e63ce3Schristos   trace_input ("mulu", OP_REG_REG_REG, 0);
200066e63ce3Schristos 
200166e63ce3Schristos   Multiply64 (0, State.regs[ OP[0] ]);
200266e63ce3Schristos 
200366e63ce3Schristos   trace_output (OP_REG_REG_REG);
200466e63ce3Schristos 
200566e63ce3Schristos   return 4;
200666e63ce3Schristos }
200766e63ce3Schristos 
200866e63ce3Schristos #define BIT_CHANGE_OP( name, binop )		\
200966e63ce3Schristos   unsigned int bit;				\
201066e63ce3Schristos   unsigned int temp;				\
201166e63ce3Schristos   						\
201266e63ce3Schristos   trace_input (name, OP_BIT_CHANGE, 0);		\
201366e63ce3Schristos   						\
201466e63ce3Schristos   bit  = 1 << (State.regs[ OP[1] ] & 0x7);	\
201566e63ce3Schristos   temp = load_mem (State.regs[ OP[0] ], 1);	\
201666e63ce3Schristos 						\
201766e63ce3Schristos   PSW &= ~PSW_Z;				\
201866e63ce3Schristos   if ((temp & bit) == 0)			\
201966e63ce3Schristos     PSW |= PSW_Z;				\
202066e63ce3Schristos   temp binop bit;				\
202166e63ce3Schristos   						\
202266e63ce3Schristos   store_mem (State.regs[ OP[0] ], 1, temp);	\
202366e63ce3Schristos 	     					\
202466e63ce3Schristos   trace_output (OP_BIT_CHANGE);			\
202566e63ce3Schristos 	     					\
202666e63ce3Schristos   return 4;
202766e63ce3Schristos 
202866e63ce3Schristos /* clr1 reg2, [reg1] */
202966e63ce3Schristos int
OP_E407E0(void)203066e63ce3Schristos OP_E407E0 (void)
203166e63ce3Schristos {
203266e63ce3Schristos   BIT_CHANGE_OP ("clr1", &= ~ );
203366e63ce3Schristos }
203466e63ce3Schristos 
203566e63ce3Schristos /* not1 reg2, [reg1] */
203666e63ce3Schristos int
OP_E207E0(void)203766e63ce3Schristos OP_E207E0 (void)
203866e63ce3Schristos {
203966e63ce3Schristos   BIT_CHANGE_OP ("not1", ^= );
204066e63ce3Schristos }
204166e63ce3Schristos 
204266e63ce3Schristos /* set1 */
204366e63ce3Schristos int
OP_E007E0(void)204466e63ce3Schristos OP_E007E0 (void)
204566e63ce3Schristos {
204666e63ce3Schristos   BIT_CHANGE_OP ("set1", |= );
204766e63ce3Schristos }
204866e63ce3Schristos 
204966e63ce3Schristos /* sasf */
205066e63ce3Schristos int
OP_20007E0(void)205166e63ce3Schristos OP_20007E0 (void)
205266e63ce3Schristos {
205366e63ce3Schristos   trace_input ("sasf", OP_EX1, 0);
205466e63ce3Schristos 
205566e63ce3Schristos   State.regs[ OP[1] ] = (State.regs[ OP[1] ] << 1) | condition_met (OP[0]);
205666e63ce3Schristos 
205766e63ce3Schristos   trace_output (OP_EX1);
205866e63ce3Schristos 
205966e63ce3Schristos   return 4;
206066e63ce3Schristos }
206166e63ce3Schristos 
206266e63ce3Schristos /* This function is courtesy of Sugimoto at NEC, via Seow Tan
206366e63ce3Schristos    (Soew_Tan@el.nec.com) */
206466e63ce3Schristos void
divun(unsigned int N,unsigned long int als,unsigned long int sfi,unsigned32 * quotient_ptr,unsigned32 * remainder_ptr,int * overflow_ptr)206566e63ce3Schristos divun
206666e63ce3Schristos (
206766e63ce3Schristos   unsigned int       N,
206866e63ce3Schristos   unsigned long int  als,
206966e63ce3Schristos   unsigned long int  sfi,
207066e63ce3Schristos   unsigned32 /*unsigned long int*/ *  quotient_ptr,
207166e63ce3Schristos   unsigned32 /*unsigned long int*/ *  remainder_ptr,
207266e63ce3Schristos   int *          overflow_ptr
207366e63ce3Schristos )
207466e63ce3Schristos {
207566e63ce3Schristos   unsigned long   ald = sfi >> (N - 1);
207666e63ce3Schristos   unsigned long   alo = als;
207766e63ce3Schristos   unsigned int    Q   = 1;
207866e63ce3Schristos   unsigned int    C;
207966e63ce3Schristos   unsigned int    S   = 0;
208066e63ce3Schristos   unsigned int    i;
208166e63ce3Schristos   unsigned int    R1  = 1;
208266e63ce3Schristos   unsigned int    DBZ = (als == 0) ? 1 : 0;
208366e63ce3Schristos   unsigned long   alt = Q ? ~als : als;
208466e63ce3Schristos 
208566e63ce3Schristos   /* 1st Loop */
208666e63ce3Schristos   alo = ald + alt + Q;
208766e63ce3Schristos   C   = (((alt >> 31) & (ald >> 31))
208866e63ce3Schristos 	 | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
208966e63ce3Schristos   C   = C ^ Q;
209066e63ce3Schristos   Q   = ~(C ^ S) & 1;
209166e63ce3Schristos   R1  = (alo == 0) ? 0 : (R1 & Q);
209266e63ce3Schristos   if ((S ^ (alo>>31)) && !C)
209366e63ce3Schristos     {
209466e63ce3Schristos       DBZ = 1;
209566e63ce3Schristos     }
209666e63ce3Schristos   S   = alo >> 31;
209766e63ce3Schristos   sfi = (sfi << (32-N+1)) | Q;
209866e63ce3Schristos   ald = (alo << 1) | (sfi >> 31);
209966e63ce3Schristos 
210066e63ce3Schristos   /* 2nd - N-1th Loop */
210166e63ce3Schristos   for (i = 2; i < N; i++)
210266e63ce3Schristos     {
210366e63ce3Schristos       alt = Q ? ~als : als;
210466e63ce3Schristos       alo = ald + alt + Q;
210566e63ce3Schristos       C   = (((alt >> 31) & (ald >> 31))
210666e63ce3Schristos 	     | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
210766e63ce3Schristos       C   = C ^ Q;
210866e63ce3Schristos       Q   = ~(C ^ S) & 1;
210966e63ce3Schristos       R1  = (alo == 0) ? 0 : (R1 & Q);
211066e63ce3Schristos       if ((S ^ (alo>>31)) && !C && !DBZ)
211166e63ce3Schristos 	{
211266e63ce3Schristos 	  DBZ = 1;
211366e63ce3Schristos 	}
211466e63ce3Schristos       S   = alo >> 31;
211566e63ce3Schristos       sfi = (sfi << 1) | Q;
211666e63ce3Schristos       ald = (alo << 1) | (sfi >> 31);
211766e63ce3Schristos     }
211866e63ce3Schristos 
211966e63ce3Schristos   /* Nth Loop */
212066e63ce3Schristos   alt = Q ? ~als : als;
212166e63ce3Schristos   alo = ald + alt + Q;
212266e63ce3Schristos   C   = (((alt >> 31) & (ald >> 31))
212366e63ce3Schristos 	 | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
212466e63ce3Schristos   C   = C ^ Q;
212566e63ce3Schristos   Q   = ~(C ^ S) & 1;
212666e63ce3Schristos   R1  = (alo == 0) ? 0 : (R1 & Q);
212766e63ce3Schristos   if ((S ^ (alo>>31)) && !C)
212866e63ce3Schristos     {
212966e63ce3Schristos       DBZ = 1;
213066e63ce3Schristos     }
213166e63ce3Schristos 
213266e63ce3Schristos   * quotient_ptr  = (sfi << 1) | Q;
213366e63ce3Schristos   * remainder_ptr = Q ? alo : (alo + als);
213466e63ce3Schristos   * overflow_ptr  = DBZ | R1;
213566e63ce3Schristos }
213666e63ce3Schristos 
213766e63ce3Schristos /* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
213866e63ce3Schristos void
divn(unsigned int N,unsigned long int als,unsigned long int sfi,signed32 * quotient_ptr,signed32 * remainder_ptr,int * overflow_ptr)213966e63ce3Schristos divn
214066e63ce3Schristos (
214166e63ce3Schristos   unsigned int       N,
214266e63ce3Schristos   unsigned long int  als,
214366e63ce3Schristos   unsigned long int  sfi,
214466e63ce3Schristos   signed32 /*signed long int*/ *  quotient_ptr,
214566e63ce3Schristos   signed32 /*signed long int*/ *  remainder_ptr,
214666e63ce3Schristos   int *          overflow_ptr
214766e63ce3Schristos )
214866e63ce3Schristos {
214966e63ce3Schristos   unsigned long	  ald = (signed long) sfi >> (N - 1);
215066e63ce3Schristos   unsigned long   alo = als;
215166e63ce3Schristos   unsigned int    SS  = als >> 31;
215266e63ce3Schristos   unsigned int	  SD  = sfi >> 31;
215366e63ce3Schristos   unsigned int    R1  = 1;
215466e63ce3Schristos   unsigned int    OV;
215566e63ce3Schristos   unsigned int    DBZ = als == 0 ? 1 : 0;
215666e63ce3Schristos   unsigned int    Q   = ~(SS ^ SD) & 1;
215766e63ce3Schristos   unsigned int    C;
215866e63ce3Schristos   unsigned int    S;
215966e63ce3Schristos   unsigned int    i;
216066e63ce3Schristos   unsigned long   alt = Q ? ~als : als;
216166e63ce3Schristos 
216266e63ce3Schristos 
216366e63ce3Schristos   /* 1st Loop */
216466e63ce3Schristos 
216566e63ce3Schristos   alo = ald + alt + Q;
216666e63ce3Schristos   C   = (((alt >> 31) & (ald >> 31))
216766e63ce3Schristos 	 | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
216866e63ce3Schristos   Q   = C ^ SS;
216966e63ce3Schristos   R1  = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
217066e63ce3Schristos   S   = alo >> 31;
217166e63ce3Schristos   sfi = (sfi << (32-N+1)) | Q;
217266e63ce3Schristos   ald = (alo << 1) | (sfi >> 31);
217366e63ce3Schristos   if ((alo >> 31) ^ (ald >> 31))
217466e63ce3Schristos     {
217566e63ce3Schristos       DBZ = 1;
217666e63ce3Schristos     }
217766e63ce3Schristos 
217866e63ce3Schristos   /* 2nd - N-1th Loop */
217966e63ce3Schristos 
218066e63ce3Schristos   for (i = 2; i < N; i++)
218166e63ce3Schristos     {
218266e63ce3Schristos       alt = Q ? ~als : als;
218366e63ce3Schristos       alo = ald + alt + Q;
218466e63ce3Schristos       C   = (((alt >> 31) & (ald >> 31))
218566e63ce3Schristos 	     | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
218666e63ce3Schristos       Q   = C ^ SS;
218766e63ce3Schristos       R1  = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
218866e63ce3Schristos       S   = alo >> 31;
218966e63ce3Schristos       sfi = (sfi << 1) | Q;
219066e63ce3Schristos       ald = (alo << 1) | (sfi >> 31);
219166e63ce3Schristos       if ((alo >> 31) ^ (ald >> 31))
219266e63ce3Schristos 	{
219366e63ce3Schristos 	  DBZ = 1;
219466e63ce3Schristos 	}
219566e63ce3Schristos     }
219666e63ce3Schristos 
219766e63ce3Schristos   /* Nth Loop */
219866e63ce3Schristos   alt = Q ? ~als : als;
219966e63ce3Schristos   alo = ald + alt + Q;
220066e63ce3Schristos   C   = (((alt >> 31) & (ald >> 31))
220166e63ce3Schristos 	 | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
220266e63ce3Schristos   Q   = C ^ SS;
220366e63ce3Schristos   R1  = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
220466e63ce3Schristos   sfi = (sfi << (32-N+1));
220566e63ce3Schristos   ald = alo;
220666e63ce3Schristos 
220766e63ce3Schristos   /* End */
220866e63ce3Schristos   if (alo != 0)
220966e63ce3Schristos     {
221066e63ce3Schristos       alt = Q ? ~als : als;
221166e63ce3Schristos       alo = ald + alt + Q;
221266e63ce3Schristos     }
221366e63ce3Schristos   R1  = R1 & ((~alo >> 31) ^ SD);
221466e63ce3Schristos   if ((alo != 0) && ((Q ^ (SS ^ SD)) ^ R1)) alo = ald;
221566e63ce3Schristos   if (N != 32)
221666e63ce3Schristos     ald = sfi = (long) ((sfi >> 1) | (SS ^ SD) << 31) >> (32-N-1) | Q;
221766e63ce3Schristos   else
221866e63ce3Schristos     ald = sfi = sfi | Q;
221966e63ce3Schristos 
222066e63ce3Schristos   OV = DBZ | ((alo == 0) ? 0 : R1);
222166e63ce3Schristos 
222266e63ce3Schristos   * remainder_ptr = alo;
222366e63ce3Schristos 
222466e63ce3Schristos   /* Adj */
222566e63ce3Schristos   if (((alo != 0) && ((SS ^ SD) ^ R1))
222666e63ce3Schristos       || ((alo == 0) && (SS ^ R1)))
222766e63ce3Schristos     alo = ald + 1;
222866e63ce3Schristos   else
222966e63ce3Schristos     alo = ald;
223066e63ce3Schristos 
223166e63ce3Schristos   OV  = (DBZ | R1) ? OV : ((alo >> 31) & (~ald >> 31));
223266e63ce3Schristos 
223366e63ce3Schristos   * quotient_ptr  = alo;
223466e63ce3Schristos   * overflow_ptr  = OV;
223566e63ce3Schristos }
223666e63ce3Schristos 
223766e63ce3Schristos /* sdivun imm5, reg1, reg2, reg3 */
223866e63ce3Schristos int
OP_1C207E0(void)223966e63ce3Schristos OP_1C207E0 (void)
224066e63ce3Schristos {
224166e63ce3Schristos   unsigned32 /*unsigned long int*/  quotient;
224266e63ce3Schristos   unsigned32 /*unsigned long int*/  remainder;
224366e63ce3Schristos   unsigned long int  divide_by;
224466e63ce3Schristos   unsigned long int  divide_this;
224566e63ce3Schristos   int            overflow = 0;
224666e63ce3Schristos   unsigned int       imm5;
224766e63ce3Schristos 
224866e63ce3Schristos   trace_input ("sdivun", OP_IMM_REG_REG_REG, 0);
224966e63ce3Schristos 
225066e63ce3Schristos   imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
225166e63ce3Schristos 
225266e63ce3Schristos   divide_by   = State.regs[ OP[0] ];
225366e63ce3Schristos   divide_this = State.regs[ OP[1] ] << imm5;
225466e63ce3Schristos 
225566e63ce3Schristos   divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
225666e63ce3Schristos 
225766e63ce3Schristos   State.regs[ OP[1]       ] = quotient;
225866e63ce3Schristos   State.regs[ OP[2] >> 11 ] = remainder;
225966e63ce3Schristos 
226066e63ce3Schristos   /* Set condition codes.  */
226166e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
226266e63ce3Schristos 
226366e63ce3Schristos   if (overflow)      PSW |= PSW_OV;
226466e63ce3Schristos   if (quotient == 0) PSW |= PSW_Z;
226566e63ce3Schristos   if (quotient & 0x80000000) PSW |= PSW_S;
226666e63ce3Schristos 
226766e63ce3Schristos   trace_output (OP_IMM_REG_REG_REG);
226866e63ce3Schristos 
226966e63ce3Schristos   return 4;
227066e63ce3Schristos }
227166e63ce3Schristos 
227266e63ce3Schristos /* sdivn imm5, reg1, reg2, reg3 */
227366e63ce3Schristos int
OP_1C007E0(void)227466e63ce3Schristos OP_1C007E0 (void)
227566e63ce3Schristos {
227666e63ce3Schristos   signed32 /*signed long int*/  quotient;
227766e63ce3Schristos   signed32 /*signed long int*/  remainder;
227866e63ce3Schristos   signed long int  divide_by;
227966e63ce3Schristos   signed long int  divide_this;
228066e63ce3Schristos   int          overflow = 0;
228166e63ce3Schristos   unsigned int     imm5;
228266e63ce3Schristos 
228366e63ce3Schristos   trace_input ("sdivn", OP_IMM_REG_REG_REG, 0);
228466e63ce3Schristos 
228566e63ce3Schristos   imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
228666e63ce3Schristos 
228766e63ce3Schristos   divide_by   = (signed32) State.regs[ OP[0] ];
228866e63ce3Schristos   divide_this = (signed32) (State.regs[ OP[1] ] << imm5);
228966e63ce3Schristos 
229066e63ce3Schristos   divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
229166e63ce3Schristos 
229266e63ce3Schristos   State.regs[ OP[1]       ] = quotient;
229366e63ce3Schristos   State.regs[ OP[2] >> 11 ] = remainder;
229466e63ce3Schristos 
229566e63ce3Schristos   /* Set condition codes.  */
229666e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
229766e63ce3Schristos 
229866e63ce3Schristos   if (overflow)      PSW |= PSW_OV;
229966e63ce3Schristos   if (quotient == 0) PSW |= PSW_Z;
230066e63ce3Schristos   if (quotient <  0) PSW |= PSW_S;
230166e63ce3Schristos 
230266e63ce3Schristos   trace_output (OP_IMM_REG_REG_REG);
230366e63ce3Schristos 
230466e63ce3Schristos   return 4;
230566e63ce3Schristos }
230666e63ce3Schristos 
230766e63ce3Schristos /* sdivhun imm5, reg1, reg2, reg3 */
230866e63ce3Schristos int
OP_18207E0(void)230966e63ce3Schristos OP_18207E0 (void)
231066e63ce3Schristos {
231166e63ce3Schristos   unsigned32 /*unsigned long int*/  quotient;
231266e63ce3Schristos   unsigned32 /*unsigned long int*/  remainder;
231366e63ce3Schristos   unsigned long int  divide_by;
231466e63ce3Schristos   unsigned long int  divide_this;
231566e63ce3Schristos   int            overflow = 0;
231666e63ce3Schristos   unsigned int       imm5;
231766e63ce3Schristos 
231866e63ce3Schristos   trace_input ("sdivhun", OP_IMM_REG_REG_REG, 0);
231966e63ce3Schristos 
232066e63ce3Schristos   imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
232166e63ce3Schristos 
232266e63ce3Schristos   divide_by   = State.regs[ OP[0] ] & 0xffff;
232366e63ce3Schristos   divide_this = State.regs[ OP[1] ] << imm5;
232466e63ce3Schristos 
232566e63ce3Schristos   divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
232666e63ce3Schristos 
232766e63ce3Schristos   State.regs[ OP[1]       ] = quotient;
232866e63ce3Schristos   State.regs[ OP[2] >> 11 ] = remainder;
232966e63ce3Schristos 
233066e63ce3Schristos   /* Set condition codes.  */
233166e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
233266e63ce3Schristos 
233366e63ce3Schristos   if (overflow)      PSW |= PSW_OV;
233466e63ce3Schristos   if (quotient == 0) PSW |= PSW_Z;
233566e63ce3Schristos   if (quotient & 0x80000000) PSW |= PSW_S;
233666e63ce3Schristos 
233766e63ce3Schristos   trace_output (OP_IMM_REG_REG_REG);
233866e63ce3Schristos 
233966e63ce3Schristos   return 4;
234066e63ce3Schristos }
234166e63ce3Schristos 
234266e63ce3Schristos /* sdivhn imm5, reg1, reg2, reg3 */
234366e63ce3Schristos int
OP_18007E0(void)234466e63ce3Schristos OP_18007E0 (void)
234566e63ce3Schristos {
234666e63ce3Schristos   signed32 /*signed long int*/  quotient;
234766e63ce3Schristos   signed32 /*signed long int*/  remainder;
234866e63ce3Schristos   signed long int  divide_by;
234966e63ce3Schristos   signed long int  divide_this;
235066e63ce3Schristos   int          overflow = 0;
235166e63ce3Schristos   unsigned int     imm5;
235266e63ce3Schristos 
235366e63ce3Schristos   trace_input ("sdivhn", OP_IMM_REG_REG_REG, 0);
235466e63ce3Schristos 
235566e63ce3Schristos   imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
235666e63ce3Schristos 
235766e63ce3Schristos   divide_by   = EXTEND16 (State.regs[ OP[0] ]);
235866e63ce3Schristos   divide_this = (signed32) (State.regs[ OP[1] ] << imm5);
235966e63ce3Schristos 
236066e63ce3Schristos   divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
236166e63ce3Schristos 
236266e63ce3Schristos   State.regs[ OP[1]       ] = quotient;
236366e63ce3Schristos   State.regs[ OP[2] >> 11 ] = remainder;
236466e63ce3Schristos 
236566e63ce3Schristos   /* Set condition codes.  */
236666e63ce3Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
236766e63ce3Schristos 
236866e63ce3Schristos   if (overflow)      PSW |= PSW_OV;
236966e63ce3Schristos   if (quotient == 0) PSW |= PSW_Z;
237066e63ce3Schristos   if (quotient <  0) PSW |= PSW_S;
237166e63ce3Schristos 
237266e63ce3Schristos   trace_output (OP_IMM_REG_REG_REG);
237366e63ce3Schristos 
237466e63ce3Schristos   return 4;
237566e63ce3Schristos }
237666e63ce3Schristos 
237766e63ce3Schristos /* divu  reg1, reg2, reg3 */
237866e63ce3Schristos int
OP_2C207E0(void)237966e63ce3Schristos OP_2C207E0 (void)
238066e63ce3Schristos {
238166e63ce3Schristos   unsigned long int quotient;
238266e63ce3Schristos   unsigned long int remainder;
238366e63ce3Schristos   unsigned long int divide_by;
238466e63ce3Schristos   unsigned long int divide_this;
238566e63ce3Schristos   int           overflow = 0;
238666e63ce3Schristos 
238766e63ce3Schristos   trace_input ("divu", OP_REG_REG_REG, 0);
238866e63ce3Schristos 
238966e63ce3Schristos   /* Compute the result.  */
239066e63ce3Schristos 
239166e63ce3Schristos   divide_by   = State.regs[ OP[0] ];
239266e63ce3Schristos   divide_this = State.regs[ OP[1] ];
239366e63ce3Schristos 
239466e63ce3Schristos   if (divide_by == 0)
239566e63ce3Schristos     {
239666e63ce3Schristos       PSW |= PSW_OV;
239766e63ce3Schristos     }
239866e63ce3Schristos   else
239966e63ce3Schristos     {
240066e63ce3Schristos       State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
240166e63ce3Schristos       State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
240266e63ce3Schristos 
240366e63ce3Schristos       /* Set condition codes.  */
240466e63ce3Schristos       PSW &= ~(PSW_Z | PSW_S | PSW_OV);
240566e63ce3Schristos 
240666e63ce3Schristos       if (overflow)      PSW |= PSW_OV;
240766e63ce3Schristos       if (quotient == 0) PSW |= PSW_Z;
240866e63ce3Schristos       if (quotient & 0x80000000) PSW |= PSW_S;
240966e63ce3Schristos     }
241066e63ce3Schristos 
241166e63ce3Schristos   trace_output (OP_REG_REG_REG);
241266e63ce3Schristos 
241366e63ce3Schristos   return 4;
241466e63ce3Schristos }
241566e63ce3Schristos 
241666e63ce3Schristos /* div  reg1, reg2, reg3 */
241766e63ce3Schristos int
OP_2C007E0(void)241866e63ce3Schristos OP_2C007E0 (void)
241966e63ce3Schristos {
242066e63ce3Schristos   signed long int quotient;
242166e63ce3Schristos   signed long int remainder;
242266e63ce3Schristos   signed long int divide_by;
242366e63ce3Schristos   signed long int divide_this;
242466e63ce3Schristos 
242566e63ce3Schristos   trace_input ("div", OP_REG_REG_REG, 0);
242666e63ce3Schristos 
242766e63ce3Schristos   /* Compute the result.  */
242866e63ce3Schristos 
242966e63ce3Schristos   divide_by   = (signed32) State.regs[ OP[0] ];
243066e63ce3Schristos   divide_this = State.regs[ OP[1] ];
243166e63ce3Schristos 
243266e63ce3Schristos   if (divide_by == 0)
243366e63ce3Schristos     {
243466e63ce3Schristos       PSW |= PSW_OV;
243566e63ce3Schristos     }
243666e63ce3Schristos   else if (divide_by == -1 && divide_this == (1L << 31))
243766e63ce3Schristos     {
243866e63ce3Schristos       PSW &= ~PSW_Z;
243966e63ce3Schristos       PSW |= PSW_OV | PSW_S;
244066e63ce3Schristos       State.regs[ OP[1] ] = (1 << 31);
244166e63ce3Schristos       State.regs[ OP[2] >> 11 ] = 0;
244266e63ce3Schristos     }
244366e63ce3Schristos   else
244466e63ce3Schristos     {
244566e63ce3Schristos       divide_this = (signed32) divide_this;
244666e63ce3Schristos       State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
244766e63ce3Schristos       State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
244866e63ce3Schristos 
244966e63ce3Schristos       /* Set condition codes.  */
245066e63ce3Schristos       PSW &= ~(PSW_Z | PSW_S | PSW_OV);
245166e63ce3Schristos 
245266e63ce3Schristos       if (quotient == 0) PSW |= PSW_Z;
245366e63ce3Schristos       if (quotient <  0) PSW |= PSW_S;
245466e63ce3Schristos     }
245566e63ce3Schristos 
245666e63ce3Schristos   trace_output (OP_REG_REG_REG);
245766e63ce3Schristos 
245866e63ce3Schristos   return 4;
245966e63ce3Schristos }
246066e63ce3Schristos 
246166e63ce3Schristos /* divhu  reg1, reg2, reg3 */
246266e63ce3Schristos int
OP_28207E0(void)246366e63ce3Schristos OP_28207E0 (void)
246466e63ce3Schristos {
246566e63ce3Schristos   unsigned long int quotient;
246666e63ce3Schristos   unsigned long int remainder;
246766e63ce3Schristos   unsigned long int divide_by;
246866e63ce3Schristos   unsigned long int divide_this;
246966e63ce3Schristos   int           overflow = 0;
247066e63ce3Schristos 
247166e63ce3Schristos   trace_input ("divhu", OP_REG_REG_REG, 0);
247266e63ce3Schristos 
247366e63ce3Schristos   /* Compute the result.  */
247466e63ce3Schristos 
247566e63ce3Schristos   divide_by   = State.regs[ OP[0] ] & 0xffff;
247666e63ce3Schristos   divide_this = State.regs[ OP[1] ];
247766e63ce3Schristos 
247866e63ce3Schristos   if (divide_by == 0)
247966e63ce3Schristos     {
248066e63ce3Schristos       PSW |= PSW_OV;
248166e63ce3Schristos     }
248266e63ce3Schristos   else
248366e63ce3Schristos     {
248466e63ce3Schristos       State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
248566e63ce3Schristos       State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
248666e63ce3Schristos 
248766e63ce3Schristos       /* Set condition codes.  */
248866e63ce3Schristos       PSW &= ~(PSW_Z | PSW_S | PSW_OV);
248966e63ce3Schristos 
249066e63ce3Schristos       if (overflow)      PSW |= PSW_OV;
249166e63ce3Schristos       if (quotient == 0) PSW |= PSW_Z;
249266e63ce3Schristos       if (quotient & 0x80000000) PSW |= PSW_S;
249366e63ce3Schristos     }
249466e63ce3Schristos 
249566e63ce3Schristos   trace_output (OP_REG_REG_REG);
249666e63ce3Schristos 
249766e63ce3Schristos   return 4;
249866e63ce3Schristos }
249966e63ce3Schristos 
250066e63ce3Schristos /* divh  reg1, reg2, reg3 */
250166e63ce3Schristos int
OP_28007E0(void)250266e63ce3Schristos OP_28007E0 (void)
250366e63ce3Schristos {
250466e63ce3Schristos   signed long int quotient;
250566e63ce3Schristos   signed long int remainder;
250666e63ce3Schristos   signed long int divide_by;
250766e63ce3Schristos   signed long int divide_this;
250866e63ce3Schristos   int         overflow = 0;
250966e63ce3Schristos 
251066e63ce3Schristos   trace_input ("divh", OP_REG_REG_REG, 0);
251166e63ce3Schristos 
251266e63ce3Schristos   /* Compute the result.  */
251366e63ce3Schristos 
251466e63ce3Schristos   divide_by  = EXTEND16 (State.regs[ OP[0] ]);
251566e63ce3Schristos   divide_this = State.regs[ OP[1] ];
251666e63ce3Schristos 
251766e63ce3Schristos   if (divide_by == 0)
251866e63ce3Schristos     {
251966e63ce3Schristos       PSW |= PSW_OV;
252066e63ce3Schristos     }
252166e63ce3Schristos   else if (divide_by == -1 && divide_this == (1L << 31))
252266e63ce3Schristos     {
252366e63ce3Schristos       PSW &= ~PSW_Z;
252466e63ce3Schristos       PSW |= PSW_OV | PSW_S;
252566e63ce3Schristos       State.regs[ OP[1] ] = (1 << 31);
252666e63ce3Schristos       State.regs[ OP[2] >> 11 ] = 0;
252766e63ce3Schristos     }
252866e63ce3Schristos   else
252966e63ce3Schristos     {
253066e63ce3Schristos       divide_this = (signed32) divide_this;
253166e63ce3Schristos       State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
253266e63ce3Schristos       State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
253366e63ce3Schristos 
253466e63ce3Schristos       /* Set condition codes.  */
253566e63ce3Schristos       PSW &= ~(PSW_Z | PSW_S | PSW_OV);
253666e63ce3Schristos 
253766e63ce3Schristos       if (quotient == 0) PSW |= PSW_Z;
253866e63ce3Schristos       if (quotient <  0) PSW |= PSW_S;
253966e63ce3Schristos     }
254066e63ce3Schristos 
254166e63ce3Schristos   trace_output (OP_REG_REG_REG);
254266e63ce3Schristos 
254366e63ce3Schristos   return 4;
254466e63ce3Schristos }
254566e63ce3Schristos 
254666e63ce3Schristos /* mulu imm9, reg2, reg3 */
254766e63ce3Schristos int
OP_24207E0(void)254866e63ce3Schristos OP_24207E0 (void)
254966e63ce3Schristos {
255066e63ce3Schristos   trace_input ("mulu", OP_IMM_REG_REG, 0);
255166e63ce3Schristos 
255266e63ce3Schristos   Multiply64 (0, (OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0));
255366e63ce3Schristos 
255466e63ce3Schristos   trace_output (OP_IMM_REG_REG);
255566e63ce3Schristos 
255666e63ce3Schristos   return 4;
255766e63ce3Schristos }
255866e63ce3Schristos 
255966e63ce3Schristos /* mul imm9, reg2, reg3 */
256066e63ce3Schristos int
OP_24007E0(void)256166e63ce3Schristos OP_24007E0 (void)
256266e63ce3Schristos {
256366e63ce3Schristos   trace_input ("mul", OP_IMM_REG_REG, 0);
256466e63ce3Schristos 
256566e63ce3Schristos   Multiply64 (1, SEXT9 ((OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0)));
256666e63ce3Schristos 
256766e63ce3Schristos   trace_output (OP_IMM_REG_REG);
256866e63ce3Schristos 
256966e63ce3Schristos   return 4;
257066e63ce3Schristos }
257166e63ce3Schristos 
257266e63ce3Schristos /* ld.hu */
257366e63ce3Schristos int
OP_107E0(void)257466e63ce3Schristos OP_107E0 (void)
257566e63ce3Schristos {
257666e63ce3Schristos   int adr;
257766e63ce3Schristos 
257866e63ce3Schristos   trace_input ("ld.hu", OP_LOAD32, 2);
257966e63ce3Schristos 
258066e63ce3Schristos   adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1);
258166e63ce3Schristos   adr &= ~0x1;
258266e63ce3Schristos 
258366e63ce3Schristos   State.regs[ OP[1] ] = load_mem (adr, 2);
258466e63ce3Schristos 
258566e63ce3Schristos   trace_output (OP_LOAD32);
258666e63ce3Schristos 
258766e63ce3Schristos   return 4;
258866e63ce3Schristos }
258966e63ce3Schristos 
259066e63ce3Schristos 
259166e63ce3Schristos /* ld.bu */
259266e63ce3Schristos int
OP_10780(void)259366e63ce3Schristos OP_10780 (void)
259466e63ce3Schristos {
259566e63ce3Schristos   int adr;
259666e63ce3Schristos 
259766e63ce3Schristos   trace_input ("ld.bu", OP_LOAD32, 1);
259866e63ce3Schristos 
259966e63ce3Schristos   adr = (State.regs[ OP[0] ]
260066e63ce3Schristos 	 + (EXTEND16 (OP[2] & ~1) | ((OP[3] >> 5) & 1)));
260166e63ce3Schristos 
260266e63ce3Schristos   State.regs[ OP[1] ] = load_mem (adr, 1);
260366e63ce3Schristos 
260466e63ce3Schristos   trace_output (OP_LOAD32);
260566e63ce3Schristos 
260666e63ce3Schristos   return 4;
260766e63ce3Schristos }
260866e63ce3Schristos 
260966e63ce3Schristos /* prepare list12, imm5, imm32 */
261066e63ce3Schristos int
OP_1B0780(void)261166e63ce3Schristos OP_1B0780 (void)
261266e63ce3Schristos {
261366e63ce3Schristos   int  i;
261466e63ce3Schristos 
261566e63ce3Schristos   trace_input ("prepare", OP_PUSHPOP1, 0);
261666e63ce3Schristos 
261766e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
261866e63ce3Schristos   for (i = 0; i < 12; i++)
261966e63ce3Schristos     if ((OP[3] & (1 << type1_regs[ i ])))
262066e63ce3Schristos       {
262166e63ce3Schristos 	SP -= 4;
262266e63ce3Schristos 	store_mem (SP, 4, State.regs[ 20 + i ]);
262366e63ce3Schristos       }
262466e63ce3Schristos 
262566e63ce3Schristos   SP -= (OP[3] & 0x3e) << 1;
262666e63ce3Schristos 
262766e63ce3Schristos   EP = load_mem (PC + 4, 4);
262866e63ce3Schristos 
262966e63ce3Schristos   trace_output (OP_PUSHPOP1);
263066e63ce3Schristos 
263166e63ce3Schristos   return 8;
263266e63ce3Schristos }
263366e63ce3Schristos 
263466e63ce3Schristos /* prepare list12, imm5, imm16-32 */
263566e63ce3Schristos int
OP_130780(void)263666e63ce3Schristos OP_130780 (void)
263766e63ce3Schristos {
263866e63ce3Schristos   int  i;
263966e63ce3Schristos 
264066e63ce3Schristos   trace_input ("prepare", OP_PUSHPOP1, 0);
264166e63ce3Schristos 
264266e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
264366e63ce3Schristos   for (i = 0; i < 12; i++)
264466e63ce3Schristos     if ((OP[3] & (1 << type1_regs[ i ])))
264566e63ce3Schristos       {
264666e63ce3Schristos 	SP -= 4;
264766e63ce3Schristos 	store_mem (SP, 4, State.regs[ 20 + i ]);
264866e63ce3Schristos       }
264966e63ce3Schristos 
265066e63ce3Schristos   SP -= (OP[3] & 0x3e) << 1;
265166e63ce3Schristos 
265266e63ce3Schristos   EP = load_mem (PC + 4, 2) << 16;
265366e63ce3Schristos 
265466e63ce3Schristos   trace_output (OP_PUSHPOP1);
265566e63ce3Schristos 
265666e63ce3Schristos   return 6;
265766e63ce3Schristos }
265866e63ce3Schristos 
265966e63ce3Schristos /* prepare list12, imm5, imm16 */
266066e63ce3Schristos int
OP_B0780(void)266166e63ce3Schristos OP_B0780 (void)
266266e63ce3Schristos {
266366e63ce3Schristos   int  i;
266466e63ce3Schristos 
266566e63ce3Schristos   trace_input ("prepare", OP_PUSHPOP1, 0);
266666e63ce3Schristos 
266766e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
266866e63ce3Schristos   for (i = 0; i < 12; i++)
266966e63ce3Schristos     if ((OP[3] & (1 << type1_regs[ i ])))
267066e63ce3Schristos       {
267166e63ce3Schristos 	SP -= 4;
267266e63ce3Schristos 	store_mem (SP, 4, State.regs[ 20 + i ]);
267366e63ce3Schristos       }
267466e63ce3Schristos 
267566e63ce3Schristos   SP -= (OP[3] & 0x3e) << 1;
267666e63ce3Schristos 
267766e63ce3Schristos   EP = EXTEND16 (load_mem (PC + 4, 2));
267866e63ce3Schristos 
267966e63ce3Schristos   trace_output (OP_PUSHPOP1);
268066e63ce3Schristos 
268166e63ce3Schristos   return 6;
268266e63ce3Schristos }
268366e63ce3Schristos 
268466e63ce3Schristos /* prepare list12, imm5, sp */
268566e63ce3Schristos int
OP_30780(void)268666e63ce3Schristos OP_30780 (void)
268766e63ce3Schristos {
268866e63ce3Schristos   int  i;
268966e63ce3Schristos 
269066e63ce3Schristos   trace_input ("prepare", OP_PUSHPOP1, 0);
269166e63ce3Schristos 
269266e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
269366e63ce3Schristos   for (i = 0; i < 12; i++)
269466e63ce3Schristos     if ((OP[3] & (1 << type1_regs[ i ])))
269566e63ce3Schristos       {
269666e63ce3Schristos 	SP -= 4;
269766e63ce3Schristos 	store_mem (SP, 4, State.regs[ 20 + i ]);
269866e63ce3Schristos       }
269966e63ce3Schristos 
270066e63ce3Schristos   SP -= (OP[3] & 0x3e) << 1;
270166e63ce3Schristos 
270266e63ce3Schristos   EP = SP;
270366e63ce3Schristos 
270466e63ce3Schristos   trace_output (OP_PUSHPOP1);
270566e63ce3Schristos 
270666e63ce3Schristos   return 4;
270766e63ce3Schristos }
270866e63ce3Schristos 
270966e63ce3Schristos /* mul reg1, reg2, reg3 */
271066e63ce3Schristos int
OP_22007E0(void)271166e63ce3Schristos OP_22007E0 (void)
271266e63ce3Schristos {
271366e63ce3Schristos   trace_input ("mul", OP_REG_REG_REG, 0);
271466e63ce3Schristos 
271566e63ce3Schristos   Multiply64 (1, State.regs[ OP[0] ]);
271666e63ce3Schristos 
271766e63ce3Schristos   trace_output (OP_REG_REG_REG);
271866e63ce3Schristos 
271966e63ce3Schristos   return 4;
272066e63ce3Schristos }
272166e63ce3Schristos 
272266e63ce3Schristos /* popmh list18 */
272366e63ce3Schristos int
OP_307F0(void)272466e63ce3Schristos OP_307F0 (void)
272566e63ce3Schristos {
272666e63ce3Schristos   int i;
272766e63ce3Schristos 
272866e63ce3Schristos   trace_input ("popmh", OP_PUSHPOP2, 0);
272966e63ce3Schristos 
273066e63ce3Schristos   if (OP[3] & (1 << 19))
273166e63ce3Schristos     {
273266e63ce3Schristos       if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
273366e63ce3Schristos 	{
273466e63ce3Schristos 	  FEPSW = load_mem ( SP      & ~ 3, 4);
273566e63ce3Schristos 	  FEPC  = load_mem ((SP + 4) & ~ 3, 4);
273666e63ce3Schristos 	}
273766e63ce3Schristos       else
273866e63ce3Schristos 	{
273966e63ce3Schristos 	  EIPSW = load_mem ( SP      & ~ 3, 4);
274066e63ce3Schristos 	  EIPC  = load_mem ((SP + 4) & ~ 3, 4);
274166e63ce3Schristos 	}
274266e63ce3Schristos 
274366e63ce3Schristos       SP += 8;
274466e63ce3Schristos     }
274566e63ce3Schristos 
274666e63ce3Schristos   /* Load the registers with lower number registers being retrieved from higher addresses.  */
274766e63ce3Schristos   for (i = 16; i--;)
274866e63ce3Schristos     if ((OP[3] & (1 << type2_regs[ i ])))
274966e63ce3Schristos       {
275066e63ce3Schristos 	State.regs[ i + 16 ] = load_mem (SP & ~ 3, 4);
275166e63ce3Schristos 	SP += 4;
275266e63ce3Schristos       }
275366e63ce3Schristos 
275466e63ce3Schristos   trace_output (OP_PUSHPOP2);
275566e63ce3Schristos 
275666e63ce3Schristos   return 4;
275766e63ce3Schristos }
275866e63ce3Schristos 
275966e63ce3Schristos /* popml lsit18 */
276066e63ce3Schristos int
OP_107F0(void)276166e63ce3Schristos OP_107F0 (void)
276266e63ce3Schristos {
276366e63ce3Schristos   int i;
276466e63ce3Schristos 
276566e63ce3Schristos   trace_input ("popml", OP_PUSHPOP3, 0);
276666e63ce3Schristos 
276766e63ce3Schristos   if (OP[3] & (1 << 19))
276866e63ce3Schristos     {
276966e63ce3Schristos       if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
277066e63ce3Schristos 	{
277166e63ce3Schristos 	  FEPSW = load_mem ( SP      & ~ 3, 4);
277266e63ce3Schristos 	  FEPC =  load_mem ((SP + 4) & ~ 3, 4);
277366e63ce3Schristos 	}
277466e63ce3Schristos       else
277566e63ce3Schristos 	{
277666e63ce3Schristos 	  EIPSW = load_mem ( SP      & ~ 3, 4);
277766e63ce3Schristos 	  EIPC  = load_mem ((SP + 4) & ~ 3, 4);
277866e63ce3Schristos 	}
277966e63ce3Schristos 
278066e63ce3Schristos       SP += 8;
278166e63ce3Schristos     }
278266e63ce3Schristos 
278366e63ce3Schristos   if (OP[3] & (1 << 3))
278466e63ce3Schristos     {
278566e63ce3Schristos       PSW = load_mem (SP & ~ 3, 4);
278666e63ce3Schristos       SP += 4;
278766e63ce3Schristos     }
278866e63ce3Schristos 
278966e63ce3Schristos   /* Load the registers with lower number registers being retrieved from higher addresses.  */
279066e63ce3Schristos   for (i = 15; i--;)
279166e63ce3Schristos     if ((OP[3] & (1 << type3_regs[ i ])))
279266e63ce3Schristos       {
279366e63ce3Schristos 	State.regs[ i + 1 ] = load_mem (SP & ~ 3, 4);
279466e63ce3Schristos 	SP += 4;
279566e63ce3Schristos       }
279666e63ce3Schristos 
279766e63ce3Schristos   trace_output (OP_PUSHPOP2);
279866e63ce3Schristos 
279966e63ce3Schristos   return 4;
280066e63ce3Schristos }
280166e63ce3Schristos 
280266e63ce3Schristos /* pushmh list18 */
280366e63ce3Schristos int
OP_307E0(void)280466e63ce3Schristos OP_307E0 (void)
280566e63ce3Schristos {
280666e63ce3Schristos   int i;
280766e63ce3Schristos 
280866e63ce3Schristos   trace_input ("pushmh", OP_PUSHPOP2, 0);
280966e63ce3Schristos 
281066e63ce3Schristos   /* Store the registers with lower number registers being placed at higher addresses.  */
281166e63ce3Schristos   for (i = 0; i < 16; i++)
281266e63ce3Schristos     if ((OP[3] & (1 << type2_regs[ i ])))
281366e63ce3Schristos       {
281466e63ce3Schristos 	SP -= 4;
281566e63ce3Schristos 	store_mem (SP & ~ 3, 4, State.regs[ i + 16 ]);
281666e63ce3Schristos       }
281766e63ce3Schristos 
281866e63ce3Schristos   if (OP[3] & (1 << 19))
281966e63ce3Schristos     {
282066e63ce3Schristos       SP -= 8;
282166e63ce3Schristos 
282266e63ce3Schristos       if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
282366e63ce3Schristos 	{
282466e63ce3Schristos 	  store_mem ((SP + 4) & ~ 3, 4, FEPC);
282566e63ce3Schristos 	  store_mem ( SP      & ~ 3, 4, FEPSW);
282666e63ce3Schristos 	}
282766e63ce3Schristos       else
282866e63ce3Schristos 	{
282966e63ce3Schristos 	  store_mem ((SP + 4) & ~ 3, 4, EIPC);
283066e63ce3Schristos 	  store_mem ( SP      & ~ 3, 4, EIPSW);
283166e63ce3Schristos 	}
283266e63ce3Schristos     }
283366e63ce3Schristos 
283466e63ce3Schristos   trace_output (OP_PUSHPOP2);
283566e63ce3Schristos 
283666e63ce3Schristos   return 4;
283766e63ce3Schristos }
283866e63ce3Schristos 
283948596154Schristos /* V850E2R FPU functions */
284048596154Schristos /*
284148596154Schristos   sim_fpu_status_invalid_snan = 1,				-V--- (sim spec.)
284248596154Schristos   sim_fpu_status_invalid_qnan = 2,				----- (sim spec.)
284348596154Schristos   sim_fpu_status_invalid_isi = 4, (inf - inf)			-V---
284448596154Schristos   sim_fpu_status_invalid_idi = 8, (inf / inf)			-V---
284548596154Schristos   sim_fpu_status_invalid_zdz = 16, (0 / 0)			-V---
284648596154Schristos   sim_fpu_status_invalid_imz = 32, (inf * 0)			-V---
284748596154Schristos   sim_fpu_status_invalid_cvi = 64, convert to integer		-V---
284848596154Schristos   sim_fpu_status_invalid_div0 = 128, (X / 0)			--Z--
284948596154Schristos   sim_fpu_status_invalid_cmp = 256, compare			----- (sim spec.)
285048596154Schristos   sim_fpu_status_invalid_sqrt = 512,				-V---
285148596154Schristos   sim_fpu_status_rounded = 1024,				I----
285248596154Schristos   sim_fpu_status_inexact = 2048,				I---- (sim spec.)
285348596154Schristos   sim_fpu_status_overflow = 4096,				I--O-
285448596154Schristos   sim_fpu_status_underflow = 8192,				I---U
285548596154Schristos   sim_fpu_status_denorm = 16384,				----U (sim spec.)
285648596154Schristos */
285748596154Schristos 
2858ed6a76a9Schristos void
update_fpsr(SIM_DESC sd,sim_fpu_status status,unsigned int mask,unsigned int double_op_p)2859ed6a76a9Schristos update_fpsr (SIM_DESC sd, sim_fpu_status status, unsigned int mask, unsigned int double_op_p)
286048596154Schristos {
286148596154Schristos   unsigned int fpsr = FPSR & mask;
286248596154Schristos 
286348596154Schristos   unsigned int flags = 0;
286448596154Schristos 
286548596154Schristos   if (fpsr & FPSR_XEI
286648596154Schristos       && ((status & (sim_fpu_status_rounded
286748596154Schristos 		     | sim_fpu_status_overflow
286848596154Schristos 		     | sim_fpu_status_inexact))
286948596154Schristos 	  || (status & sim_fpu_status_underflow
287048596154Schristos 	      && (fpsr & (FPSR_XEU | FPSR_XEI)) == 0
287148596154Schristos 	      && fpsr & FPSR_FS)))
287248596154Schristos     {
287348596154Schristos       flags |= FPSR_XCI | FPSR_XPI;
287448596154Schristos     }
287548596154Schristos 
287648596154Schristos   if (fpsr & FPSR_XEV
287748596154Schristos       && (status & (sim_fpu_status_invalid_isi
287848596154Schristos 		    | sim_fpu_status_invalid_imz
287948596154Schristos 		    | sim_fpu_status_invalid_zdz
288048596154Schristos 		    | sim_fpu_status_invalid_idi
288148596154Schristos 		    | sim_fpu_status_invalid_cvi
288248596154Schristos 		    | sim_fpu_status_invalid_sqrt
288348596154Schristos 		    | sim_fpu_status_invalid_snan)))
288448596154Schristos     {
288548596154Schristos       flags |= FPSR_XCV | FPSR_XPV;
288648596154Schristos     }
288748596154Schristos 
288848596154Schristos   if (fpsr & FPSR_XEZ
288948596154Schristos       && (status & sim_fpu_status_invalid_div0))
289048596154Schristos     {
289148596154Schristos       flags |= FPSR_XCV | FPSR_XPV;
289248596154Schristos     }
289348596154Schristos 
289448596154Schristos   if (fpsr & FPSR_XEO
289548596154Schristos       && (status & sim_fpu_status_overflow))
289648596154Schristos     {
289748596154Schristos       flags |= FPSR_XCO | FPSR_XPO;
289848596154Schristos     }
289948596154Schristos 
290048596154Schristos   if (((fpsr & FPSR_XEU) || (fpsr & FPSR_FS) == 0)
290148596154Schristos       && (status & (sim_fpu_status_underflow
290248596154Schristos 		    | sim_fpu_status_denorm)))
290348596154Schristos     {
290448596154Schristos       flags |= FPSR_XCU | FPSR_XPU;
290548596154Schristos     }
290648596154Schristos 
290748596154Schristos   if (flags)
290848596154Schristos     {
290948596154Schristos       FPSR &= ~FPSR_XC;
291048596154Schristos       FPSR |= flags;
291148596154Schristos 
291248596154Schristos       SignalExceptionFPE (sd, double_op_p);
291348596154Schristos     }
291448596154Schristos }
291548596154Schristos 
2916ed6a76a9Schristos /* Exception.  */
291748596154Schristos 
2918ed6a76a9Schristos void
SignalException(SIM_DESC sd)2919ed6a76a9Schristos SignalException (SIM_DESC sd)
292048596154Schristos {
292148596154Schristos   if (MPM & MPM_AUE)
292248596154Schristos     {
292348596154Schristos       PSW = PSW & ~(PSW_NPV | PSW_DMP | PSW_IMP);
292448596154Schristos     }
292548596154Schristos }
292648596154Schristos 
2927ed6a76a9Schristos void
SignalExceptionFPE(SIM_DESC sd,unsigned int double_op_p)2928ed6a76a9Schristos SignalExceptionFPE (SIM_DESC sd, unsigned int double_op_p)
292948596154Schristos {
293048596154Schristos   if (((PSW & (PSW_NP|PSW_ID)) == 0)
293148596154Schristos       || !(FPSR & (double_op_p ? FPSR_DEM : FPSR_SEM)))
293248596154Schristos     {
293348596154Schristos       EIPC = PC;
293448596154Schristos       EIPSW = PSW;
293548596154Schristos       EIIC = (FPSR & (double_op_p ? FPSR_DEM : FPSR_SEM))
293648596154Schristos 	? 0x71 : 0x72;
293748596154Schristos       PSW |= (PSW_EP | PSW_ID);
293848596154Schristos       PC = 0x70;
293948596154Schristos 
294048596154Schristos       SignalException (sd);
294148596154Schristos     }
294248596154Schristos }
294348596154Schristos 
2944ed6a76a9Schristos void
check_invalid_snan(SIM_DESC sd,sim_fpu_status status,unsigned int double_op_p)2945ed6a76a9Schristos check_invalid_snan (SIM_DESC sd, sim_fpu_status status, unsigned int double_op_p)
294648596154Schristos {
294748596154Schristos   if ((FPSR & FPSR_XEI)
294848596154Schristos       && (status & sim_fpu_status_invalid_snan))
294948596154Schristos     {
295048596154Schristos       FPSR &= ~FPSR_XC;
295148596154Schristos       FPSR |= FPSR_XCV;
295248596154Schristos       FPSR |= FPSR_XPV;
295348596154Schristos       SignalExceptionFPE (sd, double_op_p);
295448596154Schristos     }
295548596154Schristos }
295648596154Schristos 
2957ed6a76a9Schristos int
v850_float_compare(SIM_DESC sd,int cmp,sim_fpu wop1,sim_fpu wop2,int double_op_p)2958ed6a76a9Schristos v850_float_compare (SIM_DESC sd, int cmp, sim_fpu wop1, sim_fpu wop2, int double_op_p)
295948596154Schristos {
296048596154Schristos   int result = -1;
296148596154Schristos 
296248596154Schristos   if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
296348596154Schristos     {
296448596154Schristos       if (cmp & 0x8)
296548596154Schristos 	{
296648596154Schristos 	  if (FPSR & FPSR_XEV)
296748596154Schristos 	    {
296848596154Schristos 	      FPSR |= FPSR_XCV | FPSR_XPV;
296948596154Schristos 	      SignalExceptionFPE (sd, double_op_p);
297048596154Schristos 	    }
297148596154Schristos 	}
297248596154Schristos 
297348596154Schristos       switch (cmp)
297448596154Schristos 	{
297548596154Schristos 	case FPU_CMP_F:
297648596154Schristos 	  result = 0;
297748596154Schristos 	  break;
297848596154Schristos 	case FPU_CMP_UN:
297948596154Schristos 	  result = 1;
298048596154Schristos 	  break;
298148596154Schristos 	case FPU_CMP_EQ:
298248596154Schristos 	  result = 0;
298348596154Schristos 	  break;
298448596154Schristos 	case FPU_CMP_UEQ:
298548596154Schristos 	  result = 1;
298648596154Schristos 	  break;
298748596154Schristos 	case FPU_CMP_OLT:
298848596154Schristos 	  result = 0;
298948596154Schristos 	  break;
299048596154Schristos 	case FPU_CMP_ULT:
299148596154Schristos 	  result = 1;
299248596154Schristos 	  break;
299348596154Schristos 	case FPU_CMP_OLE:
299448596154Schristos 	  result = 0;
299548596154Schristos 	  break;
299648596154Schristos 	case FPU_CMP_ULE:
299748596154Schristos 	  result = 1;
299848596154Schristos 	  break;
299948596154Schristos 	case FPU_CMP_SF:
300048596154Schristos 	  result = 0;
300148596154Schristos 	  break;
300248596154Schristos 	case FPU_CMP_NGLE:
300348596154Schristos 	  result = 1;
300448596154Schristos 	  break;
300548596154Schristos 	case FPU_CMP_SEQ:
300648596154Schristos 	  result = 0;
300748596154Schristos 	  break;
300848596154Schristos 	case FPU_CMP_NGL:
300948596154Schristos 	  result = 1;
301048596154Schristos 	  break;
301148596154Schristos 	case FPU_CMP_LT:
301248596154Schristos 	  result = 0;
301348596154Schristos 	  break;
301448596154Schristos 	case FPU_CMP_NGE:
301548596154Schristos 	  result = 1;
301648596154Schristos 	  break;
301748596154Schristos 	case FPU_CMP_LE:
301848596154Schristos 	  result = 0;
301948596154Schristos 	  break;
302048596154Schristos 	case FPU_CMP_NGT:
302148596154Schristos 	  result = 1;
302248596154Schristos 	  break;
302348596154Schristos 	default:
302448596154Schristos 	  abort ();
302548596154Schristos 	}
302648596154Schristos     }
302748596154Schristos   else if (sim_fpu_is_infinity (&wop1) && sim_fpu_is_infinity (&wop2)
302848596154Schristos 	   && sim_fpu_sign (&wop1) == sim_fpu_sign (&wop2))
302948596154Schristos     {
303048596154Schristos       switch (cmp)
303148596154Schristos 	{
303248596154Schristos 	case FPU_CMP_F:
303348596154Schristos 	  result = 0;
303448596154Schristos 	  break;
303548596154Schristos 	case FPU_CMP_UN:
303648596154Schristos 	  result = 0;
303748596154Schristos 	  break;
303848596154Schristos 	case FPU_CMP_EQ:
303948596154Schristos 	  result = 1;
304048596154Schristos 	  break;
304148596154Schristos 	case FPU_CMP_UEQ:
304248596154Schristos 	  result = 1;
304348596154Schristos 	  break;
304448596154Schristos 	case FPU_CMP_OLT:
304548596154Schristos 	  result = 0;
304648596154Schristos 	  break;
304748596154Schristos 	case FPU_CMP_ULT:
304848596154Schristos 	  result = 0;
304948596154Schristos 	  break;
305048596154Schristos 	case FPU_CMP_OLE:
305148596154Schristos 	  result = 1;
305248596154Schristos 	  break;
305348596154Schristos 	case FPU_CMP_ULE:
305448596154Schristos 	  result = 1;
305548596154Schristos 	  break;
305648596154Schristos 	case FPU_CMP_SF:
305748596154Schristos 	  result = 0;
305848596154Schristos 	  break;
305948596154Schristos 	case FPU_CMP_NGLE:
306048596154Schristos 	  result = 0;
306148596154Schristos 	  break;
306248596154Schristos 	case FPU_CMP_SEQ:
306348596154Schristos 	  result = 1;
306448596154Schristos 	  break;
306548596154Schristos 	case FPU_CMP_NGL:
306648596154Schristos 	  result = 1;
306748596154Schristos 	  break;
306848596154Schristos 	case FPU_CMP_LT:
306948596154Schristos 	  result = 0;
307048596154Schristos 	  break;
307148596154Schristos 	case FPU_CMP_NGE:
307248596154Schristos 	  result = 0;
307348596154Schristos 	  break;
307448596154Schristos 	case FPU_CMP_LE:
307548596154Schristos 	  result = 1;
307648596154Schristos 	  break;
307748596154Schristos 	case FPU_CMP_NGT:
307848596154Schristos 	  result = 1;
307948596154Schristos 	  break;
308048596154Schristos 	default:
308148596154Schristos 	  abort ();
308248596154Schristos 	}
308348596154Schristos     }
308448596154Schristos   else
308548596154Schristos     {
308648596154Schristos       int gt = 0,lt = 0,eq = 0, status;
308748596154Schristos 
308848596154Schristos       status = sim_fpu_cmp (&wop1, &wop2);
308948596154Schristos 
3090ed6a76a9Schristos       switch (status)
3091ed6a76a9Schristos 	{
309248596154Schristos 	case SIM_FPU_IS_SNAN:
309348596154Schristos 	case SIM_FPU_IS_QNAN:
309448596154Schristos 	  abort ();
309548596154Schristos 	  break;
309648596154Schristos 
309748596154Schristos 	case SIM_FPU_IS_NINF:
309848596154Schristos 	  lt = 1;
309948596154Schristos 	  break;
310048596154Schristos 	case SIM_FPU_IS_PINF:
310148596154Schristos 	  gt = 1;
310248596154Schristos 	  break;
310348596154Schristos 	case SIM_FPU_IS_NNUMBER:
310448596154Schristos 	  lt = 1;
310548596154Schristos 	  break;
310648596154Schristos 	case SIM_FPU_IS_PNUMBER:
310748596154Schristos 	  gt = 1;
310848596154Schristos 	  break;
310948596154Schristos 	case SIM_FPU_IS_NDENORM:
311048596154Schristos 	  lt = 1;
311148596154Schristos 	  break;
311248596154Schristos 	case SIM_FPU_IS_PDENORM:
311348596154Schristos 	  gt = 1;
311448596154Schristos 	  break;
311548596154Schristos 	case SIM_FPU_IS_NZERO:
311648596154Schristos 	case SIM_FPU_IS_PZERO:
311748596154Schristos 	  eq = 1;
311848596154Schristos 	  break;
311948596154Schristos 	}
312048596154Schristos 
312148596154Schristos       switch (cmp)
312248596154Schristos 	{
312348596154Schristos 	case FPU_CMP_F:
312448596154Schristos 	  result = 0;
312548596154Schristos 	  break;
312648596154Schristos 	case FPU_CMP_UN:
312748596154Schristos 	  result = 0;
312848596154Schristos 	  break;
312948596154Schristos 	case FPU_CMP_EQ:
313048596154Schristos 	  result = eq;
313148596154Schristos 	  break;
313248596154Schristos 	case FPU_CMP_UEQ:
313348596154Schristos 	  result = eq;
313448596154Schristos 	  break;
313548596154Schristos 	case FPU_CMP_OLT:
313648596154Schristos 	  result = lt;
313748596154Schristos 	  break;
313848596154Schristos 	case FPU_CMP_ULT:
313948596154Schristos 	  result = lt;
314048596154Schristos 	  break;
314148596154Schristos 	case FPU_CMP_OLE:
314248596154Schristos 	  result = lt || eq;
314348596154Schristos 	  break;
314448596154Schristos 	case FPU_CMP_ULE:
314548596154Schristos 	  result = lt || eq;
314648596154Schristos 	  break;
314748596154Schristos 	case FPU_CMP_SF:
314848596154Schristos 	  result = 0;
314948596154Schristos 	  break;
315048596154Schristos 	case FPU_CMP_NGLE:
315148596154Schristos 	  result = 0;
315248596154Schristos 	  break;
315348596154Schristos 	case FPU_CMP_SEQ:
315448596154Schristos 	  result = eq;
315548596154Schristos 	  break;
315648596154Schristos 	case FPU_CMP_NGL:
315748596154Schristos 	  result = eq;
315848596154Schristos 	  break;
315948596154Schristos 	case FPU_CMP_LT:
316048596154Schristos 	  result = lt;
316148596154Schristos 	  break;
316248596154Schristos 	case FPU_CMP_NGE:
316348596154Schristos 	  result = lt;
316448596154Schristos 	  break;
316548596154Schristos 	case FPU_CMP_LE:
316648596154Schristos 	  result = lt || eq;
316748596154Schristos 	  break;
316848596154Schristos 	case FPU_CMP_NGT:
316948596154Schristos 	  result = lt || eq;
317048596154Schristos 	  break;
317148596154Schristos 	}
317248596154Schristos     }
317348596154Schristos 
317448596154Schristos   ASSERT (result != -1);
317548596154Schristos   return result;
317648596154Schristos }
317748596154Schristos 
3178ed6a76a9Schristos void
v850_div(SIM_DESC sd,unsigned int op0,unsigned int op1,unsigned int * op2p,unsigned int * op3p)3179ed6a76a9Schristos v850_div (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p)
318048596154Schristos {
318148596154Schristos   signed long int quotient;
318248596154Schristos   signed long int remainder;
318348596154Schristos   signed long int divide_by;
318448596154Schristos   signed long int divide_this;
318548596154Schristos   bfd_boolean     overflow = FALSE;
318648596154Schristos 
318748596154Schristos   /* Compute the result.  */
318848596154Schristos   divide_by   = op0;
318948596154Schristos   divide_this = op1;
319048596154Schristos 
319148596154Schristos   if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
319248596154Schristos     {
319348596154Schristos       overflow  = TRUE;
319448596154Schristos       divide_by = 1;
319548596154Schristos     }
319648596154Schristos 
319748596154Schristos   quotient  = divide_this / divide_by;
319848596154Schristos   remainder = divide_this % divide_by;
319948596154Schristos 
320048596154Schristos   /* Set condition codes.  */
320148596154Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
320248596154Schristos 
320348596154Schristos   if (overflow)      PSW |= PSW_OV;
320448596154Schristos   if (quotient == 0) PSW |= PSW_Z;
320548596154Schristos   if (quotient <  0) PSW |= PSW_S;
320648596154Schristos 
320748596154Schristos   *op2p = quotient;
320848596154Schristos   *op3p = remainder;
320948596154Schristos }
321048596154Schristos 
3211ed6a76a9Schristos void
v850_divu(SIM_DESC sd,unsigned int op0,unsigned int op1,unsigned int * op2p,unsigned int * op3p)3212ed6a76a9Schristos v850_divu (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p)
321348596154Schristos {
321448596154Schristos   unsigned long int quotient;
321548596154Schristos   unsigned long int remainder;
321648596154Schristos   unsigned long int divide_by;
321748596154Schristos   unsigned long int divide_this;
321848596154Schristos   bfd_boolean       overflow = FALSE;
321948596154Schristos 
322048596154Schristos   /* Compute the result.  */
322148596154Schristos 
322248596154Schristos   divide_by   = op0;
322348596154Schristos   divide_this = op1;
322448596154Schristos 
322548596154Schristos   if (divide_by == 0)
322648596154Schristos     {
322748596154Schristos       overflow = TRUE;
322848596154Schristos       divide_by  = 1;
322948596154Schristos     }
323048596154Schristos 
323148596154Schristos   quotient  = divide_this / divide_by;
323248596154Schristos   remainder = divide_this % divide_by;
323348596154Schristos 
323448596154Schristos   /* Set condition codes.  */
323548596154Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV);
323648596154Schristos 
323748596154Schristos   if (overflow)      PSW |= PSW_OV;
323848596154Schristos   if (quotient == 0) PSW |= PSW_Z;
323948596154Schristos   if (quotient & 0x80000000) PSW |= PSW_S;
324048596154Schristos 
324148596154Schristos   *op2p = quotient;
324248596154Schristos   *op3p = remainder;
324348596154Schristos }
324448596154Schristos 
3245ed6a76a9Schristos void
v850_sar(SIM_DESC sd,unsigned int op0,unsigned int op1,unsigned int * op2p)3246ed6a76a9Schristos v850_sar (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
324748596154Schristos {
324848596154Schristos   unsigned int result, z, s, cy;
324948596154Schristos 
325048596154Schristos   op0 &= 0x1f;
325148596154Schristos   result = (signed)op1 >> op0;
325248596154Schristos 
325348596154Schristos   /* Compute the condition codes.  */
325448596154Schristos   z = (result == 0);
325548596154Schristos   s = (result & 0x80000000);
325648596154Schristos   cy = (op1 & (1 << (op0 - 1)));
325748596154Schristos 
325848596154Schristos   /* Store the result and condition codes.  */
325948596154Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
326048596154Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
326148596154Schristos 		| (cy ? PSW_CY : 0));
326248596154Schristos 
326348596154Schristos   *op2p = result;
326448596154Schristos }
326548596154Schristos 
3266ed6a76a9Schristos void
v850_shl(SIM_DESC sd,unsigned int op0,unsigned int op1,unsigned int * op2p)3267ed6a76a9Schristos v850_shl (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
326848596154Schristos {
326948596154Schristos   unsigned int result, z, s, cy;
327048596154Schristos 
327148596154Schristos   op0 &= 0x1f;
327248596154Schristos   result = op1 << op0;
327348596154Schristos 
327448596154Schristos   /* Compute the condition codes.  */
327548596154Schristos   z = (result == 0);
327648596154Schristos   s = (result & 0x80000000);
327748596154Schristos   cy = (op1 & (1 << (32 - op0)));
327848596154Schristos 
327948596154Schristos   /* Store the result and condition codes.  */
328048596154Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
328148596154Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
328248596154Schristos 		| (cy ? PSW_CY : 0));
328348596154Schristos 
328448596154Schristos   *op2p = result;
328548596154Schristos }
328648596154Schristos 
328748596154Schristos void
v850_rotl(SIM_DESC sd,unsigned int amount,unsigned int src,unsigned int * dest)328848596154Schristos v850_rotl (SIM_DESC sd, unsigned int amount, unsigned int src, unsigned int * dest)
328948596154Schristos {
329048596154Schristos   unsigned int result, z, s, cy;
329148596154Schristos 
329248596154Schristos   amount &= 0x1f;
329348596154Schristos   result = src << amount;
329448596154Schristos   result |= src >> (32 - amount);
329548596154Schristos 
329648596154Schristos   /* Compute the condition codes.  */
329748596154Schristos   z = (result == 0);
329848596154Schristos   s = (result & 0x80000000);
329948596154Schristos   cy = ! (result & 1);
330048596154Schristos 
330148596154Schristos   /* Store the result and condition codes.  */
330248596154Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
330348596154Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
330448596154Schristos 		| (cy ? PSW_CY : 0));
330548596154Schristos 
330648596154Schristos   * dest = result;
330748596154Schristos }
330848596154Schristos 
330948596154Schristos void
v850_bins(SIM_DESC sd,unsigned int source,unsigned int lsb,unsigned int msb,unsigned int * dest)331048596154Schristos v850_bins (SIM_DESC sd, unsigned int source, unsigned int lsb, unsigned int msb,
331148596154Schristos 	   unsigned int * dest)
331248596154Schristos {
331348596154Schristos   unsigned int mask;
331448596154Schristos   unsigned int result, pos, width;
331548596154Schristos   unsigned int z, s;
331648596154Schristos 
331748596154Schristos   pos = lsb;
331848596154Schristos   width = (msb - lsb) + 1;
331948596154Schristos 
3320*c03b94e9Schristos   mask = ~ (-(1 << width));
332148596154Schristos   source &= mask;
332248596154Schristos   mask <<= pos;
332348596154Schristos   result = (* dest) & ~ mask;
332448596154Schristos   result |= source << pos;
332548596154Schristos 
332648596154Schristos   /* Compute the condition codes.  */
332748596154Schristos   z = (result == 0);
332848596154Schristos   s = result & 0x80000000;
332948596154Schristos 
333048596154Schristos   /* Store the result and condition codes.  */
333148596154Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV );
333248596154Schristos   PSW |= (z ? PSW_Z : 0) | (s ? PSW_S : 0);
333348596154Schristos 
333448596154Schristos   * dest = result;
333548596154Schristos }
333648596154Schristos 
3337ed6a76a9Schristos void
v850_shr(SIM_DESC sd,unsigned int op0,unsigned int op1,unsigned int * op2p)3338ed6a76a9Schristos v850_shr (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
333948596154Schristos {
334048596154Schristos   unsigned int result, z, s, cy;
334148596154Schristos 
334248596154Schristos   op0 &=  0x1f;
334348596154Schristos   result = op1 >> op0;
334448596154Schristos 
334548596154Schristos   /* Compute the condition codes.  */
334648596154Schristos   z = (result == 0);
334748596154Schristos   s = (result & 0x80000000);
334848596154Schristos   cy = (op1 & (1 << (op0 - 1)));
334948596154Schristos 
335048596154Schristos   /* Store the result and condition codes.  */
335148596154Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
335248596154Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
335348596154Schristos 		| (cy ? PSW_CY : 0));
335448596154Schristos 
335548596154Schristos   *op2p = result;
335648596154Schristos }
335748596154Schristos 
3358ed6a76a9Schristos void
v850_satadd(SIM_DESC sd,unsigned int op0,unsigned int op1,unsigned int * op2p)3359ed6a76a9Schristos v850_satadd (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
336048596154Schristos {
336148596154Schristos   unsigned int result, z, s, cy, ov, sat;
336248596154Schristos 
336348596154Schristos   result = op0 + op1;
336448596154Schristos 
336548596154Schristos   /* Compute the condition codes.  */
336648596154Schristos   z = (result == 0);
336748596154Schristos   s = (result & 0x80000000);
336848596154Schristos   cy = (result < op0 || result < op1);
336948596154Schristos   ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
337048596154Schristos 	&& (op0 & 0x80000000) != (result & 0x80000000));
337148596154Schristos   sat = ov;
337248596154Schristos 
337348596154Schristos   /* Store the result and condition codes.  */
337448596154Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
337548596154Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
337648596154Schristos 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
337748596154Schristos 	  | (sat ? PSW_SAT : 0));
337848596154Schristos 
337948596154Schristos   /* Handle saturated results.  */
338048596154Schristos   if (sat && s)
338148596154Schristos     {
338248596154Schristos       result = 0x7fffffff;
338348596154Schristos       PSW &= ~PSW_S;
338448596154Schristos     }
338548596154Schristos   else if (sat)
338648596154Schristos     {
338748596154Schristos       result = 0x80000000;
338848596154Schristos       PSW |= PSW_S;
338948596154Schristos     }
339048596154Schristos 
339148596154Schristos   *op2p = result;
339248596154Schristos }
339348596154Schristos 
3394ed6a76a9Schristos void
v850_satsub(SIM_DESC sd,unsigned int op0,unsigned int op1,unsigned int * op2p)3395ed6a76a9Schristos v850_satsub (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
339648596154Schristos {
339748596154Schristos   unsigned int result, z, s, cy, ov, sat;
339848596154Schristos 
339948596154Schristos   /* Compute the result.  */
340048596154Schristos   result = op1 - op0;
340148596154Schristos 
340248596154Schristos   /* Compute the condition codes.  */
340348596154Schristos   z = (result == 0);
340448596154Schristos   s = (result & 0x80000000);
340548596154Schristos   cy = (op1 < op0);
340648596154Schristos   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
340748596154Schristos 	&& (op1 & 0x80000000) != (result & 0x80000000));
340848596154Schristos   sat = ov;
340948596154Schristos 
341048596154Schristos   /* Store the result and condition codes.  */
341148596154Schristos   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
341248596154Schristos   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
341348596154Schristos 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
341448596154Schristos 	  | (sat ? PSW_SAT : 0));
341548596154Schristos 
341648596154Schristos   /* Handle saturated results.  */
341748596154Schristos   if (sat && s)
341848596154Schristos     {
341948596154Schristos       result = 0x7fffffff;
342048596154Schristos       PSW &= ~PSW_S;
342148596154Schristos     }
342248596154Schristos   else if (sat)
342348596154Schristos     {
342448596154Schristos       result = 0x80000000;
342548596154Schristos       PSW |= PSW_S;
342648596154Schristos     }
342748596154Schristos 
342848596154Schristos   *op2p = result;
342948596154Schristos }
343048596154Schristos 
343148596154Schristos unsigned32
load_data_mem(SIM_DESC sd,SIM_ADDR addr,int len)3432ed6a76a9Schristos load_data_mem (SIM_DESC  sd,
3433ed6a76a9Schristos 	       SIM_ADDR  addr,
3434ed6a76a9Schristos 	       int       len)
343548596154Schristos {
343648596154Schristos   uint32 data;
343748596154Schristos 
343848596154Schristos   switch (len)
343948596154Schristos     {
344048596154Schristos     case 1:
344148596154Schristos       data = sim_core_read_unaligned_1 (STATE_CPU (sd, 0),
344248596154Schristos 					PC, read_map, addr);
344348596154Schristos       break;
344448596154Schristos     case 2:
344548596154Schristos       data = sim_core_read_unaligned_2 (STATE_CPU (sd, 0),
344648596154Schristos 					PC, read_map, addr);
344748596154Schristos       break;
344848596154Schristos     case 4:
344948596154Schristos       data = sim_core_read_unaligned_4 (STATE_CPU (sd, 0),
345048596154Schristos 					PC, read_map, addr);
345148596154Schristos       break;
345248596154Schristos     default:
345348596154Schristos       abort ();
345448596154Schristos     }
345548596154Schristos   return data;
345648596154Schristos }
345748596154Schristos 
345848596154Schristos void
store_data_mem(SIM_DESC sd,SIM_ADDR addr,int len,unsigned32 data)3459ed6a76a9Schristos store_data_mem (SIM_DESC    sd,
3460ed6a76a9Schristos 		SIM_ADDR    addr,
3461ed6a76a9Schristos 		int         len,
3462ed6a76a9Schristos 		unsigned32  data)
346348596154Schristos {
346448596154Schristos   switch (len)
346548596154Schristos     {
346648596154Schristos     case 1:
346748596154Schristos       store_mem (addr, 1, data);
346848596154Schristos       break;
346948596154Schristos     case 2:
347048596154Schristos       store_mem (addr, 2, data);
347148596154Schristos       break;
347248596154Schristos     case 4:
347348596154Schristos       store_mem (addr, 4, data);
347448596154Schristos       break;
347548596154Schristos     default:
347648596154Schristos       abort ();
347748596154Schristos     }
347848596154Schristos }
347948596154Schristos 
3480ed6a76a9Schristos int
mpu_load_mem_test(SIM_DESC sd,unsigned int addr,int size,int base_reg)3481ed6a76a9Schristos mpu_load_mem_test (SIM_DESC sd, unsigned int addr, int size, int base_reg)
348248596154Schristos {
348348596154Schristos   int result = 1;
348448596154Schristos 
348548596154Schristos   if (PSW & PSW_DMP)
348648596154Schristos     {
348748596154Schristos       if (IPE0 && addr >= IPA2ADDR (IPA0L) && addr <= IPA2ADDR (IPA0L) && IPR0)
348848596154Schristos 	{
348948596154Schristos 	  /* text area */
349048596154Schristos 	}
349148596154Schristos       else if (IPE1 && addr >= IPA2ADDR (IPA1L) && addr <= IPA2ADDR (IPA1L) && IPR1)
349248596154Schristos 	{
349348596154Schristos 	  /* text area */
349448596154Schristos 	}
349548596154Schristos       else if (IPE2 && addr >= IPA2ADDR (IPA2L) && addr <= IPA2ADDR (IPA2L) && IPR2)
349648596154Schristos 	{
349748596154Schristos 	  /* text area */
349848596154Schristos 	}
349948596154Schristos       else if (IPE3 && addr >= IPA2ADDR (IPA3L) && addr <= IPA2ADDR (IPA3L) && IPR3)
350048596154Schristos 	{
350148596154Schristos 	  /* text area */
350248596154Schristos 	}
350348596154Schristos       else if (addr >= PPA2ADDR (PPA & ~PPM) && addr <= DPA2ADDR (PPA | PPM))
350448596154Schristos 	{
350548596154Schristos 	  /* preifarallel area */
350648596154Schristos 	}
350748596154Schristos       else if (addr >= PPA2ADDR (SPAL) && addr <= DPA2ADDR (SPAU))
350848596154Schristos 	{
350948596154Schristos 	  /* stack area */
351048596154Schristos 	}
351148596154Schristos       else if (DPE0 && addr >= DPA2ADDR (DPA0L) && addr <= DPA2ADDR (DPA0L) && DPR0
351248596154Schristos 	       && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
351348596154Schristos 	{
351448596154Schristos 	  /* data area */
351548596154Schristos 	}
351648596154Schristos       else if (DPE1 && addr >= DPA2ADDR (DPA1L) && addr <= DPA2ADDR (DPA1L) && DPR1
351748596154Schristos 	       && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
351848596154Schristos 	{
351948596154Schristos 	  /* data area */
352048596154Schristos 	}
352148596154Schristos       else if (DPE2 && addr >= DPA2ADDR (DPA2L) && addr <= DPA2ADDR (DPA2L) && DPR2
352248596154Schristos 	       && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
352348596154Schristos 	{
352448596154Schristos 	  /* data area */
352548596154Schristos 	}
352648596154Schristos       else if (DPE3 && addr >= DPA2ADDR (DPA3L) && addr <= DPA2ADDR (DPA3L) && DPR3
352748596154Schristos 	       && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
352848596154Schristos 	{
352948596154Schristos 	  /* data area */
353048596154Schristos 	}
353148596154Schristos       else
353248596154Schristos 	{
353348596154Schristos 	  VMECR &= ~(VMECR_VMW | VMECR_VMX);
353448596154Schristos 	  VMECR |= VMECR_VMR;
353548596154Schristos 	  VMADR = addr;
353648596154Schristos 	  VMTID = TID;
353748596154Schristos 	  FEIC = 0x431;
353848596154Schristos 
353948596154Schristos 	  PC = 0x30;
354048596154Schristos 
354148596154Schristos 	  SignalException (sd);
354248596154Schristos 	  result = 0;
354348596154Schristos 	}
354448596154Schristos     }
354548596154Schristos 
354648596154Schristos   return result;
354748596154Schristos }
354848596154Schristos 
3549ed6a76a9Schristos int
mpu_store_mem_test(SIM_DESC sd,unsigned int addr,int size,int base_reg)3550ed6a76a9Schristos mpu_store_mem_test (SIM_DESC sd, unsigned int addr, int size, int base_reg)
355148596154Schristos {
355248596154Schristos   int result = 1;
355348596154Schristos 
355448596154Schristos   if (PSW & PSW_DMP)
355548596154Schristos     {
355648596154Schristos       if (addr >= PPA2ADDR (PPA & ~PPM) && addr <= DPA2ADDR (PPA | PPM))
355748596154Schristos 	{
355848596154Schristos 	  /* preifarallel area */
355948596154Schristos 	}
356048596154Schristos       else if (addr >= PPA2ADDR (SPAL) && addr <= DPA2ADDR (SPAU))
356148596154Schristos 	{
356248596154Schristos 	  /* stack area */
356348596154Schristos 	}
356448596154Schristos       else if (DPE0 && addr >= DPA2ADDR (DPA0L) && addr <= DPA2ADDR (DPA0L) && DPW0
356548596154Schristos 	       && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
356648596154Schristos 	{
356748596154Schristos 	  /* data area */
356848596154Schristos 	}
356948596154Schristos       else if (DPE1 && addr >= DPA2ADDR (DPA1L) && addr <= DPA2ADDR (DPA1L) && DPW1
357048596154Schristos 	       && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
357148596154Schristos 	{
357248596154Schristos 	  /* data area */
357348596154Schristos 	}
357448596154Schristos       else if (DPE2 && addr >= DPA2ADDR (DPA2L) && addr <= DPA2ADDR (DPA2L) && DPW2
357548596154Schristos 	       && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
357648596154Schristos 	{
357748596154Schristos 	  /* data area */
357848596154Schristos 	}
357948596154Schristos       else if (DPE3 && addr >= DPA2ADDR (DPA3L) && addr <= DPA2ADDR (DPA3L) && DPW3
358048596154Schristos 	       && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
358148596154Schristos 	{
358248596154Schristos 	  /* data area */
358348596154Schristos 	}
358448596154Schristos       else
358548596154Schristos 	{
358648596154Schristos 	  if (addr >= PPA2ADDR (PPA & ~PPM) && addr <= DPA2ADDR (PPA | PPM))
358748596154Schristos 	    {
358848596154Schristos 	      FEIC = 0x432;
358948596154Schristos 	      VPTID = TID;
359048596154Schristos 	      VPADR = PC;
359148596154Schristos #ifdef NOT_YET
359248596154Schristos 	      VIP_PP;
359348596154Schristos 	      VPECR;
359448596154Schristos #endif
359548596154Schristos 	    }
359648596154Schristos 	  else
359748596154Schristos 	    {
359848596154Schristos 	      FEIC = 0x431;
359948596154Schristos 	      VMTID = TID;
360048596154Schristos 	      VMADR = VMECR;
360148596154Schristos 	      VMECR &= ~(VMECR_VMW | VMECR_VMX);
360248596154Schristos 	      VMECR |= VMECR_VMR;
360348596154Schristos 	      PC = 0x30;
360448596154Schristos 	    }
360548596154Schristos 	  result = 0;
360648596154Schristos 	}
360748596154Schristos     }
360848596154Schristos 
360948596154Schristos   return result;
361048596154Schristos }
361148596154Schristos 
3612