2 * avr-sim: An atmel AVR simulator
3 * Copyright (C) 2008 Tom Haber
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "Instructions.h"
21 #include "DecoderHelp.h"
22 #include "ImplementationException.h"
32 #define EIND 0x10 //TODO
40 SReg(Core
*c
) : c(c
) {
41 reg
= c
->readStatus();
66 static int get_add_carry( byte res
, byte rd
, byte rr
, int b
) {
67 byte resb
= res
>> b
& 0x1;
68 byte rdb
= rd
>> b
& 0x1;
69 byte rrb
= rr
>> b
& 0x1;
70 return (rdb
& rrb
) | (rrb
& ~resb
) | (~resb
& rdb
);
73 static int get_add_overflow( byte res
, byte rd
, byte rr
) {
74 byte res7
= res
>> 7 & 0x1;
75 byte rd7
= rd
>> 7 & 0x1;
76 byte rr7
= rr
>> 7 & 0x1;
77 return (rd7
& rr7
& ~res7
) | (~rd7
& ~rr7
& res7
);
80 static int get_sub_carry( byte res
, byte rd
, byte rr
, int b
) {
81 byte resb
= res
>> b
& 0x1;
82 byte rdb
= rd
>> b
& 0x1;
83 byte rrb
= rr
>> b
& 0x1;
84 return (~rdb
& rrb
) | (rrb
& resb
) | (resb
& ~rdb
);
87 static int get_sub_overflow( byte res
, byte rd
, byte rr
) {
88 byte res7
= res
>> 7 & 0x1;
89 byte rd7
= rd
>> 7 & 0x1;
90 byte rr7
= rr
>> 7 & 0x1;
91 return (rd7
& ~rr7
& ~res7
) | (~rd7
& rr7
& res7
);
94 static int get_compare_carry( byte res
, byte rd
, byte rr
, int b
) {
95 byte resb
= res
>> b
& 0x1;
96 byte rdb
= rd
>> b
& 0x1;
97 byte rrb
= rr
>> b
& 0x1;
98 return (~rdb
& rrb
) | (rrb
& resb
) | (resb
& ~rdb
);
101 static int get_compare_overflow( byte res
, byte rd
, byte rr
) {
102 byte res7
= res
>> 7 & 0x1;
103 byte rd7
= rd
>> 7 & 0x1;
104 byte rr7
= rr
>> 7 & 0x1;
105 /* The atmel data sheet says the second term is ~rd7 for CP
106 * but that doesn't make any sense. You be the judge. */
107 return (rd7
& ~rr7
& ~res7
) | (~rd7
& rr7
& res7
);
110 static int n_bit_unsigned_to_signed( unsigned int val
, int n
) {
111 /* Convert n-bit unsigned value to a signed value. */
114 if ( (val
& (1 << (n
-1))) == 0)
117 /* manually calculate two's complement */
119 return -1 * ((~val
& mask
) + 1);
122 ADC::ADC(word opcode
) :
123 Rd( get_rd_5(opcode
) ),
124 Rr( get_rr_5(opcode
) ) {
127 int ADC::operator ()(Core
*core
) const {
129 unsigned char rd
= core
->readRegister(Rd
);
130 unsigned char rr
= core
->readRegister(Rr
);
131 unsigned char res
= rd
+ rr
+ status
.C
;
133 status
.H
= get_add_carry( res
, rd
, rr
, 3 );
134 status
.V
= get_add_overflow( res
, rd
, rr
);
135 status
.N
= ((res
>> 7) & 0x1);
136 status
.S
= (status
.N
^ status
.V
);
137 status
.Z
= ((res
& 0xff) == 0);
138 status
.C
= get_add_carry( res
, rd
, rr
, 7 );
140 core
->writeRegister(Rd
, res
);
141 return 1; //used clocks
144 ADD::ADD(word opcode
) :
145 Rd( get_rd_5(opcode
) ),
146 Rr( get_rr_5(opcode
) ) {
149 int ADD::operator ()(Core
*core
) const {
151 unsigned char rd
= core
->readRegister(Rd
);
152 unsigned char rr
= core
->readRegister(Rr
);
153 unsigned char res
= rd
+ rr
;
155 status
.H
= get_add_carry( res
, rd
, rr
, 3 ) ;
156 status
.V
= get_add_overflow( res
, rd
, rr
) ;
157 status
.N
= ((res
>> 7) & 0x1) ;
158 status
.S
= (status
.N
^ status
.V
) ;
159 status
.Z
= ((res
& 0xff) == 0) ;
160 status
.C
= get_add_carry( res
, rd
, rr
, 7 ) ;
162 core
->writeRegister(Rd
, res
);
163 return 1; //used clocks
166 ADIW::ADIW(word opcode
) :
167 Rl( get_rd_2(opcode
) ),
168 Rh( get_rd_2(opcode
) + 1 ),
169 K( get_K_6(opcode
) ) {
172 int ADIW::operator()(Core
*core
) const {
174 word rd
= (core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
177 unsigned char rdh
= Rh
;
178 status
.V
= (~(rdh
>> 7 & 0x1) & (res
>> 15 & 0x1));
179 status
.N
= ((res
>> 15) & 0x1);
180 status
.S
= (status
.N
^ status
.V
);
181 status
.Z
= ((res
& 0xffff) == 0);
182 status
.C
= (~(res
>> 15 & 0x1) & (rdh
>> 7 & 0x1));
184 core
->writeRegister(Rl
, res
& 0xff);
185 core
->writeRegister(Rh
, (res
>> 8) & 0xff);
189 AND::AND(word opcode
) :
190 Rd( get_rd_5(opcode
) ),
191 Rr( get_rr_5(opcode
) ) {
194 int AND::operator()(Core
*core
) const {
196 byte res
= core
->readRegister(Rd
) & core
->readRegister(Rr
);
199 status
.N
= ((res
>> 7) & 0x1) ;
200 status
.S
= (status
.N
^ status
.V
);
201 status
.Z
= ((res
& 0xff) == 0);
203 core
->writeRegister(Rd
, res
);
207 ANDI::ANDI(word opcode
) :
208 Rd( get_rd_4(opcode
) ),
209 K( get_K_8(opcode
) ) {
212 int ANDI::operator()(Core
*core
) const {
214 byte rd
= core
->readRegister(Rd
);
218 status
.N
= ((res
>> 7) & 0x1);
219 status
.S
= (status
.N
^ status
.V
);
220 status
.Z
= ((res
& 0xff) == 0);
222 core
->writeRegister(Rd
, res
);
226 ASR::ASR(word opcode
) :
227 Rd( get_rd_5(opcode
) ) {
230 int ASR::operator()(Core
*core
) const {
232 byte rd
= core
->readRegister(Rd
);
233 byte res
= (rd
>> 1) + (rd
& 0x80);
235 status
.N
= ((res
>> 7) & 0x1);
236 status
.C
= (rd
& 0x1);
237 status
.V
= (status
.N
^ status
.C
);
238 status
.S
= (status
.N
^ status
.V
);
239 status
.Z
= ((res
& 0xff) == 0);
241 core
->writeRegister(Rd
, res
);
245 BCLR::BCLR(word opcode
) :
246 K( ~(1<<get_sreg_bit(opcode
)) ) {
249 int BCLR::operator()(Core
*core
) const {
251 status
.reg
= status
.reg
& K
;
255 BLD::BLD(word opcode
) :
256 Rd( get_rd_5(opcode
) ),
257 Kadd(1<<get_reg_bit(opcode
)),
258 Kremove(~(1<<get_reg_bit(opcode
))) {
261 int BLD::operator()(Core
*core
) const {
263 byte rd
= core
->readRegister(Rd
);
272 core
->writeRegister(Rd
, res
);
276 BRBC::BRBC(word opcode
) :
277 bitmask( 1 << get_reg_bit(opcode
) ),
278 offset( n_bit_unsigned_to_signed( get_k_7(opcode
), 7) ) {
281 int BRBC::operator()(Core
*core
) const {
285 if( (status
.reg
& bitmask
) == 0 ) {
286 core
->jump( offset
);
296 BRBS::BRBS(word opcode
) :
297 bitmask( 1 << get_reg_bit(opcode
) ),
298 offset( n_bit_unsigned_to_signed( get_k_7(opcode
), 7) ) {
301 int BRBS::operator()(Core
*core
) const {
305 if( (status
.reg
& bitmask
) != 0 ) {
306 core
->jump( offset
);
315 BSET::BSET(word opcode
) :
316 K(1<<get_sreg_bit(opcode
)) {
319 int BSET::operator()(Core
*core
) const {
321 status
.reg
= status
.reg
| K
;
325 BST::BST(word opcode
) :
326 Rd( get_rd_5(opcode
) ),
327 K( get_reg_bit(opcode
) ) {
330 int BST::operator()(Core
*core
) const {
332 status
.T
= ((core
->readRegister(Rd
) & K
) != 0 );
336 CALL::CALL(word opcode
) :
337 KH( get_k_22(opcode
) ) {
340 int CALL::operator()(Core
*core
) const {
341 word offset
= core
->fetchOperand();
342 dword k
= (KH
<<16) | offset
;
344 core
->call( k
- 1, true );
345 return core
->pcBytes() + 2;
348 CBI::CBI(word opcode
) :
349 ioreg( get_A_5(opcode
) ),
350 K( ~( 1 << get_reg_bit(opcode
) ) ) {
353 int CBI::operator()(Core
*core
) const {
354 core
->writeIORegister(ioreg
, core
->readIORegister(ioreg
) & K
);
358 COM::COM(word opcode
) :
359 Rd( get_rd_5(opcode
) ) {
362 int COM::operator()(Core
*core
) const {
364 byte rd
= core
->readRegister(Rd
);
365 byte res
= 0xff - rd
;
367 status
.N
= ((res
>> 7) & 0x1) ;
370 status
.S
= (status
.N
^ status
.V
) ;
371 status
.Z
= ((res
& 0xff) == 0) ;
373 core
->writeRegister(Rd
, res
);
377 CP::CP(word opcode
) :
378 Rd( get_rd_5(opcode
) ),
379 Rr( get_rr_5(opcode
) ) {
382 int CP::operator()(Core
*core
) const {
384 byte rd
= core
->readRegister(Rd
);
385 byte rr
= core
->readRegister(Rr
);
388 status
.H
= get_compare_carry( res
, rd
, rr
, 3 ) ;
389 status
.V
= get_compare_overflow( res
, rd
, rr
) ;
390 status
.N
= ((res
>> 7) & 0x1);
391 status
.S
= (status
.N
^ status
.V
);
392 status
.Z
= ((res
& 0xff) == 0) ;
393 status
.C
= get_compare_carry( res
, rd
, rr
, 7 ) ;
398 CPC::CPC(word opcode
) :
399 Rd( get_rd_5(opcode
) ),
400 Rr( get_rr_5(opcode
) ) {
403 int CPC::operator()(Core
*core
) const {
405 byte rd
= core
->readRegister(Rd
);
406 byte rr
= core
->readRegister(Rr
);
407 byte res
= rd
- rr
- status
.C
;
409 status
.H
= get_compare_carry( res
, rd
, rr
, 3 ) ;
410 status
.V
= get_compare_overflow( res
, rd
, rr
) ;
411 status
.N
= ((res
>> 7) & 0x1) ;
412 status
.S
= (status
.N
^ status
.V
) ;
413 status
.C
= get_compare_carry( res
, rd
, rr
, 7 ) ;
415 /* Previous value remains unchanged when result is 0; cleared otherwise */
416 bool Z
= ((res
& 0xff) == 0);
417 bool prev_Z
= status
.Z
;
418 status
.Z
= Z
&& prev_Z
;
424 CPI::CPI(word opcode
) :
425 Rd( get_rd_4(opcode
) ),
429 int CPI::operator()(Core
*core
) const{
431 byte rd
= core
->readRegister(Rd
);
434 status
.H
= get_compare_carry( res
, rd
, K
, 3 ) ;
435 status
.V
= get_compare_overflow( res
, rd
, K
) ;
436 status
.N
= ((res
>> 7) & 0x1) ;
437 status
.S
= (status
.N
^ status
.V
) ;
438 status
.Z
= ((res
& 0xff) == 0) ;
439 status
.C
= get_compare_carry( res
, rd
, K
, 7 ) ;
444 CPSE::CPSE(word opcode
) :
445 Rd( get_rd_5(opcode
) ),
446 Rr( get_rr_5(opcode
) ) {
449 int CPSE::operator()(Core
*core
) const {
450 byte rd
= core
->readRegister(Rd
);
451 byte rr
= core
->readRegister(Rr
);
455 clks
+= core
->skip();
460 DEC::DEC(word opcode
) :
461 Rd( get_rd_5(opcode
) ) {
464 int DEC::operator()(Core
*core
) const {
466 byte res
= core
->readRegister(Rd
) - 1;
468 status
.N
= ((res
>> 7) & 0x1) ;
469 status
.V
= (res
== 0x7f) ;
470 status
.S
= (status
.N
^ status
.V
) ;
471 status
.Z
= ((res
& 0xff) == 0) ;
473 core
->writeRegister(Rd
, res
);
477 EICALL:: EICALL(word opcode
) :
481 int EICALL::operator()(Core
*core
) const {
483 throw util::ImplementationException("Instruction EICALL not fully implemented");
484 int new_pc
= core
->readRegister(Zl
) |
485 (core
->readRegister(Zh
)<<8) |
486 core
->readIORegister(eind
) << 16;
487 core
->call( new_pc
, true );
491 EIJMP::EIJMP(word opcode
) :
495 int EIJMP::operator()(Core
*core
) const {
497 throw util::ImplementationException("Instruction EIJMP not fully implemented");
498 int new_pc
= core
->readRegister(Zl
) |
499 (core
->readRegister(Zh
)<<8) |
500 (core
->readIORegister(eind
) & 0x3f) << 16;
501 core
->call( new_pc
, true );
505 ELPM_Z::ELPM_Z(word opcode
) :
506 Rd( get_rd_5(opcode
) ) {
509 int ELPM_Z::operator()(Core
*core
) const {
513 throw util::ImplementationException("Instruction ELPM_Z not fully implemented");
515 Z
= ((core
->GetRampz() & 0x3f) << 16) |
519 core
->writeRegister( Rd
, core
->readFlash(Z
) );
523 ELPM_Z_incr::ELPM_Z_incr(word opcode
) :
524 Rd( get_rd_5(opcode
) ) {
527 int ELPM_Z_incr::operator()(Core
*core
) const {
531 throw util::ImplementationException("Instruction ELPM_Z_incr not fully implemented");
533 Z
= ((core
->GetRampz() & 0x3f) << 16) |
537 core
->writeRegister( Rd
, core
->readFlash(Z
) );
539 /* post increment Z */
542 core
->SetRampz((Z
>> 16) & 0x3f);
544 core
->writeRegister(Zl
, Z
& 0xff);
545 core
->writeRegister(Zh
, (Z
>>8 & 0xff));
549 ELPM::ELPM(word opcode
) {}
551 int ELPM::operator()(Core
*core
) const {
555 throw util::ImplementationException("Instruction ELPM not fully implemented");
557 Z
= ((core
->GetRampz() & 0x3f) << 16) |
561 core
->writeRegister( R0
, core
->readFlash(Z
) );
565 EOR::EOR(word opcode
) :
566 Rd( get_rd_5(opcode
) ),
567 Rr( get_rr_5(opcode
) ) {
570 int EOR::operator()(Core
*core
) const {
572 byte rd
= core
->readRegister(Rd
);
573 byte rr
= core
->readRegister(Rr
);
578 status
.N
= ((res
>> 7) & 0x1) ;
579 status
.S
= (status
.N
^ status
.V
) ;
580 status
.Z
= ((res
& 0xff) == 0 ) ;
582 core
->writeRegister(Rd
, res
);
586 ESPM::ESPM(word opcode
) {}
588 int ESPM::operator()(Core
*core
) const {
592 FMUL::FMUL(word opcode
) :
593 Rd( get_rd_3(opcode
) ),
594 Rr( get_rr_3(opcode
) ) {
597 int FMUL::operator()(Core
*core
) const {
599 byte rd
= core
->readRegister(Rd
);
600 byte rr
= core
->readRegister(Rr
);
603 word res
= resp
<< 1;
605 status
.Z
= ((res
& 0xffff) == 0) ;
606 status
.C
= ((resp
>> 15) & 0x1);
608 /* result goes in R1:R0 */
609 core
->writeRegister(R0
, res
& 0xff);
610 core
->writeRegister(R1
, (res
>> 8) & 0xff);
614 FMULS::FMULS(word opcode
) :
615 Rd( get_rd_3(opcode
) ),
616 Rr( get_rr_3(opcode
) ) {
619 int FMULS::operator()(Core
*core
) const {
621 sbyte rd
= core
->readRegister(Rd
);
622 sbyte rr
= core
->readRegister(Rr
);
625 word res
= resp
<< 1;
627 status
.Z
= ((res
& 0xffff) == 0) ;
628 status
.C
= ((resp
>> 15) & 0x1) ;
630 /* result goes in R1:R0 */
631 core
->writeRegister(R0
, res
& 0xff);
632 core
->writeRegister(R1
, (res
>> 8) & 0xff);
636 FMULSU::FMULSU(word opcode
) :
637 Rd( get_rd_3(opcode
) ),
638 Rr( get_rr_3(opcode
) ) {
641 int FMULSU::operator()(Core
*core
) const {
643 sbyte rd
= core
->readRegister(Rd
);
644 sbyte rr
= core
->readRegister(Rr
);
647 word res
= resp
<< 1;
649 status
.Z
= ((res
& 0xffff) == 0) ;
650 status
.C
= ((resp
>> 15) & 0x1) ;
652 /* result goes in R1:R0 */
653 core
->writeRegister(R0
, res
& 0xff);
654 core
->writeRegister(R1
, (res
>> 8) & 0xff);
658 ICALL::ICALL(word opcode
) {}
660 int ICALL::operator()(Core
*core
) const {
662 int new_pc
= (core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
664 core
->call( new_pc
- 1, true );
665 return core
->pcBytes() + 1;
669 IJMP::IJMP(word opcode
) {}
671 int IJMP::operator()(Core
*core
) const {
672 int new_pc
= (core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
673 core
->call( new_pc
- 1, false );
678 IN::IN(word opcode
) :
679 Rd( get_rd_5(opcode
) ),
680 ioreg( get_A_6(opcode
) ) {
683 int IN::operator()(Core
*core
) const {
684 core
->writeRegister(Rd
, core
->readIORegister(ioreg
) );
688 INC::INC(word opcode
) :
689 Rd( get_rd_5(opcode
) ) {
692 int INC::operator()(Core
*core
) const {
694 byte rd
= core
->readRegister(Rd
);
697 status
.N
= ((res
>> 7) & 0x1) ;
698 status
.V
= (rd
== 0x7f) ;
699 status
.S
= (status
.N
^ status
.V
) ;
700 status
.Z
= ((res
& 0xff) == 0) ;
702 core
->writeRegister(Rd
, res
);
706 JMP::JMP(word opcode
) :
707 K( get_k_22(opcode
) ) {
710 int JMP::operator()(Core
*core
) const {
711 word offset
= core
->fetchOperand();
712 core
->call( K
+ offset
- 1, false );
716 LDD_Y::LDD_Y(word opcode
) :
717 Rd( get_rd_5(opcode
) ),
721 int LDD_Y::operator()(Core
*core
) const {
723 word Y
= ( core
->readRegister(Yh
) << 8) | core
->readRegister(Yl
);
724 byte res
= core
->readByte(Y
+K
);
725 core
->writeRegister(Rd
, res
);
729 LDD_Z::LDD_Z(word opcode
):
730 Rd( get_rd_5(opcode
) ),
734 int LDD_Z::operator()(Core
*core
) const {
736 word Z
= ( core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
737 byte res
= core
->readByte(Z
+K
);
738 core
->writeRegister(Rd
, res
);
742 LDI::LDI(word opcode
) :
743 Rd( get_rd_4(opcode
) ),
744 K( get_K_8(opcode
) ) {
747 int LDI::operator()(Core
*core
) const {
748 core
->writeRegister(Rd
, K
);
752 LDS::LDS(word opcode
) :
753 Rd( get_rd_5(opcode
) ) {
756 int LDS::operator()(Core
*core
) const {
758 * The LDS instruction uses the RAMPD register to access memory
761 /* Get data at k in current data segment and put into Rd */
762 word offset
= core
->fetchOperand();
763 byte res
= core
->readByte(offset
);
764 core
->writeRegister(Rd
, res
);
768 LD_X::LD_X(word opcode
) :
769 Rd( get_rd_5(opcode
) ) {
772 int LD_X::operator()(Core
*core
) const {
774 word X
= ( core
->readRegister(Xh
) << 8) | core
->readRegister(Xl
);
775 byte res
= core
->readByte(X
);
776 core
->writeRegister(Rd
, res
);
780 LD_X_decr::LD_X_decr(word opcode
) : LD_X(opcode
) {}
782 int LD_X_decr::operator()(Core
*core
) const {
784 word X
= ( core
->readRegister(Xh
) << 8) | core
->readRegister(Xl
);
786 /* Perform pre-decrement */
789 byte res
= core
->readByte(X
);
790 core
->writeRegister(Rd
, res
);
792 core
->writeRegister(Xl
, X
& 0xff);
793 core
->writeRegister(Xh
, (X
>>8) & 0xff);
797 LD_X_incr::LD_X_incr(word opcode
) : LD_X(opcode
) {}
799 int LD_X_incr::operator()(Core
*core
) const {
801 word X
= ( core
->readRegister(Xh
) << 8) | core
->readRegister(Xl
);
803 byte res
= core
->readByte(X
);
804 core
->writeRegister(Rd
, res
);
806 /* Perform post-increment */
808 core
->writeRegister(Xl
, X
& 0xff);
809 core
->writeRegister(Xh
, (X
>>8) & 0xff);
814 LD_Y_decr::LD_Y_decr(word opcode
) :
815 Rd( get_rd_5(opcode
) ) {
818 int LD_Y_decr::operator()(Core
*core
) const {
820 word Y
= ( core
->readRegister(Yh
) << 8) | core
->readRegister(Yl
);
822 /* Perform pre-decrement */
824 byte res
= core
->readByte(Y
);
825 core
->writeRegister(Rd
, res
);
827 core
->writeRegister(Yl
, Y
& 0xff);
828 core
->writeRegister(Yh
, (Y
>>8) & 0xff);
833 LD_Y_incr::LD_Y_incr(word opcode
) :
834 Rd( get_rd_5(opcode
) ) {
837 int LD_Y_incr::operator()(Core
*core
) const {
839 word Y
= ( core
->readRegister(Yh
) << 8) | core
->readRegister(Yl
);
841 byte res
= core
->readByte(Y
);
842 core
->writeRegister(Rd
, res
);
846 core
->writeRegister(Yl
, Y
& 0xff);
847 core
->writeRegister(Yh
, (Y
>>8) & 0xff);
851 LD_Z_incr::LD_Z_incr(word opcode
) :
852 Rd( get_rd_5(opcode
) ) {
855 int LD_Z_incr::operator()(Core
*core
) const {
857 word Z
= ( core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
859 byte res
= core
->readByte(Z
);
860 core
->writeRegister(Rd
, res
);
862 /* Perform post-increment */
864 core
->writeRegister(Zl
, Z
& 0xff);
865 core
->writeRegister(Zh
, (Z
>>8) & 0xff);
869 LD_Z_decr::LD_Z_decr(word opcode
) :
870 Rd( get_rd_5(opcode
) ) {
873 int LD_Z_decr::operator()(Core
*core
) const {
875 word Z
= ( core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
877 /* Perform pre-decrement */
880 byte res
= core
->readByte(Z
);
881 core
->writeRegister(Rd
, res
);
883 core
->writeRegister(Zl
, Z
& 0xff);
884 core
->writeRegister(Zh
, (Z
>>8) & 0xff);
888 LPM_Z::LPM_Z(word opcode
) :
889 Rd( get_rd_5(opcode
) ) {
892 int LPM_Z::operator()(Core
*core
) const {
894 word Z
= ( core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
896 byte data
= core
->readFlash(Z
);
897 core
->writeRegister(Rd
, data
);
901 LPM::LPM(word opcode
) {}
903 int LPM::operator()(Core
*core
) const {
905 word Z
= ( core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
907 byte data
= core
->readFlash(Z
);
908 core
->writeRegister(R0
, data
);
912 LPM_Z_incr::LPM_Z_incr(word opcode
) :
913 Rd( get_rd_5(opcode
) ) {
916 int LPM_Z_incr::operator()(Core
*core
) const {
918 word Z
= ( core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
920 byte data
= core
->readFlash(Z
);
921 core
->writeRegister(Rd
, data
);
924 core
->writeRegister(Zl
, Z
& 0xff);
925 core
->writeRegister(Zh
, (Z
>>8) & 0xff);
929 LSR::LSR(word opcode
) :
930 Rd( get_rd_5(opcode
) ) {
933 int LSR::operator()(Core
*core
) const {
935 byte rd
= core
->readRegister(Rd
);
936 byte res
= (rd
>> 1) & 0x7f;
938 status
.C
= (rd
& 0x1) ;
940 status
.V
= (status
.N
^ status
.C
) ;
941 status
.S
= (status
.N
^ status
.V
) ;
942 status
.Z
= ((res
& 0xff) == 0) ;
944 core
->writeRegister(Rd
, res
);
948 MOV::MOV(word opcode
) :
949 Rd( get_rd_5(opcode
) ),
950 Rr( get_rr_5(opcode
) ) {
953 int MOV::operator()(Core
*core
) const {
954 core
->writeRegister(Rd
, core
->readRegister(Rr
) );
958 MOVW::MOVW(word opcode
) :
959 Rdl( (get_rd_4(opcode
) - 16)<<1 ),
960 Rdh( ((get_rd_4(opcode
) - 16)<<1) + 1),
961 Rrl( (get_rr_4(opcode
) - 16)<<1 ),
962 Rrh( ((get_rr_4(opcode
) - 16)<<1) + 1) {
965 int MOVW::operator()(Core
*core
) const {
966 core
->writeRegister(Rdl
, core
->readRegister(Rrl
) );
967 core
->writeRegister(Rdh
, core
->readRegister(Rrh
) );
971 MUL::MUL(word opcode
) :
972 Rd( get_rd_5(opcode
) ),
973 Rr( get_rr_5(opcode
) ) {
976 int MUL::operator()(Core
*core
) const {
978 byte rd
= core
->readRegister(Rd
);
979 byte rr
= core
->readRegister(Rr
);
983 status
.Z
= ((res
& 0xffff) == 0);
984 status
.C
= ((res
>> 15) & 0x1);
986 /* result goes in R1:R0 */
987 core
->writeRegister(R0
, res
& 0xff);
988 core
->writeRegister(R1
, (res
>>8) & 0xff);
992 MULS::MULS(word opcode
) :
993 Rd( get_rd_4(opcode
) ),
994 Rr( get_rr_4(opcode
) ) {
997 int MULS::operator()(Core
*core
) const {
999 sbyte rd
= (sbyte
)core
->readRegister(Rd
);
1000 sbyte rr
= (sbyte
)core
->readRegister(Rr
);
1001 sword res
= rd
* rr
;
1003 status
.Z
= ((res
& 0xffff) == 0) ;
1004 status
.C
= ((res
>> 15) & 0x1) ;
1006 /* result goes in R1:R0 */
1007 core
->writeRegister(R0
, res
& 0xff);
1008 core
->writeRegister(R1
, (res
>>8) & 0xff);
1012 MULSU::MULSU(word opcode
) :
1013 Rd( get_rd_3(opcode
) ),
1014 Rr( get_rr_3(opcode
) ) {
1017 int MULSU::operator()(Core
*core
) const {
1018 SReg
status( core
);
1019 sbyte rd
= (sbyte
)core
->readRegister(Rd
);
1020 byte rr
= core
->readRegister(Rr
);
1022 sword res
= rd
* rr
;
1024 status
.Z
= ((res
& 0xffff) == 0);
1025 status
.C
= ((res
>> 15) & 0x1);
1027 /* result goes in R1:R0 */
1028 core
->writeRegister(R0
, res
& 0xff);
1029 core
->writeRegister(R1
, (res
>>8) & 0xff);
1033 NEG::NEG(word opcode
) :
1034 Rd( get_rd_5(opcode
) ) {
1037 int NEG::operator()(Core
*core
) const {
1038 SReg
status( core
);
1039 byte rd
= core
->readRegister(Rd
);
1040 byte res
= (0x0 - rd
) & 0xff;
1042 status
.H
= (((res
>> 3) | (rd
>> 3)) & 0x1);
1043 status
.V
= (res
== 0x80);
1044 status
.N
= ((res
>> 7) & 0x1);
1045 status
.S
= (status
.N
^ status
.V
);
1046 status
.Z
= (res
== 0x0);
1047 status
.C
= (res
!= 0x0);
1049 core
->writeRegister(Rd
, res
);
1053 NOP::NOP(word opcode
) {}
1055 int NOP::operator()(Core */
*core*/
) const {
1059 OR::OR(word opcode
) :
1060 Rd( get_rd_5(opcode
) ),
1061 Rr(get_rr_5(opcode
) ) {
1064 int OR::operator()(Core
*core
) const{
1065 SReg
status( core
);
1066 byte res
= core
->readRegister(Rd
) | core
->readRegister(Rr
);
1069 status
.N
= ((res
>> 7) & 0x1);
1070 status
.S
= (status
.N
^ status
.V
);
1071 status
.Z
= (res
== 0x0);
1073 core
->writeRegister(Rd
, res
);
1077 ORI::ORI(word opcode
) :
1078 Rd( get_rd_4(opcode
) ),
1079 K( get_K_8(opcode
) ) {
1082 int ORI::operator()(Core
*core
) const{
1083 SReg
status( core
);
1084 byte res
= core
->readRegister(Rd
) | K
;
1087 status
.N
= ((res
>> 7) & 0x1);
1088 status
.S
= (status
.N
^ status
.V
);
1089 status
.Z
= (res
== 0x0);
1091 core
->writeRegister(Rd
, res
);
1095 OUT::OUT(word opcode
) :
1096 Rd( get_rd_5(opcode
) ),
1097 ioreg( get_A_6(opcode
) ) {
1100 int OUT::operator()(Core
*core
) const {
1101 core
->writeIORegister(ioreg
, core
->readRegister(Rd
));
1105 POP::POP(word opcode
) :
1106 Rd( get_rd_5(opcode
) ) {
1109 int POP::operator()(Core
*core
) const {
1110 core
->writeRegister(Rd
, core
->pop());
1114 PUSH::PUSH(word opcode
) :
1115 Rd( get_rd_5(opcode
) ) {
1118 int PUSH::operator()(Core
*core
) const {
1119 core
->push( core
->readRegister(Rd
) );
1123 RCALL::RCALL(word opcode
) :
1124 K( n_bit_unsigned_to_signed( get_k_12(opcode
), 12 ) ) {
1127 int RCALL::operator()(Core
*core
) const {
1128 int cost
= core
->pcBytes();
1129 core
->jump(K
, true);
1133 RET::RET(word opcode
) { }
1135 int RET::operator()(Core
*core
) const {
1136 int cost
= core
->pcBytes();
1141 RETI::RETI(word opcode
) {}
1143 int RETI::operator()(Core
*core
) const {
1144 SReg
status( core
);
1145 int cost
= core
->pcBytes();
1151 RJMP::RJMP(word opcode
) :
1152 K( n_bit_unsigned_to_signed( get_k_12(opcode
), 12 ) ) {
1155 int RJMP::operator()(Core
*core
) const {
1156 core
->jump( K
, false );
1160 ROR::ROR(word opcode
) :
1161 Rd( get_rd_5(opcode
) ) {
1164 int ROR::operator()(Core
*core
) const {
1165 SReg
status( core
);
1166 byte rd
= core
->readRegister(Rd
);
1168 byte res
= (rd
>> 1) | ((( status
.C
) << 7) & 0x80);
1170 status
.C
= (rd
& 0x1) ;
1171 status
.N
= ((res
>> 7) & 0x1) ;
1172 status
.V
= (status
.N
^ status
.C
) ;
1173 status
.S
= (status
.N
^ status
.V
) ;
1174 status
.Z
= (res
== 0) ;
1176 core
->writeRegister(Rd
, res
);
1180 SBC::SBC(word opcode
) :
1181 Rd( get_rd_5(opcode
) ),
1182 Rr( get_rr_5(opcode
) ) {
1185 int SBC::operator()(Core
*core
) const {
1186 SReg
status( core
);
1187 byte rd
= core
->readRegister(Rd
);
1188 byte rr
= core
->readRegister(Rr
);
1190 byte res
= rd
- rr
- ( status
.C
);
1192 status
.H
= (get_sub_carry( res
, rd
, rr
, 3 )) ;
1193 status
.V
= (get_sub_overflow( res
, rd
, rr
)) ;
1194 status
.N
= ((res
>> 7) & 0x1) ;
1195 status
.S
= (status
.N
^ status
.V
) ;
1196 status
.C
= (get_sub_carry( res
, rd
, rr
, 7 )) ;
1198 if ((res
& 0xff) != 0)
1201 core
->writeRegister(Rd
, res
);
1205 SBCI::SBCI(word opcode
) :
1206 Rd( get_rd_4(opcode
) ),
1207 K( get_K_8(opcode
) ) {
1210 int SBCI::operator()(Core
*core
) const {
1211 SReg
status( core
);
1212 byte rd
= core
->readRegister(Rd
);
1214 byte res
= rd
- K
- ( status
.C
);
1216 status
.H
= (get_sub_carry( res
, rd
, K
, 3 )) ;
1217 status
.V
= (get_sub_overflow( res
, rd
, K
)) ;
1218 status
.N
= ((res
>> 7) & 0x1) ;
1219 status
.S
= (status
.N
^ status
.V
) ;
1220 status
.C
= (get_sub_carry( res
, rd
, K
, 7 )) ;
1222 if ((res
& 0xff) != 0)
1225 core
->writeRegister(Rd
, res
);
1229 SBI::SBI(word opcode
) :
1230 ioreg(get_A_5(opcode
) ),
1231 K( 1 << get_reg_bit(opcode
) ) {
1234 int SBI::operator()(Core
*core
) const {
1235 core
->writeIORegister(ioreg
, core
->readIORegister(ioreg
) | K
);
1239 SBIC::SBIC(word opcode
) :
1240 ioreg( get_A_5(opcode
) ),
1241 K( 1 << get_reg_bit(opcode
) ) {
1244 int SBIC::operator()(Core
*core
) const {
1246 if( (core
->readIORegister(ioreg
) & K
) == 0 )
1247 cost
+= core
->skip();
1251 SBIS::SBIS(word opcode
) :
1252 ioreg( get_A_5(opcode
) ),
1253 K( 1 << get_reg_bit(opcode
) ) {
1256 int SBIS::operator()(Core
*core
) const {
1258 if( (core
->readIORegister(ioreg
) & K
) != 0 )
1259 cost
+= core
->skip();
1263 SBIW::SBIW(word opcode
) :
1264 Rl( get_rd_2(opcode
) ),
1265 Rh( get_rd_2(opcode
)+1 ),
1266 K( get_K_6(opcode
) ) {
1269 int SBIW::operator()(Core
*core
) const {
1270 SReg
status( core
);
1271 byte rdl
= core
->readRegister(Rl
);
1272 byte rdh
= core
->readRegister(Rh
);
1274 word rd
= (rdh
<< 8) + rdl
;
1278 status
.V
= ((rdh
>> 7 & 0x1) & ~(res
>> 15 & 0x1)) ;
1279 status
.N
= ((res
>> 15) & 0x1) ;
1280 status
.S
= (status
.N
^ status
.V
) ;
1281 status
.Z
= ((res
& 0xffff) == 0) ;
1282 status
.C
= ((res
>> 15 & 0x1) & ~(rdh
>> 7 & 0x1)) ;
1284 core
->writeRegister(Rl
, res
& 0xff);
1285 core
->writeRegister(Rh
, (res
>>8) & 0xff);
1289 SBRC::SBRC(word opcode
) :
1290 Rd( get_rd_5(opcode
) ),
1291 K( 1 << get_reg_bit(opcode
) ) {
1294 int SBRC::operator()(Core
*core
) const {
1296 if( (core
->readRegister(Rd
) & K
) == 0 )
1297 cost
+= core
->skip();
1301 SBRS::SBRS(word opcode
) :
1302 Rd( get_rd_5(opcode
) ),
1303 K( 1 << get_reg_bit(opcode
) ) {
1306 int SBRS::operator()(Core
*core
) const {
1308 if( (core
->readRegister(Rd
) & K
) != 0 )
1309 cost
+= core
->skip();
1313 SLEEP::SLEEP(word opcode
) {}
1315 int SLEEP::operator()(Core
*core
) const {
1320 SPM::SPM(word opcode
) {
1323 int SPM::operator()(Core
*core
) const {
1324 word Z
= ( core
->readRegister(Zh
) << 8 ) | core
->readRegister(Zl
);
1326 word data
= ( core
->readRegister(R1
) << 8 ) | core
->readRegister(R0
);
1327 int ret
= core
->writeFlash(Z
, data
);
1331 STD_Y::STD_Y(word opcode
) :
1332 Rd( get_rd_5(opcode
) ),
1333 K( get_q(opcode
) ) {
1336 int STD_Y::operator()(Core
*core
) const {
1338 word Y
= ( core
->readRegister(Yh
) << 8 ) | core
->readRegister(Yl
);
1340 core
->writeByte( Y
+K
, core
->readRegister(Rd
) );
1344 STD_Z::STD_Z(word opcode
) :
1345 Rd( get_rd_5(opcode
) ),
1346 K( get_q(opcode
) ) {
1349 int STD_Z::operator()(Core
*core
) const {
1351 word Z
= ( core
->readRegister(Zh
) << 8 ) | core
->readRegister(Zl
);
1353 core
->writeByte( Z
+K
, core
->readRegister(Rd
) );
1357 STS::STS(word opcode
) :
1358 Rd( get_rd_5(opcode
) ) {
1361 int STS::operator()(Core
*core
) const {
1362 word k
= core
->fetchOperand();
1363 core
->writeByte( k
, core
->readRegister(Rd
) );
1367 ST_X::ST_X(word opcode
) :
1368 Rd( get_rd_5(opcode
) ) {
1371 int ST_X::operator()(Core
*core
) const {
1373 word X
= ( core
->readRegister(Xh
) << 8) | core
->readRegister(Xl
);
1375 core
->writeByte( X
, core
->readRegister(Rd
) );
1379 ST_X_decr::ST_X_decr(word opcode
) : ST_X(opcode
) {}
1381 int ST_X_decr::operator()(Core
*core
) const {
1383 word X
= ( core
->readRegister(Xh
) << 8) | core
->readRegister(Xl
);
1385 /* Perform pre-decrement */
1388 core
->writeByte( X
, core
->readRegister(Rd
) );
1390 core
->writeRegister(Xl
, X
& 0xff);
1391 core
->writeRegister(Xh
, (X
>>8) & 0xff);
1395 ST_X_incr::ST_X_incr(word opcode
) : ST_X(opcode
) {}
1397 int ST_X_incr::operator()(Core
*core
) const {
1399 word X
= ( core
->readRegister(Xh
) << 8) | core
->readRegister(Xl
);
1401 core
->writeByte( X
, core
->readRegister(Rd
) );
1403 /* Perform post-increment */
1405 core
->writeRegister(Xl
, X
& 0xff);
1406 core
->writeRegister(Xh
, (X
>>8) & 0xff);
1410 ST_Y_decr::ST_Y_decr(word opcode
) :
1411 Rd( get_rd_5(opcode
) ) {
1414 int ST_Y_decr::operator()(Core
*core
) const {
1416 word Y
= ( core
->readRegister(Yh
) << 8) | core
->readRegister(Yl
);
1418 /* Perform pre-decrement */
1421 core
->writeByte( Y
, core
->readRegister(Rd
) );
1422 core
->writeRegister(Yl
, Y
& 0xff);
1423 core
->writeRegister(Yh
, (Y
>>8) & 0xff);
1427 ST_Y_incr::ST_Y_incr(word opcode
) :
1428 Rd( get_rd_5(opcode
) ) {
1431 int ST_Y_incr::operator()(Core
*core
) const {
1433 word Y
= ( core
->readRegister(Yh
) << 8) | core
->readRegister(Yl
);
1435 core
->writeByte( Y
, core
->readRegister(Rd
) );
1437 /* Perform post-increment */
1440 core
->writeRegister(Yl
, Y
& 0xff);
1441 core
->writeRegister(Yh
, (Y
>>8) & 0xff);
1445 ST_Z_decr::ST_Z_decr(word opcode
) :
1446 Rd( get_rd_5(opcode
) ) {
1449 int ST_Z_decr::operator()(Core
*core
) const {
1451 word Z
= ( core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
1453 /* Perform pre-decrement */
1456 core
->writeByte( Z
, core
->readRegister(Rd
) );
1458 core
->writeRegister(Zl
, Z
& 0xff);
1459 core
->writeRegister(Zh
, (Z
>>8) & 0xff);
1463 ST_Z_incr::ST_Z_incr(word opcode
) :
1464 Rd( get_rd_5(opcode
) ) {
1467 int ST_Z_incr::operator()(Core
*core
) const {
1469 word Z
= ( core
->readRegister(Zh
) << 8) | core
->readRegister(Zl
);
1471 core
->writeByte( Z
, core
->readRegister(Rd
) );
1473 /* Perform post-increment */
1476 core
->writeRegister(Zl
, Z
& 0xff);
1477 core
->writeRegister(Zh
, (Z
>>8) & 0xff);
1481 SUB::SUB(word opcode
) :
1482 Rd( get_rd_5(opcode
) ),
1483 Rr( get_rr_5(opcode
) ) {
1486 int SUB::operator()(Core
*core
) const {
1487 SReg
status( core
);
1488 byte rd
= core
->readRegister(Rd
);
1489 byte rr
= core
->readRegister(Rr
);
1493 status
.H
= (get_sub_carry( res
, rd
, rr
, 3 )) ;
1494 status
.V
= (get_sub_overflow( res
, rd
, rr
)) ;
1495 status
.N
= ((res
>> 7) & 0x1) ;
1496 status
.S
= (status
.N
^ status
.V
) ;
1497 status
.Z
= ((res
& 0xff) == 0) ;
1498 status
.C
= (get_sub_carry( res
, rd
, rr
, 7 )) ;
1500 core
->writeRegister(Rd
, res
);
1504 SUBI::SUBI(word opcode
) :
1505 Rd( get_rd_4(opcode
) ),
1506 K( get_K_8(opcode
) ) {
1509 int SUBI::operator()(Core
*core
) const {
1510 SReg
status( core
);
1511 byte rd
= core
->readRegister(Rd
);
1515 status
.H
= (get_sub_carry( res
, rd
, K
, 3 )) ;
1516 status
.V
= (get_sub_overflow( res
, rd
, K
)) ;
1517 status
.N
= ((res
>> 7) & 0x1) ;
1518 status
.S
= (status
.N
^ status
.V
) ;
1519 status
.Z
= ((res
& 0xff) == 0) ;
1520 status
.C
= (get_sub_carry( res
, rd
, K
, 7 )) ;
1522 core
->writeRegister(Rd
, res
);
1526 SWAP::SWAP(word opcode
) :
1527 Rd( get_rd_5(opcode
) ) {
1530 int SWAP::operator()(Core
*core
) const {
1531 byte rd
= core
->readRegister(Rd
);
1532 byte res
= ((rd
<< 4) & 0xf0) | ((rd
>> 4) & 0x0f);
1533 core
->writeRegister(Rd
, res
);
1537 WDR::WDR(word opcode
) {}
1539 int WDR::operator()(Core
*core
) const {
1540 throw util::ImplementationException("Instruction WDR not fully implemented");
1544 BREAK::BREAK(word opcode
) {}
1546 int BREAK::operator()(Core
*core
) const {
1547 core
->systemBreak();
1551 ILLEGAL::ILLEGAL(word opcode
) : opcode(opcode
) {}
1553 int ILLEGAL::operator()(Core
*core
) const {
1554 throw IllegalInstruction(opcode
);