This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.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 }