1 #include "Instructions.h"
3 #include "DecoderHelp.h"
4 #include "ImplementationException.h"
12 #define EIND 0x10 //TODO
20 SReg(Core
*c
) : c(c
) {
21 reg
= c
->readStatus();
46 static int get_add_carry( byte res
, byte rd
, byte rr
, int b
) {
47 byte resb
= res
>> b
& 0x1;
48 byte rdb
= rd
>> b
& 0x1;
49 byte rrb
= rr
>> b
& 0x1;
50 return (rdb
& rrb
) | (rrb
& ~resb
) | (~resb
& rdb
);
53 static int get_add_overflow( byte res
, byte rd
, byte rr
) {
54 byte res7
= res
>> 7 & 0x1;
55 byte rd7
= rd
>> 7 & 0x1;
56 byte rr7
= rr
>> 7 & 0x1;
57 return (rd7
& rr7
& ~res7
) | (~rd7
& ~rr7
& res7
);
60 static int get_sub_carry( byte res
, byte rd
, byte rr
, int b
) {
61 byte resb
= res
>> b
& 0x1;
62 byte rdb
= rd
>> b
& 0x1;
63 byte rrb
= rr
>> b
& 0x1;
64 return (~rdb
& rrb
) | (rrb
& resb
) | (resb
& ~rdb
);
67 static int get_sub_overflow( byte res
, byte rd
, byte rr
) {
68 byte res7
= res
>> 7 & 0x1;
69 byte rd7
= rd
>> 7 & 0x1;
70 byte rr7
= rr
>> 7 & 0x1;
71 return (rd7
& ~rr7
& ~res7
) | (~rd7
& rr7
& res7
);
74 static int get_compare_carry( byte res
, byte rd
, byte rr
, int b
) {
75 byte resb
= res
>> b
& 0x1;
76 byte rdb
= rd
>> b
& 0x1;
77 byte rrb
= rr
>> b
& 0x1;
78 return (~rdb
& rrb
) | (rrb
& resb
) | (resb
& ~rdb
);
81 static int get_compare_overflow( byte res
, byte rd
, byte rr
) {
82 byte res7
= res
>> 7 & 0x1;
83 byte rd7
= rd
>> 7 & 0x1;
84 byte rr7
= rr
>> 7 & 0x1;
85 /* The atmel data sheet says the second term is ~rd7 for CP
86 * but that doesn't make any sense. You be the judge. */
87 return (rd7
& ~rr7
& ~res7
) | (~rd7
& rr7
& res7
);
90 static int n_bit_unsigned_to_signed( unsigned int val
, int n
) {
91 /* Convert n-bit unsigned value to a signed value. */
94 if ( (val
& (1 << (n
-1))) == 0)
97 /* manually calculate two's complement */
99 return -1 * ((~val
& mask
) + 1);
102 ADC::ADC(word opcode
) :
103 Rd( get_rd_5(opcode
) ),
104 Rr( get_rr_5(opcode
) ) {
107 int ADC::operator ()(Core
*core
) {
109 unsigned char rd
= core
->readRegister(Rd
);
110 unsigned char rr
= core
->readRegister(Rr
);
111 unsigned char res
= rd
+ rr
+ status
.C
;
113 status
.H
= get_add_carry( res
, rd
, rr
, 3 );
114 status
.V
= get_add_overflow( res
, rd
, rr
);
115 status
.N
= ((res
>> 7) & 0x1);
116 status
.S
= (status
.N
^ status
.V
);
117 status
.Z
= ((res
& 0xff) == 0);
118 status
.C
= get_add_carry( res
, rd
, rr
, 7 );
120 core
->writeRegister(Rd
, res
);
121 return 1; //used clocks
124 ADD::ADD(word opcode
) :
125 Rd( get_rd_5(opcode
) ),
126 Rr( get_rr_5(opcode
) ) {
129 int ADD::operator ()(Core
*core
) {
131 unsigned char rd
= core
->readRegister(Rd
);
132 unsigned char rr
= core
->readRegister(Rr
);
133 unsigned char res
= rd
+ rr
;
135 status
.H
= get_add_carry( res
, rd
, rr
, 3 ) ;
136 status
.V
= get_add_overflow( res
, rd
, rr
) ;
137 status
.N
= ((res
>> 7) & 0x1) ;
138 status
.S
= (status
.N
^ status
.V
) ;
139 status
.Z
= ((res
& 0xff) == 0) ;
140 status
.C
= get_add_carry( res
, rd
, rr
, 7 ) ;
142 core
->writeRegister(Rd
, res
);
143 return 1; //used clocks
146 ADIW::ADIW(word opcode
) :
147 Rl( get_rd_2(opcode
) ),
148 Rh( get_rd_2(opcode
) + 1 ),
149 K( get_K_6(opcode
) ) {
152 int ADIW::operator()(Core
*core
) {
154 word rd
= (core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
157 unsigned char rdh
= Rh
;
158 status
.V
= (~(rdh
>> 7 & 0x1) & (res
>> 15 & 0x1));
159 status
.N
= ((res
>> 15) & 0x1);
160 status
.S
= (status
.N
^ status
.V
);
161 status
.Z
= ((res
& 0xffff) == 0);
162 status
.C
= (~(res
>> 15 & 0x1) & (rdh
>> 7 & 0x1));
164 core
->writeRegister(Rl
, res
& 0xff);
165 core
->writeRegister(Rh
, (res
>> 8) & 0xff);
171 AND::AND(word opcode
) :
172 Rd( get_rd_5(opcode
) ),
173 Rr( get_rr_5(opcode
) ) {
176 int AND::operator()(Core
*core
) {
178 byte res
= core
->readRegister(Rd
) & core
->readRegister(Rr
);
181 status
.N
= ((res
>> 7) & 0x1) ;
182 status
.S
= (status
.N
^ status
.V
);
183 status
.Z
= ((res
& 0xff) == 0);
185 core
->writeRegister(Rd
, res
);
189 ANDI::ANDI(word opcode
) :
190 Rd( get_rd_4(opcode
) ),
191 K( get_K_8(opcode
) ) {
194 int ANDI::operator()(Core
*core
) {
196 byte rd
= core
->readRegister(Rd
);
200 status
.N
= ((res
>> 7) & 0x1);
201 status
.S
= (status
.N
^ status
.V
);
202 status
.Z
= ((res
& 0xff) == 0);
204 core
->writeRegister(Rd
, res
);
208 ASR::ASR(word opcode
) :
209 Rd( get_rd_5(opcode
) ) {
212 int ASR::operator()(Core
*core
) {
214 byte rd
= core
->readRegister(Rd
);
215 byte res
= (rd
>> 1) + (rd
& 0x80);
217 status
.N
= ((res
>> 7) & 0x1);
218 status
.C
= (rd
& 0x1);
219 status
.V
= (status
.N
^ status
.C
);
220 status
.S
= (status
.N
^ status
.V
);
221 status
.Z
= ((res
& 0xff) == 0);
223 core
->writeRegister(Rd
, res
);
227 BCLR::BCLR(word opcode
) :
228 K( ~(1<<get_sreg_bit(opcode
)) ) {
231 int BCLR::operator()(Core
*core
) {
233 status
.reg
= status
.reg
& K
;
237 BLD::BLD(word opcode
) :
238 Rd( get_rd_5(opcode
) ),
239 Kadd(1<<get_reg_bit(opcode
)),
240 Kremove(~(1<<get_reg_bit(opcode
))) {
243 int BLD::operator()(Core
*core
) {
245 byte rd
= core
->readRegister(Rd
);
254 core
->writeRegister(Rd
, res
);
258 BRBC::BRBC(word opcode
) :
259 bitmask( 1 << get_reg_bit(opcode
) ),
260 offset( n_bit_unsigned_to_signed( get_k_7(opcode
), 7) ) {
263 int BRBC::operator()(Core
*core
) {
267 if( (status
.reg
& bitmask
) == 0 ) {
268 core
->jump( offset
);
278 BRBS::BRBS(word opcode
) :
279 bitmask( 1 << get_reg_bit(opcode
) ),
280 offset( n_bit_unsigned_to_signed( get_k_7(opcode
), 7) ) {
283 int BRBS::operator()(Core
*core
) {
287 if( (status
.reg
& bitmask
) != 0 ) {
288 core
->jump( offset
);
297 BSET::BSET(word opcode
) :
298 K(1<<get_sreg_bit(opcode
)) {
301 int BSET::operator()(Core
*core
) {
303 status
.reg
= status
.reg
| K
;
307 BST::BST(word opcode
) :
308 Rd( get_rd_5(opcode
) ),
309 K( get_reg_bit(opcode
) ) {
312 int BST::operator()(Core
*core
) {
314 status
.T
= ((core
->readRegister(Rd
) & K
) != 0 );
318 CALL::CALL(word opcode
) :
319 KH( get_k_22(opcode
) ) {
322 int CALL::operator()(Core
*core
) {
323 word offset
= core
->fetchOperand();
324 dword k
= (KH
<<16) | offset
;
326 core
->call( k
- 1, true );
327 return core
->pcBytes() + 2;
330 CBI::CBI(word opcode
) :
331 ioreg( get_A_5(opcode
) ),
332 K( ~( 1 << get_reg_bit(opcode
) ) ) {
335 int CBI::operator()(Core
*core
) {
336 core
->writeIORegister(ioreg
, core
->readIORegister(ioreg
) & K
);
340 COM::COM(word opcode
) :
341 Rd( get_rd_5(opcode
) ) {
344 int COM::operator()(Core
*core
) {
346 byte rd
= core
->readRegister(Rd
);
347 byte res
= 0xff - rd
;
349 status
.N
= ((res
>> 7) & 0x1) ;
352 status
.S
= (status
.N
^ status
.V
) ;
353 status
.Z
= ((res
& 0xff) == 0) ;
355 core
->writeRegister(Rd
, res
);
359 CP::CP(word opcode
) :
360 Rd( get_rd_5(opcode
) ),
361 Rr( get_rr_5(opcode
) ) {
364 int CP::operator()(Core
*core
) {
366 byte rd
= core
->readRegister(Rd
);
367 byte rr
= core
->readRegister(Rr
);
370 status
.H
= get_compare_carry( res
, rd
, rr
, 3 ) ;
371 status
.V
= get_compare_overflow( res
, rd
, rr
) ;
372 status
.N
= ((res
>> 7) & 0x1);
373 status
.S
= (status
.N
^ status
.V
);
374 status
.Z
= ((res
& 0xff) == 0) ;
375 status
.C
= get_compare_carry( res
, rd
, rr
, 7 ) ;
380 CPC::CPC(word opcode
) :
381 Rd( get_rd_5(opcode
) ),
382 Rr( get_rr_5(opcode
) ) {
385 int CPC::operator()(Core
*core
) {
387 byte rd
= core
->readRegister(Rd
);
388 byte rr
= core
->readRegister(Rr
);
389 byte res
= rd
- rr
- status
.C
;
391 status
.H
= get_compare_carry( res
, rd
, rr
, 3 ) ;
392 status
.V
= get_compare_overflow( res
, rd
, rr
) ;
393 status
.N
= ((res
>> 7) & 0x1) ;
394 status
.S
= (status
.N
^ status
.V
) ;
395 status
.C
= get_compare_carry( res
, rd
, rr
, 7 ) ;
397 /* Previous value remains unchanged when result is 0; cleared otherwise */
398 bool Z
= ((res
& 0xff) == 0);
399 bool prev_Z
= status
.Z
;
400 status
.Z
= Z
&& prev_Z
;
406 CPI::CPI(word opcode
) :
407 Rd( get_rd_4(opcode
) ),
411 int CPI::operator()(Core
*core
){
413 byte rd
= core
->readRegister(Rd
);
416 status
.H
= get_compare_carry( res
, rd
, K
, 3 ) ;
417 status
.V
= get_compare_overflow( res
, rd
, K
) ;
418 status
.N
= ((res
>> 7) & 0x1) ;
419 status
.S
= (status
.N
^ status
.V
) ;
420 status
.Z
= ((res
& 0xff) == 0) ;
421 status
.C
= get_compare_carry( res
, rd
, K
, 7 ) ;
426 CPSE::CPSE(word opcode
) :
427 Rd( get_rd_5(opcode
) ),
428 Rr( get_rr_5(opcode
) ) {
431 int CPSE::operator()(Core
*core
) {
432 byte rd
= core
->readRegister(Rd
);
433 byte rr
= core
->readRegister(Rr
);
437 clks
+= core
->skip();
442 DEC::DEC(word opcode
) :
443 Rd( get_rd_5(opcode
) ) {
446 int DEC::operator()(Core
*core
) {
448 byte res
= core
->readRegister(Rd
) - 1;
450 status
.N
= ((res
>> 7) & 0x1) ;
451 status
.V
= (res
== 0x7f) ;
452 status
.S
= (status
.N
^ status
.V
) ;
453 status
.Z
= ((res
& 0xff) == 0) ;
455 core
->writeRegister(Rd
, res
);
459 EICALL:: EICALL(word opcode
) :
465 int EICALL::operator()(Core
*core
) {
467 throw util::ImplementationException("Instruction EICALL not fully implemented");
468 int new_pc
= core
->readRegister(Rl
) |
469 (core
->readRegister(Rh
)<<8) |
470 core
->readIORegister(eind
) << 16;
471 core
->call( new_pc
, true );
475 EIJMP::EIJMP(word opcode
) :
481 int EIJMP::operator()(Core
*core
) {
483 throw util::ImplementationException("Instruction EIJMP not fully implemented");
484 int new_pc
= core
->readRegister(Rl
) |
485 (core
->readRegister(Rh
)<<8) |
486 (core
->readIORegister(eind
) & 0x3f) << 16;
487 core
->call( new_pc
, true );
491 ELPM_Z::ELPM_Z(word opcode
) :
494 Rd( get_rd_5(opcode
) ) {
497 int ELPM_Z::operator()(Core
*core
) {
501 throw util::ImplementationException("Instruction ELPM_Z not fully implemented");
503 Z
= ((core
->GetRampz() & 0x3f) << 16) |
507 core
->writeRegister( Rd
, core
->readFlash(Z
) );
511 ELPM_Z_incr::ELPM_Z_incr(word opcode
) :
514 Rd( get_rd_5(opcode
) ) {
517 int ELPM_Z_incr::operator()(Core
*core
) {
521 throw util::ImplementationException("Instruction ELPM_Z_incr not fully implemented");
523 Z
= ((core
->GetRampz() & 0x3f) << 16) |
527 core
->writeRegister( Rd
, core
->readFlash(Z
) );
529 /* post increment Z */
532 core
->SetRampz((Z
>> 16) & 0x3f);
534 core
->writeRegister(Rl
, Z
& 0xff);
535 core
->writeRegister(Rh
, (Z
>>8 & 0xff));
539 ELPM::ELPM(word opcode
) :
545 int ELPM::operator()(Core
*core
) {
549 throw util::ImplementationException("Instruction ELPM not fully implemented");
551 Z
= ((core
->GetRampz() & 0x3f) << 16) |
555 core
->writeRegister( R0
, core
->readFlash(Z
) );
559 EOR::EOR(word opcode
) :
560 Rd( get_rd_5(opcode
) ),
561 Rr( get_rr_5(opcode
) ) {
564 int EOR::operator()(Core
*core
) {
566 byte rd
= core
->readRegister(Rd
);
567 byte rr
= core
->readRegister(Rr
);
572 status
.N
= ((res
>> 7) & 0x1) ;
573 status
.S
= (status
.N
^ status
.V
) ;
574 status
.Z
= ((res
& 0xff) == 0 ) ;
576 core
->writeRegister(Rd
, res
);
580 ESPM::ESPM(word opcode
) :
585 int ESPM::operator()(Core
*core
) {
589 FMUL::FMUL(word opcode
) :
592 Rd( get_rd_3(opcode
) ),
593 Rr( get_rr_3(opcode
) ) {
596 int FMUL::operator()(Core
*core
) {
598 byte rd
= core
->readRegister(Rd
);
599 byte rr
= core
->readRegister(Rr
);
602 word res
= resp
<< 1;
604 status
.Z
= ((res
& 0xffff) == 0) ;
605 status
.C
= ((resp
>> 15) & 0x1);
607 /* result goes in R1:R0 */
608 core
->writeRegister(R0
, res
& 0xff);
609 core
->writeRegister(R1
, (res
>> 8) & 0xff);
613 FMULS::FMULS(word opcode
) :
616 Rd( get_rd_3(opcode
) ),
617 Rr( get_rr_3(opcode
) ) {
620 int FMULS::operator()(Core
*core
) {
622 sbyte rd
= core
->readRegister(Rd
);
623 sbyte rr
= core
->readRegister(Rr
);
626 word res
= resp
<< 1;
628 status
.Z
= ((res
& 0xffff) == 0) ;
629 status
.C
= ((resp
>> 15) & 0x1) ;
631 /* result goes in R1:R0 */
632 core
->writeRegister(R0
, res
& 0xff);
633 core
->writeRegister(R1
, (res
>> 8) & 0xff);
637 FMULSU::FMULSU(word opcode
) :
640 Rd( get_rd_3(opcode
) ),
641 Rr( get_rr_3(opcode
) ) {
644 int FMULSU::operator()(Core
*core
) {
646 sbyte rd
= core
->readRegister(Rd
);
647 sbyte rr
= core
->readRegister(Rr
);
650 word res
= resp
<< 1;
652 status
.Z
= ((res
& 0xffff) == 0) ;
653 status
.C
= ((resp
>> 15) & 0x1) ;
655 /* result goes in R1:R0 */
656 core
->writeRegister(R0
, res
& 0xff);
657 core
->writeRegister(R1
, (res
>> 8) & 0xff);
661 ICALL::ICALL(word opcode
) :
666 int ICALL::operator()(Core
*core
) {
668 int new_pc
= (core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
670 core
->call( new_pc
- 1, true );
671 return core
->pcBytes() + 1;
675 IJMP::IJMP(word opcode
) :
680 int IJMP::operator()(Core
*core
) {
681 int new_pc
= (core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
682 core
->call( new_pc
- 1, false );
687 IN::IN(word opcode
) :
688 Rd( get_rd_5(opcode
) ),
689 ioreg( get_A_6(opcode
) ) {
692 int IN::operator()(Core
*core
) {
693 core
->writeRegister(Rd
, core
->readIORegister(ioreg
) );
697 INC::INC(word opcode
) :
698 Rd( get_rd_5(opcode
) ) {
701 int INC::operator()(Core
*core
) {
703 byte rd
= core
->readRegister(Rd
);
706 status
.N
= ((res
>> 7) & 0x1) ;
707 status
.V
= (rd
== 0x7f) ;
708 status
.S
= (status
.N
^ status
.V
) ;
709 status
.Z
= ((res
& 0xff) == 0) ;
711 core
->writeRegister(Rd
, res
);
715 JMP::JMP(word opcode
) :
716 K( get_k_22(opcode
) ) {
719 int JMP::operator()(Core
*core
) {
720 word offset
= core
->fetchOperand();
721 core
->call( K
+ offset
- 1, false );
725 LDD_Y::LDD_Y(word opcode
) :
728 Rd( get_rd_5(opcode
) ),
732 int LDD_Y::operator()(Core
*core
) {
734 word Y
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
735 byte res
= core
->readByte(Y
+K
);
736 core
->writeRegister(Rd
, res
);
740 LDD_Z::LDD_Z(word opcode
):
743 Rd( get_rd_5(opcode
) ),
747 int LDD_Z::operator()(Core
*core
) {
749 word Z
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
750 byte res
= core
->readByte(Z
+K
);
751 core
->writeRegister(Rd
, res
);
755 LDI::LDI(word opcode
) :
756 Rd( get_rd_4(opcode
) ),
757 K( get_K_8(opcode
) ) {
760 int LDI::operator()(Core
*core
) {
761 core
->writeRegister(Rd
, K
);
765 LDS::LDS(word opcode
) :
766 Rd( get_rd_5(opcode
) ) {
769 int LDS::operator()(Core
*core
) {
771 * The LDS instruction uses the RAMPD register to access memory
774 /* Get data at k in current data segment and put into Rd */
775 word offset
= core
->fetchOperand();
776 byte res
= core
->readByte(offset
);
777 core
->writeRegister(Rd
, res
);
781 LD_X::LD_X(word opcode
) :
784 Rd( get_rd_5(opcode
) ) {
787 int LD_X::operator()(Core
*core
) {
789 word X
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
790 byte res
= core
->readByte(X
);
791 core
->writeRegister(Rd
, res
);
795 LD_X_decr::LD_X_decr(word opcode
) : LD_X(opcode
) {}
797 int LD_X_decr::operator()(Core
*core
) {
799 word X
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
801 /* Perform pre-decrement */
804 byte res
= core
->readByte(X
);
805 core
->writeRegister(Rd
, res
);
807 core
->writeRegister(Rl
, X
& 0xff);
808 core
->writeRegister(Rh
, (X
>>8) & 0xff);
812 LD_X_incr::LD_X_incr(word opcode
) : LD_X(opcode
) {}
814 int LD_X_incr::operator()(Core
*core
) {
816 word X
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
818 byte res
= core
->readByte(X
);
819 core
->writeRegister(Rd
, res
);
821 /* Perform post-increment */
823 core
->writeRegister(Rl
, X
& 0xff);
824 core
->writeRegister(Rh
, (X
>>8) & 0xff);
829 LD_Y_decr::LD_Y_decr(word opcode
) :
832 Rd( get_rd_5(opcode
) ) {
835 int LD_Y_decr::operator()(Core
*core
) {
837 word Y
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
839 /* Perform pre-decrement */
841 byte res
= core
->readByte(Y
);
842 core
->writeRegister(Rd
, res
);
844 core
->writeRegister(Rl
, Y
& 0xff);
845 core
->writeRegister(Rh
, (Y
>>8) & 0xff);
850 LD_Y_incr::LD_Y_incr(word opcode
) :
853 Rd( get_rd_5(opcode
) ) {
856 int LD_Y_incr::operator()(Core
*core
) {
858 word Y
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
860 byte res
= core
->readByte(Y
);
861 core
->writeRegister(Rd
, res
);
865 core
->writeRegister(Rl
, Y
& 0xff);
866 core
->writeRegister(Rh
, (Y
>>8) & 0xff);
870 LD_Z_incr::LD_Z_incr(word opcode
) :
873 Rd( get_rd_5(opcode
) ) {
876 int LD_Z_incr::operator()(Core
*core
) {
878 word Z
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
880 byte res
= core
->readByte(Z
);
881 core
->writeRegister(Rd
, res
);
883 /* Perform post-increment */
885 core
->writeRegister(Rl
, Z
& 0xff);
886 core
->writeRegister(Rh
, (Z
>>8) & 0xff);
890 LD_Z_decr::LD_Z_decr(word opcode
) :
893 Rd( get_rd_5(opcode
) ) {
896 int LD_Z_decr::operator()(Core
*core
) {
898 word Z
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
900 /* Perform pre-decrement */
903 byte res
= core
->readByte(Z
);
904 core
->writeRegister(Rd
, res
);
906 core
->writeRegister(Rl
, Z
& 0xff);
907 core
->writeRegister(Rh
, (Z
>>8) & 0xff);
911 LPM_Z::LPM_Z(word opcode
) :
914 Rd( get_rd_5(opcode
) ) {
917 int LPM_Z::operator()(Core
*core
) {
919 word Z
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
921 byte data
= core
->readFlash(Z
);
922 core
->writeRegister(Rd
, data
);
926 LPM::LPM(word opcode
) :
932 int LPM::operator()(Core
*core
) {
934 word Z
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
936 byte data
= core
->readFlash(Z
);
937 core
->writeRegister(Rd
, data
);
941 LPM_Z_incr::LPM_Z_incr(word opcode
) :
944 Rd( get_rd_5(opcode
) ) {
947 int LPM_Z_incr::operator()(Core
*core
) {
949 word Z
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
951 byte data
= core
->readFlash(Z
);
952 core
->writeRegister(Rd
, data
);
955 core
->writeRegister(Rl
, Z
& 0xff);
956 core
->writeRegister(Rh
, (Z
>>8) & 0xff);
960 LSR::LSR(word opcode
) :
961 Rd( get_rd_5(opcode
) ) {
964 int LSR::operator()(Core
*core
) {
966 byte rd
= core
->readRegister(Rd
);
967 byte res
= (rd
>> 1) & 0x7f;
969 status
.C
= (rd
& 0x1) ;
971 status
.V
= (status
.N
^ status
.C
) ;
972 status
.S
= (status
.N
^ status
.V
) ;
973 status
.Z
= ((res
& 0xff) == 0) ;
975 core
->writeRegister(Rd
, res
);
979 MOV::MOV(word opcode
) :
980 Rd( get_rd_5(opcode
) ),
981 Rr( get_rr_5(opcode
) ) {
984 int MOV::operator()(Core
*core
) {
985 core
->writeRegister(Rd
, core
->readRegister(Rr
) );
989 MOVW::MOVW(word opcode
) :
990 Rdl( (get_rd_4(opcode
) - 16)<<1 ),
991 Rdh( ((get_rd_4(opcode
) - 16)<<1) + 1),
992 Rrl( (get_rr_4(opcode
) - 16)<<1 ),
993 Rrh( ((get_rr_4(opcode
) - 16)<<1) + 1) {
996 int MOVW::operator()(Core
*core
) {
997 core
->writeRegister(Rdl
, core
->readRegister(Rrl
) );
998 core
->writeRegister(Rdh
, core
->readRegister(Rrh
) );
1002 MUL::MUL(word opcode
) :
1005 Rd( get_rd_5(opcode
) ),
1006 Rr( get_rr_5(opcode
) ) {
1009 int MUL::operator()(Core
*core
) {
1010 SReg
status( core
);
1011 byte rd
= core
->readRegister(Rd
);
1012 byte rr
= core
->readRegister(Rr
);
1016 status
.Z
= ((res
& 0xffff) == 0);
1017 status
.C
= ((res
>> 15) & 0x1);
1019 /* result goes in R1:R0 */
1020 core
->writeRegister(R0
, res
& 0xff);
1021 core
->writeRegister(R1
, (res
>>8) & 0xff);
1025 MULS::MULS(word opcode
) :
1028 Rd( get_rd_4(opcode
) ),
1029 Rr( get_rr_4(opcode
) ) {
1032 int MULS::operator()(Core
*core
) {
1033 SReg
status( core
);
1034 sbyte rd
= (sbyte
)core
->readRegister(Rd
);
1035 sbyte rr
= (sbyte
)core
->readRegister(Rr
);
1036 sword res
= rd
* rr
;
1038 status
.Z
= ((res
& 0xffff) == 0) ;
1039 status
.C
= ((res
>> 15) & 0x1) ;
1041 /* result goes in R1:R0 */
1042 core
->writeRegister(R0
, res
& 0xff);
1043 core
->writeRegister(R1
, (res
>>8) & 0xff);
1047 MULSU::MULSU(word opcode
) :
1050 Rd( get_rd_3(opcode
) ),
1051 Rr( get_rr_3(opcode
) ) {
1054 int MULSU::operator()(Core
*core
) {
1055 SReg
status( core
);
1056 sbyte rd
= (sbyte
)core
->readRegister(Rd
);
1057 byte rr
= core
->readRegister(Rr
);
1059 sword res
= rd
* rr
;
1061 status
.Z
= ((res
& 0xffff) == 0);
1062 status
.C
= ((res
>> 15) & 0x1);
1064 /* result goes in R1:R0 */
1065 core
->writeRegister(R0
, res
& 0xff);
1066 core
->writeRegister(R1
, (res
>>8) & 0xff);
1070 NEG::NEG(word opcode
) :
1071 Rd( get_rd_5(opcode
) ) {
1074 int NEG::operator()(Core
*core
) {
1075 SReg
status( core
);
1076 byte rd
= core
->readRegister(Rd
);
1077 byte res
= (0x0 - rd
) & 0xff;
1079 status
.H
= (((res
>> 3) | (rd
>> 3)) & 0x1);
1080 status
.V
= (res
== 0x80);
1081 status
.N
= ((res
>> 7) & 0x1);
1082 status
.S
= (status
.N
^ status
.V
);
1083 status
.Z
= (res
== 0x0);
1084 status
.C
= (res
!= 0x0);
1086 core
->writeRegister(Rd
, res
);
1090 NOP::NOP(word opcode
) {}
1092 int NOP::operator()(Core */
*core*/
){
1096 OR::OR(word opcode
) :
1097 Rd( get_rd_5(opcode
) ),
1098 Rr(get_rr_5(opcode
) ) {
1101 int OR::operator()(Core
*core
){
1102 SReg
status( core
);
1103 byte res
= core
->readRegister(Rd
) | core
->readRegister(Rr
);
1106 status
.N
= ((res
>> 7) & 0x1);
1107 status
.S
= (status
.N
^ status
.V
);
1108 status
.Z
= (res
== 0x0);
1110 core
->writeRegister(Rd
, res
);
1114 ORI::ORI(word opcode
) :
1115 Rd( get_rd_4(opcode
) ),
1116 K( get_K_8(opcode
) ) {
1119 int ORI::operator()(Core
*core
){
1120 SReg
status( core
);
1121 byte res
= core
->readRegister(Rd
) | K
;
1124 status
.N
= ((res
>> 7) & 0x1);
1125 status
.S
= (status
.N
^ status
.V
);
1126 status
.Z
= (res
== 0x0);
1128 core
->writeRegister(Rd
, res
);
1132 OUT::OUT(word opcode
) :
1133 Rd( get_rd_5(opcode
) ),
1134 ioreg( get_A_6(opcode
) ) {
1137 int OUT::operator()(Core
*core
) {
1138 core
->writeIORegister(ioreg
, core
->readRegister(Rd
));
1142 POP::POP(word opcode
) :
1143 Rd( get_rd_5(opcode
) ) {
1146 int POP::operator()(Core
*core
) {
1147 core
->writeRegister(Rd
, core
->pop());
1151 PUSH::PUSH(word opcode
) :
1152 Rd( get_rd_5(opcode
) ) {
1155 int PUSH::operator()(Core
*core
) {
1156 core
->push( core
->readRegister(Rd
) );
1160 RCALL::RCALL(word opcode
) :
1161 K( n_bit_unsigned_to_signed( get_k_12(opcode
), 12 ) ) {
1164 int RCALL::operator()(Core
*core
) {
1165 int cost
= core
->pcBytes();
1166 core
->jump(K
, true);
1170 RET::RET(word opcode
) { }
1172 int RET::operator()(Core
*core
) {
1173 int cost
= core
->pcBytes();
1178 RETI::RETI(word opcode
) {}
1180 int RETI::operator()(Core
*core
) {
1181 SReg
status( core
);
1182 int cost
= core
->pcBytes();
1188 RJMP::RJMP(word opcode
) :
1189 K( n_bit_unsigned_to_signed( get_k_12(opcode
), 12 ) ) {
1192 int RJMP::operator()(Core
*core
) {
1193 core
->jump( K
, false );
1197 ROR::ROR(word opcode
) :
1198 Rd( get_rd_5(opcode
) ) {
1201 int ROR::operator()(Core
*core
) {
1202 SReg
status( core
);
1203 byte rd
= core
->readRegister(Rd
);
1205 byte res
= (rd
>> 1) | ((( status
.C
) << 7) & 0x80);
1207 status
.C
= (rd
& 0x1) ;
1208 status
.N
= ((res
>> 7) & 0x1) ;
1209 status
.V
= (status
.N
^ status
.C
) ;
1210 status
.S
= (status
.N
^ status
.V
) ;
1211 status
.Z
= (res
== 0) ;
1213 core
->writeRegister(Rd
, res
);
1217 SBC::SBC(word opcode
) :
1218 Rd( get_rd_5(opcode
) ),
1219 Rr( get_rr_5(opcode
) ) {
1222 int SBC::operator()(Core
*core
) {
1223 SReg
status( core
);
1224 byte rd
= core
->readRegister(Rd
);
1225 byte rr
= core
->readRegister(Rr
);
1227 byte res
= rd
- rr
- ( status
.C
);
1229 status
.H
= (get_sub_carry( res
, rd
, rr
, 3 )) ;
1230 status
.V
= (get_sub_overflow( res
, rd
, rr
)) ;
1231 status
.N
= ((res
>> 7) & 0x1) ;
1232 status
.S
= (status
.N
^ status
.V
) ;
1233 status
.C
= (get_sub_carry( res
, rd
, rr
, 7 )) ;
1235 if ((res
& 0xff) != 0)
1238 core
->writeRegister(Rd
, res
);
1242 SBCI::SBCI(word opcode
) :
1243 Rd( get_rd_4(opcode
) ),
1244 K( get_K_8(opcode
) ) {
1247 int SBCI::operator()(Core
*core
) {
1248 SReg
status( core
);
1249 byte rd
= core
->readRegister(Rd
);
1251 byte res
= rd
- K
- ( status
.C
);
1253 status
.H
= (get_sub_carry( res
, rd
, K
, 3 )) ;
1254 status
.V
= (get_sub_overflow( res
, rd
, K
)) ;
1255 status
.N
= ((res
>> 7) & 0x1) ;
1256 status
.S
= (status
.N
^ status
.V
) ;
1257 status
.C
= (get_sub_carry( res
, rd
, K
, 7 )) ;
1259 if ((res
& 0xff) != 0)
1262 core
->writeRegister(Rd
, res
);
1266 SBI::SBI(word opcode
) :
1267 ioreg(get_A_5(opcode
) ),
1268 K( 1 << get_reg_bit(opcode
) ) {
1271 int SBI::operator()(Core
*core
) {
1272 core
->writeIORegister(ioreg
, core
->readIORegister(ioreg
) | K
);
1276 SBIC::SBIC(word opcode
) :
1277 ioreg( get_A_5(opcode
) ),
1278 K( 1 << get_reg_bit(opcode
) ) {
1281 int SBIC::operator()(Core
*core
) {
1283 if( (core
->readIORegister(ioreg
) & K
) == 0 )
1284 cost
+= core
->skip();
1288 SBIS::SBIS(word opcode
) :
1289 ioreg( get_A_5(opcode
) ),
1290 K( 1 << get_reg_bit(opcode
) ) {
1293 int SBIS::operator()(Core
*core
) {
1295 if( (core
->readIORegister(ioreg
) & K
) != 0 )
1296 cost
+= core
->skip();
1300 SBIW::SBIW(word opcode
) :
1301 Rl( get_rd_2(opcode
) ),
1302 Rh( get_rd_2(opcode
)+1 ),
1303 K( get_K_6(opcode
) ) {
1306 int SBIW::operator()(Core
*core
) {
1307 SReg
status( core
);
1308 byte rdl
= core
->readRegister(Rl
);
1309 byte rdh
= core
->readRegister(Rh
);
1311 word rd
= (rdh
<< 8) + rdl
;
1315 status
.V
= ((rdh
>> 7 & 0x1) & ~(res
>> 15 & 0x1)) ;
1316 status
.N
= ((res
>> 15) & 0x1) ;
1317 status
.S
= (status
.N
^ status
.V
) ;
1318 status
.Z
= ((res
& 0xffff) == 0) ;
1319 status
.C
= ((res
>> 15 & 0x1) & ~(rdh
>> 7 & 0x1)) ;
1321 core
->writeRegister(Rl
, res
& 0xff);
1322 core
->writeRegister(Rh
, (res
>>8) & 0xff);
1326 SBRC::SBRC(word opcode
) :
1327 Rd( get_rd_5(opcode
) ),
1328 K( 1 << get_reg_bit(opcode
) ) {
1331 int SBRC::operator()(Core
*core
) {
1333 if( (core
->readRegister(Rd
) & K
) == 0 )
1334 cost
+= core
->skip();
1338 SBRS::SBRS(word opcode
) :
1339 Rd( get_rd_5(opcode
) ),
1340 K( 1 << get_reg_bit(opcode
) ) {
1343 int SBRS::operator()(Core
*core
) {
1345 if( (core
->readRegister(Rd
) & K
) != 0 )
1346 cost
+= core
->skip();
1350 SLEEP::SLEEP(word opcode
) {}
1352 int SLEEP::operator()(Core
*core
) {
1357 SPM::SPM(word opcode
) :
1364 int SPM::operator()(Core
*core
) {
1365 word Z
= ( core
->readRegister(Rh
) << 8 ) | core
->readRegister(Rl
);
1367 word data
= ( core
->readRegister(R1
) << 8 ) | core
->readRegister(R0
);
1368 int ret
= core
->writeFlash(Z
, data
);
1372 STD_Y::STD_Y(word opcode
) :
1375 Rd( get_rd_5(opcode
) ),
1376 K( get_q(opcode
) ) {
1379 int STD_Y::operator()(Core
*core
) {
1381 word Y
= ( core
->readRegister(Rh
) << 8 ) | core
->readRegister(Rl
);
1383 core
->writeByte( Y
+K
, core
->readRegister(Rd
) );
1387 STD_Z::STD_Z(word opcode
) :
1390 Rd( get_rd_5(opcode
) ),
1391 K( get_q(opcode
) ) {
1394 int STD_Z::operator()(Core
*core
) {
1396 word Z
= ( core
->readRegister(Rh
) << 8 ) | core
->readRegister(Rl
);
1398 core
->writeByte( Z
+K
, core
->readRegister(Rd
) );
1402 STS::STS(word opcode
) :
1403 Rd( get_rd_5(opcode
) ) {
1406 int STS::operator()(Core
*core
) {
1407 word k
= core
->fetchOperand();
1408 core
->writeByte( k
, core
->readRegister(Rd
) );
1412 ST_X::ST_X(word opcode
) :
1415 Rd( get_rd_5(opcode
) ) {
1418 int ST_X::operator()(Core
*core
) {
1420 word X
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
1422 core
->writeByte( X
, core
->readRegister(Rd
) );
1426 ST_X_decr::ST_X_decr(word opcode
) : ST_X(opcode
) {}
1428 int ST_X_decr::operator()(Core
*core
) {
1430 word X
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
1432 /* Perform pre-decrement */
1435 core
->writeByte( X
, core
->readRegister(Rd
) );
1437 core
->writeRegister(Rl
, X
& 0xff);
1438 core
->writeRegister(Rh
, (X
>>8) & 0xff);
1442 ST_X_incr::ST_X_incr(word opcode
) : ST_X(opcode
) {}
1444 int ST_X_incr::operator()(Core
*core
) {
1446 word X
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
1448 core
->writeByte( X
, core
->readRegister(Rd
) );
1450 /* Perform post-increment */
1452 core
->writeRegister(Rl
, X
& 0xff);
1453 core
->writeRegister(Rh
, (X
>>8) & 0xff);
1457 ST_Y_decr::ST_Y_decr(word opcode
) :
1460 Rd( get_rd_5(opcode
) ) {
1463 int ST_Y_decr::operator()(Core
*core
) {
1465 word Y
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
1467 /* Perform pre-decrement */
1470 core
->writeByte( Y
, core
->readRegister(Rd
) );
1471 core
->writeRegister(Rl
, Y
& 0xff);
1472 core
->writeRegister(Rh
, (Y
>>8) & 0xff);
1476 ST_Y_incr::ST_Y_incr(word opcode
) :
1479 Rd( get_rd_5(opcode
) ) {
1482 int ST_Y_incr::operator()(Core
*core
) {
1484 word Y
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
1486 core
->writeByte( Y
, core
->readRegister(Rd
) );
1488 /* Perform post-increment */
1491 core
->writeRegister(Rl
, Y
& 0xff);
1492 core
->writeRegister(Rh
, (Y
>>8) & 0xff);
1496 ST_Z_decr::ST_Z_decr(word opcode
) :
1499 Rd( get_rd_5(opcode
) ) {
1502 int ST_Z_decr::operator()(Core
*core
) {
1504 word Z
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
1506 /* Perform pre-decrement */
1509 core
->writeByte( Z
, core
->readRegister(Rd
) );
1511 core
->writeRegister(Rl
, Z
& 0xff);
1512 core
->writeRegister(Rh
, (Z
>>8) & 0xff);
1516 ST_Z_incr::ST_Z_incr(word opcode
) :
1519 Rd( get_rd_5(opcode
) ) {
1522 int ST_Z_incr::operator()(Core
*core
) {
1524 word Z
= ( core
->readRegister(Rh
) << 8) | core
->readRegister(Rl
);
1526 core
->writeByte( Z
, core
->readRegister(Rd
) );
1528 /* Perform post-increment */
1531 core
->writeRegister(Rl
, Z
& 0xff);
1532 core
->writeRegister(Rh
, (Z
>>8) & 0xff);
1536 SUB::SUB(word opcode
) :
1537 Rd( get_rd_5(opcode
) ),
1538 Rr( get_rr_5(opcode
) ) {
1541 int SUB::operator()(Core
*core
) {
1542 SReg
status( core
);
1543 byte rd
= core
->readRegister(Rd
);
1544 byte rr
= core
->readRegister(Rr
);
1548 status
.H
= (get_sub_carry( res
, rd
, rr
, 3 )) ;
1549 status
.V
= (get_sub_overflow( res
, rd
, rr
)) ;
1550 status
.N
= ((res
>> 7) & 0x1) ;
1551 status
.S
= (status
.N
^ status
.V
) ;
1552 status
.Z
= ((res
& 0xff) == 0) ;
1553 status
.C
= (get_sub_carry( res
, rd
, rr
, 7 )) ;
1555 core
->writeRegister(Rd
, res
);
1559 SUBI::SUBI(word opcode
) :
1560 Rd( get_rd_4(opcode
) ),
1561 K( get_K_8(opcode
) ) {
1564 int SUBI::operator()(Core
*core
) {
1565 SReg
status( core
);
1566 byte rd
= core
->readRegister(Rd
);
1570 status
.H
= (get_sub_carry( res
, rd
, K
, 3 )) ;
1571 status
.V
= (get_sub_overflow( res
, rd
, K
)) ;
1572 status
.N
= ((res
>> 7) & 0x1) ;
1573 status
.S
= (status
.N
^ status
.V
) ;
1574 status
.Z
= ((res
& 0xff) == 0) ;
1575 status
.C
= (get_sub_carry( res
, rd
, K
, 7 )) ;
1577 core
->writeRegister(Rd
, res
);
1581 SWAP::SWAP(word opcode
) :
1582 Rd( get_rd_5(opcode
) ) {
1585 int SWAP::operator()(Core
*core
) {
1586 byte rd
= core
->readRegister(Rd
);
1587 byte res
= ((rd
<< 4) & 0xf0) | ((rd
>> 4) & 0x0f);
1588 core
->writeRegister(Rd
, res
);
1592 WDR::WDR(word opcode
) {}
1594 int WDR::operator()(Core
*core
) {
1595 throw util::ImplementationException("Instruction WDR not fully implemented");
1599 BREAK::BREAK(word opcode
) {}
1601 int BREAK::operator()(Core
*core
) {
1602 throw util::ImplementationException("Instruction BREAK not fully implemented");
1606 ILLEGAL::ILLEGAL(word opcode
) : opcode(opcode
) {}
1608 int ILLEGAL::operator()(Core
*core
) {
1609 throw IllegalInstruction(opcode
);