xref: /netbsd-src/external/gpl3/gdb/dist/sim/mn10300/op_utils.c (revision 0388e998654430ce19a2917dec7ff0950bcf2e1c)
1 /* This must come before any other includes.  */
2 #include "defs.h"
3 
4 #include <errno.h>
5 #include <time.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <sys/stat.h>
9 #include <sys/time.h>
10 
11 #include "sim/callback.h"
12 
13 #include "sim-main.h"
14 #include "sim-fpu.h"
15 #include "sim-signal.h"
16 #include "sim-syscall.h"
17 
18 #include "mn10300-sim.h"
19 
20 #define REG0(X) ((X) & 0x3)
21 #define REG1(X) (((X) & 0xc) >> 2)
22 #define REG0_4(X) (((X) & 0x30) >> 4)
23 #define REG0_8(X) (((X) & 0x300) >> 8)
24 #define REG1_8(X) (((X) & 0xc00) >> 10)
25 #define REG0_16(X) (((X) & 0x30000) >> 16)
26 #define REG1_16(X) (((X) & 0xc0000) >> 18)
27 
28 
29 INLINE_SIM_MAIN (void)
30 genericAdd(uint32_t source, uint32_t destReg)
31 {
32   int z, c, n, v;
33   uint32_t dest, sum;
34 
35   dest = State.regs[destReg];
36   sum = source + dest;
37   State.regs[destReg] = sum;
38 
39   z = (sum == 0);
40   n = (sum & 0x80000000);
41   c = (sum < source) || (sum < dest);
42   v = ((dest & 0x80000000) == (source & 0x80000000)
43        && (dest & 0x80000000) != (sum & 0x80000000));
44 
45   PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
46   PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
47 	  | (c ? PSW_C : 0) | (v ? PSW_V : 0));
48 }
49 
50 
51 
52 
53 INLINE_SIM_MAIN (void)
54 genericSub(uint32_t source, uint32_t destReg)
55 {
56   int z, c, n, v;
57   uint32_t dest, difference;
58 
59   dest = State.regs[destReg];
60   difference = dest - source;
61   State.regs[destReg] = difference;
62 
63   z = (difference == 0);
64   n = (difference & 0x80000000);
65   c = (source > dest);
66   v = ((dest & 0x80000000) != (source & 0x80000000)
67        && (dest & 0x80000000) != (difference & 0x80000000));
68 
69   PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
70   PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
71 	  | (c ? PSW_C : 0) | (v ? PSW_V : 0));
72 }
73 
74 INLINE_SIM_MAIN (void)
75 genericCmp(uint32_t leftOpnd, uint32_t rightOpnd)
76 {
77   int z, c, n, v;
78   uint32_t value;
79 
80   value = rightOpnd - leftOpnd;
81 
82   z = (value == 0);
83   n = (value & 0x80000000);
84   c = (leftOpnd > rightOpnd);
85   v = ((rightOpnd & 0x80000000) != (leftOpnd & 0x80000000)
86        && (rightOpnd & 0x80000000) != (value & 0x80000000));
87 
88   PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
89   PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
90 	  | (c ? PSW_C : 0) | (v ? PSW_V : 0));
91 }
92 
93 
94 INLINE_SIM_MAIN (void)
95 genericOr(uint32_t source, uint32_t destReg)
96 {
97   int n, z;
98 
99   State.regs[destReg] |= source;
100   z = (State.regs[destReg] == 0);
101   n = (State.regs[destReg] & 0x80000000) != 0;
102   PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
103   PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
104 }
105 
106 
107 INLINE_SIM_MAIN (void)
108 genericXor(uint32_t source, uint32_t destReg)
109 {
110   int n, z;
111 
112   State.regs[destReg] ^= source;
113   z = (State.regs[destReg] == 0);
114   n = (State.regs[destReg] & 0x80000000) != 0;
115   PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
116   PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
117 }
118 
119 
120 INLINE_SIM_MAIN (void)
121 genericBtst(uint32_t leftOpnd, uint32_t rightOpnd)
122 {
123   uint32_t temp;
124   int z, n;
125 
126   temp = rightOpnd;
127   temp &= leftOpnd;
128   n = (temp & 0x80000000) != 0;
129   z = (temp == 0);
130   PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
131   PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0);
132 }
133 
134 /* syscall */
135 INLINE_SIM_MAIN (void)
136 do_syscall (SIM_DESC sd)
137 {
138   /* Registers passed to trap 0.  */
139 
140   /* Function number.  */
141   reg_t func = State.regs[0];
142   /* Parameters.  */
143   reg_t parm1 = State.regs[1];
144   reg_t parm2 = load_word (State.regs[REG_SP] + 12);
145   reg_t parm3 = load_word (State.regs[REG_SP] + 16);
146   reg_t parm4 = load_word (State.regs[REG_SP] + 20);
147 
148   /* We use this for simulated system calls; we may need to change
149      it to a reserved instruction if we conflict with uses at
150      Matsushita.  */
151   int save_errno = errno;
152   errno = 0;
153 
154   if (cb_target_to_host_syscall (STATE_CALLBACK (sd), func) == CB_SYS_exit)
155     {
156       /* EXIT - caller can look in parm1 to work out the reason */
157       sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
158 		       parm1 == 0xdead ? sim_stopped : sim_exited,
159 		       parm1 == 0xdead ? SIM_SIGABRT : parm1);
160     }
161   else
162     {
163       long result, result2;
164       int errcode;
165 
166       sim_syscall_multi (STATE_CPU (simulator, 0), func, parm1, parm2,
167 			 parm3, parm4, &result, &result2, &errcode);
168 
169       /* Registers set by trap 0.  */
170       State.regs[0] = errcode;
171       State.regs[1] = result;
172     }
173 
174   errno = save_errno;
175 }
176