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"
25 #define reg(r) core->getR( (r) )
26 #define hexchar(a) std::hex << int(a) << std::dec
27 #define duoreg(Rh, Rl) core->getR(Rh) << ":" << core->getR(Rl)
29 static std::ostream
& operator <<(std::ostream
& ostr
, const avr::Register
& r
) {
38 int ADC::trace(Core
*core
, std::ostream
& ostr
) const {
39 ostr
<< "ADC " << reg(Rd
) << ", " << reg(Rr
);
43 int ADD::trace(Core
*core
, std::ostream
& ostr
) const {
44 ostr
<< "ADD " << reg(Rd
) << ", " << reg(Rr
);
48 int ADIW::trace(Core
*core
, std::ostream
& ostr
) const {
49 ostr
<< "ADIW " << duoreg(Rh
, Rl
) << ", " << hexchar(K
);
53 int AND::trace(Core
*core
, std::ostream
& ostr
) const {
54 ostr
<< "AND " << reg(Rd
) << ", R" << reg(Rr
);
58 int ANDI::trace(Core
*core
, std::ostream
& ostr
) const {
59 ostr
<< "ANDI " << reg(Rd
) << ", " << hexchar(K
);
63 int ASR::trace(Core
*core
, std::ostream
& ostr
) const {
64 ostr
<< "ASR " << reg(Rd
);
68 const char *opcodes_bclr
[8]= {
79 int BCLR::trace(Core
* /*core*/, std::ostream
& ostr
) const {
81 for(i
= 0; i
< 8; ++i
)
82 if( K
== (unsigned char)~(1<<i
) )
85 ostr
<< opcodes_bclr
[i
];
89 int BLD::trace(Core
*core
, std::ostream
& ostr
) const {
90 ostr
<< "BLD " << reg(Rd
) << ", " << hexchar(Kadd
);
94 const char *branch_opcodes_clear
[8] = {
105 int BRBC::trace(Core
* /*core*/, std::ostream
& ostr
) const {
107 for(i
= 0; i
< 8; ++i
)
108 if( bitmask
== (1<<i
) )
111 ostr
<< branch_opcodes_clear
[i
] << " " << int(char(offset
) * 2);
113 string sym(core->Flash->GetSymbolAtAddress(core->PC+1+p2));
115 for (int len = sym.length(); len<30;len++) { ostr << " " ; }
120 const char *branch_opcodes_set
[8] = {
131 int BRBS::trace(Core
* /*core*/, std::ostream
& ostr
) const {
133 for(i
= 0; i
< 8; ++i
)
134 if( bitmask
== (1<<i
) )
137 ostr
<< branch_opcodes_set
[i
] << " " << int(char(offset
)*2);
141 const char *opcodes_bset
[8]= {
152 int BSET::trace(Core
* /*core*/, std::ostream
& ostr
) const {
154 for(i
= 0; i
< 8; ++i
)
158 ostr
<< opcodes_bset
[i
];
162 int BST::trace(Core
*core
, std::ostream
& ostr
) const {
163 ostr
<< "BST " << reg(Rd
) << ", " << hexchar(K
);
167 int CALL::trace(Core
*core
, std::ostream
& ostr
) const {
168 ostr
<< "CALL " << hexchar(KH
);
169 return core
->pcBytes() + 2;
172 int CBI::trace(Core
*core
, std::ostream
& ostr
) const {
173 ostr
<< "CBI " << core
->getIoreg(ioreg
) << ", " << hexchar(K
);
177 int COM::trace(Core
*core
, std::ostream
& ostr
) const {
178 ostr
<< "COM " << reg(Rd
);
182 int CP::trace(Core
*core
, std::ostream
& ostr
) const {
183 ostr
<< "CP " << reg(Rd
) << ", " << reg(Rr
);
187 int CPC::trace(Core
*core
, std::ostream
& ostr
) const {
188 ostr
<< "CPC " << reg(Rd
) << ", " << reg(Rr
);
192 int CPI::trace(Core
*core
, std::ostream
& ostr
) const {
193 ostr
<< "CPI " << reg(Rd
) << ", " << hexchar(K
);
197 int CPSE::trace(Core
*core
, std::ostream
& ostr
) const {
198 ostr
<< "CPSE " << reg(Rd
) << ", " << reg(Rr
);
202 int DEC::trace(Core
*core
, std::ostream
& ostr
) const {
203 ostr
<< "DEC " << reg(Rd
);
207 int EICALL::trace(Core
* /*core*/, std::ostream
& ostr
) const {
212 int EIJMP::trace(Core
* /*core*/, std::ostream
& ostr
) const {
217 int ELPM_Z::trace(Core
*core
, std::ostream
& ostr
) const {
218 ostr
<< "ELPM " << reg(Rd
) << ", Z";
220 unsigned int Z = ((core->GetRampz() & 0x3f) << 16) +
221 (((*(core->R))[31]) << 8) +
224 unsigned int flash_addr = Z;// / 2;
226 ostr << " Flash[0x"<<hex<< (unsigned int) flash_addr<<"] ";
231 int ELPM_Z_incr::trace(Core
*core
, std::ostream
& ostr
) const {
232 ostr
<< "ELPM " << reg(Rd
) << ", Z+";
234 /* unsigned int Z = ((core->GetRampz() & 0x3f) << 16) +
235 (((*(core->R))[31]) << 8) +
238 unsigned int flash_addr = Z; // / 2;
240 ostr << " Flash[0x"<<hex<< (unsigned int) flash_addr<<"] ";
246 int ELPM::trace(Core
* /*core*/, std::ostream
& ostr
) const {
249 /* unsigned int Z = ((core->GetRampz() & 0x3f) << 16) +
250 (((*(core->R))[31]) << 8) +
253 unsigned int flash_addr = Z; // / 2;
255 ostr << " Flash[0x"<<hex<< (unsigned int) flash_addr<<"] ";
260 int EOR::trace(Core
*core
, std::ostream
& ostr
) const {
261 ostr
<< "EOR " << reg(Rd
) << ", " << reg(Rr
);
265 int ESPM::trace(Core
* /*core*/, std::ostream
& ostr
) const {
270 int FMUL::trace(Core
*core
, std::ostream
& ostr
) const {
271 ostr
<< "FMUL " << reg(Rd
) << ", " << reg(Rr
);
275 int FMULS::trace(Core
*core
, std::ostream
& ostr
) const {
276 ostr
<< "FMULS " << reg(Rd
) << ", " << reg(Rr
);
280 int FMULSU::trace(Core
*core
, std::ostream
& ostr
) const {
281 ostr
<< "FMULSU " << reg(Rd
) << ", " << reg(Rr
);
285 int ICALL::trace(Core
*core
, std::ostream
& ostr
) const {
287 return core
->pcBytes() + 1;
290 int IJMP::trace(Core
* /*core*/, std::ostream
& ostr
) const {
295 int IN::trace(Core
*core
, std::ostream
& ostr
) const {
296 ostr
<< "IN " << reg(Rd
) << ", " << core
->getIoreg(ioreg
);
300 int INC::trace(Core
*core
, std::ostream
& ostr
) const {
301 ostr
<< "INC " << reg(Rd
);
305 int JMP::trace(Core
* /*core*/, std::ostream
& ostr
) const {
310 int LDD_Y::trace(Core
*core
, std::ostream
& ostr
) const {
311 ostr
<< "LD " << reg(Rd
) << ", Y+" << hexchar(K
);
315 int LDD_Z::trace(Core
*core
, std::ostream
& ostr
) const {
316 ostr
<< "LDD " << reg(Rd
) << ", Z";
320 int LDI::trace(Core
*core
, std::ostream
& ostr
) const {
321 ostr
<< "LDI " << reg(Rd
) << ", " << hexchar(K
);
325 int LDS::trace(Core
*core
, std::ostream
& ostr
) const {
326 ostr
<< "LDS " << reg(Rd
);
327 //<< ", " << hex << "0x" << offset << dec << " ";
331 int LD_X::trace(Core
*core
, std::ostream
& ostr
) const {
332 ostr
<< "LD " << reg(Rd
) << ", X ";
336 int LD_X_decr::trace(Core
*core
, std::ostream
& ostr
) const {
337 ostr
<< "LD " << reg(Rd
) << ", -X";
341 int LD_X_incr::trace(Core
*core
, std::ostream
& ostr
) const {
342 ostr
<< "LD " << reg(Rd
) << ", X+";
346 int LD_Y_decr::trace(Core
*core
, std::ostream
& ostr
) const {
347 ostr
<< "LD " << reg(Rd
) << ", -Y";
351 int LD_Y_incr::trace(Core
*core
, std::ostream
& ostr
) const {
352 ostr
<< "LD " << reg(Rd
) << ", Y+";
356 int LD_Z_incr::trace(Core
*core
, std::ostream
& ostr
) const {
357 ostr
<< "LD " << reg(Rd
) << ", Z+";
361 int LD_Z_decr::trace(Core
*core
, std::ostream
& ostr
) const {
362 ostr
<< "LD R" << reg(Rd
) << ", -Z";
366 int LPM_Z::trace(Core
*core
, std::ostream
& ostr
) const {
367 ostr
<< "LPM " << reg(Rd
) << ", Z";
370 //int Z = ((*(core->R))[ 31] << 8) + (*(core->R))[ 30];
371 //string sym(core->Flash->GetSymbolAtAddressLpm(Z));
372 //string sym(core->Flash->GetSymbolAtAddress(Z));
373 //ostr << "FLASH[" << hex << Z << "," << sym << "] ";
378 int LPM::trace(Core
* /*core*/, std::ostream
& ostr
) const {
382 //int Z = ((*(core->R))[ 31] << 8) + (*(core->R))[ 30];
383 //string sym(core->Flash->GetSymbolAtAddressLpm(Z));
384 //string sym(core->Flash->GetSymbolAtAddress(Z));
385 //ostr << "FLASH[" << hex << Z << "," << sym << "] ";
390 int LPM_Z_incr::trace(Core
*core
, std::ostream
& ostr
) const {
391 ostr
<< "LPM " << reg(Rd
) << ", Z+";
394 //int Z = ((*(core->R))[ 31] << 8) + (*(core->R))[ 30];
395 //string sym(core->Flash->GetSymbolAtAddressLpm(Z));
396 //string sym(core->Flash->GetSymbolAtAddress(Z));
397 //ostr << "FLASH[" << hex << Z << "," << sym << "] ";
402 int LSR::trace(Core
*core
, std::ostream
& ostr
) const {
403 ostr
<< "LSR " << reg(Rd
);
407 int MOV::trace(Core
*core
, std::ostream
& ostr
) const {
408 ostr
<< "MOV " << reg(Rd
) << ", " << reg(Rr
);
412 int MOVW::trace(Core
*core
, std::ostream
& ostr
) const {
413 ostr
<< "MOVW " << duoreg(Rdh
,Rdl
) << ", " << duoreg(Rrh
,Rrl
);
417 int MUL::trace(Core
*core
, std::ostream
& ostr
) const {
418 ostr
<< "MUL " << reg(Rd
) << ", " << reg(Rr
);
422 int MULS::trace(Core
*core
, std::ostream
& ostr
) const {
423 ostr
<< "MULS " << reg(Rd
) << ", " << reg(Rr
);
427 int MULSU::trace(Core
*core
, std::ostream
& ostr
) const {
428 ostr
<< "MULSU " << reg(Rd
) << ", " << reg(Rr
);
432 int NEG::trace(Core
*core
, std::ostream
& ostr
) const {
433 ostr
<< "NEG " << reg(Rd
);
437 int NOP::trace(Core
* /*core*/, std::ostream
& ostr
) const {
442 int OR::trace(Core
*core
, std::ostream
& ostr
) const {
443 ostr
<< "OR " << reg(Rd
) << ", " << reg(Rr
);
447 int ORI::trace(Core
*core
, std::ostream
& ostr
) const {
448 ostr
<< "ORI " << reg(Rd
) << ", " << hexchar(K
);
452 int OUT::trace(Core
*core
, std::ostream
& ostr
) const {
453 ostr
<< "OUT " << core
->getIoreg(ioreg
) << ", " << reg(Rd
);
457 int POP::trace(Core
*core
, std::ostream
& ostr
) const {
458 ostr
<< "POP " << reg(Rd
);
462 int PUSH::trace(Core
*core
, std::ostream
& ostr
) const {
463 ostr
<< "PUSH " << reg(Rd
);
467 int RCALL::trace(Core
* /*core*/, std::ostream
& ostr
) const {
468 ostr
<< "RCALL " << hexchar(K
);
472 int RET::trace(Core
* /*core*/, std::ostream
& ostr
) const {
477 int RETI::trace(Core
* /*core*/, std::ostream
& ostr
) const {
482 int RJMP::trace(Core
* /*core*/, std::ostream
& ostr
) const {
483 ostr
<< "RJMP " << int(char(K
))*2;
487 int ROR::trace(Core
*core
, std::ostream
& ostr
) const {
488 ostr
<< "ROR " << reg(Rd
);
492 int SBC::trace(Core
*core
, std::ostream
& ostr
) const {
493 ostr
<< "SBC " << reg(Rd
) << ", " << reg(Rr
);
497 int SBCI::trace(Core
*core
, std::ostream
& ostr
) const {
498 ostr
<< "SBCI " << reg(Rd
) << ", " << hexchar(K
);
502 int SBI::trace(Core
*core
, std::ostream
& ostr
) const {
503 ostr
<< "SBI " << core
->getIoreg(ioreg
) << ", " << hexchar(K
);
507 int SBIC::trace(Core
*core
, std::ostream
& ostr
) const {
508 ostr
<< "SBIC " << core
->getIoreg(ioreg
) << ", " << hexchar(K
);
512 int SBIS::trace(Core
*core
, std::ostream
& ostr
) const {
513 ostr
<< "SBIS " << core
->getIoreg(ioreg
) << ", " << hexchar(K
);
517 int SBIW::trace(Core
*core
, std::ostream
& ostr
) const {
518 ostr
<< "SBIW " << duoreg(Rh
,Rl
) << ", " << hexchar(K
);
522 int SBRC::trace(Core
*core
, std::ostream
& ostr
) const {
523 ostr
<< "SBRC " << reg(Rd
) << ", " << hexchar(K
);
527 int SBRS::trace(Core
*core
, std::ostream
& ostr
) const {
528 ostr
<< "SBRS " << reg(Rd
) << ", " << hexchar(K
);
532 int SLEEP::trace(Core
* /*core*/, std::ostream
& ostr
) const {
537 int SPM::trace(Core
* /*core*/, std::ostream
& ostr
) const {
542 int STD_Y::trace(Core
*core
, std::ostream
& ostr
) const {
543 ostr
<< "STD Y+"<< hexchar(K
) <<", " << reg(Rd
);
547 int STD_Z::trace(Core
*core
, std::ostream
& ostr
) const {
548 ostr
<< "STD Z, " << reg(Rd
);
552 int STS::trace(Core
*core
, std::ostream
& ostr
) const {
553 ostr
<< "STS " << reg(Rd
);
557 int ST_X::trace(Core
*core
, std::ostream
& ostr
) const {
558 ostr
<< "ST X, " << reg(Rd
);
562 int ST_X_decr::trace(Core
*core
, std::ostream
& ostr
) const {
563 ostr
<< "ST -X, " << reg(Rd
);
567 int ST_X_incr::trace(Core
*core
, std::ostream
& ostr
) const {
568 ostr
<< "ST X+, " << reg(Rd
);
572 int ST_Y_decr::trace(Core
*core
, std::ostream
& ostr
) const {
573 ostr
<< "ST -Y, " << reg(Rd
);
577 int ST_Y_incr::trace(Core
*core
, std::ostream
& ostr
) const {
578 ostr
<< "ST Y+, " << reg(Rd
);
582 int ST_Z_decr::trace(Core
*core
, std::ostream
& ostr
) const {
583 ostr
<< "ST -Z, " << reg(Rd
);
587 int ST_Z_incr::trace(Core
*core
, std::ostream
& ostr
) const {
588 ostr
<< "ST Z+, " << reg(Rd
);
592 int SUB::trace(Core
*core
, std::ostream
& ostr
) const {
593 ostr
<< "SUB " << reg(Rd
) << ", " << reg(Rr
);
597 int SUBI::trace(Core
*core
, std::ostream
& ostr
) const {
598 ostr
<< "SUBI " << reg(Rd
) << ", " << hexchar(K
);
602 int SWAP::trace(Core
*core
, std::ostream
& ostr
) const {
603 ostr
<< "SWAP " << reg(Rd
);
607 int WDR::trace(Core
* /*core*/, std::ostream
& ostr
) const {
612 int BREAK::trace(Core
* /*core*/, std::ostream
& ostr
) const {
617 int ILLEGAL::trace(Core
* /*core*/, std::ostream
& /*ostr*/) const {