* sim/ucsim/avr.src/arith_inst.cc: fixed bug #1088372- savr is not
[fw/sdcc] / sim / ucsim / avr.src / arith_inst.cc
1 /*
2  * Simulator of microcontrollers (arith_inst.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * 
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING.  If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26 /*@1@*/
27
28 #include "avrcl.h"
29 #include "regsavr.h"
30
31
32 /*
33  * Compare with Immediate
34  * CPI Rd,K 16<=d<=31, 0<=K<=255
35  * 0011 KKKK dddd KKKK
36  *____________________________________________________________________________
37  */
38
39 int
40 cl_avr::cpi_Rd_K(t_mem code)
41 {
42   t_addr d;
43   t_mem D, K, result, res;
44
45   d= 16+(code&0xf0)>>4;
46   K= (code&0xf) | ((code&0xf00)>>8);
47   D= ram->read(d);
48
49   if (K & 0x80)
50     K|= ~0xff;
51   if (D & 0x80)
52     D|= ~0xff;
53   t_mem sreg= ram->get(SREG);
54   result= (signed)D-(signed)K;
55   res= result & 0xff;
56   
57   sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C|BIT_Z);
58   if (0x08 & (((~D)&K) | (K&res) | (res&(~D))))
59     sreg|= BIT_H;
60   int n= 0, v= 0;
61   if (0x80 & ((D&(~K)&(~res)) | ((~D)&K&res)))
62     {
63       sreg|= BIT_V;
64       v= 1;
65     }
66   if (res & 0x80)
67     {
68       sreg|= BIT_N;
69       n= 1;
70     }
71   if ((n ^ v) & 1)
72     sreg|= BIT_S;
73   if (!res)
74     sreg|= BIT_Z;
75   if (0x80 & (((~D)&K) | (K&res) | (res&(~D))))
76     sreg|= BIT_C;
77   ram->set(SREG, sreg);
78   return(resGO);
79 }
80
81
82 /*
83  * Substract Immediate with Carry
84  * SBCI Rd,K 16<=d<=31, 0<=K<=255
85  * 0100 KKKK dddd KKKK
86  *____________________________________________________________________________
87  */
88
89 int
90 cl_avr::sbci_Rd_K(t_mem code)
91 {
92   t_addr d;
93   t_mem D, K, result, res;
94
95   d= 16+(code&0xf0)>>4;
96   K= (code&0xf) | ((code&0xf00)>>8);
97   D= ram->read(d);
98
99   if (K & 0x80)
100     K|= ~0xff;
101   if (D & 0x80)
102     D|= ~0xff;
103   t_mem sreg= ram->get(SREG);
104   result= (signed)D-(signed)K-(sreg&BIT_C)?1:0;
105   res= result & 0xff;
106   ram->write(d, res);
107   
108   sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C);
109   if (0x08 & (((~D)&K) | (K&res) | (res&(~D))))
110     sreg|= BIT_H;
111   int n= 0, v= 0;
112   if (0x80 & ((D&(~K)&(~res)) | ((~D)&K&res)))
113     {
114       sreg|= BIT_V;
115       v= 1;
116     }
117   if (res & 0x80)
118     {
119       sreg|= BIT_N;
120       n= 1;
121     }
122   if ((n ^ v) & 1)
123     sreg|= BIT_S;
124   if (res)
125     sreg&= ~BIT_Z;
126   if (0x80 & (((~D)&K) | (K&res) | (res&(~D))))
127     sreg|= BIT_C;
128   ram->set(SREG, sreg);
129   return(resGO);
130 }
131
132
133 /*
134  * Substract Immediate
135  * SUBI Rd,K 16<=d<=31, 0<=K<=255
136  * 0101 KKKK dddd KKKK
137  *____________________________________________________________________________
138  */
139
140 int
141 cl_avr::subi_Rd_K(t_mem code)
142 {
143   t_addr d;
144   t_mem D, K, result, res;
145
146   d= 16+(code&0xf0)>>4;
147   K= (code&0xf) | ((code&0xf00)>>8);
148   D= ram->read(d);
149
150   if (K & 0x80)
151     K|= ~0xff;
152   if (D & 0x80)
153     D|= ~0xff;
154   result= (signed)D-(signed)K;
155   res= result & 0xff;
156   ram->write(d, res);
157   
158   t_mem sreg= ram->get(SREG) & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
159   if (0x08 & (((~D)&K) | (K&res) | (res&(~D))))
160     sreg|= BIT_H;
161   int n= 0, v= 0;
162   if (0x80 & ((D&(~K)&(~res)) | ((~D)&K&res)))
163     {
164       sreg|= BIT_V;
165       v= 1;
166     }
167   if (res & 0x80)
168     {
169       sreg|= BIT_N;
170       n= 1;
171     }
172   if ((n ^ v) & 1)
173     sreg|= BIT_S;
174   if (!res)
175     sreg|= BIT_Z;
176   if (0x80 & (((~D)&K) | (K&res) | (res&(~D))))
177     sreg|= BIT_C;
178   ram->set(SREG, sreg);
179   return(resGO);
180 }
181
182
183 int
184 cl_avr::muls_Rd_Rr(t_mem code)
185 {
186   return(resGO);
187 }
188
189
190 int
191 cl_avr::mulsu_Rd_Rr(t_mem code)
192 {
193   return(resGO);
194 }
195
196
197 int
198 cl_avr::fmul_Rd_Rr(t_mem code)
199 {
200   return(resGO);
201 }
202
203
204 int
205 cl_avr::fmuls_Rd_Rr(t_mem code)
206 {
207   return(resGO);
208 }
209
210
211 int
212 cl_avr::fmulsu_Rd_Rr(t_mem code)
213 {
214   return(resGO);
215 }
216
217
218 /*
219  * Compare with Carry
220  * CPC Rd,Rr 0<=d<=31, 0<=r<=31
221  * 0000 01rd dddd rrrr
222  *____________________________________________________________________________
223  */
224
225 int
226 cl_avr::cpc_Rd_Rr(t_mem code)
227 {
228   t_addr r, d;
229   t_mem R, D, result, res;
230
231   d= (code&0x1f0)>>4;
232   r= ((code&0x200)>>5)|(code&0xf);
233   R= ram->read(r);
234   D= ram->read(d);
235   if (R & 0x80)
236     R|= ~0xff;
237   if (D & 0x80)
238     D|= ~0xff;
239   t_mem sreg= ram->get(SREG);
240   result= (signed)D-(signed)R-(sreg&BIT_C)?1:0;
241   res= result & 0xff;
242   
243   sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C);
244   if (0x08 & (((~D)&R) | (R&res) | (res&(~D))))
245     sreg|= BIT_H;
246   int n= 0, v= 0;
247   if (0x80 & ((D&(~R)&(~res)) | ((~D)&R&res)))
248     {
249       sreg|= BIT_V;
250       v= 1;
251     }
252   if (res & 0x80)
253     {
254       sreg|= BIT_N;
255       n= 1;
256     }
257   if ((n ^ v) & 1)
258     sreg|= BIT_S;
259   if (res)
260     sreg&= ~BIT_Z;
261   if (0x80 & (((~D)&R) | (R&res) | (res&(~D))))
262     sreg|= BIT_C;
263   ram->set(SREG, sreg);
264   return(resGO);
265 }
266
267
268 /*
269  * Substract with Carry
270  * SBC Rd,Rr 0<=d<=31, 0<=r<=31
271  * 0000 10rd dddd rrrr
272  *____________________________________________________________________________
273  */
274
275 int
276 cl_avr::sbc_Rd_Rr(t_mem code)
277 {
278   t_addr r, d;
279   t_mem R, D, result, res;
280
281   d= (code&0x1f0)>>4;
282   r= ((code&0x200)>>5)|(code&0xf);
283   R= ram->read(r);
284   D= ram->read(d);
285   if (R & 0x80)
286     R|= ~0xff;
287   if (D & 0x80)
288     D|= ~0xff;
289   t_mem sreg= ram->get(SREG);
290   result= (signed)D-(signed)R-(sreg&BIT_C)?1:0;
291   res= result & 0xff;
292   ram->write(d, res);
293   
294   sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C);
295   if (0x08 & (((~D)&R) | (R&res) | (res&(~D))))
296     sreg|= BIT_H;
297   int n= 0, v= 0;
298   if (0x80 & ((D&(~R)&(~res)) | ((~D)&R&res)))
299     {
300       sreg|= BIT_V;
301       v= 1;
302     }
303   if (res & 0x80)
304     {
305       sreg|= BIT_N;
306       n= 1;
307     }
308   if ((n ^ v) & 1)
309     sreg|= BIT_S;
310   if (res)
311     sreg&= ~BIT_Z;
312   if (0x80 & (((~D)&R) | (R&res) | (res&(~D))))
313     sreg|= BIT_C;
314   ram->set(SREG, sreg);
315   return(resGO);
316 }
317
318
319 /*
320  * Add without Carry
321  * ADD Rd,Rr 0<=d<=31, 0<=r<=31
322  * 0000 11rd dddd rrrr
323  *____________________________________________________________________________
324  */
325
326 int
327 cl_avr::add_Rd_Rr(t_mem code)
328 {
329   t_addr r, d;
330   t_mem R, D, result, res;
331
332   d= (code&0x1f0)>>4;
333   r= ((code&0x200)>>5)|(code&0xf);
334   R= ram->read(r);
335   D= ram->read(d);
336   result= D+R;
337   res= result & 0xff;
338   ram->write(d, res);
339   
340   t_mem sreg= ram->get(SREG);
341   if (!res)
342     sreg|= BIT_Z;
343   else
344     sreg&= ~BIT_Z;
345   if (((D&R&~res)&0x80) ||
346       ((~D&~R&res)&0x80))
347     sreg|= (BIT_V|BIT_S);
348   else
349     sreg&= ~(BIT_V|BIT_S);
350   if (res & 0x80)
351     {
352       sreg|= BIT_N;
353       sreg^= BIT_S;
354     }
355   else
356     sreg&= ~BIT_N;
357   if (result & ~0xff)
358     sreg|= BIT_C;
359   else
360     sreg&= ~BIT_C;
361   if ((R&0xf) + (D&0xf) > 15)
362     sreg|= BIT_H;
363   else
364     sreg&= ~BIT_H;
365   ram->set(SREG, sreg);
366
367   return(resGO);
368 }
369
370
371 /*
372  * Compare
373  * CP Rd,Rr 0<=d<=31, 0<=r<=31
374  * 0001 01rd dddd rrrr
375  *____________________________________________________________________________
376  */
377
378 int
379 cl_avr::cp_Rd_Rr(t_mem code)
380 {
381   t_addr r, d;
382   t_mem R, D, result, res;
383
384   d= (code&0x1f0)>>4;
385   r= ((code&0x200)>>5)|(code&0xf);
386   R= ram->read(r);
387   D= ram->read(d);
388   if (R & 0x80)
389     R|= ~0xff;
390   if (D & 0x80)
391     D|= ~0xff;
392   result= (signed)D-(signed)R;
393   res= result & 0xff;
394   
395   t_mem sreg= ram->get(SREG) & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
396   if (0x08 & (((~D)&R) | (R&res) | (res&(~D))))
397     sreg|= BIT_H;
398   int n= 0, v= 0;
399   if (0x80 & ((D&(~R)&(~res)) | ((~D)&R&res)))
400     {
401       sreg|= BIT_V;
402       v= 1;
403     }
404   if (res & 0x80)
405     {
406       sreg|= BIT_N;
407       n= 1;
408     }
409   if ((n ^ v) & 1)
410     sreg|= BIT_S;
411   if (!res)
412     sreg|= BIT_Z;
413   if (0x80 & (((~D)&R) | (R&res) | (res&(~D))))
414     sreg|= BIT_C;
415   ram->set(SREG, sreg);
416   return(resGO);
417 }
418
419
420 /*
421  * Substract without Carry
422  * SUB Rd,Rr 0<=d<=31, 0<=r<=31
423  * 0001 10rd dddd rrrr
424  *____________________________________________________________________________
425  */
426
427 int
428 cl_avr::sub_Rd_Rr(t_mem code)
429 {
430   t_addr r, d;
431   t_mem R, D, result, res;
432
433   d= (code&0x1f0)>>4;
434   r= ((code&0x200)>>5)|(code&0xf);
435   R= ram->read(r);
436   D= ram->read(d);
437   if (R & 0x80)
438     R|= ~0xff;
439   if (D & 0x80)
440     D|= ~0xff;
441   result= (signed)D-(signed)R;
442   res= result & 0xff;
443   ram->write(d, res);
444   
445   t_mem sreg= ram->get(SREG) & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
446   if (0x08 & (((~D)&R) | (R&res) | (res&(~D))))
447     sreg|= BIT_H;
448   int n= 0, v= 0;
449   if (0x80 & ((D&(~R)&(~res)) | ((~D)&R&res)))
450     {
451       sreg|= BIT_V;
452       v= 1;
453     }
454   if (res & 0x80)
455     {
456       sreg|= BIT_N;
457       n= 1;
458     }
459   if ((n ^ v) & 1)
460     sreg|= BIT_S;
461   if (!res)
462     sreg|= BIT_Z;
463   if (0x80 & (((~D)&R) | (R&res) | (res&(~D))))
464     sreg|= BIT_C;
465   ram->set(SREG, sreg);
466   return(resGO);
467 }
468
469
470 /*
471  * Add with Carry
472  * ADC Rd,Rr 0<=d<=31, 0<=r<=31
473  * 0001 11rd dddd rrrr
474  *____________________________________________________________________________
475  */
476
477 int
478 cl_avr::adc_Rd_Rr(t_mem code)
479 {
480   t_addr r, d;
481   t_mem R, D, result, res;
482
483   d= (code&0x1f0)>>4;
484   r= ((code&0x200)>>5)|(code&0xf);
485   R= ram->read(r);
486   D= ram->read(d);
487   t_mem sreg= ram->get(SREG);
488   result= D+R+((sreg&BIT_C)?1:0);
489   res= result & 0xff;
490   ram->write(d, res);
491   
492   if (!res)
493     sreg|= BIT_Z;
494   else
495     sreg&= ~BIT_Z;
496   if (((D&R&~res)&0x80) ||
497       ((~D&~R&res)&0x80))
498     sreg|= (BIT_V|BIT_S);
499   else
500     sreg&= ~(BIT_V|BIT_S);
501   if (res & 0x80)
502     {
503       sreg|= BIT_N;
504       sreg^= BIT_S;
505     }
506   else
507     sreg&= ~BIT_N;
508   if (result & ~0xff)
509     sreg|= BIT_C;
510   else
511     sreg&= ~BIT_C;
512   if ((R&0xf) + (D&0xf) > 15)
513     sreg|= BIT_H;
514   else
515     sreg&= ~BIT_H;
516   ram->set(SREG, sreg);
517
518   return(resGO);
519 }
520
521
522 /*
523  * One's Complement
524  * COM Rd 0<=d<=31
525  * 1001 010d dddd 0000
526  *____________________________________________________________________________
527  */
528
529 int
530 cl_avr::com_Rd(t_mem code)
531 {
532   t_addr d;
533   t_mem D, result, res;
534
535   d= (code&0x1f0)>>4;
536   D= ram->read(d);
537   result= ~D;
538   res= result & 0xff;
539   ram->write(d, res);
540   
541   t_mem sreg= ram->get(SREG);
542   if (!res)
543     sreg|= BIT_Z;
544   else
545     sreg&= ~BIT_Z;
546   sreg&= ~BIT_V;
547   if (res & 0x80)
548     sreg|= (BIT_N|BIT_S);
549   else
550     sreg&= ~(BIT_N|BIT_S);
551   sreg|= BIT_C;
552   ram->set(SREG, sreg);
553
554   return(resGO);
555 }
556
557
558 /*
559  * Two's Complement
560  * NEG Rd 0<=d<=31
561  * 1001 010d dddd 0001
562  *____________________________________________________________________________
563  */
564
565 int
566 cl_avr::neg_Rd(t_mem code)
567 {
568   t_addr d;
569   t_mem D, result, res;
570
571   d= (code&0x1f0)>>4;
572   D= ram->read(d);
573   result= (~D)+1;
574   res= result & 0xff;
575   ram->write(d, res);
576   
577   t_mem sreg= ram->get(SREG);
578   if (res & (~d) & 0x08)
579     sreg|= BIT_H;
580   else
581     sreg&= ~BIT_H;
582   if (res > 0x80)
583     sreg|= BIT_S;
584   else
585     sreg&= ~BIT_S;
586   if (!res)
587     {
588       sreg|= BIT_Z;
589       sreg&= ~BIT_C;
590     }
591   else
592     {
593       sreg&= ~BIT_Z;
594       sreg|= BIT_C;
595     }
596   if (res == 0x80)
597     sreg|= BIT_V;
598   else
599     sreg&= ~BIT_V;
600   if (res & 0x80)
601     sreg|= (BIT_N);
602   else
603     sreg&= ~BIT_N;
604   ram->set(SREG, sreg);
605
606   return(resGO);
607 }
608
609
610 /*
611  * Increment
612  * INC Rd 0<=d<=31
613  * 1001 010d dddd 0011
614  *____________________________________________________________________________
615  */
616
617 int
618 cl_avr::inc_Rd(t_mem code)
619 {
620   t_addr d;
621
622   d= (code&0x1f0)>>4;
623   t_mem data= ram->read(d)+1;
624   ram->write(d, data);
625
626   t_mem sreg= ram->get(SREG);
627   data= data&0xff;
628   if (data & 0x80)
629     {
630       sreg|= (BIT_N);
631       if (data == 0x80)
632         {
633           sreg|= BIT_V;
634           sreg&= ~BIT_S;
635         }
636       else
637         {
638           sreg&= ~BIT_V;
639           sreg|= BIT_S;
640         }
641       sreg&= ~BIT_Z;
642     }
643   else
644     {
645       sreg&= ~(BIT_N|BIT_V|BIT_S);
646       if (!data)
647         sreg|= BIT_Z;
648       else
649         sreg&= ~BIT_Z;
650     }
651   ram->set(SREG, sreg);
652   return(resGO);
653 }
654
655
656 /*
657  * Arithmetic Shift Right
658  * ASR Rd 0<=d<=31
659  * 1001 010d dddd 0101
660  *____________________________________________________________________________
661  */
662
663 int
664 cl_avr::asr_Rd(t_mem code)
665 {
666   t_addr d;
667   t_mem D, result, res;
668
669   d= (code&0x1f0)>>4;
670   D= ram->read(d);
671   t_mem sreg= ram->read(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
672   int n=0, v= 0, c= 0;
673   if (D & 1)
674     {
675       sreg|= BIT_C;
676       c= 1;
677     }
678   result= D>>1;
679   if (result & 0x40)
680     result|= 0x80;
681   res= result & 0xff;
682   ram->write(d, res);
683   if (res & 0x80)
684     {
685       sreg|= BIT_N;
686       n= 1;
687     }
688   if ((n ^ c) & 1)
689     {
690       sreg|= BIT_V;
691       v= 1;
692     }
693   if ((n ^ v) & 1)
694     sreg|= BIT_S;
695   if (!res)
696     sreg|= BIT_Z;
697   ram->write(SREG, sreg);
698   return(resGO);
699 }
700
701
702 /*
703  * Logical Shift Right
704  * LSR Rd 0<=d<=31
705  * 1001 010d dddd 0110
706  *____________________________________________________________________________
707  */
708
709 int
710 cl_avr::lsr_Rd(t_mem code)
711 {
712   t_addr d;
713   t_mem D, result, res;
714
715   d= (code &0x1f0)>>4;
716   D= ram->read(d);
717   t_mem sreg= ram->read(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
718   if (D & 1)
719     sreg|= (BIT_C|BIT_V|BIT_S);
720   result= D >> 1;
721   res= result & 0xff;
722   ram->write(d, res);
723   if (!res)
724     sreg|= BIT_Z;
725   ram->write(SREG, sreg);
726   return(resGO);
727 }
728
729
730 /*
731  * Rotate Right trough Carry
732  * ROR Rd 0<=d<=31
733  * 1001 010d dddd 0111
734  *____________________________________________________________________________
735  */
736
737 int
738 cl_avr::ror_Rd(t_mem code)
739 {
740   t_addr d;
741   t_mem D, result, res;
742
743   d= (code&0x1f0)>>4;
744   D= ram->read(d);
745   t_mem sreg= ram->read(SREG);
746   int oldc= sreg & BIT_C;
747   sreg= sreg & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
748   int n= 0, v= 0, c= 0;
749   if (D & 1)
750     {
751       sreg|= BIT_C;
752       c= 1;
753     }
754   result= (D >> 1) | oldc?0x80:0;
755   res= result & 0xff;
756   ram->write(d, res);
757   if (res & 0x80)
758     {
759       sreg|= BIT_N;
760       n= 1;
761     }
762   if ((n ^ c) & 1)
763     {
764       sreg|= BIT_V;
765       v= 1;
766     }
767   if ((n ^ v) & 1)
768     sreg|= BIT_S;
769   if (!res)
770     sreg|= BIT_Z;
771   ram->write(SREG, sreg);
772   return(resGO);
773 }
774
775
776 /*
777  * Decrement
778  * DEC Rd 0<=d<=31
779  * 1001 010d dddd 1010
780  *____________________________________________________________________________
781  */
782
783 int
784 cl_avr::dec_Rd(t_mem code)
785 {
786   t_addr d;
787   t_mem D, result, res;
788
789   d= (code&0x1f0)>>4;
790   D= ram->read(d);
791   result= D-1;
792   res= result & 0xff;
793   ram->write(d, res);
794
795   t_mem sreg= ram->get(SREG);
796   if (!res)
797     sreg|= BIT_Z;
798   else
799     sreg&= ~BIT_Z;
800   int n= 0, v= 0;
801   if (res & 0x80)
802     {
803       sreg|= BIT_N;
804       n= 1;
805     }
806   else
807     sreg&= ~BIT_N;
808   if (D == 0x80)
809     {
810       sreg|= BIT_V;
811       v= 1;
812     }
813   else
814     sreg&= ~BIT_V;
815   if ((n ^ v) & 1)
816     sreg|= BIT_S;
817   else
818     sreg&= ~BIT_S;
819   ram->set(SREG, sreg);
820
821   return(resGO);
822 }
823
824
825 /*
826  * Multiply
827  * MUL Rd,Rr 0<=d<=31, 0<=r<=31
828  * 1001 11rd dddd rrrr
829  *____________________________________________________________________________
830  */
831
832 int
833 cl_avr::mul_Rd_Rr(t_mem code)
834 {
835   t_addr d, r;
836   t_mem D, R, result, resl, resh;
837
838   d= (code>>4) & 0x1f;
839   r= ((code&0x200)>>5) | (code&0xf);
840   D= ram->read(d);
841   R= ram->read(r);
842   result= R*D;
843   resl= result & 0xff;
844   resh= (result>>8) & 0xff;
845   ram->write(0, resl);
846   ram->write(1, resh);
847   t_mem sreg= ram->read(SREG) & ~BIT_C;
848   if (resh & 0x80)
849     sreg|= BIT_C;
850   ram->write(SREG, sreg);
851   tick(1);
852   return(resGO);
853 }
854
855
856 /*
857  * Add Immediate to Word
858  * ADIW Rdl,K dl={24,26,28,30}, 0<=K<=63
859  * 1001 0110 KK dd KKKK
860  *____________________________________________________________________________
861  */
862
863 int
864 cl_avr::adiw_Rdl_K(t_mem code)
865 {
866   t_addr dl;
867   t_mem D, K, result, res;
868
869   dl= 24+(2*((code&0x30)>>4));
870   K= ((code&0xc0)>>2)|(code&0xf);
871   D= ram->read(dl+1)*256 + ram->read(dl);
872   result= D+K;
873   res= result & 0xffff;
874   t_mem resl= result&0xff, resh= (result>>8)&0xff;
875   ram->write(dl+1, resh);
876   ram->write(dl, resl);
877   
878   t_mem sreg= ram->get(SREG);
879   if (!res)
880     sreg|= BIT_Z;
881   else
882     sreg&= ~BIT_Z;
883   if (D&res&0x8000)
884     sreg|= (BIT_V|BIT_S);
885   else
886     sreg&= ~(BIT_V|BIT_S);
887   if (res & 0x8000)
888     {
889       sreg|= BIT_N;
890       sreg^= BIT_S;
891     }
892   else
893     sreg&= ~BIT_N;
894   if ((~res)&D&0x8000)
895     sreg|= BIT_C;
896   else
897     sreg&= ~BIT_C;
898   ram->set(SREG, sreg);
899   tick(1);
900
901   return(resGO);
902 }
903
904
905 /*
906  * Substract Immediate from Word
907  * SBIW Rdl,K dl={24,26,28,30}, 0<=K<=63
908  * 1001 0111 KK dd KKKK
909  *____________________________________________________________________________
910  */
911
912 int
913 cl_avr::sbiw_Rdl_K(t_mem code)
914 {
915   t_addr dl;
916   t_mem D, K, result, res;
917
918   dl= 24+(2*((code&0x30)>>4));
919   K= ((code&0xc0)>>2)|(code&0xf);
920   D= ram->read(dl+1)*256 + ram->read(dl);
921   if (K & 0x20)
922     K|= ~0x3f;
923   if (D & 0x8000)
924     D|= ~0xffff;
925   result= (signed)D-(signed)K;
926   res= result & 0xffff;
927   t_mem resl= res&0xff, resh= (res>>8)&0xff;
928   ram->write(dl+1, resh);
929   ram->write(dl, resl);
930
931   t_mem sreg= ram->get(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
932   int n= 0, v= 0;
933   if (0x8000 & D & (~res))
934     {
935       sreg|= BIT_V;
936       v= 1;
937     }
938   if (res & 0x8000)
939     {
940       sreg|= BIT_N;
941       n= 1;
942     }
943   if ((n ^ v) & 1)
944     sreg|= BIT_S;
945   if (!res)
946     sreg|= BIT_Z;
947   if (0x8000 & res & (~D))
948     sreg|= BIT_C;
949   ram->set(SREG, sreg);
950   tick(1);
951
952   return(resGO);
953 }
954
955
956 /* End of avr.src/arith_inst.cc */