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