Fixed problem in DeviceSettings::strParam, returned wrong string
[avr-sim.git] / src / InstructionsTrace.cpp
blobf8a6ed051c491492aae9b943b155a17d6508ca01
1 /*
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"
20 #include "Core.h"
21 #include "DecoderHelp.h"
23 #include <iostream>
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) {
30 ostr << r.getName();
31 return ostr;
34 namespace avr {
36 namespace op {
38 int ADC::trace(Core *core, std::ostream & ostr) const {
39 ostr << "ADC " << reg(Rd) << ", " << reg(Rr);
40 return 1;
43 int ADD::trace(Core *core, std::ostream & ostr) const {
44 ostr << "ADD " << reg(Rd) << ", " << reg(Rr);
45 return 2;
48 int ADIW::trace(Core *core, std::ostream & ostr) const {
49 ostr << "ADIW " << duoreg(Rh, Rl) << ", " << hexchar(K);
50 return 1;
53 int AND::trace(Core *core, std::ostream & ostr) const {
54 ostr << "AND " << reg(Rd) << ", R" << reg(Rr);
55 return 1;
58 int ANDI::trace(Core *core, std::ostream & ostr) const {
59 ostr << "ANDI " << reg(Rd) << ", " << hexchar(K);
60 return 1;
63 int ASR::trace(Core *core, std::ostream & ostr) const {
64 ostr << "ASR " << reg(Rd);
65 return 1;
68 const char *opcodes_bclr[8]= {
69 "CLC",
70 "CLZ",
71 "CLN",
72 "CLV",
73 "CLS",
74 "CLH",
75 "CLT",
76 "CLI"
79 int BCLR::trace(Core * /*core*/, std::ostream & ostr) const {
80 int i;
81 for(i = 0; i < 8; ++i)
82 if( K == (unsigned char)~(1<<i) )
83 break;
85 ostr << opcodes_bclr[i];
86 return 1;
89 int BLD::trace(Core *core, std::ostream & ostr) const {
90 ostr << "BLD " << reg(Rd) << ", " << hexchar(Kadd);
91 return 1;
94 const char *branch_opcodes_clear[8] = {
95 "BRCC",
96 "BRNE",
97 "BRPL",
98 "BRVC",
99 "BRGE",
100 "BRHC",
101 "BRTC",
102 "BRID"
105 int BRBC::trace(Core * /*core*/, std::ostream & ostr) const {
106 int i;
107 for(i = 0; i < 8; ++i)
108 if( bitmask == (1<<i) )
109 break;
111 ostr << branch_opcodes_clear[i] << " " << int(char(offset) * 2);
113 string sym(core->Flash->GetSymbolAtAddress(core->PC+1+p2));
114 ostr << sym << " ";
115 for (int len = sym.length(); len<30;len++) { ostr << " " ; }
117 return 1;
120 const char *branch_opcodes_set[8] = {
121 "BRCS",
122 "BREQ",
123 "BRMO",
124 "BRVS",
125 "BRLT",
126 "BRHS",
127 "BRTS",
128 "BRIE"
131 int BRBS::trace(Core * /*core*/, std::ostream & ostr) const {
132 int i;
133 for(i = 0; i < 8; ++i)
134 if( bitmask == (1<<i) )
135 break;
137 ostr << branch_opcodes_set[i] << " " << int(char(offset)*2);
138 return 1;
141 const char *opcodes_bset[8]= {
142 "SEC",
143 "SEZ",
144 "SEN",
145 "SEV",
146 "SES",
147 "SEH",
148 "SET",
149 "SEI"
152 int BSET::trace(Core * /*core*/, std::ostream & ostr) const {
153 int i;
154 for(i = 0; i < 8; ++i)
155 if( K == (1<<i) )
156 break;
158 ostr << opcodes_bset[i];
159 return 1;
162 int BST::trace(Core *core, std::ostream & ostr) const {
163 ostr << "BST " << reg(Rd) << ", " << hexchar(K);
164 return 1;
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);
174 return 2;
177 int COM::trace(Core *core, std::ostream & ostr) const {
178 ostr << "COM " << reg(Rd);
179 return 1;
182 int CP::trace(Core *core, std::ostream & ostr) const {
183 ostr << "CP " << reg(Rd) << ", " << reg(Rr);
184 return 1;
187 int CPC::trace(Core *core, std::ostream & ostr) const {
188 ostr << "CPC " << reg(Rd) << ", " << reg(Rr);
189 return 1;
192 int CPI::trace(Core *core, std::ostream & ostr) const {
193 ostr << "CPI " << reg(Rd) << ", " << hexchar(K);
194 return 1;
197 int CPSE::trace(Core *core, std::ostream & ostr) const {
198 ostr << "CPSE " << reg(Rd) << ", " << reg(Rr);
199 return 1;
202 int DEC::trace(Core *core, std::ostream & ostr) const {
203 ostr << "DEC " << reg(Rd);
204 return 1;
207 int EICALL::trace(Core * /*core*/, std::ostream & ostr) const {
208 ostr << "EICALL";
209 return 4;
212 int EIJMP::trace(Core * /*core*/, std::ostream & ostr) const {
213 ostr << "EIJMP";
214 return 2;
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) +
222 (*(core->R))[30];
224 unsigned int flash_addr = Z;// / 2;
226 ostr << " Flash[0x"<<hex<< (unsigned int) flash_addr<<"] ";
228 return 3;
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) +
236 (*(core->R))[30];
238 unsigned int flash_addr = Z; // / 2;
240 ostr << " Flash[0x"<<hex<< (unsigned int) flash_addr<<"] ";
243 return 3;
246 int ELPM::trace(Core * /*core*/, std::ostream & ostr) const {
247 ostr << "ELPM";
249 /* unsigned int Z = ((core->GetRampz() & 0x3f) << 16) +
250 (((*(core->R))[31]) << 8) +
251 (*(core->R))[30];
253 unsigned int flash_addr = Z; // / 2;
255 ostr << " Flash[0x"<<hex<< (unsigned int) flash_addr<<"] ";
257 return 3;
260 int EOR::trace(Core *core, std::ostream & ostr) const {
261 ostr << "EOR " << reg(Rd) << ", " << reg(Rr);
262 return 1;
265 int ESPM::trace(Core * /*core*/, std::ostream & ostr) const {
266 ostr << "ESPM";
267 return 0;
270 int FMUL::trace(Core *core, std::ostream & ostr) const {
271 ostr << "FMUL " << reg(Rd) << ", " << reg(Rr);
272 return 2;
275 int FMULS::trace(Core *core, std::ostream & ostr) const {
276 ostr << "FMULS " << reg(Rd) << ", " << reg(Rr);
277 return 2;
280 int FMULSU::trace(Core *core, std::ostream & ostr) const {
281 ostr << "FMULSU " << reg(Rd) << ", " << reg(Rr);
282 return 2;
285 int ICALL::trace(Core *core, std::ostream & ostr) const {
286 ostr << "ICALL";
287 return core->pcBytes() + 1;
290 int IJMP::trace(Core * /*core*/, std::ostream & ostr) const {
291 ostr << "IJMP";
292 return 2;
295 int IN::trace(Core *core, std::ostream & ostr) const {
296 ostr << "IN " << reg(Rd) << ", " << core->getIoreg(ioreg);
297 return 1;
300 int INC::trace(Core *core, std::ostream & ostr) const {
301 ostr << "INC " << reg(Rd);
302 return 1;
305 int JMP::trace(Core * /*core*/, std::ostream & ostr) const {
306 ostr << "JMP";
307 return 3;
310 int LDD_Y::trace(Core *core, std::ostream & ostr) const {
311 ostr << "LD " << reg(Rd) << ", Y+" << hexchar(K);
312 return 2;
315 int LDD_Z::trace(Core *core, std::ostream & ostr) const {
316 ostr << "LDD " << reg(Rd) << ", Z";
317 return 2;
320 int LDI::trace(Core *core, std::ostream & ostr) const {
321 ostr << "LDI " << reg(Rd) << ", " << hexchar(K);
322 return 1;
325 int LDS::trace(Core *core, std::ostream & ostr) const {
326 ostr << "LDS " << reg(Rd);
327 //<< ", " << hex << "0x" << offset << dec << " ";
328 return 2;
331 int LD_X::trace(Core *core, std::ostream & ostr) const {
332 ostr << "LD " << reg(Rd) << ", X ";
333 return 2;
336 int LD_X_decr::trace(Core *core, std::ostream & ostr) const {
337 ostr << "LD " << reg(Rd) << ", -X";
338 return 2;
341 int LD_X_incr::trace(Core *core, std::ostream & ostr) const {
342 ostr << "LD " << reg(Rd) << ", X+";
343 return 2;
346 int LD_Y_decr::trace(Core *core, std::ostream & ostr) const {
347 ostr << "LD " << reg(Rd) << ", -Y";
348 return 2;
351 int LD_Y_incr::trace(Core *core, std::ostream & ostr) const {
352 ostr << "LD " << reg(Rd) << ", Y+";
353 return 2;
356 int LD_Z_incr::trace(Core *core, std::ostream & ostr) const {
357 ostr << "LD " << reg(Rd) << ", Z+";
358 return 2;
361 int LD_Z_decr::trace(Core *core, std::ostream & ostr) const {
362 ostr << "LD R" << reg(Rd) << ", -Z";
363 return 2;
366 int LPM_Z::trace(Core *core, std::ostream & ostr) const {
367 ostr << "LPM " << reg(Rd) << ", Z";
369 /* Z is R31:R30 */
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 << "] ";
375 return 3;
378 int LPM::trace(Core * /*core*/, std::ostream & ostr) const {
379 ostr << "LPM";
381 /* Z is R31:R30 */
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 << "] ";
387 return 3;
390 int LPM_Z_incr::trace(Core *core, std::ostream & ostr) const {
391 ostr << "LPM " << reg(Rd) << ", Z+";
393 /* Z is R31:R30 */
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 << "] ";
399 return 3;
402 int LSR::trace(Core *core, std::ostream & ostr) const {
403 ostr << "LSR " << reg(Rd);
404 return 1;
407 int MOV::trace(Core *core, std::ostream & ostr) const {
408 ostr << "MOV " << reg(Rd) << ", " << reg(Rr);
409 return 1;
412 int MOVW::trace(Core *core, std::ostream & ostr) const {
413 ostr << "MOVW " << duoreg(Rdh,Rdl) << ", " << duoreg(Rrh,Rrl);
414 return 1;
417 int MUL::trace(Core *core, std::ostream & ostr) const {
418 ostr << "MUL " << reg(Rd) << ", " << reg(Rr);
419 return 2;
422 int MULS::trace(Core *core, std::ostream & ostr) const {
423 ostr << "MULS " << reg(Rd) << ", " << reg(Rr);
424 return 2;
427 int MULSU::trace(Core *core, std::ostream & ostr) const {
428 ostr << "MULSU " << reg(Rd) << ", " << reg(Rr);
429 return 2;
432 int NEG::trace(Core *core, std::ostream & ostr) const {
433 ostr << "NEG " << reg(Rd);
434 return 1;
437 int NOP::trace(Core * /*core*/, std::ostream & ostr) const {
438 ostr << "NOP";
439 return 1;
442 int OR::trace(Core *core, std::ostream & ostr) const {
443 ostr << "OR " << reg(Rd) << ", " << reg(Rr);
444 return 1;
447 int ORI::trace(Core *core, std::ostream & ostr) const {
448 ostr << "ORI " << reg(Rd) << ", " << hexchar(K);
449 return 1;
452 int OUT::trace(Core *core, std::ostream & ostr) const {
453 ostr << "OUT " << core->getIoreg(ioreg) << ", " << reg(Rd);
454 return 1;
457 int POP::trace(Core *core, std::ostream & ostr) const {
458 ostr << "POP " << reg(Rd);
459 return 2;
462 int PUSH::trace(Core *core, std::ostream & ostr) const {
463 ostr << "PUSH " << reg(Rd);
464 return 2;
467 int RCALL::trace(Core * /*core*/, std::ostream & ostr) const {
468 ostr << "RCALL " << hexchar(K);
469 return 1;
472 int RET::trace(Core * /*core*/, std::ostream & ostr) const {
473 ostr << "RET";
474 return 2;
477 int RETI::trace(Core * /*core*/, std::ostream & ostr) const {
478 ostr << "RETI";
479 return 2;
482 int RJMP::trace(Core * /*core*/, std::ostream & ostr) const {
483 ostr << "RJMP " << int(char(K))*2;
484 return 2;
487 int ROR::trace(Core *core, std::ostream & ostr) const {
488 ostr << "ROR " << reg(Rd);
489 return 1;
492 int SBC::trace(Core *core, std::ostream & ostr) const {
493 ostr << "SBC " << reg(Rd) << ", " << reg(Rr);
494 return 1;
497 int SBCI::trace(Core *core, std::ostream & ostr) const {
498 ostr << "SBCI " << reg(Rd) << ", " << hexchar(K);
499 return 1;
502 int SBI::trace(Core *core, std::ostream & ostr) const {
503 ostr << "SBI " << core->getIoreg(ioreg) << ", " << hexchar(K);
504 return 2;
507 int SBIC::trace(Core *core, std::ostream & ostr) const {
508 ostr << "SBIC " << core->getIoreg(ioreg) << ", " << hexchar(K);
509 return 2;
512 int SBIS::trace(Core *core, std::ostream & ostr) const {
513 ostr << "SBIS " << core->getIoreg(ioreg) << ", " << hexchar(K);
514 return 2;
517 int SBIW::trace(Core *core, std::ostream & ostr) const {
518 ostr << "SBIW " << duoreg(Rh,Rl) << ", " << hexchar(K);
519 return 2;
522 int SBRC::trace(Core *core, std::ostream & ostr) const {
523 ostr << "SBRC " << reg(Rd) << ", " << hexchar(K);
524 return 1;
527 int SBRS::trace(Core *core, std::ostream & ostr) const {
528 ostr << "SBRS " << reg(Rd) << ", " << hexchar(K);
529 return 1;
532 int SLEEP::trace(Core * /*core*/, std::ostream & ostr) const {
533 ostr << "SLEEP";
534 return 0;
537 int SPM::trace(Core * /*core*/, std::ostream & ostr) const {
538 ostr << "SPM";
539 return 0;
542 int STD_Y::trace(Core *core, std::ostream & ostr) const {
543 ostr << "STD Y+"<< hexchar(K) <<", " << reg(Rd);
544 return 2;
547 int STD_Z::trace(Core *core, std::ostream & ostr) const {
548 ostr << "STD Z, " << reg(Rd);
549 return 2;
552 int STS::trace(Core *core, std::ostream & ostr) const {
553 ostr << "STS " << reg(Rd);
554 return 2;
557 int ST_X::trace(Core *core, std::ostream & ostr) const {
558 ostr << "ST X, " << reg(Rd);
559 return 2;
562 int ST_X_decr::trace(Core *core, std::ostream & ostr) const {
563 ostr << "ST -X, " << reg(Rd);
564 return 2;
567 int ST_X_incr::trace(Core *core, std::ostream & ostr) const {
568 ostr << "ST X+, " << reg(Rd);
569 return 2;
572 int ST_Y_decr::trace(Core *core, std::ostream & ostr) const {
573 ostr << "ST -Y, " << reg(Rd);
574 return 2;
577 int ST_Y_incr::trace(Core *core, std::ostream & ostr) const {
578 ostr << "ST Y+, " << reg(Rd);
579 return 2;
582 int ST_Z_decr::trace(Core *core, std::ostream & ostr) const {
583 ostr << "ST -Z, " << reg(Rd);
584 return 2;
587 int ST_Z_incr::trace(Core *core, std::ostream & ostr) const {
588 ostr << "ST Z+, " << reg(Rd);
589 return 2;
592 int SUB::trace(Core *core, std::ostream & ostr) const {
593 ostr << "SUB " << reg(Rd) << ", " << reg(Rr);
594 return 1;
597 int SUBI::trace(Core *core, std::ostream & ostr) const {
598 ostr << "SUBI " << reg(Rd) << ", " << hexchar(K);
599 return 1;
602 int SWAP::trace(Core *core, std::ostream & ostr) const {
603 ostr << "SWAP " << reg(Rd);
604 return 1;
607 int WDR::trace(Core * /*core*/, std::ostream & ostr) const {
608 ostr << "WDR";
609 return 1;
612 int BREAK::trace(Core * /*core*/, std::ostream & ostr) const {
613 ostr << "BREAK";
614 return 1;
617 int ILLEGAL::trace(Core * /*core*/, std::ostream & /*ostr*/) const {
618 return 0;