daily update
[deliverable/binutils-gdb.git] / sim / z8k / inlines.h
1 /* inline functions for Z8KSIM
2 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of Z8KSIM
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Z8KZIM; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #ifndef INLINE
21 #define INLINE
22 #endif
23 #define UGT 0x0b
24 #define ULE 0x03
25 #define ULT 0x07
26 #define UGE 0x0f
27 #define SLOW 0
28 #define T 0x8
29 #define F 0x0
30 #define LT 0x1
31 #define GT 0xa
32 #define LE 0x2
33 #define EQ 0x6
34 #define NE 0xe
35 #define GE 0x9
36
37 static int is_cond_true PARAMS((sim_state_type *context, int c));
38 static void makeflags PARAMS((sim_state_type *context, int mask));
39
40 static INLINE
41 long
42 sitoptr (si)
43 long si;
44 {
45 return ((si & 0xff000000) >> 8) | (si & 0xffff);
46 }
47 static INLINE long
48 ptrtosi (ptr)
49 long ptr;
50 {
51 return ((ptr & 0xff0000) << 8) | (ptr & 0xffff);
52 }
53
54 static INLINE
55 void
56 put_long_reg (context, reg, val)
57 sim_state_type *context;
58 int reg;
59 int val;
60 {
61 context->regs[reg].word = val >> 16;
62 context->regs[reg + 1].word = val;
63 }
64
65 static INLINE
66 void
67 put_quad_reg (context, reg, val1, val2)
68 sim_state_type *context;
69 int reg;
70 int val1;
71 int val2;
72 {
73 context->regs[reg].word = val2 >> 16;
74 context->regs[reg + 1].word = val2;
75 context->regs[reg + 2].word = val1 >> 16;
76 context->regs[reg + 3].word = val1;
77 }
78
79 static INLINE
80 void
81 put_word_reg (context, reg, val)
82 sim_state_type *context;
83 int reg;
84 int val;
85 {
86 context->regs[reg].word = val;
87 }
88
89 static INLINE
90 SItype get_long_reg (context, reg)
91 sim_state_type *context;
92 int reg;
93 {
94 USItype lsw = context->regs[reg + 1].word;
95 USItype msw = context->regs[reg].word;
96
97 return (msw << 16) | lsw;
98 }
99
100 #ifdef __GNUC__
101 static INLINE
102 struct UDIstruct
103 get_quad_reg (context, reg)
104 sim_state_type *context;
105 int reg;
106 {
107 UDItype res;
108 USItype lsw = get_long_reg (context, reg + 2);
109 USItype msw = get_long_reg (context, reg);
110
111 res.low = lsw;
112 res.high = msw;
113 return res;
114 }
115
116 #endif
117
118 static INLINE void
119 put_byte_mem_da (context, addr, value)
120 sim_state_type *context;
121 int addr;
122 int value;
123 {
124 ((unsigned char *) (context->memory))[addr] = value;
125 }
126
127 static INLINE
128 void
129 put_byte_reg (context, reg, val)
130 sim_state_type *context;
131 int reg;
132 int val;
133 {
134 int old = context->regs[reg & 0x7].word;
135 if (reg & 0x8)
136 {
137 old = old & 0xff00 | (val & 0xff);
138 }
139 else
140 {
141 old = old & 0x00ff | (val << 8);
142 }
143 context->regs[reg & 0x7].word = old;
144 }
145
146 static INLINE
147 int
148 get_byte_reg (context, reg)
149 sim_state_type *context;
150 int reg;
151 {
152 if (reg & 0x8)
153 return context->regs[reg & 0x7].word & 0xff;
154 else
155 return (context->regs[reg & 0x7].word >> 8) & 0xff;
156 }
157
158 static INLINE
159 void
160 put_word_mem_da (context, addr, value)
161 sim_state_type *context;
162 int addr;
163 int value;
164 {
165 if (addr & 1)
166 {
167 context->exception = SIM_BAD_ALIGN;
168 addr &= ~1;
169 }
170 put_byte_mem_da(context, addr, value>>8);
171 put_byte_mem_da(context, addr+1, value);
172 }
173
174 static INLINE unsigned char
175 get_byte_mem_da (context, addr)
176 sim_state_type *context;
177 int addr;
178 {
179 return ((unsigned char *) (context->memory))[addr];
180 }
181
182
183 #if 0
184 #define get_word_mem_da(context,addr)\
185 *((unsigned short*)((char*)((context)->memory)+(addr)))
186
187 #else
188 #define get_word_mem_da(context,addr) (get_byte_mem_da(context, addr) << 8) | (get_byte_mem_da(context,addr+1))
189 #endif
190
191 #define get_word_reg(context,reg) (context)->regs[reg].word
192
193 static INLINE
194 SItype
195 get_long_mem_da (context, addr)
196 sim_state_type *context;
197 int addr;
198 {
199 USItype lsw = get_word_mem_da(context,addr+2);
200 USItype msw = get_word_mem_da(context, addr);
201
202 return (msw << 16) + lsw;
203 }
204
205 static INLINE
206 void
207 put_long_mem_da (context, addr, value)
208 sim_state_type *context;
209 int addr;
210 int value;
211 {
212 put_word_mem_da(context,addr, value>>16);
213 put_word_mem_da(context,addr+2, value);
214 }
215
216 static INLINE
217 int
218 get_word_mem_ir (context, reg)
219 sim_state_type *context;
220 int reg;
221 {
222 return get_word_mem_da (context, get_word_reg (context, reg));
223 }
224
225 static INLINE
226 void
227 put_word_mem_ir (context, reg, value)
228 sim_state_type *context;
229 int reg;
230 int value;
231 {
232
233 put_word_mem_da (context, get_word_reg (context, reg), value);
234 }
235
236 static INLINE
237 int
238 get_byte_mem_ir (context, reg)
239 sim_state_type *context;
240 int reg;
241 {
242 return get_byte_mem_da (context, get_word_reg (context, reg));
243 }
244
245 static INLINE
246 void
247 put_byte_mem_ir (context, reg, value)
248 sim_state_type *context;
249 int reg;
250 int value;
251 {
252 put_byte_mem_da (context, get_word_reg (context, reg), value);
253 }
254
255 static INLINE
256 int
257 get_long_mem_ir (context, reg)
258 sim_state_type *context;
259 int reg;
260 {
261 return get_long_mem_da (context, get_word_reg (context, reg));
262 }
263
264 static INLINE
265 void
266 put_long_mem_ir (context, reg, value)
267 sim_state_type *context;
268 int reg;
269 int value;
270 {
271
272 put_long_mem_da (context, get_word_reg (context, reg), value);
273 }
274
275 static INLINE
276 void
277 put_long_mem_x (context, base, reg, value)
278 sim_state_type *context;
279 int base;
280 int reg;
281 int value;
282 {
283 put_long_mem_da (context, get_word_reg (context, reg) + base, value);
284 }
285
286 static INLINE
287 void
288 put_word_mem_x (context, base, reg, value)
289 sim_state_type *context;
290 int base;
291 int reg;
292 int value;
293 {
294 put_word_mem_da (context, get_word_reg (context, reg) + base, value);
295 }
296
297 static INLINE
298 void
299 put_byte_mem_x (context, base, reg, value)
300 sim_state_type *context;
301 int base;
302 int reg;
303 int value;
304 {
305 put_byte_mem_da (context, get_word_reg (context, reg) + base, value);
306 }
307
308 static INLINE
309 int
310 get_word_mem_x (context, base, reg)
311 sim_state_type *context;
312 int base;
313 int reg;
314 {
315 return get_word_mem_da (context, base + get_word_reg (context, reg));
316 }
317
318 static INLINE
319 int
320 get_byte_mem_x (context, base, reg)
321 sim_state_type *context;
322 int base;
323 int reg;
324 {
325 return get_byte_mem_da (context, base + get_word_reg (context, reg));
326 }
327
328 static INLINE
329 int
330 get_long_mem_x (context, base, reg)
331 sim_state_type *context;
332 int base;
333 int reg;
334 {
335 return get_long_mem_da (context, base + get_word_reg (context, reg));
336 }
337
338
339 static
340 void
341 makeflags (context, mask)
342 sim_state_type *context;
343 int mask;
344 {
345
346 PSW_ZERO = (context->dst & mask) == 0;
347 PSW_SIGN = (context->dst >> (context->size - 1));
348
349 if (context->broken_flags == TST_FLAGS)
350 {
351 extern char the_parity[];
352
353 if (context->size == 8)
354 {
355 PSW_OVERFLOW = the_parity[context->dst & 0xff];
356 }
357 }
358 else
359 {
360 /* Overflow is set if both operands have the same sign and the
361 result is of different sign.
362
363 V = A==B && R!=B jumping logic
364 (~(A^B))&(R^B)
365 V = (A^B)^(R^B) boolean
366 */
367
368 PSW_OVERFLOW =
369 ((
370 (~(context->srca ^ context->srcb)
371 & (context->srca ^ context->dst))
372 ) >> (context->size - 1)
373 );
374
375 if (context->size < 32)
376 {
377 PSW_CARRY = ((context->dst >> context->size)) & 1;
378 }
379 else
380 {
381 /* carry is set when the result is smaller than a source */
382
383
384 PSW_CARRY = (unsigned) context->dst > (unsigned) context->srca ;
385
386 }
387 }
388 context->broken_flags = 0;
389 }
390
391
392 /* There are two ways to calculate the flags. We can
393 either always calculate them and so the cc will always
394 be correct, or we can only keep the arguments around and
395 calc the flags when they're actually going to be used. */
396
397 /* Right now we always calc the flags - I think it may be faster*/
398
399
400 #define NORMAL_FLAGS(c,s,d,sa,sb,sub) \
401 if (s == 8) \
402 normal_flags_8(c,d,sa,sb,sub); \
403 else if (s == 16) \
404 normal_flags_16(c,d,sa,sb,sub); \
405 else if (s == 32) \
406 normal_flags_32(c,d,sa,sb,sub);
407
408 static INLINE
409 void
410 normal_flags (context, size, dst, srca, srcb)
411 sim_state_type *context;
412 int size;
413 int dst;
414 int srca;
415 int srcb;
416 {
417 context->srca = srca;
418 context->srcb = srcb;
419 context->dst = dst;
420 context->size = size;
421 context->broken_flags = CMP_FLAGS;
422 }
423
424 static INLINE
425 void
426 TEST_NORMAL_FLAGS (context, size, dst)
427 sim_state_type *context;
428 int size;
429 int dst;
430 {
431 context->dst = dst;
432 context->size = size;
433 context->broken_flags = TST_FLAGS;
434 }
435
436 static INLINE
437 void
438 put_ptr_long_reg (context, reg, val)
439 sim_state_type *context;
440 int reg;
441 int val;
442 {
443 context->regs[reg].word = (val >> 8) & 0x7f00;
444 context->regs[reg + 1].word = val;
445 }
446
447 static INLINE
448 long
449 get_ptr_long_reg (context, reg)
450 sim_state_type *context;
451 int reg;
452 {
453 int val;
454
455 val = (context->regs[reg].word << 8) | context->regs[reg + 1].word;
456 return val;
457 }
458
459 static INLINE
460 long
461 get_ptr_long_mem_ir (context, reg)
462 sim_state_type *context;
463 int reg;
464 {
465 return sitoptr (get_long_mem_da (context, get_ptr_long_reg (context, reg)));
466 }
467
468 static INLINE
469 long
470 get_ptr_long_mem_da (context, addr)
471 sim_state_type *context;
472 long addr;
473 {
474 return sitoptr (get_long_mem_da (context, addr));
475 }
476
477 static INLINE
478 void
479 put_ptr_long_mem_da (context, addr, ptr)
480 sim_state_type *context;
481 long addr;
482 long ptr;
483 {
484 put_long_mem_da (context, addr, ptrtosi (ptr));
485
486 }
This page took 0.038925 seconds and 4 git commands to generate.