1 /***************************************************************************
2 * Copyright (C) 2004-2005 by Daniel Clarke <daniel.jc@gmail.com> *
3 * 2005 by David Saxton <david@bluehaze.org> *
4 * *
5 * 24-04-2007 *
6 * Modified to add pic 16f877,16f627 and 16f628 *
7 * by george john george@space-kerala.org *
8 * supported by SPACE www.space-kerala.org *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 ***************************************************************************/
25
26 #include "instruction.h"
27 #include "optimizer.h"
28 #include "pic14.h"
29 #include <QDebug>
30 #include <QStringList>
31 #include <cassert>
32 #include <iostream>
33 using namespace std;
34 //modified new varable pic_type is added
35 extern QString pic_type;
36 //BEGIN class Register
Register(Type type)37 Register::Register( Type type )
38 {
39 m_type = type;
40 //***********modified almost all the register names are included**************//
41 switch ( m_type )
42 {
43 //----------------------------------------------Bank0---------------------------//
44 case TMR0:
45 m_name = "TMR0";
46 break;
47 case PCL:
48 m_name = "PCL";
49 break;
50 case STATUS:
51 m_name = "STATUS";
52 break;
53 case FSR:
54 m_name = "FSR";
55 break;
56 case PORTA:
57 m_name = "PORTA";
58 break;
59 case PORTB:
60 m_name = "PORTB";
61 break;
62 case PORTC:
63 m_name = "PORTC";
64 break;
65 case PORTD:
66 m_name = "PORTD";
67 break;
68 case PORTE:
69 m_name = "PORTE";
70 break;
71 case PCLATH:
72 m_name = "PCLATH";
73 break;
74 case INTCON:
75 m_name = "INTCON";
76 break;
77 case PIR1:
78 m_name = "PIR1";
79 break;
80 case PIR2:
81 m_name = "PIR2";
82 break;
83 case TMR1L:
84 m_name = "TMR1L";
85 break;
86 case TMR1H:
87 m_name = "TMR1H";
88 break;
89 case T1CON:
90 m_name = "T1CON";
91 break;
92 case TMR2:
93 m_name = "TMR2";
94 break;
95 case T2CON:
96 m_name = "T2CON";
97 break;
98 case SSPBUF:
99 m_name = "SSPBUF";
100 break;
101 case SSPCON:
102 m_name = "SSPCON";
103 break;
104 case CCPR1L:
105 m_name = "CCPR1L";
106 break;
107 case CCPR1H:
108 m_name = "CCPR1H";
109 break;
110 case CCP1CON:
111 m_name = "CCP1CON";
112 break;
113 case RCSTA:
114 m_name = "RCSTA";
115 break;
116 case TXREG:
117 m_name = "TXREG";
118 break;
119 case RCREG:
120 m_name = "RCREG";
121 break;
122 case CCPR2L:
123 m_name = "CCPR2L";
124 break;
125 case CCPR2H:
126 m_name = "CCPR2H";
127 break;
128 case CCP2CON:
129 m_name = "CCP2CON";
130 break;
131 case ADRESH:
132 m_name = "ADRESH";
133 break;
134 case ADCON0:
135 m_name = "ADCON0";
136 break;
137 case CMCON:
138 m_name = "CMCON";
139 break;
140 //----------------------------------------------Bank1---------------------------//
141
142 case OPTION_REG:
143 m_name = "OPTION_REG";
144 break;
145 case TRISA:
146 m_name = "TRISA";
147 break;
148 case TRISB:
149 m_name = "TRISB";
150 break;
151 case TRISC:
152 m_name = "TRISC";
153 break;
154 case TRISD:
155 m_name = "TRISD";
156 break;
157 case TRISE:
158 m_name = "TRISE";
159 break;
160 case PIE1:
161 m_name = "PIE1";
162 break;
163 case PIE2:
164 m_name = "PIE2";
165 break;
166 case PCON:
167 m_name = "PCON";
168 break;
169 case SSPCON2:
170 m_name = "SSPCON2";
171 break;
172 case PR2:
173 m_name = "PR2";
174 break;
175 case SSPADD:
176 m_name = "SSPADD";
177 break;
178 case SSPSTAT:
179 m_name = "SSPSTAT";
180 break;
181 case TXSTA:
182 m_name = "TXSTA";
183 break;
184 case SPBRG:
185 m_name = "SPBRG";
186 break;
187 case ADRESL:
188 m_name = "ADRESL";
189 break;
190 case ADCON1:
191 m_name = "ADCON1";
192 break;
193 case VRCON:
194 m_name = "VRCON";
195 break;
196 //----------------------------------------------Bank2---------------------------//
197 case EEDATA:
198 m_name = "EEDATA";
199 break;
200 case EEADR:
201 m_name = "EEADR";
202 break;
203 case EEDATH:
204 m_name = "EEDATH";
205 break;
206 case EEADRH:
207 m_name = "EEADRH";
208 break;
209 //----------------------------------------------Bank3---------------------------//
210 case EECON1:
211 m_name = "EECON1";
212 break;
213
214 case EECON2:
215 m_name = "EECON2";
216 break;
217 //---------------------------------------------NoBank---------------------------//
218 case WORKING:
219 m_name = "<working>";
220 break;
221 case GPR:
222 case none:
223 break;
224 }
225 }
226
227
Register(const QString & name)228 Register::Register( const QString & name )//--to find a name varable or register(ex trise)
229 {
230 m_name = name.trimmed();
231 QString upper = m_name.toUpper();
232 //--------------------------------------------Bank0-------------------//
233 if ( upper == "TMR0" )
234 m_type = TMR0;
235 else if ( upper == "PCL" )
236 m_type = PCL;
237 else if ( upper == "STATUS")
238 m_type = STATUS;
239 else if ( upper == "FSR")
240 m_type = FSR;
241 else if ( upper == "PORTA")
242 m_type = PORTA;
243 else if ( upper == "PORTB")
244 m_type = PORTB;
245 else if ( upper == "PORTC")
246 m_type = PORTC;
247 else if ( upper == "PORTD")
248 m_type = PORTD;
249 else if ( upper == "PORTE")
250 m_type = PORTE;
251 else if ( upper == "PCLATH")
252 m_type = PCLATH;
253 else if ( upper == "INTCON")
254 m_type = INTCON;
255 else if ( upper == "PIR1")
256 m_type = PIR1;
257 else if ( upper == "PIR2")
258 m_type = PIR2;
259 else if ( upper == "TMR1L")
260 m_type = TMR1L;
261 else if ( upper == "TMR1H")
262 m_type = TMR1H;
263 else if ( upper == "T1CON")
264 m_type = T1CON;
265 else if ( upper == "TMR2")
266 m_type = TMR2;
267 else if ( upper == "T2CON")
268 m_type = T2CON;
269 else if ( upper == "SSPBUF")
270 m_type = SSPBUF;
271 else if ( upper == "SSPCON")
272 m_type = SSPCON;
273 else if ( upper == "CCPR1L")
274 m_type = CCPR1L;
275 else if ( upper == "CCPR1H")
276 m_type = CCPR1H;
277 else if ( upper == "CCP1CON")
278 m_type = CCP1CON;
279 else if ( upper == "RCSTA")
280 m_type = RCSTA;
281 else if ( upper == "TXREG")
282 m_type = TXREG;
283 else if ( upper == "RCREG")
284 m_type = RCREG;
285 else if ( upper == "CCPR2L")
286 m_type = CCPR2L;
287 else if ( upper == "CCPR2H")
288 m_type = CCPR2H;
289 else if ( upper == "CCP2CON")
290 m_type = CCP2CON;
291 else if ( upper == "ADRESH")
292 m_type = ADRESH;
293 else if ( upper == "ADCON0")
294 m_type = ADCON0;
295 else if ( upper == "CMCON")
296 m_type = CMCON;
297 //--------------------------------------------Bank1-------------------//
298 else if ( upper == "OPTION_REG" )
299 m_type = OPTION_REG;
300 else if ( upper == "TRISA")
301 m_type = TRISA;
302 else if ( upper == "TRISB")
303 m_type = TRISB;
304 else if ( upper == "TRISC")
305 m_type = TRISC;
306 else if ( upper == "TRISD")
307 m_type = TRISD;
308 else if ( upper == "TRISE")
309 m_type = TRISE;
310 else if ( upper == "PIE1")
311 m_type = PIE1;
312 else if ( upper == "PIE2")
313 m_type = PIE2;
314 else if ( upper == "PCON")
315 m_type = PCON;
316 else if ( upper == "SSPCON2")
317 m_type = SSPCON2;
318 else if ( upper == "PR2")
319 m_type = PR2;
320 else if ( upper == "SSPADD")
321 m_type = SSPADD;
322 else if ( upper == "SSPSTAT")
323 m_type = SSPSTAT;
324 else if ( upper == "TXSTA")
325 m_type = TXSTA;
326 else if ( upper == "SPBRG")
327 m_type = SPBRG;
328 else if ( upper == "ADRESL")
329 m_type = ADRESL;
330 else if ( upper == "ADCON1")
331 m_type = ADCON1;
332 else if ( upper == "VRCON")
333 m_type = VRCON;
334 //--------------------------------------------Bank2-------------------//
335 else if ( upper == "EEDATA")
336 m_type = EEDATA;
337 else if ( upper == "EEADR")
338 m_type = EEADR;
339 else if ( upper == "EEDATH")
340 m_type = EEDATH;
341 else if ( upper == "EEADRH")
342 m_type = EEADRH;
343 //--------------------------------------------Bank3-------------------//
344 else if ( upper == "EECON1")
345 m_type = EECON1;
346 else if ( upper == "EECON2")
347 m_type = EECON2;
348 //---------------------------------------------NoBank----------------//
349 else
350 m_type = GPR;
351 }
352
353
Register(const char * name)354 Register::Register( const char * name )
355 {
356 *this = Register( QString(name) );
357 }
358
359
operator <(const Register & reg) const360 bool Register::operator < ( const Register & reg ) const
361 {
362 if ( (type() != GPR) || (reg.type() != GPR) )
363 return type() < reg.type();
364
365 return name() < reg.name();
366 }
367
368
operator ==(const Register & reg) const369 bool Register::operator == ( const Register & reg ) const
370 {
371 if ( type() != reg.type() )
372 return false;
373
374 return name() == reg.name();
375 }
376
377
banks() const378 uchar Register::banks() const
379 {
380 switch ( m_type )
381 {
382 //---------------------bank 0 registers return zero---------------------------//
383
384 case TMR0: return Bank0& Bank1;//Bank0
385 case PCL: return Bank0 & Bank1;//Bank0 | Bank1
386 case STATUS: return Bank0 & Bank1;//Bank0 | Bank1
387 case FSR: return Bank0 & Bank1;//Bank0 | Bank1
388 case PORTA: return Bank0 & Bank1;//Bank0
389 case PORTB: return Bank0 & Bank1;//Bank0
390 case PORTC: return Bank0 & Bank1;//Bank0
391 case PORTD: return Bank0 & Bank1;//Bank0
392 case PORTE: return Bank0 & Bank1;//Bank0
393 case PCLATH: return Bank0 & Bank1;//Bank0 | Bank1
394 case INTCON: return Bank0 & Bank1;//Bank0 | Bank1
395 case PIR1: return Bank0 & Bank1;
396 case PIR2: return Bank0 & Bank1;
397 case TMR1L: return Bank0 & Bank1;
398 case TMR1H: return Bank0 & Bank1;
399 case T1CON: return Bank0 & Bank1;
400 case TMR2: return Bank0 & Bank1;
401 case T2CON: return Bank0 & Bank1;
402 case SSPBUF: return Bank0 & Bank1;
403 case SSPCON: return Bank0 & Bank1;
404 case CCPR1L: return Bank0 & Bank1;
405 case CCPR1H: return Bank0 & Bank1;
406 case CCP1CON: return Bank0 & Bank1;
407 case RCSTA: return Bank0 & Bank1;
408 case TXREG: return Bank0 & Bank1;
409 case RCREG: return Bank0 & Bank1;
410 case CCPR2L: return Bank0 & Bank1;
411 case CCPR2H: return Bank0 & Bank1;
412 case CCP2CON: return Bank0 & Bank1;
413 case ADRESH: return Bank0 & Bank1;//Bank0
414 case ADCON0: return Bank0 & Bank1;//Bank0
415 case CMCON: return Bank0 & Bank1;//Bank0
416 //-----------------------------NO Bank-------------------------------------//
417 case GPR: return Bank0 & Bank1;//Bank0 | Bank1
418 case WORKING: return Bank0 & Bank1;//Bank0 | Bank1
419 case none: return Bank0 & Bank1;//Bank0 | Bank1
420
421 //-------------------bank 1 registers return one---------------------------//
422
423 case OPTION_REG: return Bank0;//Bank1
424 ///------tris registers-------//
425 case TRISA: return Bank0;//Bank1
426 case TRISB: return Bank0;//Bank1
427 case TRISC: return Bank0;//Bank1
428 case TRISD: return Bank0;//Bank1
429 case TRISE: return Bank0;//Bank1
430 //--------------------------------------------------------------------------//
431 case PIE1: return Bank0;
432 case PIE2: return Bank0;
433 case PCON: return Bank0;
434 case SSPCON2: return Bank0;
435 case PR2: return Bank0;
436 case SSPADD: return Bank0;
437 case SSPSTAT: return Bank0;
438 case TXSTA: return Bank0;
439 case SPBRG: return Bank0;
440 //--------adc register-------//
441 case ADRESL: return Bank0;//Bank1
442 case ADCON1: return Bank0;//Bank1
443 case VRCON: return Bank0;//Bank1
444
445 //------------------bank 2 registers return two----------completed------------//
446
447 case EEDATA: return Bank1;//Bank1
448 case EEADR: return Bank1;//Bank0
449 case EEDATH: return Bank1;//Bank0
450 case EEADRH: return Bank1;//Bank0
451
452 //------------------bank 3 registers return three--------completed----------------//
453
454 case EECON1: return Bank0|Bank1;//Bank1
455 case EECON2: return Bank0|Bank1;//Bank1
456
457 }
458
459 return Bank0 & Bank1; // Vacously true (and useful too) - a non-existent bank can be accessed anywhere
460 }
461
462
bankDependent() const463 bool Register::bankDependent() const
464 {
465 return ( banks() != (Bank0 | Bank1) );
466 }
467
468
affectsExternal() const469 bool Register::affectsExternal() const
470 {
471 switch ( m_type )
472 {
473 case PORTA:
474 case TRISA:
475 case PORTB:
476 case TRISB:
477 case PORTC:
478 case TRISC:
479 case PORTD:
480 case TRISD:
481 case PORTE:
482 case TRISE:
483 case INTCON:
484 case ADCON0:
485 case ADCON1:
486 //************************modification***************************
487 case TMR0:
488 case OPTION_REG:
489 case PCL:
490 case STATUS:
491 case FSR:
492 case EEDATA:
493 case EECON1:
494 case EEADR:
495 case EECON2:
496 case PCLATH:
497 case GPR:
498 //--------------------------------FINAL LAST-------------//
499 case PIR1:
500 case PIR2:
501 case TMR1L:
502 case TMR2:
503 case TMR1H:
504 case T1CON:
505 case T2CON:
506 case SSPBUF:
507 case SSPCON:
508 case CCPR1L:
509 case CCPR1H:
510 case CCP1CON:
511 case CCPR2L:
512 case CCPR2H:
513 case CCP2CON:
514 case ADRESH:
515 case PIE1:
516 case PIE2:
517 case PCON:
518 case SSPCON2:
519 case PR2:
520 case SSPADD:
521 case SSPSTAT:
522 case TXSTA:
523 case SPBRG:
524 case ADRESL:
525 case EEDATH:
526 case EEADRH:
527 case RCSTA:
528 case TXREG:
529 case RCREG:
530 case CMCON:
531 case VRCON:
532 return true;
533 case WORKING:
534 case none:
535 return false;
536 }
537 return false;
538 }
539
540
541
542 //BEGIN class RegisterBit
RegisterBit(uchar bitPos,Register::Type reg)543 RegisterBit::RegisterBit( uchar bitPos, Register::Type reg )
544 {
545 m_bitPos = bitPos;
546 m_registerType = reg;
547
548 switch ( m_registerType )
549 {
550 case Register::TMR0:
551 case Register::PCL:
552 break;
553 case Register::STATUS:
554 {
555 switch ( m_bitPos )
556 {
557 case 0: m_name = "C"; break;
558 case 1: m_name = "DC"; break;
559 case 2: m_name = "Z"; break;
560 case 3: m_name = "NOT_PD"; break;
561 case 4: m_name = "NOT_TO"; break;
562 case 5: m_name = "RP0"; break;
563 case 6: m_name = "RP1"; break;
564 case 7: m_name = "IRP"; break;
565 }
566 break;
567 }
568 case Register::FSR:
569 case Register::PORTA:
570 case Register::PORTB:
571 case Register::PORTC:
572 case Register::PORTD:
573 case Register::PORTE:
574 case Register::PCLATH:
575 break;
576 case Register::INTCON:
577 {
578 switch ( m_bitPos )
579 {
580 case 0: m_name = "RBIF"; break;
581 case 1: m_name = "INTF"; break;
582 case 2: m_name = "T0IF"; break;
583 case 3: m_name = "RBIE"; break;
584 case 4: m_name = "INTE"; break;
585 case 5: m_name = "T0IE"; break;
586 case 6:
587 {
588 if(pic_type=="P16F84"||pic_type=="P16C84") {
589 m_name = "EEIE"; break;
590 }
591 if(pic_type=="P16F877"||pic_type=="P16F627" ||pic_type =="P16F628") {
592 m_name = "PEIE"; break;
593 }
594 break;
595
596
597 }
598 case 7: m_name = "GIE"; break;
599 }
600 break;
601 }
602 case Register::PIR1:
603 {
604 switch ( m_bitPos )
605 {
606 case 0: m_name = "TMR1F"; break;
607 case 1: m_name = "TMR2F"; break;
608 case 2: m_name = "CCP1IF"; break;
609 case 3: m_name = "SSPIF"; break;
610 case 4: m_name = "TXIF"; break;
611 case 5: m_name = "RCIF"; break;
612 case 6:
613 if(pic_type=="P16F877") {
614 m_name = "ADIF"; break;
615 }
616 if(pic_type=="P16F627"||pic_type=="P16F628") {
617 m_name = "CMIF";break;
618 }
619 break;
620 case 7:
621 if(pic_type=="P16F877") {
622 m_name = "PSPIF"; break;
623 }
624 if(pic_type=="P16F627"||pic_type=="P16F628") {
625 m_name = "EEIF";break;
626 }
627 break;
628 }
629 break;
630 }
631 case Register::PIR2:
632 {
633 switch ( m_bitPos )
634 {
635 case 0: m_name = "CCP2IF"; break;
636 case 3: m_name = "BCLIF"; break;
637 case 4: m_name = "EEIF"; break;
638
639 }
640 break;
641 }
642 case Register::TMR1L:
643 case Register::TMR1H:
644 break;
645 case Register::T1CON:
646 {
647 switch ( m_bitPos )
648 {
649 case 0: m_name = "TMR1ON"; break;
650 case 1: m_name = "TMRCS"; break;
651 case 2:
652 if(pic_type=="P16F877") {
653 m_name = "T1SYNC"; break;
654 }
655 if(pic_type=="P16F627"||pic_type=="P16F628") {
656 m_name = "NOT_T1SYNC"; break;
657 }
658 break;
659 case 3: m_name = "T1OSCEN"; break;
660 case 4: m_name = "T1CKPS0"; break;
661 case 5: m_name = "T1CKPS1"; break;
662 }
663 break;
664 }
665 case Register::TMR2:
666 break;
667 case Register::T2CON:
668 {
669 switch ( m_bitPos )
670 {
671 case 0: m_name = "T2CKPS0"; break;
672 case 1: m_name = "T2CKPS1"; break;
673 case 2: m_name = "TMR2ON"; break;
674 case 3: m_name = "TOUTPS0"; break;
675 case 4: m_name = "TOUTPS1"; break;
676 case 5: m_name = "TOUTPS2"; break;
677 case 6: m_name = "TOUTPS3"; break;
678 }
679 break;
680 }
681 case Register::SSPBUF:
682 break;
683 case Register::SSPCON:
684 switch ( m_bitPos )
685 {
686 case 0: m_name = "SSPM0"; break;
687 case 1: m_name = "SSPM1"; break;
688 case 2: m_name = "SSPM2"; break;
689 case 3: m_name = "SSPM3"; break;
690 case 4: m_name = "CKP"; break;
691 case 5: m_name = "SSPEN"; break;
692 case 6: m_name = "SSPOV"; break;//!!!!!!START&STOPEEIE!!!
693 case 7: m_name = "WCOL"; break;
694 }
695 break;
696 case Register::CCPR1L:
697 case Register::CCPR1H:
698 break;
699 case Register::CCP1CON:
700 switch ( m_bitPos )
701 {
702 case 0: m_name = "CCP1M0"; break;
703 case 1: m_name = "CCP1M1"; break;
704 case 2: m_name = "CCP1M2"; break;
705 case 3: m_name = "CCP1M3"; break;
706 case 4: m_name = "CCP1Y"; break;
707 case 5: m_name = "CCP1X"; break;
708 }
709 break;
710 case Register::RCSTA:
711 switch ( m_bitPos )
712 {
713 case 0: m_name = "RX9D"; break;
714 case 1: m_name = "OERR"; break;
715 case 2: m_name = "FERR"; break;
716 case 3:
717 if(pic_type=="P16F877") {
718 m_name = "ADDEN"; break;
719 }
720 if(pic_type=="P16F627"||pic_type=="P16F628") {
721 m_name = "ADEN"; break;
722 }
723 break;
724 case 4: m_name = "CREN"; break;
725 case 5: m_name = "SREN"; break;
726 case 6: m_name = "RX9"; break;
727 case 7: m_name = "SPEN"; break;
728 }
729 break;
730 case Register::TXREG:
731 case Register::RCREG:
732 case Register::CCPR2L:
733 case Register::CCPR2H:
734 break;
735 case Register::CCP2CON:
736 switch ( m_bitPos )
737 {
738 case 0: m_name = "CCP2M0"; break;
739 case 1: m_name = "CCP2M1"; break;
740 case 2: m_name = "CCP2M2"; break;
741 case 3: m_name = "CCP2M3"; break;
742 case 4: m_name = "CCP2Y"; break;
743 case 5: m_name = "CCP2X"; break;
744 }
745 break;
746
747 case Register::ADRESH:
748 break;
749 case Register::ADCON0:
750 {
751 switch ( m_bitPos )
752 {
753 case 0: m_name = "ADON"; break;
754 case 2: m_name = "GO"; break;
755 case 3: m_name = "CHS0"; break;
756 case 4: m_name = "CHS1"; break;
757 case 5: m_name = "CHS2"; break;
758 case 6: m_name = "ADCS0"; break;
759 case 7: m_name = "ADCS1"; break;
760 }
761 break;
762 }
763 case Register::CMCON:
764 {
765 switch ( m_bitPos )
766 {
767 case 0: m_name = "CM0"; break;
768 case 1: m_name = "CM1"; break;
769 case 2: m_name = "CM2"; break;
770 case 3: m_name = "CIS"; break;
771 case 4: m_name = "C1INV"; break;
772 case 5: m_name = "C2INV"; break;
773 case 6: m_name = "C1OUT"; break;
774 case 7: m_name = "C2OUT"; break;
775 }
776 break;
777 }
778 //-----------------------------------------------------Bank1----------------//
779 case Register::OPTION_REG:
780 {
781 switch ( m_bitPos )
782 {
783 case 0: m_name = "PS0"; break;
784 case 1: m_name = "PS1"; break;
785 case 2: m_name = "PS2"; break;
786 case 3: m_name = "PSA"; break;
787 case 4: m_name = "T0SE"; break;
788 case 5: m_name = "T0CS"; break;
789 case 6: m_name = "INTEDG"; break;
790 case 7:
791 {
792 if(pic_type=="P16F84")
793 m_name = "RBPU";
794 if(pic_type=="P16F877"||pic_type=="P16C84"||pic_type=="P16F627"||pic_type=="P16F628")
795 m_name = "NOT_RBPU";
796 break;
797
798
799 }
800 }
801 break;
802 }
803 case Register::TRISA:
804 case Register::TRISB:
805 case Register::TRISC:
806 case Register::TRISD:
807 case Register::TRISE:
808 break;
809 case Register::PIE1:
810 switch ( m_bitPos )
811 {
812 case 0: m_name = "TMR1IE"; break;
813 case 1: m_name = "TMR2IE"; break;
814 case 2: m_name = "CCP1IE"; break;
815 case 3: m_name = "SSPIE"; break;
816 case 4: m_name = "TXIE"; break;
817 case 5: m_name = "RCIE"; break;
818 case 6:
819 {
820 if (pic_type=="P16F877") {
821 m_name = "ADIE"; break;
822 }
823 if (pic_type=="P16F627"||pic_type=="P16F628") {
824 m_name = "CMIE"; break;
825 }
826 break;
827 }
828 case 7:
829 {
830 if (pic_type=="P16F877") {
831 m_name = "PSPIE"; break;
832 }
833 if (pic_type=="P16F627"||pic_type=="P16F628") {
834 m_name = "EEIE"; break;
835 }
836 break;
837 }
838 }
839 break;
840 case Register::PIE2:
841 switch ( m_bitPos )
842 {
843 case 0: m_name = "CCP2IE"; break;
844 case 3: m_name = "BCLIE"; break;
845 case 4: m_name = "EEIE"; break;
846 }
847 break;
848 case Register::PCON:
849 switch ( m_bitPos )
850 {
851 case 0: m_name = "NOT_BOR"; break;
852 case 1: m_name = "NOT_POR"; break;
853 case 3: m_name = "OSCF"; break;
854
855 }
856 break;
857 case Register::SSPCON2:
858 switch ( m_bitPos )
859 {
860 case 0: m_name = "SEN"; break;
861 case 1: m_name = "RSEN"; break;
862 case 2: m_name = "PEN"; break;
863 case 3: m_name = "RCEN"; break;
864 case 4: m_name = "ACKEN"; break;
865 case 5: m_name = "ACKDT"; break;
866 case 6: m_name = "ACKSTAT"; break;
867 case 7: m_name = "GCEN"; break;
868 }
869 break;
870 case Register::PR2:
871 case Register::SSPADD:
872 break;
873 case Register::SSPSTAT:
874 switch ( m_bitPos )
875 {
876 case 0: m_name = "BF"; break;
877 case 1: m_name = "UA"; break;
878 case 2: m_name = "R"; break;
879 case 3: m_name = "S"; break;
880 case 4: m_name = "P"; break;
881 case 5: m_name = "D"; break;
882 case 6: m_name = "CKE"; break;
883 case 7: m_name = "SMP"; break;
884 }
885 break;
886 case Register::TXSTA:
887 switch ( m_bitPos )
888 {
889 case 0: m_name = "TX9D"; break;
890 case 1: m_name = "TRMT"; break;
891 case 2: m_name = "BRGH"; break;
892 case 4: m_name = "SYNC"; break;
893 case 5: m_name = "TXEN"; break;
894 case 6: m_name = "TX9"; break;
895 case 7: m_name = "CSRC"; break;
896 }
897 break;
898 case Register::SPBRG:
899 case Register::ADRESL:
900 break;
901 case Register::ADCON1:
902 {
903 switch ( m_bitPos )
904 {
905 case 0: m_name = "PCFG0"; break;
906 case 1: m_name = "PCFG1"; break;
907 case 2: m_name = "PCFG2"; break;
908 case 3: m_name = "PCFG3"; break;
909 case 7: m_name = "ADFM"; break;
910 }
911 break;
912 }
913
914 //-----------------------------------------------------Bank2----------------//
915 case Register::EEDATA:
916 case Register::EEADR:
917 case Register::EEDATH:
918 case Register::EEADRH:
919 break;
920 //-----------------------------------------------------Bank3----------------//
921 case Register::EECON1:
922 {
923 switch ( m_bitPos )
924 {
925 case 0: m_name = "RD"; break;
926 case 1: m_name = "WR"; break;
927 case 2: m_name = "WREN"; break;
928 case 3: m_name = "WRERR"; break;
929 case 4: m_name = "EEIF"; break;
930 case 7: m_name = "EEPGD"; break;//imp *****
931 }
932 break;
933 }
934
935 case Register::EECON2:
936 break;
937 case Register::VRCON:
938 {
939 switch ( m_bitPos )
940 {
941 case 0: m_name = "VR0"; break;
942 case 1: m_name = "VR1"; break;
943 case 2: m_name = "VR2"; break;
944 case 3: m_name = "VR3"; break;
945 case 5: m_name = "VRR"; break;
946 case 6: m_name = "VROE"; break;
947 case 7: m_name = "VREN"; break;
948 }
949 break;
950 }
951 case Register::GPR:
952 case Register::WORKING:
953 case Register::none:
954 {
955 // qCritical() << Q_FUNC_INFO << "Bad register: " << reg << endl;
956 }
957 }
958 }
959
960
RegisterBit(const QString & name)961 RegisterBit::RegisterBit( const QString & name )
962 {
963 m_name = name.toUpper().trimmed();
964 initFromName();
965 }
966
967
RegisterBit(const char * name)968 RegisterBit::RegisterBit( const char * name )
969 {
970 m_name = QString(name).toUpper().trimmed();
971 initFromName();
972 }
973
974
initFromName()975 void RegisterBit::initFromName()
976 {
977 bool ok;
978 m_bitPos = m_name.toInt( & ok, 0 );
979 if ( ok )
980 m_registerType = Register::none; // hmm it should be unknown - not none.
981 //----------------------------------------Bank0----------------------------//
982
983 //--------STATUS REGISTER--------//
984
985 else if ( m_name == "C" )
986 {
987 m_registerType = Register::STATUS;
988 m_bitPos = 0;
989 }
990 else if ( m_name == "DC" )
991 {
992 m_registerType = Register::STATUS;
993 m_bitPos = 1;
994 }
995 else if ( m_name == "Z" )
996 {
997 m_registerType = Register::STATUS;
998 m_bitPos = 2;
999 }
1000 else if ( m_name == "NOT_PD" )
1001 {
1002 m_registerType = Register::STATUS;
1003 m_bitPos = 3;
1004 }
1005 else if ( m_name == "NOT_TO" )
1006 {
1007 m_registerType = Register::STATUS;
1008 m_bitPos = 4;
1009 }
1010 else if ( m_name == "RP0" )
1011 {
1012 m_registerType = Register::STATUS;
1013 m_bitPos = 5;
1014 }
1015 else if ( m_name == "RP1" )
1016 {
1017 m_registerType = Register::STATUS;
1018 m_bitPos = 6;
1019 }
1020 else if ( m_name == "IRP" )
1021 {
1022 m_registerType = Register::STATUS;
1023 m_bitPos = 7;
1024 }
1025
1026 //-----------INTCON REGISTER---------//
1027
1028 else if ( m_name == "RBIF" )
1029 {
1030 m_registerType = Register::INTCON;
1031 m_bitPos = 0;
1032 }
1033 else if ( m_name == "INTF" )
1034 {
1035 m_registerType = Register::INTCON;
1036 m_bitPos = 1;
1037 }
1038 else if ( m_name == "T0IF" )
1039 {
1040 m_registerType = Register::INTCON;
1041 m_bitPos = 2;
1042 }
1043 else if ( m_name == "RBIE" )
1044 {
1045 m_registerType = Register::INTCON;
1046 m_bitPos = 3;
1047 }
1048 else if ( m_name == "INTE" )
1049 {
1050 m_registerType = Register::INTCON;
1051 m_bitPos = 4;
1052 }
1053 else if ( m_name == "T0IE" )
1054 {
1055 m_registerType = Register::INTCON;
1056 m_bitPos = 5;
1057 }
1058 else if ( m_name =="PEIE"&&(pic_type=="P16F877"||pic_type=="P16F627"))
1059 {
1060 m_registerType = Register::INTCON;
1061 m_bitPos = 6;
1062 }
1063 else if (m_name == "EEIE"&& (pic_type=="P16F84"||pic_type=="P16C84"))
1064 {
1065 m_registerType = Register::INTCON;
1066 m_bitPos = 6;
1067 }
1068 else if ( m_name == "GIE" )
1069 {
1070 m_registerType = Register::INTCON;
1071 m_bitPos = 7;
1072 }
1073 //-------PIR1---------//
1074
1075 else if ( m_name == "TMR1F" )
1076 {
1077 m_registerType = Register::PIR1;
1078 m_bitPos = 0;
1079 }
1080 else if ( m_name == "TMR2F" )
1081 {
1082 m_registerType = Register::PIR1;
1083 m_bitPos = 1;
1084 }
1085 else if ( m_name == "CCP1IF" )
1086 {
1087 m_registerType = Register::PIR1;
1088 m_bitPos = 2;
1089 }
1090 else if ( m_name == "SSPIF"&& pic_type=="P16F877" )
1091 {
1092 m_registerType = Register::PIR1;
1093 m_bitPos = 3;
1094 }
1095 else if ( m_name == "TXIF" )
1096 {
1097 m_registerType = Register::PIR1;
1098 m_bitPos = 4;
1099 }
1100 else if ( m_name == "RCIF" )
1101 {
1102 m_registerType = Register::PIR1;
1103 m_bitPos = 5;
1104 }
1105 else if ( m_name == "ADIF" && pic_type=="P16F877")
1106 {
1107 m_registerType = Register::PIR1;
1108 m_bitPos = 6;
1109 }
1110 else if ( m_name == "CMIF" && pic_type=="P16F627")
1111 {
1112 m_registerType = Register::PIR1;
1113 m_bitPos = 6;
1114 }
1115 else if ( m_name == "PSPIF"&& pic_type=="P16F877")
1116 {
1117 m_registerType = Register::PIR1;
1118 m_bitPos = 7;
1119 }
1120 else if ( m_name == "EEIF"&& pic_type=="P16F627")
1121 {
1122 m_registerType = Register::PIR1;
1123 m_bitPos = 7;
1124 }
1125 //-------PIR2---------//
1126 else if ( m_name == "CCP2IF" )
1127 {
1128 m_registerType = Register::PIR2;
1129 m_bitPos = 0;
1130 }
1131 else if ( m_name == "BCLIF" )
1132 {
1133 m_registerType = Register::PIR2;
1134 m_bitPos = 3;
1135 }
1136 else if ( m_name == "EEIF" && pic_type=="P16F877" )
1137 {
1138 m_registerType = Register::PIR2;
1139 m_bitPos = 4;
1140 }
1141 //-------T1CON--------//
1142 else if ( m_name == "TMR1ON" )
1143 {
1144 m_registerType = Register::T1CON;
1145 m_bitPos = 0;
1146 }
1147 else if ( m_name == "TMR1CS" )
1148 {
1149 m_registerType = Register::T1CON;
1150 m_bitPos = 1;
1151 }
1152 else if ( m_name == "T1SYNC"&& pic_type=="P16F877" )
1153 {
1154 m_registerType = Register::T1CON;
1155 m_bitPos = 2;
1156 }
1157 else if ( m_name == "NOT_T1SYNC"&& pic_type=="P16F627" )
1158 {
1159 m_registerType = Register::T1CON;
1160 m_bitPos = 2;
1161 }
1162 else if ( m_name == "T1OSCEN" )
1163 {
1164 m_registerType = Register::T1CON;
1165 m_bitPos = 3;
1166 }
1167 else if ( m_name == "T1CKPS0" )
1168 {
1169 m_registerType = Register::T1CON;
1170 m_bitPos = 4;
1171 }
1172 else if ( m_name == "T1CKPS1" )
1173 {
1174 m_registerType = Register::T1CON;
1175 m_bitPos = 5;
1176 }
1177 //-------T2CON--------//
1178
1179 else if ( m_name == "T2CKPS0" )
1180 {
1181 m_registerType = Register::T2CON;
1182 m_bitPos = 0;
1183 }
1184 else if ( m_name == "T2CKPS1" )
1185 {
1186 m_registerType = Register::T2CON;
1187 m_bitPos = 1;
1188 }
1189 else if ( m_name == "TMR2ON" )
1190 {
1191 m_registerType = Register::T2CON;
1192 m_bitPos = 2;
1193 }
1194 else if ( m_name == "TOUTPS0" )
1195 {
1196 m_registerType = Register::T2CON;
1197 m_bitPos = 3;
1198 }
1199 else if ( m_name == "TOUTPS1" )
1200 {
1201 m_registerType = Register::T2CON;
1202 m_bitPos = 4;
1203 }
1204 else if ( m_name == "TOUTPS2" )
1205 {
1206 m_registerType = Register::T2CON;
1207 m_bitPos = 5;
1208 }
1209 else if ( m_name == "TOUTPS3" )
1210 {
1211 m_registerType = Register::T2CON;
1212 m_bitPos = 6;
1213 }
1214 //---SSPCON------//
1215
1216 else if ( m_name == "SSPM0" )
1217 {
1218 m_registerType = Register::SSPCON;
1219 m_bitPos = 0;
1220 }
1221 else if ( m_name == "SSPM1" )
1222 {
1223 m_registerType = Register::SSPCON;
1224 m_bitPos = 1;
1225 }
1226 else if ( m_name == "SSPM2" )
1227 {
1228 m_registerType = Register::SSPCON;
1229 m_bitPos = 2;
1230 }
1231 else if ( m_name == "SSPM3" )
1232 {
1233 m_registerType = Register::SSPCON;
1234 m_bitPos = 3;
1235 }
1236 else if ( m_name == "CKP" )
1237 {
1238 m_registerType = Register::SSPCON;
1239 m_bitPos = 4;
1240 }
1241 else if ( m_name == "SSPEN" )
1242 {
1243 m_registerType = Register::SSPCON;
1244 m_bitPos = 5;
1245 }
1246 else if ( m_name == "SSPOV" )
1247 {
1248 m_registerType = Register::SSPCON;
1249 m_bitPos = 6;
1250 }
1251 else if ( m_name == "WCOL" )
1252 {
1253 m_registerType = Register::SSPCON;
1254 m_bitPos = 7;
1255 }
1256 //-------CCP1CON----//
1257 else if ( m_name == "CCP1M0" )
1258 {
1259 m_registerType = Register::CCP1CON;
1260 m_bitPos = 0;
1261 }
1262 else if ( m_name == "CCP1M1" )
1263 {
1264 m_registerType = Register::CCP1CON;
1265 m_bitPos = 1;
1266 }
1267 else if ( m_name == "CCP1M2" )
1268 {
1269 m_registerType = Register::CCP1CON;
1270 m_bitPos = 2;
1271 }
1272 else if ( m_name == "CCP1M3" )
1273 {
1274 m_registerType = Register::CCP1CON;
1275 m_bitPos = 3;
1276 }
1277 else if ( m_name == "CCP1Y" )
1278 {
1279 m_registerType = Register::CCP1CON;
1280 m_bitPos = 4;
1281 }
1282 else if ( m_name == "CCP1X" )
1283 {
1284 m_registerType = Register::CCP1CON;
1285 m_bitPos = 5;
1286 }
1287 //-------RCSTA----//
1288 else if ( m_name == "RX9D" )
1289 {
1290 m_registerType = Register::RCSTA;
1291 m_bitPos = 0;
1292 }
1293 else if ( m_name == "OERR" )
1294 {
1295 m_registerType = Register::RCSTA;
1296 m_bitPos = 1;
1297 }
1298 else if ( m_name == "FERR" )
1299 {
1300 m_registerType = Register::RCSTA;
1301 m_bitPos = 2;
1302 }
1303 else if ( m_name == "ADDEN"&& pic_type=="P16F877" )
1304 {
1305 m_registerType = Register::RCSTA;
1306 m_bitPos = 3;
1307 }
1308 else if ( m_name == "ADEN"&& pic_type=="P16F627" )
1309 {
1310 m_registerType = Register::RCSTA;
1311 m_bitPos = 3;
1312 }
1313 else if ( m_name == "CREN" )
1314 {
1315 m_registerType = Register::RCSTA;
1316 m_bitPos = 4;
1317 }
1318 else if ( m_name == "SREN" )
1319 {
1320 m_registerType = Register::RCSTA;
1321 m_bitPos = 5;
1322 }
1323 else if ( m_name == "RX9" )
1324 {
1325 m_registerType = Register::RCSTA;
1326 m_bitPos = 6;
1327 }
1328 else if ( m_name == "SPEN" )
1329 {
1330 m_registerType = Register::RCSTA;
1331 m_bitPos = 7;
1332 }
1333 //-----CCP2CON-------//
1334 else if ( m_name == "CCP2M0" )
1335 {
1336 m_registerType = Register::CCP2CON;
1337 m_bitPos = 0;
1338 }
1339 else if ( m_name == "CCP2M1" )
1340 {
1341 m_registerType = Register::CCP2CON;
1342 m_bitPos = 1;
1343 }
1344 else if ( m_name == "CCP2M2" )
1345 {
1346 m_registerType = Register::CCP2CON;
1347 m_bitPos = 2;
1348 }
1349 else if ( m_name == "CCP2M3" )
1350 {
1351 m_registerType = Register::CCP2CON;
1352 m_bitPos = 3;
1353 }
1354 else if ( m_name == "CCP2Y" )
1355 {
1356 m_registerType = Register::CCP2CON;
1357 m_bitPos = 4;
1358 }
1359 else if ( m_name == "CCP2X" )
1360 {
1361 m_registerType = Register::CCP2CON;
1362 m_bitPos = 5;
1363 }
1364 //--------ADCON0------//
1365 else if ( m_name == "ADON" )
1366 {
1367 m_registerType = Register::ADCON0;
1368 m_bitPos = 0;
1369 }
1370 else if ( m_name == "GO" )
1371 {
1372 m_registerType = Register::ADCON0;
1373 m_bitPos = 2;
1374 }
1375 else if ( m_name == "CHS0" )
1376 {
1377 m_registerType = Register::ADCON0;
1378 m_bitPos = 3;
1379 }
1380 else if ( m_name == "CHS1" )
1381 {
1382 m_registerType = Register::ADCON0;
1383 m_bitPos = 4;
1384 }
1385 else if ( m_name == "CHS2" )
1386 {
1387 m_registerType = Register::ADCON0;
1388 m_bitPos = 5;
1389 }
1390 else if ( m_name == "ADCS0" )
1391 {
1392 m_registerType = Register::ADCON0;
1393 m_bitPos = 6;
1394 }
1395 else if ( m_name == "ADCS1" )
1396 {
1397 m_registerType = Register::ADCON0;
1398 m_bitPos = 7;
1399 }
1400 //-------CMCON---------------//pic16f627
1401 else if ( m_name == "CM0"&& pic_type=="P16F627")
1402 {
1403 m_registerType = Register::CMCON;
1404 m_bitPos = 0;
1405 }
1406 else if ( m_name == "CM1"&& pic_type=="P16F627")
1407 {
1408 m_registerType = Register::CMCON;
1409 m_bitPos = 1;
1410 }
1411 else if ( m_name == "CM2"&& pic_type=="P16F627")
1412 {
1413 m_registerType = Register::CMCON;
1414 m_bitPos = 2;
1415 }
1416 else if ( m_name == "CM3"&& pic_type=="P16F627")
1417 {
1418 m_registerType = Register::CMCON;
1419 m_bitPos = 3;
1420 }
1421 else if ( m_name == "CIS"&& pic_type=="P16F627")
1422 {
1423 m_registerType = Register::CMCON;
1424 m_bitPos = 4;
1425 }
1426 else if ( m_name == "C2INV"&& pic_type=="P16F627")
1427 {
1428 m_registerType = Register::CMCON;
1429 m_bitPos = 5;
1430 }
1431 else if ( m_name == "C1OUT"&& pic_type=="P16F627")
1432 {
1433 m_registerType = Register::CMCON;
1434 m_bitPos = 6;
1435 }
1436 else if ( m_name == "C2OUT"&& pic_type=="P16F627")
1437 {
1438 m_registerType = Register::CMCON;
1439 m_bitPos = 7;
1440 }
1441 //---------------------------------------------Bank1-------------------------------//
1442 //-------OPTION_REGSITER---------------//
1443 else if ( m_name == "PS0" )
1444 {
1445 m_registerType = Register::OPTION_REG;
1446 m_bitPos = 0;
1447 }
1448 else if ( m_name == "PS1" )
1449 {
1450 m_registerType = Register::OPTION_REG;
1451 m_bitPos = 1;
1452 }
1453 else if ( m_name == "PS2" )
1454 {
1455 m_registerType = Register::OPTION_REG;
1456 m_bitPos = 2;
1457 }
1458 else if ( m_name == "PSA" )
1459 {
1460 m_registerType = Register::OPTION_REG;
1461 m_bitPos = 3;
1462 }
1463 else if ( m_name == "T0SE" )
1464 {
1465 m_registerType = Register::OPTION_REG;
1466 m_bitPos = 4;
1467 }
1468 else if ( m_name == "T0CS" )
1469 {
1470 m_registerType = Register::OPTION_REG;
1471 m_bitPos = 5;
1472 }
1473 else if ( m_name == "INTEDG" )
1474 {
1475 m_registerType = Register::OPTION_REG;
1476 m_bitPos = 6;
1477 }
1478 else if(m_name =="NOT_RBPU"&&(pic_type=="P16C84"||pic_type=="P16F84"||pic_type=="P16F627"))
1479 {
1480 m_registerType = Register::OPTION_REG;
1481 m_bitPos = 7;
1482 }
1483 else if (m_name == "RBPU" && pic_type=="P16C84")
1484 {
1485 m_registerType = Register::OPTION_REG;
1486 m_bitPos = 7;
1487 }
1488 //--------PIE1---------//
1489 else if ( m_name == "TMR1IE" )
1490 {
1491 m_registerType = Register::PIE1;
1492 m_bitPos = 0;
1493 }
1494 else if ( m_name == "TMR2IE" )
1495 {
1496 m_registerType = Register::PIE1;
1497 m_bitPos = 1;
1498 }
1499 else if ( m_name == "CCP1IE" )
1500 {
1501 m_registerType = Register::PIE1;
1502 m_bitPos = 2;
1503 }
1504 else if ( m_name == "SSPIE" && pic_type=="P16F877")
1505 {
1506 m_registerType = Register::PIE1;
1507 m_bitPos = 3;
1508 }
1509 else if ( m_name == "TXIE" )
1510 {
1511 m_registerType = Register::PIE1;
1512 m_bitPos = 4;
1513 }
1514 else if ( m_name == "RCIE" )
1515 {
1516 m_registerType = Register::PIE1;
1517 m_bitPos = 5;
1518 }
1519 else if ( m_name == "ADIE" && pic_type=="P16F877" )
1520 {
1521 m_registerType = Register::PIE1;
1522 m_bitPos = 6;
1523 }
1524 else if ( m_name == "CMIE" && pic_type=="P16F627" )
1525 {
1526 m_registerType = Register::PIE1;
1527 m_bitPos = 6;
1528 }
1529 else if ( m_name == "PSPIE" && pic_type=="P16F877" )
1530 {
1531 m_registerType = Register::PIE1;
1532 m_bitPos = 7;
1533 }
1534 else if ( m_name == "EEIE" && pic_type=="P16F627" )
1535 {
1536 m_registerType = Register::PIE1;
1537 m_bitPos = 7;
1538 }
1539 //--------PIE2---------//
1540 else if ( m_name == "CCP2IE" )
1541 {
1542 m_registerType = Register::PIE2;
1543 m_bitPos = 0;
1544 }
1545 else if ( m_name == "BCLIE" )
1546 {
1547 m_registerType = Register::PIE2;
1548 m_bitPos = 3;
1549 }
1550 else if ( m_name == "EEIE"&& pic_type=="P16F877" )
1551 {
1552 m_registerType = Register::PIE2;
1553 m_bitPos = 4;
1554 }
1555 //--------PCON---------//
1556 else if ( m_name == "NOT_BOR" )
1557 {
1558 m_registerType = Register::PCON;
1559 m_bitPos = 0;
1560 }
1561 else if ( m_name == "NOT_POR" )
1562 {
1563 m_registerType = Register::PCON;
1564 m_bitPos = 1;
1565 }
1566 else if ( m_name == "OSCF"&& pic_type=="P16F627" )
1567 {
1568 m_registerType = Register::PCON;
1569 m_bitPos = 3;
1570 }
1571 //--------SSPCON2------//
1572 else if ( m_name =="SEN")
1573 {
1574 m_registerType = Register::SSPCON2;
1575 m_bitPos = 0;
1576 }
1577 else if ( m_name =="RSEN")
1578 {
1579 m_registerType = Register::SSPCON2;
1580 m_bitPos = 1;
1581 }
1582 else if ( m_name =="PEN")
1583 {
1584 m_registerType = Register::SSPCON2;
1585 m_bitPos = 2;
1586 }
1587 else if ( m_name =="RCEN")
1588 {
1589 m_registerType = Register::SSPCON2;
1590 m_bitPos = 3;
1591 }
1592 else if ( m_name =="ACKEN")
1593 {
1594 m_registerType = Register::SSPCON2;
1595 m_bitPos = 4;
1596 }
1597 else if ( m_name =="ACKDT")
1598 {
1599 m_registerType = Register::SSPCON2;
1600 m_bitPos = 5;
1601 }
1602 else if ( m_name =="ACKSTAT" )
1603 {
1604 m_registerType = Register::SSPCON2;
1605 m_bitPos = 6;
1606 }
1607 else if ( m_name == "GCEN" )
1608 {
1609 m_registerType = Register::SSPCON2;
1610 m_bitPos = 7;
1611 }
1612 //--------SSPSTAT------//
1613 else if ( m_name =="BF")
1614 {
1615 m_registerType = Register::SSPSTAT;
1616 m_bitPos = 0;
1617 }
1618 else if ( m_name == "UA")
1619 {
1620 m_registerType = Register::SSPSTAT;
1621 m_bitPos = 1;
1622 }
1623 else if ( m_name =="R")
1624 {
1625 m_registerType = Register::SSPSTAT;
1626 m_bitPos = 2;
1627 }
1628 else if ( m_name =="S")
1629 {
1630 m_registerType = Register::SSPSTAT;
1631 m_bitPos = 3;
1632 }
1633 else if ( m_name == "P")
1634 {
1635 m_registerType = Register::SSPSTAT;
1636 m_bitPos = 4;
1637 }
1638 else if ( m_name == "D")
1639 {
1640 m_registerType = Register::SSPSTAT;
1641 m_bitPos = 5;
1642 }
1643 else if ( m_name == "CKE" )
1644 {
1645 m_registerType = Register::SSPSTAT;
1646 m_bitPos = 6;
1647 }
1648 else if ( m_name == "SMP" )
1649 {
1650 m_registerType = Register::SSPSTAT;
1651 m_bitPos = 7;
1652 }
1653 //--------TXSTA--------//
1654 else if ( m_name == "TX9D" )
1655 {
1656 m_registerType = Register::TXSTA;
1657 m_bitPos = 0;
1658 }
1659 else if ( m_name == "TRMT" )
1660 {
1661 m_registerType = Register::TXSTA;
1662 m_bitPos = 1;
1663 }
1664 else if ( m_name == "BRGH" )
1665 {
1666 m_registerType = Register::TXSTA;
1667 m_bitPos = 2;
1668 }
1669 else if ( m_name == "SYNC" )
1670 {
1671 m_registerType = Register::TXSTA;
1672 m_bitPos = 4;
1673 }
1674 else if ( m_name == "TXEN" )
1675 {
1676 m_registerType = Register::TXSTA;
1677 m_bitPos = 5;
1678 }
1679 else if ( m_name == "TX9" )
1680 {
1681 m_registerType = Register::TXSTA;
1682 m_bitPos = 6;
1683 }
1684 else if ( m_name == "CSRC" )
1685 {
1686 m_registerType = Register::TXSTA;
1687 m_bitPos = 7;
1688 }
1689 //---------ADCON1-----//
1690 else if ( m_name == "PCFG0" )
1691 {
1692 m_registerType = Register::ADCON1;
1693 m_bitPos = 0;
1694 }
1695 else if ( m_name == "PCFG1" )
1696 {
1697 m_registerType = Register::ADCON1;
1698 m_bitPos = 1;
1699 }
1700 else if ( m_name == "PCFG2" )
1701 {
1702 m_registerType = Register::ADCON1;
1703 m_bitPos = 2;
1704 }
1705 else if ( m_name == "PCFG3" )
1706 {
1707 m_registerType = Register::ADCON1;
1708 m_bitPos = 3;
1709 }
1710 else if ( m_name == "ADFM" )
1711 {
1712 m_registerType = Register::ADCON1;
1713 m_bitPos = 7;
1714 }
1715 //--------------------------------------------Bank2------------------//
1716 //-----NOTHING TODO---//
1717 //
1718 //--------------------------------------------Bank3------------------//
1719 else if ( m_name == "RD" )
1720 {
1721 m_registerType = Register::EECON1;
1722 m_bitPos = 0;
1723 }
1724 else if ( m_name == "WR" )
1725 {
1726 m_registerType = Register::EECON1;
1727 m_bitPos = 1;
1728 }
1729 else if ( m_name == "WREN" )
1730 {
1731 m_registerType = Register::EECON1;
1732 m_bitPos = 2;
1733 }
1734 else if ( m_name == "WRERR" )
1735 {
1736 m_registerType = Register::EECON1;
1737 m_bitPos = 3;
1738 }
1739 else if ( m_name == "EEIF"&&(pic_type=="P16F84"||pic_type=="P16C84"))//imp ****
1740 {
1741 m_registerType = Register::EECON1;
1742 m_bitPos = 4;
1743 }
1744 else if ( m_name == "EEPGD" && pic_type=="P16F877" )
1745 {
1746 m_registerType = Register::EECON1;
1747 m_bitPos = 7;
1748 }
1749 //---------VRCON------//
1750 else if ( m_name == "VR0" && pic_type=="P16F627" )
1751 {
1752 m_registerType = Register::VRCON;
1753 m_bitPos = 0;
1754 }
1755 else if ( m_name == "VR1" && pic_type=="P16F627" )
1756 {
1757 m_registerType = Register::VRCON;
1758 m_bitPos = 1;
1759 }
1760 else if ( m_name == "VR2" && pic_type=="P16F627" )
1761 {
1762 m_registerType = Register::VRCON;
1763 m_bitPos = 2;
1764 }
1765 else if ( m_name == "VR3" && pic_type=="P16F627" )
1766 {
1767 m_registerType = Register::VRCON;
1768 m_bitPos = 3;
1769 }
1770 else if ( m_name == "VRR" && pic_type=="P16F627" )
1771 {
1772 m_registerType = Register::VRCON;
1773 m_bitPos = 5;
1774 }
1775 else if ( m_name == "VROE" && pic_type=="P16F627" )
1776 {
1777 m_registerType = Register::VRCON;
1778 m_bitPos = 6;
1779 }
1780 else if ( m_name == "VREN" && pic_type=="P16F627" )
1781 {
1782 m_registerType = Register::VRCON;
1783 m_bitPos = 7;
1784 }
1785 else
1786 {
1787 m_registerType = Register::none;
1788 m_bitPos = 0;
1789 qCritical() << Q_FUNC_INFO << "Unknown bit: " << m_name << endl;
1790 }
1791 }
1792 //END class RegisterBit
1793
1794
1795
1796
1797 //BEGIN class RegisterState
RegisterState()1798 RegisterState::RegisterState()
1799 {
1800 reset();
1801 }
1802
1803
reset()1804 void RegisterState::reset()
1805 {
1806 known = 0x0;
1807 value = 0x0;
1808 }
1809
1810
merge(const RegisterState & state)1811 void RegisterState::merge( const RegisterState & state )
1812 {
1813 known &= state.known;
1814 known &= ~( value ^ state.value );
1815 }
1816
1817
operator ==(const RegisterState & state) const1818 bool RegisterState::operator == ( const RegisterState & state ) const
1819 {
1820 return (known == state.known) && (value == state.value);
1821 }
1822
1823
print()1824 void RegisterState::print()
1825 {
1826 cout << " known="<< binary(known).toStdString() <<endl;
1827 cout << " value="<< binary(value).toStdString() <<endl;
1828 }
1829 //END class RegisterState
1830
1831
1832
1833 //BEGIN class RegisterBehaviour
RegisterBehaviour()1834 RegisterBehaviour::RegisterBehaviour()
1835 {
1836 reset();
1837 }
1838
1839
reset()1840 void RegisterBehaviour::reset()
1841 {
1842 depends = 0x0;
1843 indep = 0x0;
1844 }
1845 //END class RegisterBehaviour
1846
1847
1848
1849 //BEGIN class ProcessorState
ProcessorState()1850 ProcessorState::ProcessorState()
1851 {
1852 }
1853
1854
reset()1855 void ProcessorState::reset()
1856 {
1857 working.reset();
1858 status.reset();
1859
1860 RegisterMap::iterator end = m_registers.end();
1861 for ( RegisterMap::iterator it = m_registers.begin(); it != end; ++it )
1862 (*it).reset();
1863 }
1864
1865
merge(const ProcessorState & state)1866 void ProcessorState::merge( const ProcessorState & state )
1867 {
1868 working.merge( state.working );
1869 status.merge( state.status );
1870
1871 RegisterMap::iterator this_it = m_registers.begin();
1872 RegisterMap::const_iterator other_it = state.m_registers.begin();
1873
1874 RegisterMap::iterator this_end = m_registers.end();
1875 RegisterMap::const_iterator other_end = state.m_registers.end();
1876
1877 while ( true )
1878 {
1879 if ( this_it == this_end )
1880 {
1881 // So remaining registers of this are default
1882 while ( other_it != other_end )
1883 {
1884 m_registers[ other_it.key() ].merge( *other_it );
1885 ++other_it;
1886 }
1887 return;
1888 }
1889
1890 if ( other_it == other_end )
1891 {
1892 // So remaining registers of other are default
1893 while ( this_it != this_end )
1894 {
1895 (*this_it).merge( RegisterState() );
1896 ++this_it;
1897 }
1898 return;
1899 }
1900
1901 //RegisterState thisReg = *this_it;
1902 //RegisterState otherReg = *other_it;
1903
1904 if ( this_it.key() == other_it.key() )
1905 {
1906 (*this_it).merge( *other_it );
1907 ++this_it;
1908 ++other_it;
1909 }
1910 else if ( this_it.key() < other_it.key() )
1911 {
1912 (*this_it).merge( RegisterState() );
1913 ++this_it;
1914 }
1915 else // other_it.key() < this_it.key()
1916 {
1917 m_registers[ other_it.key() ].merge( *other_it );
1918 ++other_it;
1919 }
1920 }
1921 }
1922
1923
reg(const Register & reg)1924 RegisterState & ProcessorState::reg( const Register & reg )
1925 {
1926 if ( reg.type() == Register::WORKING )
1927 return working;
1928
1929 if ( reg.type() == Register::STATUS )
1930 return status;
1931
1932 return m_registers[ reg ];
1933 }
1934
1935
reg(const Register & reg) const1936 RegisterState ProcessorState::reg( const Register & reg ) const
1937 {
1938 if ( reg.type() == Register::WORKING )
1939 return working;
1940
1941 if ( reg.type() == Register::STATUS )
1942 return status;
1943
1944 return m_registers[ reg ];
1945 }
1946
1947
operator ==(const ProcessorState & state) const1948 bool ProcessorState::operator == ( const ProcessorState & state ) const
1949 {
1950 if ( working != state.working )
1951 return false;
1952
1953 if ( status != state.status )
1954 return false;
1955
1956 RegisterMap::const_iterator this_it = m_registers.begin();
1957 RegisterMap::const_iterator other_it = state.m_registers.begin();
1958
1959 RegisterMap::const_iterator this_end = m_registers.end();
1960 RegisterMap::const_iterator other_end = state.m_registers.end();
1961
1962 while ( true )
1963 {
1964 if ( this_it == this_end )
1965 {
1966 // So remaining registers of this are default
1967 while ( other_it != other_end )
1968 {
1969 if ( *other_it != RegisterState() )
1970 return false;
1971 ++other_it;
1972 }
1973 return true;
1974 }
1975
1976 if ( other_it == other_end )
1977 {
1978 // So remaining registers of other are default
1979 while ( this_it != this_end )
1980 {
1981 if ( *this_it != RegisterState() )
1982 return false;
1983 ++this_it;
1984 }
1985 return true;
1986 }
1987
1988 //RegisterState thisReg = *this_it;
1989 //RegisterState otherReg = *other_it;
1990
1991 if ( this_it.key() == other_it.key() )
1992 {
1993 if ( *this_it != *other_it )
1994 return false;
1995 ++this_it;
1996 ++other_it;
1997 }
1998 else if ( this_it.key() < other_it.key() )
1999 {
2000 if ( *this_it != RegisterState() )
2001 return false;
2002 ++this_it;
2003 }
2004 else // other_it.key() < this_it.key()
2005 {
2006 if ( *other_it != RegisterState() )
2007 return false;
2008 ++other_it;
2009 }
2010 }
2011 }
2012
2013
print()2014 void ProcessorState::print()
2015 {
2016 cout << " WORKING:\n";
2017 working.print();
2018 cout << " STATUS:\n";
2019 working.print();
2020 RegisterMap::iterator end = m_registers.end();
2021 for ( RegisterMap::iterator it = m_registers.begin(); it != end; ++it )
2022 {
2023 cout << " " << it.key().name().toStdString() << ":\n";
2024 it.value().print();
2025 // it.value().print();
2026 }
2027 }
2028 //END class ProcessorState
2029
2030
2031
2032 //BEGIN class ProcessorBehaviour
ProcessorBehaviour()2033 ProcessorBehaviour::ProcessorBehaviour()
2034 {
2035 }
2036
2037
reset()2038 void ProcessorBehaviour::reset()
2039 {
2040 working.reset();
2041 status.reset();
2042
2043 RegisterMap::iterator end = m_registers.end();
2044 for ( RegisterMap::iterator it = m_registers.begin(); it != end; ++it )
2045 (*it).reset();
2046 }
2047
2048
reg(const Register & reg)2049 RegisterBehaviour & ProcessorBehaviour::reg( const Register & reg )
2050 {
2051 if ( reg.type() == Register::WORKING )
2052 return working;
2053
2054 if ( reg.type() == Register::STATUS )
2055 return status;
2056
2057 return m_registers[ reg ];
2058 }
2059 //END class ProcessorBehaviour
2060
2061
2062
2063 //BEGIN class RegisterDepends
RegisterDepends()2064 RegisterDepends::RegisterDepends()
2065 {
2066 reset();
2067 }
2068
2069
reset()2070 void RegisterDepends::reset()
2071 {
2072 working = 0x0;
2073 status = 0x0;
2074
2075 RegisterMap::iterator end = m_registers.end();
2076 for ( RegisterMap::iterator it = m_registers.begin(); it != end; ++it )
2077 (*it) = 0x0;
2078 }
2079
2080
reg(const Register & reg)2081 uchar & RegisterDepends::reg( const Register & reg )
2082 {
2083 if ( reg.type() == Register::WORKING )
2084 return working;
2085
2086 if ( reg.type() == Register::STATUS )
2087 return status;
2088
2089 // If we don't already have the register, we need to reset it first
2090 if ( !m_registers.contains( reg.name() ) )
2091 m_registers[ reg ] = 0xff;
2092
2093 return m_registers[ reg ];
2094 }
2095 //END class RegisterDepends
2096
2097
2098
2099 //BEGIN clas Code
Code()2100 Code::Code()
2101 {
2102 }
2103
2104
merge(Code * code,InstructionPosition middleInsertionPosition)2105 void Code::merge( Code * code, InstructionPosition middleInsertionPosition )
2106 {
2107 if ( code == this )
2108 {
2109 cout << Q_FUNC_INFO << "identical\n";
2110 return;
2111 }
2112
2113 if ( !code )
2114 return;
2115
2116 // Reparent instructions
2117 for ( unsigned i = 0; i < PositionCount; ++i )
2118 {
2119 InstructionList * list = code->instructionList( (InstructionPosition)i );
2120 InstructionList::const_iterator end = list->end();
2121 for ( InstructionList::const_iterator it = list->begin(); it != end; ++it )
2122 append( *it, ( (i == Middle) ? middleInsertionPosition : (InstructionPosition)i ) );
2123
2124 // Queue any labels that the other code has queued
2125 m_queuedLabels[i] += code->queuedLabels( (InstructionPosition)i );
2126 }
2127 }
2128
2129
queueLabel(const QString & label,InstructionPosition position)2130 void Code::queueLabel( const QString & label, InstructionPosition position )
2131 {
2132 // cout << Q_FUNC_INFO << "label="<<label<<" position="<<position<<'\n';
2133 m_queuedLabels[ position ] << label;
2134 }
2135
2136
removeInstruction(Instruction * instruction)2137 void Code::removeInstruction( Instruction * instruction )
2138 {
2139 if ( !instruction )
2140 return;
2141
2142 // If the instruction could potentially be jumped over by a BTFSS or a
2143 // BTFSC intsruction, then we must also remove the bit test instruction,
2144 // else the next instruction will be jumped over instead after removal.
2145 // Removing the bit test instruction is perfectly safe as it only does
2146 // branching (not setting of any bits, etc).
2147
2148 // Any labels that the instruction has must be given to the next
2149 // instruction.
2150
2151 iterator e = end();
2152 iterator previous = e; // Refers to the previous instruction if it was a bit test instruction
2153 for ( iterator i = begin(); i != e; ++i )
2154 {
2155 if ( *i != instruction )
2156 {
2157 if ( dynamic_cast<Instr_btfss*>(*i) || dynamic_cast<Instr_btfsc*>(*i) )
2158 previous = i;
2159 else
2160 previous = e;
2161 continue;
2162 }
2163
2164 iterator next = ++iterator(i);
2165
2166 QStringList labels = instruction->labels();
2167 i.list->erase( i.it );
2168
2169 if ( previous != e )
2170 {
2171 labels += (*previous)->labels();
2172 previous.list->erase( previous.it );
2173 }
2174
2175 if ( next != e )
2176 (*next)->addLabels( labels );
2177
2178 break;
2179 }
2180
2181 // instruction->removeOutputs();
2182 }
2183
2184
append(Instruction * instruction,InstructionPosition position)2185 void Code::append( Instruction * instruction, InstructionPosition position )
2186 {
2187 if ( !instruction )
2188 return;
2189
2190 // cout << Q_FUNC_INFO << instruction->code() << '\n';
2191
2192 removeInstruction( instruction );
2193 m_instructionLists[position].append( instruction );
2194
2195 instruction->setCode( this );
2196
2197 if ( instruction->type() == Instruction::Assembly /*||
2198 instruction->type() == Instruction::Raw*/ )
2199 {
2200 // if ( (position == Middle) && !m_queuedLabels[position].isEmpty() )
2201 // cout << "adding queued labels for 1: " << m_queuedLabels[position].join(",") << '\n';
2202 instruction->addLabels( m_queuedLabels[position] );
2203 m_queuedLabels[position].clear();
2204 }
2205 }
2206
2207
instruction(const QString & label) const2208 Instruction * Code::instruction( const QString & label ) const
2209 {
2210 for ( unsigned i = 0; i < PositionCount; ++i )
2211 {
2212 InstructionList::const_iterator end = m_instructionLists[i].end();
2213 for ( InstructionList::const_iterator it = m_instructionLists[i].begin(); it != end; ++it )
2214 {
2215 if ( (*it)->labels().contains( label ) )
2216 return *it;
2217 }
2218 }
2219 return nullptr;
2220 }
2221
2222
find(Instruction * instruction)2223 Code::iterator Code::find( Instruction * instruction )
2224 {
2225 iterator e = end();
2226 iterator i = begin();
2227 for ( ; i != e; ++i )
2228 {
2229 if ( *i == instruction )
2230 break;
2231 }
2232 return i;
2233 }
2234
2235
postCompileConstruct()2236 void Code::postCompileConstruct()
2237 {
2238 // Give any queued labels to the instructions in the subsequent code block
2239 for ( unsigned i = 0; i < PositionCount; ++i )
2240 {
2241 if ( m_queuedLabels[i].isEmpty() )
2242 continue;
2243
2244 QStringList labels = m_queuedLabels[i];
2245 m_queuedLabels[i].clear();
2246
2247 // Find an instruction to dump them onto
2248 for ( unsigned block = i+1; block < PositionCount; ++block )
2249 {
2250 bool added = false;
2251
2252 InstructionList::iterator end = m_instructionLists[block].end();
2253 for ( InstructionList::iterator it = m_instructionLists[block].begin(); it != end; ++it )
2254 {
2255 if ( (*it)->type() == Instruction::Assembly )
2256 {
2257 (*it)->addLabels( labels );
2258 added = true;
2259 break;
2260 }
2261 }
2262
2263 if ( added )
2264 break;
2265 }
2266 }
2267 }
2268
2269
generateCode(PIC14 * pic) const2270 QString Code::generateCode( PIC14 * pic ) const
2271 {
2272 QString code;
2273
2274 const QStringList variables = findVariables();
2275 if ( !variables.isEmpty() )
2276 {
2277 code += "; Variables\n";
2278 uchar reg = pic->gprStart();
2279 QStringList::const_iterator end = variables.end();
2280 for ( QStringList::const_iterator it = variables.begin(); it != end; ++it )
2281 code += QString("%1\tequ\t0x%2\n").arg( *it ).arg( QString::number( reg++, 16 ) );
2282
2283 code += "\n";
2284 }
2285
2286 QString picString = pic->minimalTypeString();
2287 code += QString("list p=%1\n").arg( picString );
2288 code += QString("include \"p%2.inc\"\n\n").arg( picString.toLower() );
2289
2290 code += "; Config options\n";
2291 code += " __config _WDT_OFF\n\n";
2292
2293 code += "START\n\n";
2294
2295 for ( unsigned i = 0; i < PositionCount; ++i )
2296 {
2297 InstructionList::const_iterator end = m_instructionLists[i].end();
2298 for ( InstructionList::const_iterator it = m_instructionLists[i].begin(); it != end; ++it )
2299 {
2300 const QStringList labels = (*it)->labels();
2301 if ( !labels.isEmpty() )
2302 {
2303 code += '\n';
2304 QStringList::const_iterator labelsEnd = labels.end();
2305 for ( QStringList::const_iterator labelsIt = labels.begin(); labelsIt != labelsEnd; ++labelsIt )
2306 code += *labelsIt + '\n';
2307 }
2308
2309 if ( (*it)->type() == Instruction::Assembly )
2310 code += '\t';
2311 code += (*it)->code() + '\n';
2312 }
2313 }
2314
2315 return code;
2316 }
2317
2318
findVariables() const2319 QStringList Code::findVariables() const
2320 {
2321 QStringList variables;
2322
2323 const_iterator e = end();
2324 for ( const_iterator i = begin(); i != e; ++i )
2325 {
2326 if ( (*i)->file().type() != Register::GPR )
2327 continue;
2328
2329 QString alias = (*i)->file().name();
2330 if ( !variables.contains( alias ) )
2331 variables << alias;
2332 }
2333
2334 return variables;
2335 }
2336
2337
generateLinksAndStates()2338 void Code::generateLinksAndStates()
2339 {
2340 CodeIterator e = end();
2341
2342 for ( CodeIterator it = begin(); it != e; ++it )
2343 (*it)->clearLinks();
2344
2345 for ( CodeIterator it = begin(); it != e; ++it )
2346 (*it)->generateLinksAndStates( it );
2347
2348 // Generate return links for call instructions
2349 // This cannot be done from the call instructions as we need to have
2350 // generated the links first.
2351 for ( CodeIterator it = begin(); it != e; ++it )
2352 {
2353 Instr_call * ins = dynamic_cast<Instr_call*>(*it);
2354 if ( !ins )
2355 continue;
2356
2357 Instruction * next = *(++Code::iterator(it));
2358 ins->makeReturnLinks( next );
2359 }
2360 }
2361
2362
setAllUnused()2363 void Code::setAllUnused()
2364 {
2365 CodeIterator e = end();
2366 for ( CodeIterator it = begin(); it != e; ++it )
2367 {
2368 (*it)->setUsed( false );
2369 (*it)->resetRegisterDepends();
2370 }
2371 }
2372
2373
begin()2374 CodeIterator Code::begin()
2375 {
2376 // Following code is very similar to the version of this function.
2377 // Make sure any changes are applied to both (when applicable).
2378
2379 for ( unsigned i = 0; i < PositionCount; ++i )
2380 {
2381 if ( m_instructionLists[i].isEmpty() )
2382 continue;
2383
2384 CodeIterator codeIterator;
2385 codeIterator.code = this;
2386 codeIterator.it = m_instructionLists[i].begin();
2387 codeIterator.pos = (Code::InstructionPosition)i;
2388 codeIterator.list = & m_instructionLists[i];
2389 codeIterator.listEnd = m_instructionLists[i].end();
2390
2391 return codeIterator;
2392 }
2393
2394 return end();
2395 }
2396
2397
end()2398 CodeIterator Code::end()
2399 {
2400 // Following code is very similar to the version of this function.
2401 // Make sure any changes are applied to both (when applicable).
2402
2403 CodeIterator codeIterator;
2404 codeIterator.code = this;
2405 codeIterator.it = m_instructionLists[ PositionCount - 1 ].end();
2406 codeIterator.pos = (Code::InstructionPosition)(Code::PositionCount - 1);
2407 codeIterator.list = & m_instructionLists[ PositionCount - 1 ];
2408 codeIterator.listEnd = m_instructionLists[ PositionCount - 1 ].end();
2409 return codeIterator;
2410 }
2411
2412
begin() const2413 CodeConstIterator Code::begin() const
2414 {
2415 // Following code is very similar to the non-const version of this function.
2416 // Make sure any changes are applied to both (when applicable).
2417
2418 for ( unsigned i = 0; i < PositionCount; ++i )
2419 {
2420 if ( m_instructionLists[i].isEmpty() )
2421 continue;
2422
2423 CodeConstIterator codeIterator;
2424 codeIterator.code = this;
2425 codeIterator.it = m_instructionLists[i].begin();
2426 codeIterator.pos = (Code::InstructionPosition)i;
2427 codeIterator.list = & m_instructionLists[i];
2428 codeIterator.listEnd = m_instructionLists[i].end();
2429
2430 return codeIterator;
2431 }
2432
2433 return end();
2434 }
2435
2436
end() const2437 CodeConstIterator Code::end() const
2438 {
2439 // Following code is very similar to the non-const version of this function.
2440 // Make sure any changes are applied to both (when applicable).
2441
2442 CodeConstIterator codeIterator;
2443 codeIterator.code = this;
2444 codeIterator.it = m_instructionLists[ PositionCount - 1 ].end();
2445 codeIterator.pos = (Code::InstructionPosition)(Code::PositionCount - 1);
2446 codeIterator.list = & m_instructionLists[ PositionCount - 1 ];
2447 codeIterator.listEnd = m_instructionLists[ PositionCount - 1 ].end();
2448 return codeIterator;
2449 }
2450 //END class Code
2451
2452
2453
2454 //BEGIN class CodeIterator
operator ++()2455 CodeIterator & CodeIterator::operator ++ ()
2456 {
2457 // NOTE: This code is very similar to the const version.
2458 // Any changes to thsi code should be applied there as well (when applicable).
2459
2460 do
2461 {
2462 if ( ++it == listEnd && pos < (Code::PositionCount - 1) )
2463 {
2464 bool found = false;
2465 for ( pos = (Code::InstructionPosition)(pos+1); pos < Code::PositionCount; pos = (Code::InstructionPosition)(pos+1) )
2466 {
2467 list = code->instructionList( pos );
2468 listEnd = list->end();
2469 if ( list->isEmpty() )
2470 continue;
2471
2472 it = list->begin();
2473 found = true;
2474 break;
2475 }
2476
2477 if ( !found )
2478 it = listEnd;
2479 }
2480 }
2481 while ( (it != listEnd) && ((*it)->type() != Instruction::Assembly) );
2482
2483 return *this;
2484 }
2485
2486
removeAndIncrement()2487 CodeIterator & CodeIterator::removeAndIncrement()
2488 {
2489 Instruction * i = *it;
2490 ++(*this);
2491 code->removeInstruction( i );
2492 return *this;
2493 }
2494
2495
insertBefore(Instruction * ins)2496 void CodeIterator::insertBefore( Instruction * ins )
2497 {
2498 list->insert( it, ins );
2499 }
2500 //END class CodeIterator
2501
2502
2503
2504 //BEGIN class CodeConstIterator
operator ++()2505 CodeConstIterator & CodeConstIterator::operator ++ ()
2506 {
2507 // NOTE: This code is very similar to the non-const version.
2508 // Any changes to thsi code should be applied there as well (when applicable).
2509
2510 do
2511 {
2512 if ( ++it == listEnd && pos < (Code::PositionCount - 1) )
2513 {
2514 bool found = false;
2515 for ( pos = (Code::InstructionPosition)(pos+1); pos < Code::PositionCount; pos = (Code::InstructionPosition)(pos+1) )
2516 {
2517 list = code->instructionList( pos );
2518 listEnd = list->end();
2519 if ( list->isEmpty() )
2520 continue;
2521
2522 it = list->begin();
2523 found = true;
2524 break;
2525 }
2526
2527 if ( !found )
2528 it = listEnd;
2529 }
2530 }
2531 while ( (it != listEnd) && ((*it)->type() != Instruction::Assembly) );
2532
2533 return *this;
2534 }
2535 //END class CodeConstIterator
2536
2537
2538
2539
2540 //BEGIN class Instruction
Instruction()2541 Instruction::Instruction()
2542 {
2543 m_bInputStateChanged = true;
2544 m_bPositionAffectsBranching = false;
2545 m_bUsed = false;
2546 m_literal = 0;
2547 m_dest = 0;
2548 }
2549
2550
~Instruction()2551 Instruction::~ Instruction()
2552 {
2553 }
2554
2555
addLabels(const QStringList & labels)2556 void Instruction::addLabels( const QStringList & labels )
2557 {
2558 m_labels += labels;
2559 }
2560
2561
setLabels(const QStringList & labels)2562 void Instruction::setLabels( const QStringList & labels )
2563 {
2564 m_labels = labels;
2565 }
2566
2567
generateLinksAndStates(Code::iterator current)2568 void Instruction::generateLinksAndStates( Code::iterator current )
2569 {
2570 makeOutputLinks( current );
2571 m_outputState.reset();
2572 }
2573
2574
behaviour() const2575 ProcessorBehaviour Instruction::behaviour() const
2576 {
2577 return ProcessorBehaviour();
2578 }
2579
2580
makeOutputLinks(Code::iterator current,bool firstOutput,bool secondOutput)2581 void Instruction::makeOutputLinks( Code::iterator current, bool firstOutput, bool secondOutput )
2582 {
2583 if ( !firstOutput && !secondOutput )
2584 return;
2585
2586 ++current;
2587 if ( !*current )
2588 {
2589 qWarning() << Q_FUNC_INFO << "current+1 is null"<<endl;
2590 return;
2591 }
2592 if ( firstOutput )
2593 (*current)->addInputLink( this );
2594
2595 if ( !secondOutput )
2596 return;
2597
2598 ++current;
2599 (*current)->addInputLink( this );
2600 }
2601
2602
makeLabelOutputLink(const QString & label)2603 void Instruction::makeLabelOutputLink( const QString & label )
2604 {
2605 Instruction * output = m_pCode->instruction( label );
2606 if ( output )
2607 output->addInputLink( this );
2608 }
2609
2610
addInputLink(Instruction * instruction)2611 void Instruction::addInputLink( Instruction * instruction )
2612 {
2613 // Don't forget that a link to ourself is valid!
2614 if ( !instruction || m_inputLinks.contains( instruction ) )
2615 return;
2616
2617 m_inputLinks << instruction;
2618 instruction->addOutputLink( this );
2619 }
2620
2621
addOutputLink(Instruction * instruction)2622 void Instruction::addOutputLink( Instruction * instruction )
2623 {
2624 // Don't forget that a link to ourself is valid!
2625 if ( !instruction || m_outputLinks.contains( instruction ) )
2626 return;
2627
2628 m_outputLinks << instruction;
2629 instruction->addInputLink( this );
2630 }
2631
2632
removeInputLink(Instruction * instruction)2633 void Instruction::removeInputLink( Instruction * instruction )
2634 {
2635 m_inputLinks.removeAll( instruction );
2636 }
2637
2638
removeOutputLink(Instruction * instruction)2639 void Instruction::removeOutputLink( Instruction * instruction )
2640 {
2641 m_outputLinks.removeAll( instruction );
2642 }
2643
2644
clearLinks()2645 void Instruction::clearLinks()
2646 {
2647 m_inputLinks.clear();
2648 m_outputLinks.clear();
2649 }
2650 //END class Instruction
2651
2652
2653
2654 //BEGIN Byte-Oriented File Register Operations
code() const2655 QString Instr_addwf::code() const
2656 {
2657 return QString("addwf\t%1,%2").arg( m_file.name() ).arg( m_dest );
2658 }
2659
generateLinksAndStates(Code::iterator current)2660 void Instr_addwf::generateLinksAndStates( Code::iterator current )
2661 {
2662 m_outputState = m_inputState;
2663
2664 m_outputState.reg( outputReg() ).value = (m_inputState.working.value + m_inputState.reg( m_file ).value) & 0xff;
2665 m_outputState.reg( outputReg() ).known = ((m_inputState.working.known == 0xff) && (m_inputState.reg( m_file ).known == 0xff)) ? 0xff : 0x0;
2666
2667 m_outputState.status.known &= ~( (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z) );
2668
2669 if ( m_file.type() != Register::PCL || m_dest == 0 )
2670 {
2671 makeOutputLinks( current );
2672 return;
2673 }
2674
2675 ++current; // Don't have a link to ourself
2676
2677 // maxInc is the greatest possibly value that we might have incremented the program counter by.
2678 // It is generated by ORing the known bits of the working register with the greatest value
2679 // of the unknown bits;
2680 uchar maxInc = m_inputState.working.maxValue();
2681 if ( maxInc < 0xff )
2682 maxInc++;
2683 // cout << "m_inputState.working.known="<<int(m_inputState.working.known)<<" maxInc="<<int(maxInc)<<'\n';
2684 Code::iterator end = m_pCode->end();
2685 for ( int i = 0; current != end && i < maxInc; ++i, ++current )
2686 {
2687 (*current)->addInputLink( this );
2688 // if ( i != maxInc-1 )
2689 // (*current)->setPositionAffectsBranching( true );
2690 }
2691 }
2692
behaviour() const2693 ProcessorBehaviour Instr_addwf::behaviour() const
2694 {
2695 ProcessorBehaviour behaviour;
2696
2697 // Depend on W and f
2698 behaviour.working.depends = 0xff;
2699 behaviour.reg( m_file ).depends = 0xff;
2700
2701 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
2702 behaviour.status.indep = (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z);
2703 return behaviour;
2704 }
2705
2706
2707
code() const2708 QString Instr_andwf::code() const
2709 {
2710 return QString("andwf\t%1,%2").arg( m_file.name() ).arg( m_dest );
2711 }
2712
generateLinksAndStates(Code::iterator current)2713 void Instr_andwf::generateLinksAndStates( Code::iterator current )
2714 {
2715 makeOutputLinks( current );
2716 m_outputState = m_inputState;
2717
2718 uchar definiteOnes = m_inputState.reg( m_file ).definiteOnes() & m_outputState.working.definiteOnes();
2719 m_outputState.reg( outputReg() ).value = definiteOnes;
2720 m_outputState.reg( outputReg() ).known = m_inputState.reg( m_file ).definiteZeros() | m_inputState.working.definiteZeros() | definiteOnes;
2721
2722 m_outputState.status.known &= ~(1 << RegisterBit::Z);
2723 }
2724
behaviour() const2725 ProcessorBehaviour Instr_andwf::behaviour() const
2726 {
2727 ProcessorBehaviour behaviour;
2728
2729 // Depend on W and f
2730 behaviour.working.depends = 0xff;
2731 behaviour.reg( m_file ).depends = 0xff;
2732
2733 if ( m_dest == 0 )
2734 behaviour.working.indep = m_inputState.reg( m_file ).known & ~( m_inputState.reg( m_file ).value);
2735
2736 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
2737 behaviour.status.indep = (1 << RegisterBit::Z);
2738 return behaviour;
2739 }
2740
2741
code() const2742 QString Instr_clrf::code() const
2743 {
2744 return QString("clrf\t%1").arg( m_file.name() );
2745 }
2746
generateLinksAndStates(Code::iterator current)2747 void Instr_clrf::generateLinksAndStates( Code::iterator current )
2748 {
2749 makeOutputLinks( current );
2750
2751 m_outputState = m_inputState;
2752 m_outputState.reg( m_file ).known = 0xff;
2753 m_outputState.reg( m_file ).value = 0x0;
2754
2755 m_outputState.status.known |= (1 << RegisterBit::Z);
2756 m_outputState.status.value |= (1 << RegisterBit::Z);
2757 }
2758
behaviour() const2759 ProcessorBehaviour Instr_clrf::behaviour() const
2760 {
2761 ProcessorBehaviour behaviour;
2762
2763 behaviour.reg( m_file ).indep = 0xff;
2764
2765 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
2766 behaviour.status.indep = (1 << RegisterBit::Z);
2767
2768 return behaviour;
2769 }
2770
2771
2772 //TODO CLRW
2773 //TODO COMF
2774
2775
code() const2776 QString Instr_decf::code() const
2777 {
2778 return QString("decf\t%1,%2").arg( m_file.name() ).arg( m_dest );
2779 }
2780
generateLinksAndStates(Code::iterator current)2781 void Instr_decf::generateLinksAndStates( Code::iterator current )
2782 {
2783 makeOutputLinks( current );
2784
2785 m_outputState = m_inputState;
2786 m_outputState.status.known &= ~(1 << RegisterBit::Z);
2787
2788 m_outputState.reg( outputReg() ).known = 0x0;
2789 }
2790
behaviour() const2791 ProcessorBehaviour Instr_decf::behaviour() const
2792 {
2793 ProcessorBehaviour behaviour;
2794
2795 behaviour.reg( m_file ).depends = 0xff;
2796
2797 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
2798 behaviour.status.indep = (1 << RegisterBit::Z);
2799
2800 return behaviour;
2801 }
2802
2803
code() const2804 QString Instr_decfsz::code() const
2805 {
2806 return QString("decfsz\t%1,%2").arg( m_file.name() ).arg( m_dest );
2807 }
2808
generateLinksAndStates(Code::iterator current)2809 void Instr_decfsz::generateLinksAndStates( Code::iterator current )
2810 {
2811 makeOutputLinks( current, true, true );
2812
2813 m_outputState = m_inputState;
2814 m_outputState.reg( outputReg() ).known = 0x0;
2815 }
2816
behaviour() const2817 ProcessorBehaviour Instr_decfsz::behaviour() const
2818 {
2819 ProcessorBehaviour behaviour;
2820
2821 behaviour.reg( m_file ).depends = 0xff;
2822
2823 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
2824 return behaviour;
2825 }
2826
2827
code() const2828 QString Instr_incf::code() const
2829 {
2830 return QString("incf\t%1,%2").arg( m_file.name() ).arg( m_dest );
2831 }
2832
generateLinksAndStates(Code::iterator current)2833 void Instr_incf::generateLinksAndStates( Code::iterator current )
2834 {
2835 makeOutputLinks( current );
2836
2837 m_outputState = m_inputState;
2838 m_outputState.status.known &= ~(1 << RegisterBit::Z);
2839
2840 m_outputState.reg( outputReg() ).known = 0x0;
2841 }
2842
behaviour() const2843 ProcessorBehaviour Instr_incf::behaviour() const
2844 {
2845 ProcessorBehaviour behaviour;
2846
2847 behaviour.reg( m_file ).depends = 0xff;
2848
2849 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
2850 behaviour.status.indep = (1 << RegisterBit::Z);
2851 return behaviour;
2852 }
2853
2854
2855 //TODO INCFSZ
2856
2857
code() const2858 QString Instr_iorwf::code() const
2859 {
2860 return QString("iorwf\t%1,%2").arg( m_file.name() ).arg( m_dest );
2861 }
2862
generateLinksAndStates(Code::iterator current)2863 void Instr_iorwf::generateLinksAndStates( Code::iterator current )
2864 {
2865 makeOutputLinks( current );
2866
2867 m_outputState = m_inputState;
2868 m_outputState.status.known &= ~(1 << RegisterBit::Z);
2869
2870 m_outputState.reg( outputReg() ).known = 0x0;
2871 }
2872
behaviour() const2873 ProcessorBehaviour Instr_iorwf::behaviour() const
2874 {
2875 ProcessorBehaviour behaviour;
2876
2877 // Depend on W and f
2878 behaviour.working.depends = 0xff;
2879 behaviour.reg( m_file ).depends = 0xff;
2880
2881 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
2882 behaviour.status.indep = (1 << RegisterBit::Z);
2883 return behaviour;
2884 }
2885
2886
code() const2887 QString Instr_movf::code() const
2888 {
2889 return QString("movf\t%1,%2").arg( m_file.name() ).arg( m_dest );
2890 }
2891
generateLinksAndStates(Code::iterator current)2892 void Instr_movf::generateLinksAndStates( Code::iterator current )
2893 {
2894 makeOutputLinks( current );
2895
2896 m_outputState = m_inputState;
2897
2898 if ( m_inputState.reg( m_file ).known == 0xff )
2899 {
2900 m_outputState.status.known |= (1 << RegisterBit::Z);
2901 bool isZero = (m_inputState.reg( m_file ).value == 0x0);
2902 if ( isZero )
2903 m_outputState.status.value |= (1 << RegisterBit::Z);
2904 else
2905 m_outputState.status.value &= ~(1 << RegisterBit::Z);
2906 }
2907 else
2908 m_outputState.status.known &= ~(1 << RegisterBit::Z);
2909
2910 if ( m_dest == 0 )
2911 {
2912 // Writing to the working register
2913 m_outputState.working.known = m_inputState.reg( m_file ).known;
2914 m_outputState.working.value = m_inputState.reg( m_file ).value;
2915 }
2916 }
2917
behaviour() const2918 ProcessorBehaviour Instr_movf::behaviour() const
2919 {
2920 ProcessorBehaviour behaviour;
2921
2922 if ( m_dest == 0 )
2923 behaviour.working.indep = 0xff;
2924
2925 behaviour.reg( m_file ).depends = 0xff;
2926
2927 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
2928 behaviour.status.indep = (1 << RegisterBit::Z);
2929 return behaviour;
2930 }
2931
2932
code() const2933 QString Instr_movwf::code() const
2934 {
2935 return QString("movwf\t%1").arg( m_file.name() );
2936 }
2937
generateLinksAndStates(Code::iterator current)2938 void Instr_movwf::generateLinksAndStates( Code::iterator current )
2939 {
2940 makeOutputLinks( current );
2941
2942 m_outputState = m_inputState;
2943 m_outputState.reg( m_file ).known = m_inputState.working.known;
2944 m_outputState.reg( m_file ).value = m_inputState.working.value;
2945 }
2946
behaviour() const2947 ProcessorBehaviour Instr_movwf::behaviour() const
2948 {
2949 ProcessorBehaviour behaviour;
2950
2951 behaviour.reg( m_file ).indep = 0xff;
2952 behaviour.working.depends = 0xff;
2953 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
2954
2955 return behaviour;
2956 }
2957
2958
2959 //TODO NOP
2960
2961
2962
code() const2963 QString Instr_rlf::code() const
2964 {
2965 return QString("rlf\t%1,%2").arg( m_file.name() ).arg( m_dest );
2966 }
2967
generateLinksAndStates(Code::iterator current)2968 void Instr_rlf::generateLinksAndStates( Code::iterator current )
2969 {
2970 makeOutputLinks( current );
2971
2972 m_outputState = m_inputState;
2973 m_outputState.status.known &= ~(1 << RegisterBit::C);
2974
2975 m_outputState.reg( outputReg() ).known = 0x0;
2976 }
2977
behaviour() const2978 ProcessorBehaviour Instr_rlf::behaviour() const
2979 {
2980 ProcessorBehaviour behaviour;
2981
2982 // Is the value written to W or f?
2983 if ( m_dest == 0 )
2984 behaviour.working.indep = 0xff;
2985
2986 behaviour.reg( m_file ).depends = 0xff;
2987
2988 behaviour.status.depends = (1 << RegisterBit::C) | (m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0);
2989 behaviour.status.indep = (1 << RegisterBit::C);
2990 return behaviour;
2991 }
2992
2993
code() const2994 QString Instr_rrf::code() const
2995 {
2996 return QString("rrf\t%1,%2").arg( m_file.name() ).arg( m_dest );
2997 }
2998
generateLinksAndStates(Code::iterator current)2999 void Instr_rrf::generateLinksAndStates( Code::iterator current )
3000 {
3001 makeOutputLinks( current );
3002
3003 m_outputState = m_inputState;
3004 m_outputState.status.known &= ~(1 << RegisterBit::C);
3005
3006 m_outputState.reg( outputReg() ).known = 0x0;
3007 }
3008
behaviour() const3009 ProcessorBehaviour Instr_rrf::behaviour() const
3010 {
3011 ProcessorBehaviour behaviour;
3012
3013 if ( m_dest == 0 )
3014 behaviour.working.indep = 0xff;
3015
3016 behaviour.reg( m_file ).depends = 0xff;
3017
3018 behaviour.status.depends = (1 << RegisterBit::C) | (m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0);
3019 behaviour.status.indep = (1 << RegisterBit::C);
3020 return behaviour;
3021 }
3022
3023
code() const3024 QString Instr_subwf::code() const
3025 {
3026 return QString("subwf\t%1,%2").arg( m_file.name() ).arg( m_dest );
3027 }
3028
generateLinksAndStates(Code::iterator current)3029 void Instr_subwf::generateLinksAndStates( Code::iterator current )
3030 {
3031 makeOutputLinks( current );
3032
3033 m_outputState = m_inputState;
3034
3035 if ( (m_inputState.working.known == 0xff) && (m_inputState.reg( m_file ).known == 0xff) )
3036 {
3037 m_outputState.reg( outputReg() ).known = 0xff;
3038 m_outputState.reg( outputReg() ).value = (m_inputState.reg( m_file ).value - m_inputState.working.value) & 0xff;
3039 }
3040 else
3041 m_outputState.reg( outputReg() ).known = 0x0;
3042
3043
3044 m_outputState.status.known &= ~( (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z) );
3045
3046 if ( m_inputState.working.minValue() > m_inputState.reg( m_file ).maxValue() )
3047 {
3048 m_outputState.status.value &= ~(1 << RegisterBit::C);
3049 m_outputState.status.known |= (1 << RegisterBit::C);
3050 }
3051 else if ( m_inputState.working.maxValue() <= m_inputState.reg( m_file ).minValue() )
3052 {
3053 m_outputState.status.value |= (1 << RegisterBit::C);
3054 m_outputState.status.known |= (1 << RegisterBit::C);
3055 }
3056
3057 if ( (m_inputState.working.known == 0xff) && (m_inputState.reg( m_file ).known == 0xff) )
3058 {
3059 bool isZero = (m_inputState.working.value == m_inputState.reg( m_file ).value);
3060 if ( isZero )
3061 m_outputState.status.value |= (1 << RegisterBit::Z);
3062 else
3063 m_outputState.status.value &= ~(1 << RegisterBit::Z);
3064 m_outputState.status.known |= (1 << RegisterBit::Z);
3065 }
3066 }
3067
behaviour() const3068 ProcessorBehaviour Instr_subwf::behaviour() const
3069 {
3070 ProcessorBehaviour behaviour;
3071
3072 // Depend on W and f
3073 behaviour.working.depends = 0xff;
3074 behaviour.reg( m_file ).depends = 0xff;
3075
3076 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
3077 behaviour.status.indep = (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z);
3078 return behaviour;
3079 }
3080
3081
code() const3082 QString Instr_swapf::code() const
3083 {
3084 return QString("swapf\t%1,%2").arg( m_file.name() ).arg( m_dest );
3085 }
3086
generateLinksAndStates(Code::iterator current)3087 void Instr_swapf::generateLinksAndStates( Code::iterator current )
3088 {
3089 makeOutputLinks( current );
3090
3091 m_outputState = m_inputState;
3092 if ( m_dest == 0 )
3093 {
3094 // Writing to the working register
3095 m_outputState.working.known = 0x0;
3096 }
3097 }
3098
behaviour() const3099 ProcessorBehaviour Instr_swapf::behaviour() const
3100 {
3101 ProcessorBehaviour behaviour;
3102 behaviour.reg( m_file ).depends = 0xff;
3103 behaviour.working.indep = ( m_dest == 0 ) ? 0xff : 0x0;
3104 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
3105 return behaviour;
3106 }
3107
3108
code() const3109 QString Instr_xorwf::code() const
3110 {
3111 return QString("xorwf\t%1,%2").arg( m_file.name() ).arg( m_dest );
3112 }
3113
generateLinksAndStates(Code::iterator current)3114 void Instr_xorwf::generateLinksAndStates( Code::iterator current )
3115 {
3116 makeOutputLinks( current );
3117
3118 m_outputState = m_inputState;
3119 m_outputState.status.known &= ~(1 << RegisterBit::Z);
3120
3121 m_outputState.reg( outputReg() ).known = 0x0;
3122 }
3123
behaviour() const3124 ProcessorBehaviour Instr_xorwf::behaviour() const
3125 {
3126 ProcessorBehaviour behaviour;
3127
3128 // Depend on W and f
3129 behaviour.working.depends = 0xff;
3130 behaviour.reg( m_file ).depends = 0xff;
3131
3132 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
3133 behaviour.status.indep = (1 << RegisterBit::Z);
3134 return behaviour;
3135 }
3136 //END Byte-Oriented File Register Operations
3137
3138
3139
3140 //BEGIN Bit-Oriented File Register Operations
code() const3141 QString Instr_bcf::code() const
3142 {
3143 return QString("bcf\t\t%1,%2").arg( m_file.name() ).arg( m_bit.name() );
3144 }
3145
generateLinksAndStates(Code::iterator current)3146 void Instr_bcf::generateLinksAndStates( Code::iterator current )
3147 {
3148 makeOutputLinks( current );
3149
3150 m_outputState = m_inputState;
3151 m_outputState.reg( m_file ).value &= ~uchar(1 << m_bit.bitPos());
3152 m_outputState.reg( m_file ).known |= uchar(1 << m_bit.bitPos());
3153 }
3154
behaviour() const3155 ProcessorBehaviour Instr_bcf::behaviour() const
3156 {
3157 ProcessorBehaviour behaviour;
3158
3159 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
3160 behaviour.reg( m_file ).indep = 1 << m_bit.bitPos();
3161 return behaviour;
3162 }
3163
3164
code() const3165 QString Instr_bsf::code() const
3166 {
3167 return QString("bsf\t\t%1,%2").arg( m_file.name() ).arg( m_bit.name() );
3168 }
3169
generateLinksAndStates(Code::iterator current)3170 void Instr_bsf::generateLinksAndStates( Code::iterator current )
3171 {
3172 makeOutputLinks( current );
3173
3174 m_outputState = m_inputState;
3175 m_outputState.reg( m_file ).value |= uchar(1 << m_bit.bitPos());
3176 m_outputState.reg( m_file ).known |= uchar(1 << m_bit.bitPos());
3177 }
3178
behaviour() const3179 ProcessorBehaviour Instr_bsf::behaviour() const
3180 {
3181 ProcessorBehaviour behaviour;
3182 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0;
3183 behaviour.reg( m_file ).indep = 1 << m_bit.bitPos();
3184 return behaviour;
3185 }
3186
3187
code() const3188 QString Instr_btfsc::code() const
3189 {
3190 return QString("btfsc\t%1,%2").arg( m_file.name() ).arg( m_bit.name() );
3191 }
3192
generateLinksAndStates(Code::iterator current)3193 void Instr_btfsc::generateLinksAndStates( Code::iterator current )
3194 {
3195 m_outputState = m_inputState;
3196
3197 if ( m_inputState.reg( m_file ).known & (1 << m_bit.bitPos()) )
3198 {
3199 bool bit = m_inputState.reg( m_file ).value & (1 << m_bit.bitPos());
3200 makeOutputLinks( current, bit, !bit );
3201 }
3202 else
3203 makeOutputLinks( current, true, true );
3204 }
3205
behaviour() const3206 ProcessorBehaviour Instr_btfsc::behaviour() const
3207 {
3208 ProcessorBehaviour behaviour;
3209 behaviour.reg( m_file ).depends = 1 << m_bit.bitPos();
3210 behaviour.status.depends = (m_file.type() == Register::STATUS) ? m_bit.bit() : 0x0;
3211 return behaviour;
3212 }
3213
3214
code() const3215 QString Instr_btfss::code() const
3216 {
3217 return QString("btfss\t%1,%2").arg( m_file.name() ).arg( m_bit.name() );
3218 }
3219
generateLinksAndStates(Code::iterator current)3220 void Instr_btfss::generateLinksAndStates( Code::iterator current )
3221 {
3222 m_outputState = m_inputState;
3223
3224 if ( m_inputState.reg( m_file ).known & (1 << m_bit.bitPos()) )
3225 {
3226 bool bit = m_inputState.reg( m_file ).value & (1 << m_bit.bitPos());
3227 makeOutputLinks( current, !bit, bit );
3228 }
3229 else
3230 makeOutputLinks( current, true, true );
3231 }
3232
behaviour() const3233 ProcessorBehaviour Instr_btfss::behaviour() const
3234 {
3235 ProcessorBehaviour behaviour;
3236 behaviour.reg( m_file ).depends = 1 << m_bit.bitPos();
3237 behaviour.status.depends = (m_file.type() == Register::STATUS) ? m_bit.bit() : 0x0;
3238 return behaviour;
3239 }
3240 //END Bit-Oriented File Register Operations
3241
3242
3243
3244 //BEGIN Literal and Control Operations
code() const3245 QString Instr_addlw::code() const
3246 {
3247 return QString("addlw\t%1").arg( m_literal );
3248 }
3249
generateLinksAndStates(Code::iterator current)3250 void Instr_addlw::generateLinksAndStates( Code::iterator current )
3251 {
3252 makeOutputLinks( current );
3253
3254 m_outputState = m_inputState;
3255 m_outputState.working.value = (m_inputState.working.value + m_literal) & 0xff;
3256 m_outputState.working.known = (m_inputState.working.known == 0xff) ? 0xff : 0x0;
3257 m_outputState.status.known &= ~( (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z) );
3258 }
3259
behaviour() const3260 ProcessorBehaviour Instr_addlw::behaviour() const
3261 {
3262 ProcessorBehaviour behaviour;
3263
3264 behaviour.working.depends = 0xff;
3265
3266 behaviour.status.indep = (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z);
3267
3268 return behaviour;
3269 }
3270
3271
code() const3272 QString Instr_andlw::code() const
3273 {
3274 return QString("andlw\t%1").arg( m_literal );
3275 }
3276
generateLinksAndStates(Code::iterator current)3277 void Instr_andlw::generateLinksAndStates( Code::iterator current )
3278 {
3279 makeOutputLinks( current );
3280
3281 m_outputState = m_inputState;
3282 m_outputState.working.value = (m_inputState.working.value & m_literal) & 0xff;
3283 m_outputState.working.known |= ~m_literal; // Now know any bits that are zero in value
3284 m_outputState.status.known &= ~(1 << RegisterBit::Z);
3285 }
3286
behaviour() const3287 ProcessorBehaviour Instr_andlw::behaviour() const
3288 {
3289 ProcessorBehaviour behaviour;
3290
3291 behaviour.working.indep = ~m_literal;
3292 behaviour.working.depends = m_literal;
3293
3294 behaviour.status.indep = (1 << RegisterBit::Z);
3295 return behaviour;
3296 }
3297
3298
code() const3299 QString Instr_call::code() const
3300 {
3301 return QString("call\t%1").arg( m_label );
3302 }
3303
generateLinksAndStates(Code::iterator current)3304 void Instr_call::generateLinksAndStates( Code::iterator current )
3305 {
3306 (void)current;
3307 makeLabelOutputLink( m_label );
3308
3309 m_outputState = m_inputState;
3310 }
3311
behaviour() const3312 ProcessorBehaviour Instr_call::behaviour() const
3313 {
3314 ProcessorBehaviour behaviour;
3315 return behaviour;
3316 }
3317
makeReturnLinks(Instruction * next)3318 void Instr_call::makeReturnLinks( Instruction * next )
3319 {
3320 m_pCode->setAllUnused();
3321 linkReturns( m_pCode->instruction( m_label ), next );
3322 }
3323
3324
linkReturns(Instruction * current,Instruction * returnPoint)3325 void Instr_call::linkReturns( Instruction * current, Instruction * returnPoint )
3326 {
3327 while (true)
3328 {
3329 if ( !current || current->isUsed() )
3330 return;
3331
3332 current->setUsed( true );
3333 if ( dynamic_cast<Instr_return*>(current) || dynamic_cast<Instr_retlw*>(current) )
3334 {
3335 // cout << "Added return link" << endl;
3336 // cout << " FROM: " << current->code() << endl;
3337 // cout << " TO: " << returnPoint->code() << endl;
3338 returnPoint->addInputLink( current );
3339 return;
3340 }
3341 if ( dynamic_cast<Instr_call*>(current) )
3342 {
3343 // Jump over the call instruction to its return point,
3344 // which will be the instruction after current.
3345 current = *(++m_pCode->find( current ));
3346 continue;
3347 }
3348
3349 const InstructionList outputs = current->outputLinks();
3350
3351 if ( outputs.isEmpty() )
3352 return;
3353
3354 if ( outputs.size() == 1 )
3355 current = outputs.first();
3356
3357 else
3358 {
3359 // Can't avoid function recursion now.
3360 InstructionList::const_iterator end = outputs.end();
3361 for ( InstructionList::const_iterator it = outputs.begin(); it != end; ++it )
3362 linkReturns( *it, returnPoint );
3363 return;
3364 }
3365 };
3366 }
3367
3368
3369 //TODO CLRWDT
3370
3371
code() const3372 QString Instr_goto::code() const
3373 {
3374 return QString("goto\t%1").arg( m_label );
3375 }
3376
generateLinksAndStates(Code::iterator current)3377 void Instr_goto::generateLinksAndStates( Code::iterator current )
3378 {
3379 (void)current;
3380
3381 makeLabelOutputLink( m_label );
3382
3383 m_outputState = m_inputState;
3384 }
3385
behaviour() const3386 ProcessorBehaviour Instr_goto::behaviour() const
3387 {
3388 ProcessorBehaviour behaviour;
3389 return behaviour;
3390 }
3391
3392
code() const3393 QString Instr_iorlw::code() const
3394 {
3395 return QString("iorlw\t%1").arg( m_literal );
3396 }
3397
generateLinksAndStates(Code::iterator current)3398 void Instr_iorlw::generateLinksAndStates( Code::iterator current )
3399 {
3400 makeOutputLinks( current );
3401
3402 m_outputState = m_inputState;
3403 m_outputState.working.value = (m_inputState.working.value | m_literal) & 0xff;
3404 m_outputState.working.known |= m_literal; // Now know any bits that are one in value
3405 m_outputState.status.known &= ~(1 << RegisterBit::Z);
3406 }
3407
behaviour() const3408 ProcessorBehaviour Instr_iorlw::behaviour() const
3409 {
3410 ProcessorBehaviour behaviour;
3411
3412 behaviour.working.indep = m_literal;
3413 behaviour.working.depends = ~m_literal;
3414
3415 behaviour.status.indep = (1 << RegisterBit::Z);;
3416 return behaviour;
3417 }
3418
3419
code() const3420 QString Instr_movlw::code() const
3421 {
3422 return QString("movlw\t%1").arg( m_literal );
3423 }
3424
generateLinksAndStates(Code::iterator current)3425 void Instr_movlw::generateLinksAndStates( Code::iterator current )
3426 {
3427 makeOutputLinks( current );
3428 m_outputState = m_inputState;
3429 m_outputState.working.known = 0xff;
3430 m_outputState.working.value = m_literal;
3431 }
3432
behaviour() const3433 ProcessorBehaviour Instr_movlw::behaviour() const
3434 {
3435 ProcessorBehaviour behaviour;
3436 behaviour.working.indep = 0xff;
3437 return behaviour;
3438 }
3439
3440
code() const3441 QString Instr_retfie::code() const
3442 {
3443 return "retfie";
3444 }
3445
generateLinksAndStates(Code::iterator current)3446 void Instr_retfie::generateLinksAndStates( Code::iterator current )
3447 {
3448 // Don't generate any output links
3449 (void)current;
3450
3451 m_inputState = m_outputState;
3452 }
3453
behaviour() const3454 ProcessorBehaviour Instr_retfie::behaviour() const
3455 {
3456 ProcessorBehaviour behaviour;
3457 return behaviour;
3458 }
3459
3460
code() const3461 QString Instr_retlw::code() const
3462 {
3463 return QString("retlw\t%1").arg( m_literal );
3464 }
3465
generateLinksAndStates(Code::iterator current)3466 void Instr_retlw::generateLinksAndStates( Code::iterator current )
3467 {
3468 (void)current;
3469
3470 m_outputState = m_inputState;
3471 m_outputState.working.known = 0xff;
3472 m_outputState.working.value = m_literal;
3473 }
3474
behaviour() const3475 ProcessorBehaviour Instr_retlw::behaviour() const
3476 {
3477 ProcessorBehaviour behaviour;
3478 behaviour.working.indep = 0xff;
3479 return behaviour;
3480 }
3481
3482
3483
code() const3484 QString Instr_return::code() const
3485 {
3486 return "return";
3487 }
3488
generateLinksAndStates(Code::iterator current)3489 void Instr_return::generateLinksAndStates( Code::iterator current )
3490 {
3491 (void)current;
3492
3493 m_outputState = m_inputState;
3494 }
3495
behaviour() const3496 ProcessorBehaviour Instr_return::behaviour() const
3497 {
3498 ProcessorBehaviour behaviour;
3499 return behaviour;
3500 }
3501
3502
code() const3503 QString Instr_sleep::code() const
3504 {
3505 return "sleep";
3506 }
3507
generateLinksAndStates(Code::iterator current)3508 void Instr_sleep::generateLinksAndStates( Code::iterator current )
3509 {
3510 // Don't generate any output links
3511 (void)current;
3512
3513 m_outputState = m_inputState;
3514 m_outputState.status.value &= ~(1 << RegisterBit::NOT_PD);
3515 m_outputState.status.value |= (1 << RegisterBit::NOT_TO);
3516 m_outputState.status.known |= (1 << RegisterBit::NOT_TO) | (1 << RegisterBit::NOT_PD);
3517 }
3518
behaviour() const3519 ProcessorBehaviour Instr_sleep::behaviour() const
3520 {
3521 ProcessorBehaviour behaviour;
3522 behaviour.status.indep = (1 << RegisterBit::NOT_TO) | (1 << RegisterBit::NOT_PD);
3523 return behaviour;
3524 }
3525
3526
code() const3527 QString Instr_sublw::code() const
3528 {
3529 return QString("sublw\t%1").arg( m_literal );
3530 }
3531
generateLinksAndStates(Code::iterator current)3532 void Instr_sublw::generateLinksAndStates( Code::iterator current )
3533 {
3534 makeOutputLinks( current );
3535
3536 m_outputState = m_inputState;
3537 m_outputState.working.value = (m_literal - m_inputState.working.value) & 0xff;
3538 m_outputState.working.known = (m_inputState.working.known == 0xff) ? 0xff : 0x00;
3539 m_outputState.status.known &= ~( (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z) );
3540
3541 if ( m_inputState.working.minValue() > m_literal )
3542 {
3543 m_outputState.status.value &= ~(1 << RegisterBit::C);
3544 m_outputState.status.known |= (1 << RegisterBit::C);
3545 }
3546 else if ( m_inputState.working.maxValue() <= m_literal )
3547 {
3548 m_outputState.status.value |= (1 << RegisterBit::C);
3549 m_outputState.status.known |= (1 << RegisterBit::C);
3550 }
3551
3552 if ( m_inputState.working.known == 0xff )
3553 {
3554 bool isZero = (m_inputState.working.value == m_literal);
3555 if ( isZero )
3556 m_outputState.status.value |= (1 << RegisterBit::Z);
3557 else
3558 m_outputState.status.value &= ~(1 << RegisterBit::Z);
3559 m_outputState.status.known |= (1 << RegisterBit::Z);
3560 }
3561 }
3562
behaviour() const3563 ProcessorBehaviour Instr_sublw::behaviour() const
3564 {
3565 ProcessorBehaviour behaviour;
3566 behaviour.working.depends = 0xff;
3567 behaviour.status.indep = (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z);
3568 return behaviour;
3569 }
3570
3571
code() const3572 QString Instr_xorlw::code() const
3573 {
3574 return QString("xorlw\t%1").arg( m_literal );
3575 }
3576
generateLinksAndStates(Code::iterator current)3577 void Instr_xorlw::generateLinksAndStates( Code::iterator current )
3578 {
3579 makeOutputLinks( current );
3580 m_outputState = m_inputState;
3581 m_outputState.working.value = (m_inputState.working.value ^ m_literal) & 0xff;
3582 m_outputState.working.known = m_inputState.working.known;
3583 m_outputState.status.known &= ~(1 << RegisterBit::Z);
3584 }
3585
behaviour() const3586 ProcessorBehaviour Instr_xorlw::behaviour() const
3587 {
3588 ProcessorBehaviour behaviour;
3589 behaviour.working.depends = 0xff;
3590 behaviour.status.indep = (1 << RegisterBit::Z);
3591 return behaviour;
3592 }
3593 //END Literal and Control Operations
3594
3595
3596
3597 //BEGIN Microbe (non-assembly) Operations
code() const3598 QString Instr_sourceCode::code() const
3599 {
3600 QStringList sourceLines = m_raw.split("\n", QString::SkipEmptyParts); // QString::split("\n",m_raw);
3601 return ";" + sourceLines.join("\n;");
3602 }
3603
3604
code() const3605 QString Instr_asm::code() const
3606 {
3607 return "; asm {\n" + m_raw + "\n; }";
3608 }
3609
3610
code() const3611 QString Instr_raw::code() const
3612 {
3613 return m_raw;
3614 }
3615 //END Microbe (non-assembly) Operations
3616
3617