File indexing completed on 2025-02-16 08:26:49
0001 /*************************************************************************** 0002 * Copyright (C) 2004-2005 by Daniel Clarke <daniel.jc@gmail.com> * 0003 * 2005 by David Saxton <david@bluehaze.org> * 0004 * * 0005 * 24-04-2007 * 0006 * Modified to add pic 16f877,16f627 and 16f628 * 0007 * by george john george@space-kerala.org * 0008 * supported by SPACE www.space-kerala.org * 0009 * * 0010 * This program is free software; you can redistribute it and/or modify * 0011 * it under the terms of the GNU General Public License as published by * 0012 * the Free Software Foundation; either version 2 of the License, or * 0013 * (at your option) any later version. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program; if not, write to the * 0022 * Free Software Foundation, Inc., * 0023 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0024 ***************************************************************************/ 0025 0026 #include "instruction.h" 0027 #include "optimizer.h" 0028 #include "pic14.h" 0029 #include <QDebug> 0030 #include <QStringList> 0031 #include <cassert> 0032 #include <iostream> 0033 using namespace std; 0034 //modified new varable pic_type is added 0035 extern QString pic_type; 0036 //BEGIN class Register 0037 Register::Register( Type type ) 0038 { 0039 m_type = type; 0040 //***********modified almost all the register names are included**************// 0041 switch ( m_type ) 0042 { 0043 //----------------------------------------------Bank0---------------------------// 0044 case TMR0: 0045 m_name = "TMR0"; 0046 break; 0047 case PCL: 0048 m_name = "PCL"; 0049 break; 0050 case STATUS: 0051 m_name = "STATUS"; 0052 break; 0053 case FSR: 0054 m_name = "FSR"; 0055 break; 0056 case PORTA: 0057 m_name = "PORTA"; 0058 break; 0059 case PORTB: 0060 m_name = "PORTB"; 0061 break; 0062 case PORTC: 0063 m_name = "PORTC"; 0064 break; 0065 case PORTD: 0066 m_name = "PORTD"; 0067 break; 0068 case PORTE: 0069 m_name = "PORTE"; 0070 break; 0071 case PCLATH: 0072 m_name = "PCLATH"; 0073 break; 0074 case INTCON: 0075 m_name = "INTCON"; 0076 break; 0077 case PIR1: 0078 m_name = "PIR1"; 0079 break; 0080 case PIR2: 0081 m_name = "PIR2"; 0082 break; 0083 case TMR1L: 0084 m_name = "TMR1L"; 0085 break; 0086 case TMR1H: 0087 m_name = "TMR1H"; 0088 break; 0089 case T1CON: 0090 m_name = "T1CON"; 0091 break; 0092 case TMR2: 0093 m_name = "TMR2"; 0094 break; 0095 case T2CON: 0096 m_name = "T2CON"; 0097 break; 0098 case SSPBUF: 0099 m_name = "SSPBUF"; 0100 break; 0101 case SSPCON: 0102 m_name = "SSPCON"; 0103 break; 0104 case CCPR1L: 0105 m_name = "CCPR1L"; 0106 break; 0107 case CCPR1H: 0108 m_name = "CCPR1H"; 0109 break; 0110 case CCP1CON: 0111 m_name = "CCP1CON"; 0112 break; 0113 case RCSTA: 0114 m_name = "RCSTA"; 0115 break; 0116 case TXREG: 0117 m_name = "TXREG"; 0118 break; 0119 case RCREG: 0120 m_name = "RCREG"; 0121 break; 0122 case CCPR2L: 0123 m_name = "CCPR2L"; 0124 break; 0125 case CCPR2H: 0126 m_name = "CCPR2H"; 0127 break; 0128 case CCP2CON: 0129 m_name = "CCP2CON"; 0130 break; 0131 case ADRESH: 0132 m_name = "ADRESH"; 0133 break; 0134 case ADCON0: 0135 m_name = "ADCON0"; 0136 break; 0137 case CMCON: 0138 m_name = "CMCON"; 0139 break; 0140 //----------------------------------------------Bank1---------------------------// 0141 0142 case OPTION_REG: 0143 m_name = "OPTION_REG"; 0144 break; 0145 case TRISA: 0146 m_name = "TRISA"; 0147 break; 0148 case TRISB: 0149 m_name = "TRISB"; 0150 break; 0151 case TRISC: 0152 m_name = "TRISC"; 0153 break; 0154 case TRISD: 0155 m_name = "TRISD"; 0156 break; 0157 case TRISE: 0158 m_name = "TRISE"; 0159 break; 0160 case PIE1: 0161 m_name = "PIE1"; 0162 break; 0163 case PIE2: 0164 m_name = "PIE2"; 0165 break; 0166 case PCON: 0167 m_name = "PCON"; 0168 break; 0169 case SSPCON2: 0170 m_name = "SSPCON2"; 0171 break; 0172 case PR2: 0173 m_name = "PR2"; 0174 break; 0175 case SSPADD: 0176 m_name = "SSPADD"; 0177 break; 0178 case SSPSTAT: 0179 m_name = "SSPSTAT"; 0180 break; 0181 case TXSTA: 0182 m_name = "TXSTA"; 0183 break; 0184 case SPBRG: 0185 m_name = "SPBRG"; 0186 break; 0187 case ADRESL: 0188 m_name = "ADRESL"; 0189 break; 0190 case ADCON1: 0191 m_name = "ADCON1"; 0192 break; 0193 case VRCON: 0194 m_name = "VRCON"; 0195 break; 0196 //----------------------------------------------Bank2---------------------------// 0197 case EEDATA: 0198 m_name = "EEDATA"; 0199 break; 0200 case EEADR: 0201 m_name = "EEADR"; 0202 break; 0203 case EEDATH: 0204 m_name = "EEDATH"; 0205 break; 0206 case EEADRH: 0207 m_name = "EEADRH"; 0208 break; 0209 //----------------------------------------------Bank3---------------------------// 0210 case EECON1: 0211 m_name = "EECON1"; 0212 break; 0213 0214 case EECON2: 0215 m_name = "EECON2"; 0216 break; 0217 //---------------------------------------------NoBank---------------------------// 0218 case WORKING: 0219 m_name = "<working>"; 0220 break; 0221 case GPR: 0222 case none: 0223 break; 0224 } 0225 } 0226 0227 0228 Register::Register( const QString & name )//--to find a name varable or register(ex trise) 0229 { 0230 m_name = name.trimmed(); 0231 QString upper = m_name.toUpper(); 0232 //--------------------------------------------Bank0-------------------// 0233 if ( upper == "TMR0" ) 0234 m_type = TMR0; 0235 else if ( upper == "PCL" ) 0236 m_type = PCL; 0237 else if ( upper == "STATUS") 0238 m_type = STATUS; 0239 else if ( upper == "FSR") 0240 m_type = FSR; 0241 else if ( upper == "PORTA") 0242 m_type = PORTA; 0243 else if ( upper == "PORTB") 0244 m_type = PORTB; 0245 else if ( upper == "PORTC") 0246 m_type = PORTC; 0247 else if ( upper == "PORTD") 0248 m_type = PORTD; 0249 else if ( upper == "PORTE") 0250 m_type = PORTE; 0251 else if ( upper == "PCLATH") 0252 m_type = PCLATH; 0253 else if ( upper == "INTCON") 0254 m_type = INTCON; 0255 else if ( upper == "PIR1") 0256 m_type = PIR1; 0257 else if ( upper == "PIR2") 0258 m_type = PIR2; 0259 else if ( upper == "TMR1L") 0260 m_type = TMR1L; 0261 else if ( upper == "TMR1H") 0262 m_type = TMR1H; 0263 else if ( upper == "T1CON") 0264 m_type = T1CON; 0265 else if ( upper == "TMR2") 0266 m_type = TMR2; 0267 else if ( upper == "T2CON") 0268 m_type = T2CON; 0269 else if ( upper == "SSPBUF") 0270 m_type = SSPBUF; 0271 else if ( upper == "SSPCON") 0272 m_type = SSPCON; 0273 else if ( upper == "CCPR1L") 0274 m_type = CCPR1L; 0275 else if ( upper == "CCPR1H") 0276 m_type = CCPR1H; 0277 else if ( upper == "CCP1CON") 0278 m_type = CCP1CON; 0279 else if ( upper == "RCSTA") 0280 m_type = RCSTA; 0281 else if ( upper == "TXREG") 0282 m_type = TXREG; 0283 else if ( upper == "RCREG") 0284 m_type = RCREG; 0285 else if ( upper == "CCPR2L") 0286 m_type = CCPR2L; 0287 else if ( upper == "CCPR2H") 0288 m_type = CCPR2H; 0289 else if ( upper == "CCP2CON") 0290 m_type = CCP2CON; 0291 else if ( upper == "ADRESH") 0292 m_type = ADRESH; 0293 else if ( upper == "ADCON0") 0294 m_type = ADCON0; 0295 else if ( upper == "CMCON") 0296 m_type = CMCON; 0297 //--------------------------------------------Bank1-------------------// 0298 else if ( upper == "OPTION_REG" ) 0299 m_type = OPTION_REG; 0300 else if ( upper == "TRISA") 0301 m_type = TRISA; 0302 else if ( upper == "TRISB") 0303 m_type = TRISB; 0304 else if ( upper == "TRISC") 0305 m_type = TRISC; 0306 else if ( upper == "TRISD") 0307 m_type = TRISD; 0308 else if ( upper == "TRISE") 0309 m_type = TRISE; 0310 else if ( upper == "PIE1") 0311 m_type = PIE1; 0312 else if ( upper == "PIE2") 0313 m_type = PIE2; 0314 else if ( upper == "PCON") 0315 m_type = PCON; 0316 else if ( upper == "SSPCON2") 0317 m_type = SSPCON2; 0318 else if ( upper == "PR2") 0319 m_type = PR2; 0320 else if ( upper == "SSPADD") 0321 m_type = SSPADD; 0322 else if ( upper == "SSPSTAT") 0323 m_type = SSPSTAT; 0324 else if ( upper == "TXSTA") 0325 m_type = TXSTA; 0326 else if ( upper == "SPBRG") 0327 m_type = SPBRG; 0328 else if ( upper == "ADRESL") 0329 m_type = ADRESL; 0330 else if ( upper == "ADCON1") 0331 m_type = ADCON1; 0332 else if ( upper == "VRCON") 0333 m_type = VRCON; 0334 //--------------------------------------------Bank2-------------------// 0335 else if ( upper == "EEDATA") 0336 m_type = EEDATA; 0337 else if ( upper == "EEADR") 0338 m_type = EEADR; 0339 else if ( upper == "EEDATH") 0340 m_type = EEDATH; 0341 else if ( upper == "EEADRH") 0342 m_type = EEADRH; 0343 //--------------------------------------------Bank3-------------------// 0344 else if ( upper == "EECON1") 0345 m_type = EECON1; 0346 else if ( upper == "EECON2") 0347 m_type = EECON2; 0348 //---------------------------------------------NoBank----------------// 0349 else 0350 m_type = GPR; 0351 } 0352 0353 0354 Register::Register( const char * name ) 0355 { 0356 *this = Register( QString(name) ); 0357 } 0358 0359 0360 bool Register::operator < ( const Register & reg ) const 0361 { 0362 if ( (type() != GPR) || (reg.type() != GPR) ) 0363 return type() < reg.type(); 0364 0365 return name() < reg.name(); 0366 } 0367 0368 0369 bool Register::operator == ( const Register & reg ) const 0370 { 0371 if ( type() != reg.type() ) 0372 return false; 0373 0374 return name() == reg.name(); 0375 } 0376 0377 0378 uchar Register::banks() const 0379 { 0380 switch ( m_type ) 0381 { 0382 //---------------------bank 0 registers return zero---------------------------// 0383 0384 case TMR0: return Bank0& Bank1;//Bank0 0385 case PCL: return Bank0 & Bank1;//Bank0 | Bank1 0386 case STATUS: return Bank0 & Bank1;//Bank0 | Bank1 0387 case FSR: return Bank0 & Bank1;//Bank0 | Bank1 0388 case PORTA: return Bank0 & Bank1;//Bank0 0389 case PORTB: return Bank0 & Bank1;//Bank0 0390 case PORTC: return Bank0 & Bank1;//Bank0 0391 case PORTD: return Bank0 & Bank1;//Bank0 0392 case PORTE: return Bank0 & Bank1;//Bank0 0393 case PCLATH: return Bank0 & Bank1;//Bank0 | Bank1 0394 case INTCON: return Bank0 & Bank1;//Bank0 | Bank1 0395 case PIR1: return Bank0 & Bank1; 0396 case PIR2: return Bank0 & Bank1; 0397 case TMR1L: return Bank0 & Bank1; 0398 case TMR1H: return Bank0 & Bank1; 0399 case T1CON: return Bank0 & Bank1; 0400 case TMR2: return Bank0 & Bank1; 0401 case T2CON: return Bank0 & Bank1; 0402 case SSPBUF: return Bank0 & Bank1; 0403 case SSPCON: return Bank0 & Bank1; 0404 case CCPR1L: return Bank0 & Bank1; 0405 case CCPR1H: return Bank0 & Bank1; 0406 case CCP1CON: return Bank0 & Bank1; 0407 case RCSTA: return Bank0 & Bank1; 0408 case TXREG: return Bank0 & Bank1; 0409 case RCREG: return Bank0 & Bank1; 0410 case CCPR2L: return Bank0 & Bank1; 0411 case CCPR2H: return Bank0 & Bank1; 0412 case CCP2CON: return Bank0 & Bank1; 0413 case ADRESH: return Bank0 & Bank1;//Bank0 0414 case ADCON0: return Bank0 & Bank1;//Bank0 0415 case CMCON: return Bank0 & Bank1;//Bank0 0416 //-----------------------------NO Bank-------------------------------------// 0417 case GPR: return Bank0 & Bank1;//Bank0 | Bank1 0418 case WORKING: return Bank0 & Bank1;//Bank0 | Bank1 0419 case none: return Bank0 & Bank1;//Bank0 | Bank1 0420 0421 //-------------------bank 1 registers return one---------------------------// 0422 0423 case OPTION_REG: return Bank0;//Bank1 0424 ///------tris registers-------// 0425 case TRISA: return Bank0;//Bank1 0426 case TRISB: return Bank0;//Bank1 0427 case TRISC: return Bank0;//Bank1 0428 case TRISD: return Bank0;//Bank1 0429 case TRISE: return Bank0;//Bank1 0430 //--------------------------------------------------------------------------// 0431 case PIE1: return Bank0; 0432 case PIE2: return Bank0; 0433 case PCON: return Bank0; 0434 case SSPCON2: return Bank0; 0435 case PR2: return Bank0; 0436 case SSPADD: return Bank0; 0437 case SSPSTAT: return Bank0; 0438 case TXSTA: return Bank0; 0439 case SPBRG: return Bank0; 0440 //--------adc register-------// 0441 case ADRESL: return Bank0;//Bank1 0442 case ADCON1: return Bank0;//Bank1 0443 case VRCON: return Bank0;//Bank1 0444 0445 //------------------bank 2 registers return two----------completed------------// 0446 0447 case EEDATA: return Bank1;//Bank1 0448 case EEADR: return Bank1;//Bank0 0449 case EEDATH: return Bank1;//Bank0 0450 case EEADRH: return Bank1;//Bank0 0451 0452 //------------------bank 3 registers return three--------completed----------------// 0453 0454 case EECON1: return Bank0|Bank1;//Bank1 0455 case EECON2: return Bank0|Bank1;//Bank1 0456 0457 } 0458 0459 return Bank0 & Bank1; // Vacously true (and useful too) - a non-existent bank can be accessed anywhere 0460 } 0461 0462 0463 bool Register::bankDependent() const 0464 { 0465 return ( banks() != (Bank0 | Bank1) ); 0466 } 0467 0468 0469 bool Register::affectsExternal() const 0470 { 0471 switch ( m_type ) 0472 { 0473 case PORTA: 0474 case TRISA: 0475 case PORTB: 0476 case TRISB: 0477 case PORTC: 0478 case TRISC: 0479 case PORTD: 0480 case TRISD: 0481 case PORTE: 0482 case TRISE: 0483 case INTCON: 0484 case ADCON0: 0485 case ADCON1: 0486 //************************modification*************************** 0487 case TMR0: 0488 case OPTION_REG: 0489 case PCL: 0490 case STATUS: 0491 case FSR: 0492 case EEDATA: 0493 case EECON1: 0494 case EEADR: 0495 case EECON2: 0496 case PCLATH: 0497 case GPR: 0498 //--------------------------------FINAL LAST-------------// 0499 case PIR1: 0500 case PIR2: 0501 case TMR1L: 0502 case TMR2: 0503 case TMR1H: 0504 case T1CON: 0505 case T2CON: 0506 case SSPBUF: 0507 case SSPCON: 0508 case CCPR1L: 0509 case CCPR1H: 0510 case CCP1CON: 0511 case CCPR2L: 0512 case CCPR2H: 0513 case CCP2CON: 0514 case ADRESH: 0515 case PIE1: 0516 case PIE2: 0517 case PCON: 0518 case SSPCON2: 0519 case PR2: 0520 case SSPADD: 0521 case SSPSTAT: 0522 case TXSTA: 0523 case SPBRG: 0524 case ADRESL: 0525 case EEDATH: 0526 case EEADRH: 0527 case RCSTA: 0528 case TXREG: 0529 case RCREG: 0530 case CMCON: 0531 case VRCON: 0532 return true; 0533 case WORKING: 0534 case none: 0535 return false; 0536 } 0537 return false; 0538 } 0539 0540 0541 0542 //BEGIN class RegisterBit 0543 RegisterBit::RegisterBit( uchar bitPos, Register::Type reg ) 0544 { 0545 m_bitPos = bitPos; 0546 m_registerType = reg; 0547 0548 switch ( m_registerType ) 0549 { 0550 case Register::TMR0: 0551 case Register::PCL: 0552 break; 0553 case Register::STATUS: 0554 { 0555 switch ( m_bitPos ) 0556 { 0557 case 0: m_name = "C"; break; 0558 case 1: m_name = "DC"; break; 0559 case 2: m_name = "Z"; break; 0560 case 3: m_name = "NOT_PD"; break; 0561 case 4: m_name = "NOT_TO"; break; 0562 case 5: m_name = "RP0"; break; 0563 case 6: m_name = "RP1"; break; 0564 case 7: m_name = "IRP"; break; 0565 } 0566 break; 0567 } 0568 case Register::FSR: 0569 case Register::PORTA: 0570 case Register::PORTB: 0571 case Register::PORTC: 0572 case Register::PORTD: 0573 case Register::PORTE: 0574 case Register::PCLATH: 0575 break; 0576 case Register::INTCON: 0577 { 0578 switch ( m_bitPos ) 0579 { 0580 case 0: m_name = "RBIF"; break; 0581 case 1: m_name = "INTF"; break; 0582 case 2: m_name = "T0IF"; break; 0583 case 3: m_name = "RBIE"; break; 0584 case 4: m_name = "INTE"; break; 0585 case 5: m_name = "T0IE"; break; 0586 case 6: 0587 { 0588 if(pic_type=="P16F84"||pic_type=="P16C84") { 0589 m_name = "EEIE"; break; 0590 } 0591 if(pic_type=="P16F877"||pic_type=="P16F627" ||pic_type =="P16F628") { 0592 m_name = "PEIE"; break; 0593 } 0594 break; 0595 0596 0597 } 0598 case 7: m_name = "GIE"; break; 0599 } 0600 break; 0601 } 0602 case Register::PIR1: 0603 { 0604 switch ( m_bitPos ) 0605 { 0606 case 0: m_name = "TMR1F"; break; 0607 case 1: m_name = "TMR2F"; break; 0608 case 2: m_name = "CCP1IF"; break; 0609 case 3: m_name = "SSPIF"; break; 0610 case 4: m_name = "TXIF"; break; 0611 case 5: m_name = "RCIF"; break; 0612 case 6: 0613 if(pic_type=="P16F877") { 0614 m_name = "ADIF"; break; 0615 } 0616 if(pic_type=="P16F627"||pic_type=="P16F628") { 0617 m_name = "CMIF";break; 0618 } 0619 break; 0620 case 7: 0621 if(pic_type=="P16F877") { 0622 m_name = "PSPIF"; break; 0623 } 0624 if(pic_type=="P16F627"||pic_type=="P16F628") { 0625 m_name = "EEIF";break; 0626 } 0627 break; 0628 } 0629 break; 0630 } 0631 case Register::PIR2: 0632 { 0633 switch ( m_bitPos ) 0634 { 0635 case 0: m_name = "CCP2IF"; break; 0636 case 3: m_name = "BCLIF"; break; 0637 case 4: m_name = "EEIF"; break; 0638 0639 } 0640 break; 0641 } 0642 case Register::TMR1L: 0643 case Register::TMR1H: 0644 break; 0645 case Register::T1CON: 0646 { 0647 switch ( m_bitPos ) 0648 { 0649 case 0: m_name = "TMR1ON"; break; 0650 case 1: m_name = "TMRCS"; break; 0651 case 2: 0652 if(pic_type=="P16F877") { 0653 m_name = "T1SYNC"; break; 0654 } 0655 if(pic_type=="P16F627"||pic_type=="P16F628") { 0656 m_name = "NOT_T1SYNC"; break; 0657 } 0658 break; 0659 case 3: m_name = "T1OSCEN"; break; 0660 case 4: m_name = "T1CKPS0"; break; 0661 case 5: m_name = "T1CKPS1"; break; 0662 } 0663 break; 0664 } 0665 case Register::TMR2: 0666 break; 0667 case Register::T2CON: 0668 { 0669 switch ( m_bitPos ) 0670 { 0671 case 0: m_name = "T2CKPS0"; break; 0672 case 1: m_name = "T2CKPS1"; break; 0673 case 2: m_name = "TMR2ON"; break; 0674 case 3: m_name = "TOUTPS0"; break; 0675 case 4: m_name = "TOUTPS1"; break; 0676 case 5: m_name = "TOUTPS2"; break; 0677 case 6: m_name = "TOUTPS3"; break; 0678 } 0679 break; 0680 } 0681 case Register::SSPBUF: 0682 break; 0683 case Register::SSPCON: 0684 switch ( m_bitPos ) 0685 { 0686 case 0: m_name = "SSPM0"; break; 0687 case 1: m_name = "SSPM1"; break; 0688 case 2: m_name = "SSPM2"; break; 0689 case 3: m_name = "SSPM3"; break; 0690 case 4: m_name = "CKP"; break; 0691 case 5: m_name = "SSPEN"; break; 0692 case 6: m_name = "SSPOV"; break;//!!!!!!START&STOPEEIE!!! 0693 case 7: m_name = "WCOL"; break; 0694 } 0695 break; 0696 case Register::CCPR1L: 0697 case Register::CCPR1H: 0698 break; 0699 case Register::CCP1CON: 0700 switch ( m_bitPos ) 0701 { 0702 case 0: m_name = "CCP1M0"; break; 0703 case 1: m_name = "CCP1M1"; break; 0704 case 2: m_name = "CCP1M2"; break; 0705 case 3: m_name = "CCP1M3"; break; 0706 case 4: m_name = "CCP1Y"; break; 0707 case 5: m_name = "CCP1X"; break; 0708 } 0709 break; 0710 case Register::RCSTA: 0711 switch ( m_bitPos ) 0712 { 0713 case 0: m_name = "RX9D"; break; 0714 case 1: m_name = "OERR"; break; 0715 case 2: m_name = "FERR"; break; 0716 case 3: 0717 if(pic_type=="P16F877") { 0718 m_name = "ADDEN"; break; 0719 } 0720 if(pic_type=="P16F627"||pic_type=="P16F628") { 0721 m_name = "ADEN"; break; 0722 } 0723 break; 0724 case 4: m_name = "CREN"; break; 0725 case 5: m_name = "SREN"; break; 0726 case 6: m_name = "RX9"; break; 0727 case 7: m_name = "SPEN"; break; 0728 } 0729 break; 0730 case Register::TXREG: 0731 case Register::RCREG: 0732 case Register::CCPR2L: 0733 case Register::CCPR2H: 0734 break; 0735 case Register::CCP2CON: 0736 switch ( m_bitPos ) 0737 { 0738 case 0: m_name = "CCP2M0"; break; 0739 case 1: m_name = "CCP2M1"; break; 0740 case 2: m_name = "CCP2M2"; break; 0741 case 3: m_name = "CCP2M3"; break; 0742 case 4: m_name = "CCP2Y"; break; 0743 case 5: m_name = "CCP2X"; break; 0744 } 0745 break; 0746 0747 case Register::ADRESH: 0748 break; 0749 case Register::ADCON0: 0750 { 0751 switch ( m_bitPos ) 0752 { 0753 case 0: m_name = "ADON"; break; 0754 case 2: m_name = "GO"; break; 0755 case 3: m_name = "CHS0"; break; 0756 case 4: m_name = "CHS1"; break; 0757 case 5: m_name = "CHS2"; break; 0758 case 6: m_name = "ADCS0"; break; 0759 case 7: m_name = "ADCS1"; break; 0760 } 0761 break; 0762 } 0763 case Register::CMCON: 0764 { 0765 switch ( m_bitPos ) 0766 { 0767 case 0: m_name = "CM0"; break; 0768 case 1: m_name = "CM1"; break; 0769 case 2: m_name = "CM2"; break; 0770 case 3: m_name = "CIS"; break; 0771 case 4: m_name = "C1INV"; break; 0772 case 5: m_name = "C2INV"; break; 0773 case 6: m_name = "C1OUT"; break; 0774 case 7: m_name = "C2OUT"; break; 0775 } 0776 break; 0777 } 0778 //-----------------------------------------------------Bank1----------------// 0779 case Register::OPTION_REG: 0780 { 0781 switch ( m_bitPos ) 0782 { 0783 case 0: m_name = "PS0"; break; 0784 case 1: m_name = "PS1"; break; 0785 case 2: m_name = "PS2"; break; 0786 case 3: m_name = "PSA"; break; 0787 case 4: m_name = "T0SE"; break; 0788 case 5: m_name = "T0CS"; break; 0789 case 6: m_name = "INTEDG"; break; 0790 case 7: 0791 { 0792 if(pic_type=="P16F84") 0793 m_name = "RBPU"; 0794 if(pic_type=="P16F877"||pic_type=="P16C84"||pic_type=="P16F627"||pic_type=="P16F628") 0795 m_name = "NOT_RBPU"; 0796 break; 0797 0798 0799 } 0800 } 0801 break; 0802 } 0803 case Register::TRISA: 0804 case Register::TRISB: 0805 case Register::TRISC: 0806 case Register::TRISD: 0807 case Register::TRISE: 0808 break; 0809 case Register::PIE1: 0810 switch ( m_bitPos ) 0811 { 0812 case 0: m_name = "TMR1IE"; break; 0813 case 1: m_name = "TMR2IE"; break; 0814 case 2: m_name = "CCP1IE"; break; 0815 case 3: m_name = "SSPIE"; break; 0816 case 4: m_name = "TXIE"; break; 0817 case 5: m_name = "RCIE"; break; 0818 case 6: 0819 { 0820 if (pic_type=="P16F877") { 0821 m_name = "ADIE"; break; 0822 } 0823 if (pic_type=="P16F627"||pic_type=="P16F628") { 0824 m_name = "CMIE"; break; 0825 } 0826 break; 0827 } 0828 case 7: 0829 { 0830 if (pic_type=="P16F877") { 0831 m_name = "PSPIE"; break; 0832 } 0833 if (pic_type=="P16F627"||pic_type=="P16F628") { 0834 m_name = "EEIE"; break; 0835 } 0836 break; 0837 } 0838 } 0839 break; 0840 case Register::PIE2: 0841 switch ( m_bitPos ) 0842 { 0843 case 0: m_name = "CCP2IE"; break; 0844 case 3: m_name = "BCLIE"; break; 0845 case 4: m_name = "EEIE"; break; 0846 } 0847 break; 0848 case Register::PCON: 0849 switch ( m_bitPos ) 0850 { 0851 case 0: m_name = "NOT_BOR"; break; 0852 case 1: m_name = "NOT_POR"; break; 0853 case 3: m_name = "OSCF"; break; 0854 0855 } 0856 break; 0857 case Register::SSPCON2: 0858 switch ( m_bitPos ) 0859 { 0860 case 0: m_name = "SEN"; break; 0861 case 1: m_name = "RSEN"; break; 0862 case 2: m_name = "PEN"; break; 0863 case 3: m_name = "RCEN"; break; 0864 case 4: m_name = "ACKEN"; break; 0865 case 5: m_name = "ACKDT"; break; 0866 case 6: m_name = "ACKSTAT"; break; 0867 case 7: m_name = "GCEN"; break; 0868 } 0869 break; 0870 case Register::PR2: 0871 case Register::SSPADD: 0872 break; 0873 case Register::SSPSTAT: 0874 switch ( m_bitPos ) 0875 { 0876 case 0: m_name = "BF"; break; 0877 case 1: m_name = "UA"; break; 0878 case 2: m_name = "R"; break; 0879 case 3: m_name = "S"; break; 0880 case 4: m_name = "P"; break; 0881 case 5: m_name = "D"; break; 0882 case 6: m_name = "CKE"; break; 0883 case 7: m_name = "SMP"; break; 0884 } 0885 break; 0886 case Register::TXSTA: 0887 switch ( m_bitPos ) 0888 { 0889 case 0: m_name = "TX9D"; break; 0890 case 1: m_name = "TRMT"; break; 0891 case 2: m_name = "BRGH"; break; 0892 case 4: m_name = "SYNC"; break; 0893 case 5: m_name = "TXEN"; break; 0894 case 6: m_name = "TX9"; break; 0895 case 7: m_name = "CSRC"; break; 0896 } 0897 break; 0898 case Register::SPBRG: 0899 case Register::ADRESL: 0900 break; 0901 case Register::ADCON1: 0902 { 0903 switch ( m_bitPos ) 0904 { 0905 case 0: m_name = "PCFG0"; break; 0906 case 1: m_name = "PCFG1"; break; 0907 case 2: m_name = "PCFG2"; break; 0908 case 3: m_name = "PCFG3"; break; 0909 case 7: m_name = "ADFM"; break; 0910 } 0911 break; 0912 } 0913 0914 //-----------------------------------------------------Bank2----------------// 0915 case Register::EEDATA: 0916 case Register::EEADR: 0917 case Register::EEDATH: 0918 case Register::EEADRH: 0919 break; 0920 //-----------------------------------------------------Bank3----------------// 0921 case Register::EECON1: 0922 { 0923 switch ( m_bitPos ) 0924 { 0925 case 0: m_name = "RD"; break; 0926 case 1: m_name = "WR"; break; 0927 case 2: m_name = "WREN"; break; 0928 case 3: m_name = "WRERR"; break; 0929 case 4: m_name = "EEIF"; break; 0930 case 7: m_name = "EEPGD"; break;//imp ***** 0931 } 0932 break; 0933 } 0934 0935 case Register::EECON2: 0936 break; 0937 case Register::VRCON: 0938 { 0939 switch ( m_bitPos ) 0940 { 0941 case 0: m_name = "VR0"; break; 0942 case 1: m_name = "VR1"; break; 0943 case 2: m_name = "VR2"; break; 0944 case 3: m_name = "VR3"; break; 0945 case 5: m_name = "VRR"; break; 0946 case 6: m_name = "VROE"; break; 0947 case 7: m_name = "VREN"; break; 0948 } 0949 break; 0950 } 0951 case Register::GPR: 0952 case Register::WORKING: 0953 case Register::none: 0954 { 0955 // qCritical() << Q_FUNC_INFO << "Bad register: " << reg; 0956 } 0957 } 0958 } 0959 0960 0961 RegisterBit::RegisterBit( const QString & name ) 0962 { 0963 m_name = name.toUpper().trimmed(); 0964 initFromName(); 0965 } 0966 0967 0968 RegisterBit::RegisterBit( const char * name ) 0969 { 0970 m_name = QString(name).toUpper().trimmed(); 0971 initFromName(); 0972 } 0973 0974 0975 void RegisterBit::initFromName() 0976 { 0977 bool ok; 0978 m_bitPos = m_name.toInt( & ok, 0 ); 0979 // work-around MSVC 2019 limitation: 0980 // ...\ktechlab\microbe\instruction.cpp(1614): fatal error C1061: compiler limit: blocks nested too deeply 0981 if ( ok ) { 0982 m_registerType = Register::none; // hmm it should be unknown - not none. 0983 return; 0984 } 0985 //----------------------------------------Bank0----------------------------// 0986 0987 //--------STATUS REGISTER--------// 0988 0989 if ( m_name == "C" ) 0990 { 0991 m_registerType = Register::STATUS; 0992 m_bitPos = 0; 0993 return; 0994 } 0995 if ( m_name == "DC" ) 0996 { 0997 m_registerType = Register::STATUS; 0998 m_bitPos = 1; 0999 return; 1000 } 1001 if ( m_name == "Z" ) 1002 { 1003 m_registerType = Register::STATUS; 1004 m_bitPos = 2; 1005 return; 1006 } 1007 if ( m_name == "NOT_PD" ) 1008 { 1009 m_registerType = Register::STATUS; 1010 m_bitPos = 3; 1011 return; 1012 } 1013 if ( m_name == "NOT_TO" ) 1014 { 1015 m_registerType = Register::STATUS; 1016 m_bitPos = 4; 1017 return; 1018 } 1019 if ( m_name == "RP0" ) 1020 { 1021 m_registerType = Register::STATUS; 1022 m_bitPos = 5; 1023 return; 1024 } 1025 if ( m_name == "RP1" ) 1026 { 1027 m_registerType = Register::STATUS; 1028 m_bitPos = 6; 1029 return; 1030 } 1031 if ( m_name == "IRP" ) 1032 { 1033 m_registerType = Register::STATUS; 1034 m_bitPos = 7; 1035 return; 1036 } 1037 1038 //-----------INTCON REGISTER---------// 1039 1040 if ( m_name == "RBIF" ) 1041 { 1042 m_registerType = Register::INTCON; 1043 m_bitPos = 0; 1044 return; 1045 } 1046 if ( m_name == "INTF" ) 1047 { 1048 m_registerType = Register::INTCON; 1049 m_bitPos = 1; 1050 return; 1051 } 1052 if ( m_name == "T0IF" ) 1053 { 1054 m_registerType = Register::INTCON; 1055 m_bitPos = 2; 1056 return; 1057 } 1058 if ( m_name == "RBIE" ) 1059 { 1060 m_registerType = Register::INTCON; 1061 m_bitPos = 3; 1062 return; 1063 } 1064 if ( m_name == "INTE" ) 1065 { 1066 m_registerType = Register::INTCON; 1067 m_bitPos = 4; 1068 return; 1069 } 1070 if ( m_name == "T0IE" ) 1071 { 1072 m_registerType = Register::INTCON; 1073 m_bitPos = 5; 1074 return; 1075 } 1076 if ( m_name =="PEIE"&&(pic_type=="P16F877"||pic_type=="P16F627")) 1077 { 1078 m_registerType = Register::INTCON; 1079 m_bitPos = 6; 1080 return; 1081 } 1082 if (m_name == "EEIE"&& (pic_type=="P16F84"||pic_type=="P16C84")) 1083 { 1084 m_registerType = Register::INTCON; 1085 m_bitPos = 6; 1086 return; 1087 } 1088 if ( m_name == "GIE" ) 1089 { 1090 m_registerType = Register::INTCON; 1091 m_bitPos = 7; 1092 return; 1093 } 1094 //-------PIR1---------// 1095 1096 if ( m_name == "TMR1F" ) 1097 { 1098 m_registerType = Register::PIR1; 1099 m_bitPos = 0; 1100 return; 1101 } 1102 if ( m_name == "TMR2F" ) 1103 { 1104 m_registerType = Register::PIR1; 1105 m_bitPos = 1; 1106 return; 1107 } 1108 if ( m_name == "CCP1IF" ) 1109 { 1110 m_registerType = Register::PIR1; 1111 m_bitPos = 2; 1112 return; 1113 } 1114 if ( m_name == "SSPIF"&& pic_type=="P16F877" ) 1115 { 1116 m_registerType = Register::PIR1; 1117 m_bitPos = 3; 1118 return; 1119 } 1120 if ( m_name == "TXIF" ) 1121 { 1122 m_registerType = Register::PIR1; 1123 m_bitPos = 4; 1124 return; 1125 } 1126 if ( m_name == "RCIF" ) 1127 { 1128 m_registerType = Register::PIR1; 1129 m_bitPos = 5; 1130 return; 1131 } 1132 if ( m_name == "ADIF" && pic_type=="P16F877") 1133 { 1134 m_registerType = Register::PIR1; 1135 m_bitPos = 6; 1136 return; 1137 } 1138 if ( m_name == "CMIF" && pic_type=="P16F627") 1139 { 1140 m_registerType = Register::PIR1; 1141 m_bitPos = 6; 1142 return; 1143 } 1144 if ( m_name == "PSPIF"&& pic_type=="P16F877") 1145 { 1146 m_registerType = Register::PIR1; 1147 m_bitPos = 7; 1148 return; 1149 } 1150 if ( m_name == "EEIF"&& pic_type=="P16F627") 1151 { 1152 m_registerType = Register::PIR1; 1153 m_bitPos = 7; 1154 return; 1155 } 1156 //-------PIR2---------// 1157 if ( m_name == "CCP2IF" ) 1158 { 1159 m_registerType = Register::PIR2; 1160 m_bitPos = 0; 1161 return; 1162 } 1163 if ( m_name == "BCLIF" ) 1164 { 1165 m_registerType = Register::PIR2; 1166 m_bitPos = 3; 1167 return; 1168 } 1169 if ( m_name == "EEIF" && pic_type=="P16F877" ) 1170 { 1171 m_registerType = Register::PIR2; 1172 m_bitPos = 4; 1173 return; 1174 } 1175 //-------T1CON--------// 1176 if ( m_name == "TMR1ON" ) 1177 { 1178 m_registerType = Register::T1CON; 1179 m_bitPos = 0; 1180 return; 1181 } 1182 if ( m_name == "TMR1CS" ) 1183 { 1184 m_registerType = Register::T1CON; 1185 m_bitPos = 1; 1186 return; 1187 } 1188 if ( m_name == "T1SYNC"&& pic_type=="P16F877" ) 1189 { 1190 m_registerType = Register::T1CON; 1191 m_bitPos = 2; 1192 return; 1193 } 1194 if ( m_name == "NOT_T1SYNC"&& pic_type=="P16F627" ) 1195 { 1196 m_registerType = Register::T1CON; 1197 m_bitPos = 2; 1198 return; 1199 } 1200 if ( m_name == "T1OSCEN" ) 1201 { 1202 m_registerType = Register::T1CON; 1203 m_bitPos = 3; 1204 return; 1205 } 1206 if ( m_name == "T1CKPS0" ) 1207 { 1208 m_registerType = Register::T1CON; 1209 m_bitPos = 4; 1210 return; 1211 } 1212 if ( m_name == "T1CKPS1" ) 1213 { 1214 m_registerType = Register::T1CON; 1215 m_bitPos = 5; 1216 return; 1217 } 1218 //-------T2CON--------// 1219 1220 if ( m_name == "T2CKPS0" ) 1221 { 1222 m_registerType = Register::T2CON; 1223 m_bitPos = 0; 1224 return; 1225 } 1226 if ( m_name == "T2CKPS1" ) 1227 { 1228 m_registerType = Register::T2CON; 1229 m_bitPos = 1; 1230 return; 1231 } 1232 if ( m_name == "TMR2ON" ) 1233 { 1234 m_registerType = Register::T2CON; 1235 m_bitPos = 2; 1236 return; 1237 } 1238 if ( m_name == "TOUTPS0" ) 1239 { 1240 m_registerType = Register::T2CON; 1241 m_bitPos = 3; 1242 return; 1243 } 1244 if ( m_name == "TOUTPS1" ) 1245 { 1246 m_registerType = Register::T2CON; 1247 m_bitPos = 4; 1248 return; 1249 } 1250 if ( m_name == "TOUTPS2" ) 1251 { 1252 m_registerType = Register::T2CON; 1253 m_bitPos = 5; 1254 return; 1255 } 1256 if ( m_name == "TOUTPS3" ) 1257 { 1258 m_registerType = Register::T2CON; 1259 m_bitPos = 6; 1260 return; 1261 } 1262 //---SSPCON------// 1263 1264 if ( m_name == "SSPM0" ) 1265 { 1266 m_registerType = Register::SSPCON; 1267 m_bitPos = 0; 1268 return; 1269 } 1270 if ( m_name == "SSPM1" ) 1271 { 1272 m_registerType = Register::SSPCON; 1273 m_bitPos = 1; 1274 return; 1275 } 1276 if ( m_name == "SSPM2" ) 1277 { 1278 m_registerType = Register::SSPCON; 1279 m_bitPos = 2; 1280 return; 1281 } 1282 if ( m_name == "SSPM3" ) 1283 { 1284 m_registerType = Register::SSPCON; 1285 m_bitPos = 3; 1286 return; 1287 } 1288 if ( m_name == "CKP" ) 1289 { 1290 m_registerType = Register::SSPCON; 1291 m_bitPos = 4; 1292 return; 1293 } 1294 if ( m_name == "SSPEN" ) 1295 { 1296 m_registerType = Register::SSPCON; 1297 m_bitPos = 5; 1298 return; 1299 } 1300 if ( m_name == "SSPOV" ) 1301 { 1302 m_registerType = Register::SSPCON; 1303 m_bitPos = 6; 1304 return; 1305 } 1306 if ( m_name == "WCOL" ) 1307 { 1308 m_registerType = Register::SSPCON; 1309 m_bitPos = 7; 1310 return; 1311 } 1312 //-------CCP1CON----// 1313 if ( m_name == "CCP1M0" ) 1314 { 1315 m_registerType = Register::CCP1CON; 1316 m_bitPos = 0; 1317 return; 1318 } 1319 if ( m_name == "CCP1M1" ) 1320 { 1321 m_registerType = Register::CCP1CON; 1322 m_bitPos = 1; 1323 return; 1324 } 1325 if ( m_name == "CCP1M2" ) 1326 { 1327 m_registerType = Register::CCP1CON; 1328 m_bitPos = 2; 1329 return; 1330 } 1331 if ( m_name == "CCP1M3" ) 1332 { 1333 m_registerType = Register::CCP1CON; 1334 m_bitPos = 3; 1335 return; 1336 } 1337 if ( m_name == "CCP1Y" ) 1338 { 1339 m_registerType = Register::CCP1CON; 1340 m_bitPos = 4; 1341 return; 1342 } 1343 if ( m_name == "CCP1X" ) 1344 { 1345 m_registerType = Register::CCP1CON; 1346 m_bitPos = 5; 1347 return; 1348 } 1349 //-------RCSTA----// 1350 if ( m_name == "RX9D" ) 1351 { 1352 m_registerType = Register::RCSTA; 1353 m_bitPos = 0; 1354 return; 1355 } 1356 if ( m_name == "OERR" ) 1357 { 1358 m_registerType = Register::RCSTA; 1359 m_bitPos = 1; 1360 return; 1361 } 1362 if ( m_name == "FERR" ) 1363 { 1364 m_registerType = Register::RCSTA; 1365 m_bitPos = 2; 1366 return; 1367 } 1368 if ( m_name == "ADDEN"&& pic_type=="P16F877" ) 1369 { 1370 m_registerType = Register::RCSTA; 1371 m_bitPos = 3; 1372 return; 1373 } 1374 if ( m_name == "ADEN"&& pic_type=="P16F627" ) 1375 { 1376 m_registerType = Register::RCSTA; 1377 m_bitPos = 3; 1378 return; 1379 } 1380 if ( m_name == "CREN" ) 1381 { 1382 m_registerType = Register::RCSTA; 1383 m_bitPos = 4; 1384 return; 1385 } 1386 if ( m_name == "SREN" ) 1387 { 1388 m_registerType = Register::RCSTA; 1389 m_bitPos = 5; 1390 return; 1391 } 1392 if ( m_name == "RX9" ) 1393 { 1394 m_registerType = Register::RCSTA; 1395 m_bitPos = 6; 1396 return; 1397 } 1398 if ( m_name == "SPEN" ) 1399 { 1400 m_registerType = Register::RCSTA; 1401 m_bitPos = 7; 1402 return; 1403 } 1404 //-----CCP2CON-------// 1405 if ( m_name == "CCP2M0" ) 1406 { 1407 m_registerType = Register::CCP2CON; 1408 m_bitPos = 0; 1409 return; 1410 } 1411 if ( m_name == "CCP2M1" ) 1412 { 1413 m_registerType = Register::CCP2CON; 1414 m_bitPos = 1; 1415 return; 1416 } 1417 if ( m_name == "CCP2M2" ) 1418 { 1419 m_registerType = Register::CCP2CON; 1420 m_bitPos = 2; 1421 return; 1422 } 1423 if ( m_name == "CCP2M3" ) 1424 { 1425 m_registerType = Register::CCP2CON; 1426 m_bitPos = 3; 1427 return; 1428 } 1429 if ( m_name == "CCP2Y" ) 1430 { 1431 m_registerType = Register::CCP2CON; 1432 m_bitPos = 4; 1433 return; 1434 } 1435 if ( m_name == "CCP2X" ) 1436 { 1437 m_registerType = Register::CCP2CON; 1438 m_bitPos = 5; 1439 return; 1440 } 1441 //--------ADCON0------// 1442 if ( m_name == "ADON" ) 1443 { 1444 m_registerType = Register::ADCON0; 1445 m_bitPos = 0; 1446 return; 1447 } 1448 if ( m_name == "GO" ) 1449 { 1450 m_registerType = Register::ADCON0; 1451 m_bitPos = 2; 1452 return; 1453 } 1454 if ( m_name == "CHS0" ) 1455 { 1456 m_registerType = Register::ADCON0; 1457 m_bitPos = 3; 1458 return; 1459 } 1460 if ( m_name == "CHS1" ) 1461 { 1462 m_registerType = Register::ADCON0; 1463 m_bitPos = 4; 1464 return; 1465 } 1466 if ( m_name == "CHS2" ) 1467 { 1468 m_registerType = Register::ADCON0; 1469 m_bitPos = 5; 1470 return; 1471 } 1472 if ( m_name == "ADCS0" ) 1473 { 1474 m_registerType = Register::ADCON0; 1475 m_bitPos = 6; 1476 return; 1477 } 1478 if ( m_name == "ADCS1" ) 1479 { 1480 m_registerType = Register::ADCON0; 1481 m_bitPos = 7; 1482 return; 1483 } 1484 //-------CMCON---------------//pic16f627 1485 if ( m_name == "CM0"&& pic_type=="P16F627") 1486 { 1487 m_registerType = Register::CMCON; 1488 m_bitPos = 0; 1489 return; 1490 } 1491 if ( m_name == "CM1"&& pic_type=="P16F627") 1492 { 1493 m_registerType = Register::CMCON; 1494 m_bitPos = 1; 1495 return; 1496 } 1497 if ( m_name == "CM2"&& pic_type=="P16F627") 1498 { 1499 m_registerType = Register::CMCON; 1500 m_bitPos = 2; 1501 return; 1502 } 1503 if ( m_name == "CM3"&& pic_type=="P16F627") 1504 { 1505 m_registerType = Register::CMCON; 1506 m_bitPos = 3; 1507 return; 1508 } 1509 if ( m_name == "CIS"&& pic_type=="P16F627") 1510 { 1511 m_registerType = Register::CMCON; 1512 m_bitPos = 4; 1513 return; 1514 } 1515 if ( m_name == "C2INV"&& pic_type=="P16F627") 1516 { 1517 m_registerType = Register::CMCON; 1518 m_bitPos = 5; 1519 return; 1520 } 1521 if ( m_name == "C1OUT"&& pic_type=="P16F627") 1522 { 1523 m_registerType = Register::CMCON; 1524 m_bitPos = 6; 1525 return; 1526 } 1527 if ( m_name == "C2OUT"&& pic_type=="P16F627") 1528 { 1529 m_registerType = Register::CMCON; 1530 m_bitPos = 7; 1531 return; 1532 } 1533 //---------------------------------------------Bank1-------------------------------// 1534 //-------OPTION_REGSITER---------------// 1535 if ( m_name == "PS0" ) 1536 { 1537 m_registerType = Register::OPTION_REG; 1538 m_bitPos = 0; 1539 return; 1540 } 1541 if ( m_name == "PS1" ) 1542 { 1543 m_registerType = Register::OPTION_REG; 1544 m_bitPos = 1; 1545 return; 1546 } 1547 if ( m_name == "PS2" ) 1548 { 1549 m_registerType = Register::OPTION_REG; 1550 m_bitPos = 2; 1551 return; 1552 } 1553 if ( m_name == "PSA" ) 1554 { 1555 m_registerType = Register::OPTION_REG; 1556 m_bitPos = 3; 1557 return; 1558 } 1559 if ( m_name == "T0SE" ) 1560 { 1561 m_registerType = Register::OPTION_REG; 1562 m_bitPos = 4; 1563 return; 1564 } 1565 if ( m_name == "T0CS" ) 1566 { 1567 m_registerType = Register::OPTION_REG; 1568 m_bitPos = 5; 1569 return; 1570 } 1571 if ( m_name == "INTEDG" ) 1572 { 1573 m_registerType = Register::OPTION_REG; 1574 m_bitPos = 6; 1575 return; 1576 } 1577 if(m_name =="NOT_RBPU"&&(pic_type=="P16C84"||pic_type=="P16F84"||pic_type=="P16F627")) 1578 { 1579 m_registerType = Register::OPTION_REG; 1580 m_bitPos = 7; 1581 return; 1582 } 1583 if (m_name == "RBPU" && pic_type=="P16C84") 1584 { 1585 m_registerType = Register::OPTION_REG; 1586 m_bitPos = 7; 1587 return; 1588 } 1589 //--------PIE1---------// 1590 if ( m_name == "TMR1IE" ) 1591 { 1592 m_registerType = Register::PIE1; 1593 m_bitPos = 0; 1594 return; 1595 } 1596 if ( m_name == "TMR2IE" ) 1597 { 1598 m_registerType = Register::PIE1; 1599 m_bitPos = 1; 1600 return; 1601 } 1602 if ( m_name == "CCP1IE" ) 1603 { 1604 m_registerType = Register::PIE1; 1605 m_bitPos = 2; 1606 return; 1607 } 1608 if ( m_name == "SSPIE" && pic_type=="P16F877") 1609 { 1610 m_registerType = Register::PIE1; 1611 m_bitPos = 3; 1612 return; 1613 } 1614 if ( m_name == "TXIE" ) 1615 { 1616 m_registerType = Register::PIE1; 1617 m_bitPos = 4; 1618 return; 1619 } 1620 if ( m_name == "RCIE" ) 1621 { 1622 m_registerType = Register::PIE1; 1623 m_bitPos = 5; 1624 return; 1625 } 1626 if ( m_name == "ADIE" && pic_type=="P16F877" ) 1627 { 1628 m_registerType = Register::PIE1; 1629 m_bitPos = 6; 1630 return; 1631 } 1632 if ( m_name == "CMIE" && pic_type=="P16F627" ) 1633 { 1634 m_registerType = Register::PIE1; 1635 m_bitPos = 6; 1636 return; 1637 } 1638 if ( m_name == "PSPIE" && pic_type=="P16F877" ) 1639 { 1640 m_registerType = Register::PIE1; 1641 m_bitPos = 7; 1642 return; 1643 } 1644 if ( m_name == "EEIE" && pic_type=="P16F627" ) 1645 { 1646 m_registerType = Register::PIE1; 1647 m_bitPos = 7; 1648 return; 1649 } 1650 //--------PIE2---------// 1651 if ( m_name == "CCP2IE" ) 1652 { 1653 m_registerType = Register::PIE2; 1654 m_bitPos = 0; 1655 return; 1656 } 1657 if ( m_name == "BCLIE" ) 1658 { 1659 m_registerType = Register::PIE2; 1660 m_bitPos = 3; 1661 return; 1662 } 1663 if ( m_name == "EEIE"&& pic_type=="P16F877" ) 1664 { 1665 m_registerType = Register::PIE2; 1666 m_bitPos = 4; 1667 return; 1668 } 1669 //--------PCON---------// 1670 if ( m_name == "NOT_BOR" ) 1671 { 1672 m_registerType = Register::PCON; 1673 m_bitPos = 0; 1674 return; 1675 } 1676 if ( m_name == "NOT_POR" ) 1677 { 1678 m_registerType = Register::PCON; 1679 m_bitPos = 1; 1680 return; 1681 } 1682 if ( m_name == "OSCF"&& pic_type=="P16F627" ) 1683 { 1684 m_registerType = Register::PCON; 1685 m_bitPos = 3; 1686 return; 1687 } 1688 //--------SSPCON2------// 1689 if ( m_name =="SEN") 1690 { 1691 m_registerType = Register::SSPCON2; 1692 m_bitPos = 0; 1693 return; 1694 } 1695 if ( m_name =="RSEN") 1696 { 1697 m_registerType = Register::SSPCON2; 1698 m_bitPos = 1; 1699 return; 1700 } 1701 if ( m_name =="PEN") 1702 { 1703 m_registerType = Register::SSPCON2; 1704 m_bitPos = 2; 1705 return; 1706 } 1707 if ( m_name =="RCEN") 1708 { 1709 m_registerType = Register::SSPCON2; 1710 m_bitPos = 3; 1711 return; 1712 } 1713 if ( m_name =="ACKEN") 1714 { 1715 m_registerType = Register::SSPCON2; 1716 m_bitPos = 4; 1717 return; 1718 } 1719 if ( m_name =="ACKDT") 1720 { 1721 m_registerType = Register::SSPCON2; 1722 m_bitPos = 5; 1723 return; 1724 } 1725 if ( m_name =="ACKSTAT" ) 1726 { 1727 m_registerType = Register::SSPCON2; 1728 m_bitPos = 6; 1729 return; 1730 } 1731 if ( m_name == "GCEN" ) 1732 { 1733 m_registerType = Register::SSPCON2; 1734 m_bitPos = 7; 1735 return; 1736 } 1737 //--------SSPSTAT------// 1738 if ( m_name =="BF") 1739 { 1740 m_registerType = Register::SSPSTAT; 1741 m_bitPos = 0; 1742 return; 1743 } 1744 if ( m_name == "UA") 1745 { 1746 m_registerType = Register::SSPSTAT; 1747 m_bitPos = 1; 1748 return; 1749 } 1750 if ( m_name =="R") 1751 { 1752 m_registerType = Register::SSPSTAT; 1753 m_bitPos = 2; 1754 return; 1755 } 1756 if ( m_name =="S") 1757 { 1758 m_registerType = Register::SSPSTAT; 1759 m_bitPos = 3; 1760 return; 1761 } 1762 if ( m_name == "P") 1763 { 1764 m_registerType = Register::SSPSTAT; 1765 m_bitPos = 4; 1766 return; 1767 } 1768 if ( m_name == "D") 1769 { 1770 m_registerType = Register::SSPSTAT; 1771 m_bitPos = 5; 1772 return; 1773 } 1774 if ( m_name == "CKE" ) 1775 { 1776 m_registerType = Register::SSPSTAT; 1777 m_bitPos = 6; 1778 return; 1779 } 1780 if ( m_name == "SMP" ) 1781 { 1782 m_registerType = Register::SSPSTAT; 1783 m_bitPos = 7; 1784 return; 1785 } 1786 //--------TXSTA--------// 1787 if ( m_name == "TX9D" ) 1788 { 1789 m_registerType = Register::TXSTA; 1790 m_bitPos = 0; 1791 return; 1792 } 1793 if ( m_name == "TRMT" ) 1794 { 1795 m_registerType = Register::TXSTA; 1796 m_bitPos = 1; 1797 return; 1798 } 1799 if ( m_name == "BRGH" ) 1800 { 1801 m_registerType = Register::TXSTA; 1802 m_bitPos = 2; 1803 return; 1804 } 1805 if ( m_name == "SYNC" ) 1806 { 1807 m_registerType = Register::TXSTA; 1808 m_bitPos = 4; 1809 return; 1810 } 1811 if ( m_name == "TXEN" ) 1812 { 1813 m_registerType = Register::TXSTA; 1814 m_bitPos = 5; 1815 return; 1816 } 1817 if ( m_name == "TX9" ) 1818 { 1819 m_registerType = Register::TXSTA; 1820 m_bitPos = 6; 1821 return; 1822 } 1823 if ( m_name == "CSRC" ) 1824 { 1825 m_registerType = Register::TXSTA; 1826 m_bitPos = 7; 1827 return; 1828 } 1829 //---------ADCON1-----// 1830 if ( m_name == "PCFG0" ) 1831 { 1832 m_registerType = Register::ADCON1; 1833 m_bitPos = 0; 1834 return; 1835 } 1836 if ( m_name == "PCFG1" ) 1837 { 1838 m_registerType = Register::ADCON1; 1839 m_bitPos = 1; 1840 return; 1841 } 1842 if ( m_name == "PCFG2" ) 1843 { 1844 m_registerType = Register::ADCON1; 1845 m_bitPos = 2; 1846 return; 1847 } 1848 if ( m_name == "PCFG3" ) 1849 { 1850 m_registerType = Register::ADCON1; 1851 m_bitPos = 3; 1852 return; 1853 } 1854 if ( m_name == "ADFM" ) 1855 { 1856 m_registerType = Register::ADCON1; 1857 m_bitPos = 7; 1858 return; 1859 } 1860 //--------------------------------------------Bank2------------------// 1861 //-----NOTHING TODO---// 1862 // 1863 //--------------------------------------------Bank3------------------// 1864 if ( m_name == "RD" ) 1865 { 1866 m_registerType = Register::EECON1; 1867 m_bitPos = 0; 1868 return; 1869 } 1870 if ( m_name == "WR" ) 1871 { 1872 m_registerType = Register::EECON1; 1873 m_bitPos = 1; 1874 return; 1875 } 1876 if ( m_name == "WREN" ) 1877 { 1878 m_registerType = Register::EECON1; 1879 m_bitPos = 2; 1880 return; 1881 } 1882 if ( m_name == "WRERR" ) 1883 { 1884 m_registerType = Register::EECON1; 1885 m_bitPos = 3; 1886 return; 1887 } 1888 if ( m_name == "EEIF"&&(pic_type=="P16F84"||pic_type=="P16C84"))//imp **** 1889 { 1890 m_registerType = Register::EECON1; 1891 m_bitPos = 4; 1892 return; 1893 } 1894 if ( m_name == "EEPGD" && pic_type=="P16F877" ) 1895 { 1896 m_registerType = Register::EECON1; 1897 m_bitPos = 7; 1898 return; 1899 } 1900 //---------VRCON------// 1901 if ( m_name == "VR0" && pic_type=="P16F627" ) 1902 { 1903 m_registerType = Register::VRCON; 1904 m_bitPos = 0; 1905 return; 1906 } 1907 if ( m_name == "VR1" && pic_type=="P16F627" ) 1908 { 1909 m_registerType = Register::VRCON; 1910 m_bitPos = 1; 1911 return; 1912 } 1913 if ( m_name == "VR2" && pic_type=="P16F627" ) 1914 { 1915 m_registerType = Register::VRCON; 1916 m_bitPos = 2; 1917 return; 1918 } 1919 if ( m_name == "VR3" && pic_type=="P16F627" ) 1920 { 1921 m_registerType = Register::VRCON; 1922 m_bitPos = 3; 1923 return; 1924 } 1925 if ( m_name == "VRR" && pic_type=="P16F627" ) 1926 { 1927 m_registerType = Register::VRCON; 1928 m_bitPos = 5; 1929 return; 1930 } 1931 if ( m_name == "VROE" && pic_type=="P16F627" ) 1932 { 1933 m_registerType = Register::VRCON; 1934 m_bitPos = 6; 1935 return; 1936 } 1937 if ( m_name == "VREN" && pic_type=="P16F627" ) 1938 { 1939 m_registerType = Register::VRCON; 1940 m_bitPos = 7; 1941 return; 1942 } 1943 // no match with anything: 1944 { 1945 m_registerType = Register::none; 1946 m_bitPos = 0; 1947 qCritical() << Q_FUNC_INFO << "Unknown bit: " << m_name; 1948 } 1949 } 1950 //END class RegisterBit 1951 1952 1953 1954 1955 //BEGIN class RegisterState 1956 RegisterState::RegisterState() 1957 { 1958 reset(); 1959 } 1960 1961 1962 void RegisterState::reset() 1963 { 1964 known = 0x0; 1965 value = 0x0; 1966 } 1967 1968 1969 void RegisterState::merge( const RegisterState & state ) 1970 { 1971 known &= state.known; 1972 known &= ~( value ^ state.value ); 1973 } 1974 1975 1976 bool RegisterState::operator == ( const RegisterState & state ) const 1977 { 1978 return (known == state.known) && (value == state.value); 1979 } 1980 1981 1982 void RegisterState::print() 1983 { 1984 cout << " known="<< binary(known).toStdString() <<endl; 1985 cout << " value="<< binary(value).toStdString() <<endl; 1986 } 1987 //END class RegisterState 1988 1989 1990 1991 //BEGIN class RegisterBehaviour 1992 RegisterBehaviour::RegisterBehaviour() 1993 { 1994 reset(); 1995 } 1996 1997 1998 void RegisterBehaviour::reset() 1999 { 2000 depends = 0x0; 2001 indep = 0x0; 2002 } 2003 //END class RegisterBehaviour 2004 2005 2006 2007 //BEGIN class ProcessorState 2008 ProcessorState::ProcessorState() 2009 { 2010 } 2011 2012 2013 void ProcessorState::reset() 2014 { 2015 working.reset(); 2016 status.reset(); 2017 2018 RegisterMap::iterator end = m_registers.end(); 2019 for ( RegisterMap::iterator it = m_registers.begin(); it != end; ++it ) 2020 (*it).reset(); 2021 } 2022 2023 2024 void ProcessorState::merge( const ProcessorState & state ) 2025 { 2026 working.merge( state.working ); 2027 status.merge( state.status ); 2028 2029 RegisterMap::iterator this_it = m_registers.begin(); 2030 RegisterMap::const_iterator other_it = state.m_registers.begin(); 2031 2032 RegisterMap::iterator this_end = m_registers.end(); 2033 RegisterMap::const_iterator other_end = state.m_registers.end(); 2034 2035 while ( true ) 2036 { 2037 if ( this_it == this_end ) 2038 { 2039 // So remaining registers of this are default 2040 while ( other_it != other_end ) 2041 { 2042 m_registers[ other_it.key() ].merge( *other_it ); 2043 ++other_it; 2044 } 2045 return; 2046 } 2047 2048 if ( other_it == other_end ) 2049 { 2050 // So remaining registers of other are default 2051 while ( this_it != this_end ) 2052 { 2053 (*this_it).merge( RegisterState() ); 2054 ++this_it; 2055 } 2056 return; 2057 } 2058 2059 //RegisterState thisReg = *this_it; 2060 //RegisterState otherReg = *other_it; 2061 2062 if ( this_it.key() == other_it.key() ) 2063 { 2064 (*this_it).merge( *other_it ); 2065 ++this_it; 2066 ++other_it; 2067 } 2068 else if ( this_it.key() < other_it.key() ) 2069 { 2070 (*this_it).merge( RegisterState() ); 2071 ++this_it; 2072 } 2073 else // other_it.key() < this_it.key() 2074 { 2075 m_registers[ other_it.key() ].merge( *other_it ); 2076 ++other_it; 2077 } 2078 } 2079 } 2080 2081 2082 RegisterState & ProcessorState::reg( const Register & reg ) 2083 { 2084 if ( reg.type() == Register::WORKING ) 2085 return working; 2086 2087 if ( reg.type() == Register::STATUS ) 2088 return status; 2089 2090 return m_registers[ reg ]; 2091 } 2092 2093 2094 RegisterState ProcessorState::reg( const Register & reg ) const 2095 { 2096 if ( reg.type() == Register::WORKING ) 2097 return working; 2098 2099 if ( reg.type() == Register::STATUS ) 2100 return status; 2101 2102 return m_registers[ reg ]; 2103 } 2104 2105 2106 bool ProcessorState::operator == ( const ProcessorState & state ) const 2107 { 2108 if ( working != state.working ) 2109 return false; 2110 2111 if ( status != state.status ) 2112 return false; 2113 2114 RegisterMap::const_iterator this_it = m_registers.begin(); 2115 RegisterMap::const_iterator other_it = state.m_registers.begin(); 2116 2117 RegisterMap::const_iterator this_end = m_registers.end(); 2118 RegisterMap::const_iterator other_end = state.m_registers.end(); 2119 2120 while ( true ) 2121 { 2122 if ( this_it == this_end ) 2123 { 2124 // So remaining registers of this are default 2125 while ( other_it != other_end ) 2126 { 2127 if ( *other_it != RegisterState() ) 2128 return false; 2129 ++other_it; 2130 } 2131 return true; 2132 } 2133 2134 if ( other_it == other_end ) 2135 { 2136 // So remaining registers of other are default 2137 while ( this_it != this_end ) 2138 { 2139 if ( *this_it != RegisterState() ) 2140 return false; 2141 ++this_it; 2142 } 2143 return true; 2144 } 2145 2146 //RegisterState thisReg = *this_it; 2147 //RegisterState otherReg = *other_it; 2148 2149 if ( this_it.key() == other_it.key() ) 2150 { 2151 if ( *this_it != *other_it ) 2152 return false; 2153 ++this_it; 2154 ++other_it; 2155 } 2156 else if ( this_it.key() < other_it.key() ) 2157 { 2158 if ( *this_it != RegisterState() ) 2159 return false; 2160 ++this_it; 2161 } 2162 else // other_it.key() < this_it.key() 2163 { 2164 if ( *other_it != RegisterState() ) 2165 return false; 2166 ++other_it; 2167 } 2168 } 2169 } 2170 2171 2172 void ProcessorState::print() 2173 { 2174 cout << " WORKING:\n"; 2175 working.print(); 2176 cout << " STATUS:\n"; 2177 working.print(); 2178 RegisterMap::iterator end = m_registers.end(); 2179 for ( RegisterMap::iterator it = m_registers.begin(); it != end; ++it ) 2180 { 2181 cout << " " << it.key().name().toStdString() << ":\n"; 2182 it.value().print(); 2183 // it.value().print(); 2184 } 2185 } 2186 //END class ProcessorState 2187 2188 2189 2190 //BEGIN class ProcessorBehaviour 2191 ProcessorBehaviour::ProcessorBehaviour() 2192 { 2193 } 2194 2195 2196 void ProcessorBehaviour::reset() 2197 { 2198 working.reset(); 2199 status.reset(); 2200 2201 RegisterMap::iterator end = m_registers.end(); 2202 for ( RegisterMap::iterator it = m_registers.begin(); it != end; ++it ) 2203 (*it).reset(); 2204 } 2205 2206 2207 RegisterBehaviour & ProcessorBehaviour::reg( const Register & reg ) 2208 { 2209 if ( reg.type() == Register::WORKING ) 2210 return working; 2211 2212 if ( reg.type() == Register::STATUS ) 2213 return status; 2214 2215 return m_registers[ reg ]; 2216 } 2217 //END class ProcessorBehaviour 2218 2219 2220 2221 //BEGIN class RegisterDepends 2222 RegisterDepends::RegisterDepends() 2223 { 2224 reset(); 2225 } 2226 2227 2228 void RegisterDepends::reset() 2229 { 2230 working = 0x0; 2231 status = 0x0; 2232 2233 RegisterMap::iterator end = m_registers.end(); 2234 for ( RegisterMap::iterator it = m_registers.begin(); it != end; ++it ) 2235 (*it) = 0x0; 2236 } 2237 2238 2239 uchar & RegisterDepends::reg( const Register & reg ) 2240 { 2241 if ( reg.type() == Register::WORKING ) 2242 return working; 2243 2244 if ( reg.type() == Register::STATUS ) 2245 return status; 2246 2247 // If we don't already have the register, we need to reset it first 2248 if ( !m_registers.contains( reg.name() ) ) 2249 m_registers[ reg ] = 0xff; 2250 2251 return m_registers[ reg ]; 2252 } 2253 //END class RegisterDepends 2254 2255 2256 2257 //BEGIN clas Code 2258 Code::Code() 2259 { 2260 } 2261 2262 2263 void Code::merge( Code * code, InstructionPosition middleInsertionPosition ) 2264 { 2265 if ( code == this ) 2266 { 2267 cout << Q_FUNC_INFO << "identical\n"; 2268 return; 2269 } 2270 2271 if ( !code ) 2272 return; 2273 2274 // Reparent instructions 2275 for ( unsigned i = 0; i < PositionCount; ++i ) 2276 { 2277 InstructionList * list = code->instructionList( static_cast<InstructionPosition>(i) ); 2278 InstructionList::const_iterator end = list->end(); 2279 for ( InstructionList::const_iterator it = list->begin(); it != end; ++it ) 2280 append( *it, ( (i == Middle) ? middleInsertionPosition : static_cast<InstructionPosition>(i) ) ); 2281 2282 // Queue any labels that the other code has queued 2283 m_queuedLabels[i] += code->queuedLabels( static_cast<InstructionPosition>(i) ); 2284 } 2285 } 2286 2287 2288 void Code::queueLabel( const QString & label, InstructionPosition position ) 2289 { 2290 // cout << Q_FUNC_INFO << "label="<<label<<" position="<<position<<'\n'; 2291 m_queuedLabels[ position ] << label; 2292 } 2293 2294 2295 void Code::removeInstruction( Instruction * instruction ) 2296 { 2297 if ( !instruction ) 2298 return; 2299 2300 // If the instruction could potentially be jumped over by a BTFSS or a 2301 // BTFSC intsruction, then we must also remove the bit test instruction, 2302 // else the next instruction will be jumped over instead after removal. 2303 // Removing the bit test instruction is perfectly safe as it only does 2304 // branching (not setting of any bits, etc). 2305 2306 // Any labels that the instruction has must be given to the next 2307 // instruction. 2308 2309 iterator e = end(); 2310 iterator previous = e; // Refers to the previous instruction if it was a bit test instruction 2311 for ( iterator i = begin(); i != e; ++i ) 2312 { 2313 if ( *i != instruction ) 2314 { 2315 if ( dynamic_cast<Instr_btfss*>(*i) || dynamic_cast<Instr_btfsc*>(*i) ) 2316 previous = i; 2317 else 2318 previous = e; 2319 continue; 2320 } 2321 2322 iterator next = ++iterator(i); 2323 2324 QStringList labels = instruction->labels(); 2325 i.list->erase( i.it ); 2326 2327 if ( previous != e ) 2328 { 2329 labels += (*previous)->labels(); 2330 previous.list->erase( previous.it ); 2331 } 2332 2333 if ( next != e ) 2334 (*next)->addLabels( labels ); 2335 2336 break; 2337 } 2338 2339 // instruction->removeOutputs(); 2340 } 2341 2342 2343 void Code::append( Instruction * instruction, InstructionPosition position ) 2344 { 2345 if ( !instruction ) 2346 return; 2347 2348 // cout << Q_FUNC_INFO << instruction->code() << '\n'; 2349 2350 removeInstruction( instruction ); 2351 m_instructionLists[position].append( instruction ); 2352 2353 instruction->setCode( this ); 2354 2355 if ( instruction->type() == Instruction::Assembly /*|| 2356 instruction->type() == Instruction::Raw*/ ) 2357 { 2358 // if ( (position == Middle) && !m_queuedLabels[position].isEmpty() ) 2359 // cout << "adding queued labels for 1: " << m_queuedLabels[position].join(",") << '\n'; 2360 instruction->addLabels( m_queuedLabels[position] ); 2361 m_queuedLabels[position].clear(); 2362 } 2363 } 2364 2365 2366 Instruction * Code::instruction( const QString & label ) const 2367 { 2368 for ( unsigned i = 0; i < PositionCount; ++i ) 2369 { 2370 InstructionList::const_iterator end = m_instructionLists[i].end(); 2371 for ( InstructionList::const_iterator it = m_instructionLists[i].begin(); it != end; ++it ) 2372 { 2373 if ( (*it)->labels().contains( label ) ) 2374 return *it; 2375 } 2376 } 2377 return nullptr; 2378 } 2379 2380 2381 Code::iterator Code::find( Instruction * instruction ) 2382 { 2383 iterator e = end(); 2384 iterator i = begin(); 2385 for ( ; i != e; ++i ) 2386 { 2387 if ( *i == instruction ) 2388 break; 2389 } 2390 return i; 2391 } 2392 2393 2394 void Code::postCompileConstruct() 2395 { 2396 // Give any queued labels to the instructions in the subsequent code block 2397 for ( unsigned i = 0; i < PositionCount; ++i ) 2398 { 2399 if ( m_queuedLabels[i].isEmpty() ) 2400 continue; 2401 2402 QStringList labels = m_queuedLabels[i]; 2403 m_queuedLabels[i].clear(); 2404 2405 // Find an instruction to dump them onto 2406 for ( unsigned block = i+1; block < PositionCount; ++block ) 2407 { 2408 bool added = false; 2409 2410 InstructionList::iterator end = m_instructionLists[block].end(); 2411 for ( InstructionList::iterator it = m_instructionLists[block].begin(); it != end; ++it ) 2412 { 2413 if ( (*it)->type() == Instruction::Assembly ) 2414 { 2415 (*it)->addLabels( labels ); 2416 added = true; 2417 break; 2418 } 2419 } 2420 2421 if ( added ) 2422 break; 2423 } 2424 } 2425 } 2426 2427 2428 QString Code::generateCode( PIC14 * pic ) const 2429 { 2430 QString code; 2431 2432 const QStringList variables = findVariables(); 2433 if ( !variables.isEmpty() ) 2434 { 2435 code += "; Variables\n"; 2436 uchar reg = pic->gprStart(); 2437 QStringList::const_iterator end = variables.end(); 2438 for ( QStringList::const_iterator it = variables.begin(); it != end; ++it ) 2439 code += QString("%1\tequ\t0x%2\n").arg( *it ).arg( QString::number( reg++, 16 ) ); 2440 2441 code += "\n"; 2442 } 2443 2444 QString picString = pic->minimalTypeString(); 2445 code += QString("list p=%1\n").arg( picString ); 2446 code += QString("include \"p%2.inc\"\n\n").arg( picString.toLower() ); 2447 2448 code += "; Config options\n"; 2449 code += " __config _WDT_OFF\n\n"; 2450 2451 code += "START\n\n"; 2452 2453 for ( unsigned i = 0; i < PositionCount; ++i ) 2454 { 2455 InstructionList::const_iterator end = m_instructionLists[i].end(); 2456 for ( InstructionList::const_iterator it = m_instructionLists[i].begin(); it != end; ++it ) 2457 { 2458 const QStringList labels = (*it)->labels(); 2459 if ( !labels.isEmpty() ) 2460 { 2461 code += '\n'; 2462 QStringList::const_iterator labelsEnd = labels.end(); 2463 for ( QStringList::const_iterator labelsIt = labels.begin(); labelsIt != labelsEnd; ++labelsIt ) 2464 code += *labelsIt + '\n'; 2465 } 2466 2467 if ( (*it)->type() == Instruction::Assembly ) 2468 code += '\t'; 2469 code += (*it)->code() + '\n'; 2470 } 2471 } 2472 2473 return code; 2474 } 2475 2476 2477 QStringList Code::findVariables() const 2478 { 2479 QStringList variables; 2480 2481 const_iterator e = end(); 2482 for ( const_iterator i = begin(); i != e; ++i ) 2483 { 2484 if ( (*i)->file().type() != Register::GPR ) 2485 continue; 2486 2487 QString alias = (*i)->file().name(); 2488 if ( !variables.contains( alias ) ) 2489 variables << alias; 2490 } 2491 2492 return variables; 2493 } 2494 2495 2496 void Code::generateLinksAndStates() 2497 { 2498 CodeIterator e = end(); 2499 2500 for ( CodeIterator it = begin(); it != e; ++it ) 2501 (*it)->clearLinks(); 2502 2503 for ( CodeIterator it = begin(); it != e; ++it ) 2504 (*it)->generateLinksAndStates( it ); 2505 2506 // Generate return links for call instructions 2507 // This cannot be done from the call instructions as we need to have 2508 // generated the links first. 2509 for ( CodeIterator it = begin(); it != e; ++it ) 2510 { 2511 Instr_call * ins = dynamic_cast<Instr_call*>(*it); 2512 if ( !ins ) 2513 continue; 2514 2515 Instruction * next = *(++Code::iterator(it)); 2516 ins->makeReturnLinks( next ); 2517 } 2518 } 2519 2520 2521 void Code::setAllUnused() 2522 { 2523 CodeIterator e = end(); 2524 for ( CodeIterator it = begin(); it != e; ++it ) 2525 { 2526 (*it)->setUsed( false ); 2527 (*it)->resetRegisterDepends(); 2528 } 2529 } 2530 2531 2532 CodeIterator Code::begin() 2533 { 2534 // Following code is very similar to the version of this function. 2535 // Make sure any changes are applied to both (when applicable). 2536 2537 for ( unsigned i = 0; i < PositionCount; ++i ) 2538 { 2539 if ( m_instructionLists[i].isEmpty() ) 2540 continue; 2541 2542 CodeIterator codeIterator; 2543 codeIterator.code = this; 2544 codeIterator.it = m_instructionLists[i].begin(); 2545 codeIterator.pos = static_cast<Code::InstructionPosition>(i); 2546 codeIterator.list = & m_instructionLists[i]; 2547 codeIterator.listEnd = m_instructionLists[i].end(); 2548 2549 return codeIterator; 2550 } 2551 2552 return end(); 2553 } 2554 2555 2556 CodeIterator Code::end() 2557 { 2558 // Following code is very similar to the version of this function. 2559 // Make sure any changes are applied to both (when applicable). 2560 2561 CodeIterator codeIterator; 2562 codeIterator.code = this; 2563 codeIterator.it = m_instructionLists[ PositionCount - 1 ].end(); 2564 codeIterator.pos = static_cast<Code::InstructionPosition>(Code::PositionCount - 1); 2565 codeIterator.list = & m_instructionLists[ PositionCount - 1 ]; 2566 codeIterator.listEnd = m_instructionLists[ PositionCount - 1 ].end(); 2567 return codeIterator; 2568 } 2569 2570 2571 CodeConstIterator Code::begin() const 2572 { 2573 // Following code is very similar to the non-const version of this function. 2574 // Make sure any changes are applied to both (when applicable). 2575 2576 for ( unsigned i = 0; i < PositionCount; ++i ) 2577 { 2578 if ( m_instructionLists[i].isEmpty() ) 2579 continue; 2580 2581 CodeConstIterator codeIterator; 2582 codeIterator.code = this; 2583 codeIterator.it = m_instructionLists[i].begin(); 2584 codeIterator.pos = static_cast<Code::InstructionPosition>(i); 2585 codeIterator.list = & m_instructionLists[i]; 2586 codeIterator.listEnd = m_instructionLists[i].end(); 2587 2588 return codeIterator; 2589 } 2590 2591 return end(); 2592 } 2593 2594 2595 CodeConstIterator Code::end() const 2596 { 2597 // Following code is very similar to the non-const version of this function. 2598 // Make sure any changes are applied to both (when applicable). 2599 2600 CodeConstIterator codeIterator; 2601 codeIterator.code = this; 2602 codeIterator.it = m_instructionLists[ PositionCount - 1 ].end(); 2603 codeIterator.pos = static_cast<Code::InstructionPosition>(Code::PositionCount - 1); 2604 codeIterator.list = & m_instructionLists[ PositionCount - 1 ]; 2605 codeIterator.listEnd = m_instructionLists[ PositionCount - 1 ].end(); 2606 return codeIterator; 2607 } 2608 //END class Code 2609 2610 2611 2612 //BEGIN class CodeIterator 2613 CodeIterator & CodeIterator::operator ++ () 2614 { 2615 // NOTE: This code is very similar to the const version. 2616 // Any changes to thsi code should be applied there as well (when applicable). 2617 2618 do 2619 { 2620 if ( ++it == listEnd && pos < (Code::PositionCount - 1) ) 2621 { 2622 bool found = false; 2623 for ( pos = static_cast<Code::InstructionPosition>(pos+1); pos < Code::PositionCount; pos = static_cast<Code::InstructionPosition>(pos+1) ) 2624 { 2625 list = code->instructionList( pos ); 2626 listEnd = list->end(); 2627 if ( list->isEmpty() ) 2628 continue; 2629 2630 it = list->begin(); 2631 found = true; 2632 break; 2633 } 2634 2635 if ( !found ) 2636 it = listEnd; 2637 } 2638 } 2639 while ( (it != listEnd) && ((*it)->type() != Instruction::Assembly) ); 2640 2641 return *this; 2642 } 2643 2644 2645 CodeIterator & CodeIterator::removeAndIncrement() 2646 { 2647 Instruction * i = *it; 2648 ++(*this); 2649 code->removeInstruction( i ); 2650 return *this; 2651 } 2652 2653 2654 void CodeIterator::insertBefore( Instruction * ins ) 2655 { 2656 list->insert( it, ins ); 2657 } 2658 //END class CodeIterator 2659 2660 2661 2662 //BEGIN class CodeConstIterator 2663 CodeConstIterator & CodeConstIterator::operator ++ () 2664 { 2665 // NOTE: This code is very similar to the non-const version. 2666 // Any changes to thsi code should be applied there as well (when applicable). 2667 2668 do 2669 { 2670 if ( ++it == listEnd && pos < (Code::PositionCount - 1) ) 2671 { 2672 bool found = false; 2673 for ( pos = static_cast<Code::InstructionPosition>(pos+1); pos < Code::PositionCount; pos = static_cast<Code::InstructionPosition>(pos+1) ) 2674 { 2675 list = code->instructionList( pos ); 2676 listEnd = list->end(); 2677 if ( list->isEmpty() ) 2678 continue; 2679 2680 it = list->begin(); 2681 found = true; 2682 break; 2683 } 2684 2685 if ( !found ) 2686 it = listEnd; 2687 } 2688 } 2689 while ( (it != listEnd) && ((*it)->type() != Instruction::Assembly) ); 2690 2691 return *this; 2692 } 2693 //END class CodeConstIterator 2694 2695 2696 2697 2698 //BEGIN class Instruction 2699 Instruction::Instruction() 2700 { 2701 m_bInputStateChanged = true; 2702 m_bPositionAffectsBranching = false; 2703 m_bUsed = false; 2704 m_literal = 0; 2705 m_dest = 0; 2706 } 2707 2708 2709 Instruction::~ Instruction() 2710 { 2711 } 2712 2713 2714 void Instruction::addLabels( const QStringList & labels ) 2715 { 2716 m_labels += labels; 2717 } 2718 2719 2720 void Instruction::setLabels( const QStringList & labels ) 2721 { 2722 m_labels = labels; 2723 } 2724 2725 2726 void Instruction::generateLinksAndStates( Code::iterator current ) 2727 { 2728 makeOutputLinks( current ); 2729 m_outputState.reset(); 2730 } 2731 2732 2733 ProcessorBehaviour Instruction::behaviour() const 2734 { 2735 return ProcessorBehaviour(); 2736 } 2737 2738 2739 void Instruction::makeOutputLinks( Code::iterator current, bool firstOutput, bool secondOutput ) 2740 { 2741 if ( !firstOutput && !secondOutput ) 2742 return; 2743 2744 ++current; 2745 if ( !*current ) 2746 { 2747 qWarning() << Q_FUNC_INFO << "current+1 is null"; 2748 return; 2749 } 2750 if ( firstOutput ) 2751 (*current)->addInputLink( this ); 2752 2753 if ( !secondOutput ) 2754 return; 2755 2756 ++current; 2757 (*current)->addInputLink( this ); 2758 } 2759 2760 2761 void Instruction::makeLabelOutputLink( const QString & label ) 2762 { 2763 Instruction * output = m_pCode->instruction( label ); 2764 if ( output ) 2765 output->addInputLink( this ); 2766 } 2767 2768 2769 void Instruction::addInputLink( Instruction * instruction ) 2770 { 2771 // Don't forget that a link to ourself is valid! 2772 if ( !instruction || m_inputLinks.contains( instruction ) ) 2773 return; 2774 2775 m_inputLinks << instruction; 2776 instruction->addOutputLink( this ); 2777 } 2778 2779 2780 void Instruction::addOutputLink( Instruction * instruction ) 2781 { 2782 // Don't forget that a link to ourself is valid! 2783 if ( !instruction || m_outputLinks.contains( instruction ) ) 2784 return; 2785 2786 m_outputLinks << instruction; 2787 instruction->addInputLink( this ); 2788 } 2789 2790 2791 void Instruction::removeInputLink( Instruction * instruction ) 2792 { 2793 m_inputLinks.removeAll( instruction ); 2794 } 2795 2796 2797 void Instruction::removeOutputLink( Instruction * instruction ) 2798 { 2799 m_outputLinks.removeAll( instruction ); 2800 } 2801 2802 2803 void Instruction::clearLinks() 2804 { 2805 m_inputLinks.clear(); 2806 m_outputLinks.clear(); 2807 } 2808 //END class Instruction 2809 2810 2811 2812 //BEGIN Byte-Oriented File Register Operations 2813 QString Instr_addwf::code() const 2814 { 2815 return QString("addwf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 2816 } 2817 2818 void Instr_addwf::generateLinksAndStates( Code::iterator current ) 2819 { 2820 m_outputState = m_inputState; 2821 2822 m_outputState.reg( outputReg() ).value = (m_inputState.working.value + m_inputState.reg( m_file ).value) & 0xff; 2823 m_outputState.reg( outputReg() ).known = ((m_inputState.working.known == 0xff) && (m_inputState.reg( m_file ).known == 0xff)) ? 0xff : 0x0; 2824 2825 m_outputState.status.known &= ~( (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z) ); 2826 2827 if ( m_file.type() != Register::PCL || m_dest == 0 ) 2828 { 2829 makeOutputLinks( current ); 2830 return; 2831 } 2832 2833 ++current; // Don't have a link to ourself 2834 2835 // maxInc is the greatest possibly value that we might have incremented the program counter by. 2836 // It is generated by ORing the known bits of the working register with the greatest value 2837 // of the unknown bits; 2838 uchar maxInc = m_inputState.working.maxValue(); 2839 if ( maxInc < 0xff ) 2840 maxInc++; 2841 // cout << "m_inputState.working.known="<<int(m_inputState.working.known)<<" maxInc="<<int(maxInc)<<'\n'; 2842 Code::iterator end = m_pCode->end(); 2843 for ( int i = 0; current != end && i < maxInc; ++i, ++current ) 2844 { 2845 (*current)->addInputLink( this ); 2846 // if ( i != maxInc-1 ) 2847 // (*current)->setPositionAffectsBranching( true ); 2848 } 2849 } 2850 2851 ProcessorBehaviour Instr_addwf::behaviour() const 2852 { 2853 ProcessorBehaviour behaviour; 2854 2855 // Depend on W and f 2856 behaviour.working.depends = 0xff; 2857 behaviour.reg( m_file ).depends = 0xff; 2858 2859 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 2860 behaviour.status.indep = (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z); 2861 return behaviour; 2862 } 2863 2864 2865 2866 QString Instr_andwf::code() const 2867 { 2868 return QString("andwf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 2869 } 2870 2871 void Instr_andwf::generateLinksAndStates( Code::iterator current ) 2872 { 2873 makeOutputLinks( current ); 2874 m_outputState = m_inputState; 2875 2876 uchar definiteOnes = m_inputState.reg( m_file ).definiteOnes() & m_outputState.working.definiteOnes(); 2877 m_outputState.reg( outputReg() ).value = definiteOnes; 2878 m_outputState.reg( outputReg() ).known = m_inputState.reg( m_file ).definiteZeros() | m_inputState.working.definiteZeros() | definiteOnes; 2879 2880 m_outputState.status.known &= ~(1 << RegisterBit::Z); 2881 } 2882 2883 ProcessorBehaviour Instr_andwf::behaviour() const 2884 { 2885 ProcessorBehaviour behaviour; 2886 2887 // Depend on W and f 2888 behaviour.working.depends = 0xff; 2889 behaviour.reg( m_file ).depends = 0xff; 2890 2891 if ( m_dest == 0 ) 2892 behaviour.working.indep = m_inputState.reg( m_file ).known & ~( m_inputState.reg( m_file ).value); 2893 2894 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 2895 behaviour.status.indep = (1 << RegisterBit::Z); 2896 return behaviour; 2897 } 2898 2899 2900 QString Instr_clrf::code() const 2901 { 2902 return QString("clrf\t%1").arg( m_file.name() ); 2903 } 2904 2905 void Instr_clrf::generateLinksAndStates( Code::iterator current ) 2906 { 2907 makeOutputLinks( current ); 2908 2909 m_outputState = m_inputState; 2910 m_outputState.reg( m_file ).known = 0xff; 2911 m_outputState.reg( m_file ).value = 0x0; 2912 2913 m_outputState.status.known |= (1 << RegisterBit::Z); 2914 m_outputState.status.value |= (1 << RegisterBit::Z); 2915 } 2916 2917 ProcessorBehaviour Instr_clrf::behaviour() const 2918 { 2919 ProcessorBehaviour behaviour; 2920 2921 behaviour.reg( m_file ).indep = 0xff; 2922 2923 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 2924 behaviour.status.indep = (1 << RegisterBit::Z); 2925 2926 return behaviour; 2927 } 2928 2929 2930 //TODO CLRW 2931 //TODO COMF 2932 2933 2934 QString Instr_decf::code() const 2935 { 2936 return QString("decf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 2937 } 2938 2939 void Instr_decf::generateLinksAndStates( Code::iterator current ) 2940 { 2941 makeOutputLinks( current ); 2942 2943 m_outputState = m_inputState; 2944 m_outputState.status.known &= ~(1 << RegisterBit::Z); 2945 2946 m_outputState.reg( outputReg() ).known = 0x0; 2947 } 2948 2949 ProcessorBehaviour Instr_decf::behaviour() const 2950 { 2951 ProcessorBehaviour behaviour; 2952 2953 behaviour.reg( m_file ).depends = 0xff; 2954 2955 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 2956 behaviour.status.indep = (1 << RegisterBit::Z); 2957 2958 return behaviour; 2959 } 2960 2961 2962 QString Instr_decfsz::code() const 2963 { 2964 return QString("decfsz\t%1,%2").arg( m_file.name() ).arg( m_dest ); 2965 } 2966 2967 void Instr_decfsz::generateLinksAndStates( Code::iterator current ) 2968 { 2969 makeOutputLinks( current, true, true ); 2970 2971 m_outputState = m_inputState; 2972 m_outputState.reg( outputReg() ).known = 0x0; 2973 } 2974 2975 ProcessorBehaviour Instr_decfsz::behaviour() const 2976 { 2977 ProcessorBehaviour behaviour; 2978 2979 behaviour.reg( m_file ).depends = 0xff; 2980 2981 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 2982 return behaviour; 2983 } 2984 2985 2986 QString Instr_incf::code() const 2987 { 2988 return QString("incf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 2989 } 2990 2991 void Instr_incf::generateLinksAndStates( Code::iterator current ) 2992 { 2993 makeOutputLinks( current ); 2994 2995 m_outputState = m_inputState; 2996 m_outputState.status.known &= ~(1 << RegisterBit::Z); 2997 2998 m_outputState.reg( outputReg() ).known = 0x0; 2999 } 3000 3001 ProcessorBehaviour Instr_incf::behaviour() const 3002 { 3003 ProcessorBehaviour behaviour; 3004 3005 behaviour.reg( m_file ).depends = 0xff; 3006 3007 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 3008 behaviour.status.indep = (1 << RegisterBit::Z); 3009 return behaviour; 3010 } 3011 3012 3013 //TODO INCFSZ 3014 3015 3016 QString Instr_iorwf::code() const 3017 { 3018 return QString("iorwf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 3019 } 3020 3021 void Instr_iorwf::generateLinksAndStates( Code::iterator current ) 3022 { 3023 makeOutputLinks( current ); 3024 3025 m_outputState = m_inputState; 3026 m_outputState.status.known &= ~(1 << RegisterBit::Z); 3027 3028 m_outputState.reg( outputReg() ).known = 0x0; 3029 } 3030 3031 ProcessorBehaviour Instr_iorwf::behaviour() const 3032 { 3033 ProcessorBehaviour behaviour; 3034 3035 // Depend on W and f 3036 behaviour.working.depends = 0xff; 3037 behaviour.reg( m_file ).depends = 0xff; 3038 3039 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 3040 behaviour.status.indep = (1 << RegisterBit::Z); 3041 return behaviour; 3042 } 3043 3044 3045 QString Instr_movf::code() const 3046 { 3047 return QString("movf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 3048 } 3049 3050 void Instr_movf::generateLinksAndStates( Code::iterator current ) 3051 { 3052 makeOutputLinks( current ); 3053 3054 m_outputState = m_inputState; 3055 3056 if ( m_inputState.reg( m_file ).known == 0xff ) 3057 { 3058 m_outputState.status.known |= (1 << RegisterBit::Z); 3059 bool isZero = (m_inputState.reg( m_file ).value == 0x0); 3060 if ( isZero ) 3061 m_outputState.status.value |= (1 << RegisterBit::Z); 3062 else 3063 m_outputState.status.value &= ~(1 << RegisterBit::Z); 3064 } 3065 else 3066 m_outputState.status.known &= ~(1 << RegisterBit::Z); 3067 3068 if ( m_dest == 0 ) 3069 { 3070 // Writing to the working register 3071 m_outputState.working.known = m_inputState.reg( m_file ).known; 3072 m_outputState.working.value = m_inputState.reg( m_file ).value; 3073 } 3074 } 3075 3076 ProcessorBehaviour Instr_movf::behaviour() const 3077 { 3078 ProcessorBehaviour behaviour; 3079 3080 if ( m_dest == 0 ) 3081 behaviour.working.indep = 0xff; 3082 3083 behaviour.reg( m_file ).depends = 0xff; 3084 3085 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 3086 behaviour.status.indep = (1 << RegisterBit::Z); 3087 return behaviour; 3088 } 3089 3090 3091 QString Instr_movwf::code() const 3092 { 3093 return QString("movwf\t%1").arg( m_file.name() ); 3094 } 3095 3096 void Instr_movwf::generateLinksAndStates( Code::iterator current ) 3097 { 3098 makeOutputLinks( current ); 3099 3100 m_outputState = m_inputState; 3101 m_outputState.reg( m_file ).known = m_inputState.working.known; 3102 m_outputState.reg( m_file ).value = m_inputState.working.value; 3103 } 3104 3105 ProcessorBehaviour Instr_movwf::behaviour() const 3106 { 3107 ProcessorBehaviour behaviour; 3108 3109 behaviour.reg( m_file ).indep = 0xff; 3110 behaviour.working.depends = 0xff; 3111 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 3112 3113 return behaviour; 3114 } 3115 3116 3117 //TODO NOP 3118 3119 3120 3121 QString Instr_rlf::code() const 3122 { 3123 return QString("rlf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 3124 } 3125 3126 void Instr_rlf::generateLinksAndStates( Code::iterator current ) 3127 { 3128 makeOutputLinks( current ); 3129 3130 m_outputState = m_inputState; 3131 m_outputState.status.known &= ~(1 << RegisterBit::C); 3132 3133 m_outputState.reg( outputReg() ).known = 0x0; 3134 } 3135 3136 ProcessorBehaviour Instr_rlf::behaviour() const 3137 { 3138 ProcessorBehaviour behaviour; 3139 3140 // Is the value written to W or f? 3141 if ( m_dest == 0 ) 3142 behaviour.working.indep = 0xff; 3143 3144 behaviour.reg( m_file ).depends = 0xff; 3145 3146 behaviour.status.depends = (1 << RegisterBit::C) | (m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0); 3147 behaviour.status.indep = (1 << RegisterBit::C); 3148 return behaviour; 3149 } 3150 3151 3152 QString Instr_rrf::code() const 3153 { 3154 return QString("rrf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 3155 } 3156 3157 void Instr_rrf::generateLinksAndStates( Code::iterator current ) 3158 { 3159 makeOutputLinks( current ); 3160 3161 m_outputState = m_inputState; 3162 m_outputState.status.known &= ~(1 << RegisterBit::C); 3163 3164 m_outputState.reg( outputReg() ).known = 0x0; 3165 } 3166 3167 ProcessorBehaviour Instr_rrf::behaviour() const 3168 { 3169 ProcessorBehaviour behaviour; 3170 3171 if ( m_dest == 0 ) 3172 behaviour.working.indep = 0xff; 3173 3174 behaviour.reg( m_file ).depends = 0xff; 3175 3176 behaviour.status.depends = (1 << RegisterBit::C) | (m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0); 3177 behaviour.status.indep = (1 << RegisterBit::C); 3178 return behaviour; 3179 } 3180 3181 3182 QString Instr_subwf::code() const 3183 { 3184 return QString("subwf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 3185 } 3186 3187 void Instr_subwf::generateLinksAndStates( Code::iterator current ) 3188 { 3189 makeOutputLinks( current ); 3190 3191 m_outputState = m_inputState; 3192 3193 if ( (m_inputState.working.known == 0xff) && (m_inputState.reg( m_file ).known == 0xff) ) 3194 { 3195 m_outputState.reg( outputReg() ).known = 0xff; 3196 m_outputState.reg( outputReg() ).value = (m_inputState.reg( m_file ).value - m_inputState.working.value) & 0xff; 3197 } 3198 else 3199 m_outputState.reg( outputReg() ).known = 0x0; 3200 3201 3202 m_outputState.status.known &= ~( (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z) ); 3203 3204 if ( m_inputState.working.minValue() > m_inputState.reg( m_file ).maxValue() ) 3205 { 3206 m_outputState.status.value &= ~(1 << RegisterBit::C); 3207 m_outputState.status.known |= (1 << RegisterBit::C); 3208 } 3209 else if ( m_inputState.working.maxValue() <= m_inputState.reg( m_file ).minValue() ) 3210 { 3211 m_outputState.status.value |= (1 << RegisterBit::C); 3212 m_outputState.status.known |= (1 << RegisterBit::C); 3213 } 3214 3215 if ( (m_inputState.working.known == 0xff) && (m_inputState.reg( m_file ).known == 0xff) ) 3216 { 3217 bool isZero = (m_inputState.working.value == m_inputState.reg( m_file ).value); 3218 if ( isZero ) 3219 m_outputState.status.value |= (1 << RegisterBit::Z); 3220 else 3221 m_outputState.status.value &= ~(1 << RegisterBit::Z); 3222 m_outputState.status.known |= (1 << RegisterBit::Z); 3223 } 3224 } 3225 3226 ProcessorBehaviour Instr_subwf::behaviour() const 3227 { 3228 ProcessorBehaviour behaviour; 3229 3230 // Depend on W and f 3231 behaviour.working.depends = 0xff; 3232 behaviour.reg( m_file ).depends = 0xff; 3233 3234 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 3235 behaviour.status.indep = (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z); 3236 return behaviour; 3237 } 3238 3239 3240 QString Instr_swapf::code() const 3241 { 3242 return QString("swapf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 3243 } 3244 3245 void Instr_swapf::generateLinksAndStates( Code::iterator current ) 3246 { 3247 makeOutputLinks( current ); 3248 3249 m_outputState = m_inputState; 3250 if ( m_dest == 0 ) 3251 { 3252 // Writing to the working register 3253 m_outputState.working.known = 0x0; 3254 } 3255 } 3256 3257 ProcessorBehaviour Instr_swapf::behaviour() const 3258 { 3259 ProcessorBehaviour behaviour; 3260 behaviour.reg( m_file ).depends = 0xff; 3261 behaviour.working.indep = ( m_dest == 0 ) ? 0xff : 0x0; 3262 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 3263 return behaviour; 3264 } 3265 3266 3267 QString Instr_xorwf::code() const 3268 { 3269 return QString("xorwf\t%1,%2").arg( m_file.name() ).arg( m_dest ); 3270 } 3271 3272 void Instr_xorwf::generateLinksAndStates( Code::iterator current ) 3273 { 3274 makeOutputLinks( current ); 3275 3276 m_outputState = m_inputState; 3277 m_outputState.status.known &= ~(1 << RegisterBit::Z); 3278 3279 m_outputState.reg( outputReg() ).known = 0x0; 3280 } 3281 3282 ProcessorBehaviour Instr_xorwf::behaviour() const 3283 { 3284 ProcessorBehaviour behaviour; 3285 3286 // Depend on W and f 3287 behaviour.working.depends = 0xff; 3288 behaviour.reg( m_file ).depends = 0xff; 3289 3290 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 3291 behaviour.status.indep = (1 << RegisterBit::Z); 3292 return behaviour; 3293 } 3294 //END Byte-Oriented File Register Operations 3295 3296 3297 3298 //BEGIN Bit-Oriented File Register Operations 3299 QString Instr_bcf::code() const 3300 { 3301 return QString("bcf\t\t%1,%2").arg( m_file.name() ).arg( m_bit.name() ); 3302 } 3303 3304 void Instr_bcf::generateLinksAndStates( Code::iterator current ) 3305 { 3306 makeOutputLinks( current ); 3307 3308 m_outputState = m_inputState; 3309 m_outputState.reg( m_file ).value &= ~uchar(1 << m_bit.bitPos()); 3310 m_outputState.reg( m_file ).known |= uchar(1 << m_bit.bitPos()); 3311 } 3312 3313 ProcessorBehaviour Instr_bcf::behaviour() const 3314 { 3315 ProcessorBehaviour behaviour; 3316 3317 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 3318 behaviour.reg( m_file ).indep = 1 << m_bit.bitPos(); 3319 return behaviour; 3320 } 3321 3322 3323 QString Instr_bsf::code() const 3324 { 3325 return QString("bsf\t\t%1,%2").arg( m_file.name() ).arg( m_bit.name() ); 3326 } 3327 3328 void Instr_bsf::generateLinksAndStates( Code::iterator current ) 3329 { 3330 makeOutputLinks( current ); 3331 3332 m_outputState = m_inputState; 3333 m_outputState.reg( m_file ).value |= uchar(1 << m_bit.bitPos()); 3334 m_outputState.reg( m_file ).known |= uchar(1 << m_bit.bitPos()); 3335 } 3336 3337 ProcessorBehaviour Instr_bsf::behaviour() const 3338 { 3339 ProcessorBehaviour behaviour; 3340 behaviour.status.depends = m_file.bankDependent() ? (1 << RegisterBit::RP0) : 0x0; 3341 behaviour.reg( m_file ).indep = 1 << m_bit.bitPos(); 3342 return behaviour; 3343 } 3344 3345 3346 QString Instr_btfsc::code() const 3347 { 3348 return QString("btfsc\t%1,%2").arg( m_file.name() ).arg( m_bit.name() ); 3349 } 3350 3351 void Instr_btfsc::generateLinksAndStates( Code::iterator current ) 3352 { 3353 m_outputState = m_inputState; 3354 3355 if ( m_inputState.reg( m_file ).known & (1 << m_bit.bitPos()) ) 3356 { 3357 bool bit = m_inputState.reg( m_file ).value & (1 << m_bit.bitPos()); 3358 makeOutputLinks( current, bit, !bit ); 3359 } 3360 else 3361 makeOutputLinks( current, true, true ); 3362 } 3363 3364 ProcessorBehaviour Instr_btfsc::behaviour() const 3365 { 3366 ProcessorBehaviour behaviour; 3367 behaviour.reg( m_file ).depends = 1 << m_bit.bitPos(); 3368 behaviour.status.depends = (m_file.type() == Register::STATUS) ? m_bit.bit() : 0x0; 3369 return behaviour; 3370 } 3371 3372 3373 QString Instr_btfss::code() const 3374 { 3375 return QString("btfss\t%1,%2").arg( m_file.name() ).arg( m_bit.name() ); 3376 } 3377 3378 void Instr_btfss::generateLinksAndStates( Code::iterator current ) 3379 { 3380 m_outputState = m_inputState; 3381 3382 if ( m_inputState.reg( m_file ).known & (1 << m_bit.bitPos()) ) 3383 { 3384 bool bit = m_inputState.reg( m_file ).value & (1 << m_bit.bitPos()); 3385 makeOutputLinks( current, !bit, bit ); 3386 } 3387 else 3388 makeOutputLinks( current, true, true ); 3389 } 3390 3391 ProcessorBehaviour Instr_btfss::behaviour() const 3392 { 3393 ProcessorBehaviour behaviour; 3394 behaviour.reg( m_file ).depends = 1 << m_bit.bitPos(); 3395 behaviour.status.depends = (m_file.type() == Register::STATUS) ? m_bit.bit() : 0x0; 3396 return behaviour; 3397 } 3398 //END Bit-Oriented File Register Operations 3399 3400 3401 3402 //BEGIN Literal and Control Operations 3403 QString Instr_addlw::code() const 3404 { 3405 return QString("addlw\t%1").arg( m_literal ); 3406 } 3407 3408 void Instr_addlw::generateLinksAndStates( Code::iterator current ) 3409 { 3410 makeOutputLinks( current ); 3411 3412 m_outputState = m_inputState; 3413 m_outputState.working.value = (m_inputState.working.value + m_literal) & 0xff; 3414 m_outputState.working.known = (m_inputState.working.known == 0xff) ? 0xff : 0x0; 3415 m_outputState.status.known &= ~( (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z) ); 3416 } 3417 3418 ProcessorBehaviour Instr_addlw::behaviour() const 3419 { 3420 ProcessorBehaviour behaviour; 3421 3422 behaviour.working.depends = 0xff; 3423 3424 behaviour.status.indep = (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z); 3425 3426 return behaviour; 3427 } 3428 3429 3430 QString Instr_andlw::code() const 3431 { 3432 return QString("andlw\t%1").arg( m_literal ); 3433 } 3434 3435 void Instr_andlw::generateLinksAndStates( Code::iterator current ) 3436 { 3437 makeOutputLinks( current ); 3438 3439 m_outputState = m_inputState; 3440 m_outputState.working.value = (m_inputState.working.value & m_literal) & 0xff; 3441 m_outputState.working.known |= ~m_literal; // Now know any bits that are zero in value 3442 m_outputState.status.known &= ~(1 << RegisterBit::Z); 3443 } 3444 3445 ProcessorBehaviour Instr_andlw::behaviour() const 3446 { 3447 ProcessorBehaviour behaviour; 3448 3449 behaviour.working.indep = ~m_literal; 3450 behaviour.working.depends = m_literal; 3451 3452 behaviour.status.indep = (1 << RegisterBit::Z); 3453 return behaviour; 3454 } 3455 3456 3457 QString Instr_call::code() const 3458 { 3459 return QString("call\t%1").arg( m_label ); 3460 } 3461 3462 void Instr_call::generateLinksAndStates( Code::iterator current ) 3463 { 3464 (void)current; 3465 makeLabelOutputLink( m_label ); 3466 3467 m_outputState = m_inputState; 3468 } 3469 3470 ProcessorBehaviour Instr_call::behaviour() const 3471 { 3472 ProcessorBehaviour behaviour; 3473 return behaviour; 3474 } 3475 3476 void Instr_call::makeReturnLinks( Instruction * next ) 3477 { 3478 m_pCode->setAllUnused(); 3479 linkReturns( m_pCode->instruction( m_label ), next ); 3480 } 3481 3482 3483 void Instr_call::linkReturns( Instruction * current, Instruction * returnPoint ) 3484 { 3485 while (true) 3486 { 3487 if ( !current || current->isUsed() ) 3488 return; 3489 3490 current->setUsed( true ); 3491 if ( dynamic_cast<Instr_return*>(current) || dynamic_cast<Instr_retlw*>(current) ) 3492 { 3493 // cout << "Added return link" << endl; 3494 // cout << " FROM: " << current->code() << endl; 3495 // cout << " TO: " << returnPoint->code() << endl; 3496 returnPoint->addInputLink( current ); 3497 return; 3498 } 3499 if ( dynamic_cast<Instr_call*>(current) ) 3500 { 3501 // Jump over the call instruction to its return point, 3502 // which will be the instruction after current. 3503 current = *(++m_pCode->find( current )); 3504 continue; 3505 } 3506 3507 const InstructionList outputs = current->outputLinks(); 3508 3509 if ( outputs.isEmpty() ) 3510 return; 3511 3512 if ( outputs.size() == 1 ) 3513 current = outputs.first(); 3514 3515 else 3516 { 3517 // Can't avoid function recursion now. 3518 InstructionList::const_iterator end = outputs.end(); 3519 for ( InstructionList::const_iterator it = outputs.begin(); it != end; ++it ) 3520 linkReturns( *it, returnPoint ); 3521 return; 3522 } 3523 }; 3524 } 3525 3526 3527 //TODO CLRWDT 3528 3529 3530 QString Instr_goto::code() const 3531 { 3532 return QString("goto\t%1").arg( m_label ); 3533 } 3534 3535 void Instr_goto::generateLinksAndStates( Code::iterator current ) 3536 { 3537 (void)current; 3538 3539 makeLabelOutputLink( m_label ); 3540 3541 m_outputState = m_inputState; 3542 } 3543 3544 ProcessorBehaviour Instr_goto::behaviour() const 3545 { 3546 ProcessorBehaviour behaviour; 3547 return behaviour; 3548 } 3549 3550 3551 QString Instr_iorlw::code() const 3552 { 3553 return QString("iorlw\t%1").arg( m_literal ); 3554 } 3555 3556 void Instr_iorlw::generateLinksAndStates( Code::iterator current ) 3557 { 3558 makeOutputLinks( current ); 3559 3560 m_outputState = m_inputState; 3561 m_outputState.working.value = (m_inputState.working.value | m_literal) & 0xff; 3562 m_outputState.working.known |= m_literal; // Now know any bits that are one in value 3563 m_outputState.status.known &= ~(1 << RegisterBit::Z); 3564 } 3565 3566 ProcessorBehaviour Instr_iorlw::behaviour() const 3567 { 3568 ProcessorBehaviour behaviour; 3569 3570 behaviour.working.indep = m_literal; 3571 behaviour.working.depends = ~m_literal; 3572 3573 behaviour.status.indep = (1 << RegisterBit::Z);; 3574 return behaviour; 3575 } 3576 3577 3578 QString Instr_movlw::code() const 3579 { 3580 return QString("movlw\t%1").arg( m_literal ); 3581 } 3582 3583 void Instr_movlw::generateLinksAndStates( Code::iterator current ) 3584 { 3585 makeOutputLinks( current ); 3586 m_outputState = m_inputState; 3587 m_outputState.working.known = 0xff; 3588 m_outputState.working.value = m_literal; 3589 } 3590 3591 ProcessorBehaviour Instr_movlw::behaviour() const 3592 { 3593 ProcessorBehaviour behaviour; 3594 behaviour.working.indep = 0xff; 3595 return behaviour; 3596 } 3597 3598 3599 QString Instr_retfie::code() const 3600 { 3601 return "retfie"; 3602 } 3603 3604 void Instr_retfie::generateLinksAndStates( Code::iterator current ) 3605 { 3606 // Don't generate any output links 3607 (void)current; 3608 3609 m_inputState = m_outputState; 3610 } 3611 3612 ProcessorBehaviour Instr_retfie::behaviour() const 3613 { 3614 ProcessorBehaviour behaviour; 3615 return behaviour; 3616 } 3617 3618 3619 QString Instr_retlw::code() const 3620 { 3621 return QString("retlw\t%1").arg( m_literal ); 3622 } 3623 3624 void Instr_retlw::generateLinksAndStates( Code::iterator current ) 3625 { 3626 (void)current; 3627 3628 m_outputState = m_inputState; 3629 m_outputState.working.known = 0xff; 3630 m_outputState.working.value = m_literal; 3631 } 3632 3633 ProcessorBehaviour Instr_retlw::behaviour() const 3634 { 3635 ProcessorBehaviour behaviour; 3636 behaviour.working.indep = 0xff; 3637 return behaviour; 3638 } 3639 3640 3641 3642 QString Instr_return::code() const 3643 { 3644 return "return"; 3645 } 3646 3647 void Instr_return::generateLinksAndStates( Code::iterator current ) 3648 { 3649 (void)current; 3650 3651 m_outputState = m_inputState; 3652 } 3653 3654 ProcessorBehaviour Instr_return::behaviour() const 3655 { 3656 ProcessorBehaviour behaviour; 3657 return behaviour; 3658 } 3659 3660 3661 QString Instr_sleep::code() const 3662 { 3663 return "sleep"; 3664 } 3665 3666 void Instr_sleep::generateLinksAndStates( Code::iterator current ) 3667 { 3668 // Don't generate any output links 3669 (void)current; 3670 3671 m_outputState = m_inputState; 3672 m_outputState.status.value &= ~(1 << RegisterBit::NOT_PD); 3673 m_outputState.status.value |= (1 << RegisterBit::NOT_TO); 3674 m_outputState.status.known |= (1 << RegisterBit::NOT_TO) | (1 << RegisterBit::NOT_PD); 3675 } 3676 3677 ProcessorBehaviour Instr_sleep::behaviour() const 3678 { 3679 ProcessorBehaviour behaviour; 3680 behaviour.status.indep = (1 << RegisterBit::NOT_TO) | (1 << RegisterBit::NOT_PD); 3681 return behaviour; 3682 } 3683 3684 3685 QString Instr_sublw::code() const 3686 { 3687 return QString("sublw\t%1").arg( m_literal ); 3688 } 3689 3690 void Instr_sublw::generateLinksAndStates( Code::iterator current ) 3691 { 3692 makeOutputLinks( current ); 3693 3694 m_outputState = m_inputState; 3695 m_outputState.working.value = (m_literal - m_inputState.working.value) & 0xff; 3696 m_outputState.working.known = (m_inputState.working.known == 0xff) ? 0xff : 0x00; 3697 m_outputState.status.known &= ~( (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z) ); 3698 3699 if ( m_inputState.working.minValue() > m_literal ) 3700 { 3701 m_outputState.status.value &= ~(1 << RegisterBit::C); 3702 m_outputState.status.known |= (1 << RegisterBit::C); 3703 } 3704 else if ( m_inputState.working.maxValue() <= m_literal ) 3705 { 3706 m_outputState.status.value |= (1 << RegisterBit::C); 3707 m_outputState.status.known |= (1 << RegisterBit::C); 3708 } 3709 3710 if ( m_inputState.working.known == 0xff ) 3711 { 3712 bool isZero = (m_inputState.working.value == m_literal); 3713 if ( isZero ) 3714 m_outputState.status.value |= (1 << RegisterBit::Z); 3715 else 3716 m_outputState.status.value &= ~(1 << RegisterBit::Z); 3717 m_outputState.status.known |= (1 << RegisterBit::Z); 3718 } 3719 } 3720 3721 ProcessorBehaviour Instr_sublw::behaviour() const 3722 { 3723 ProcessorBehaviour behaviour; 3724 behaviour.working.depends = 0xff; 3725 behaviour.status.indep = (1 << RegisterBit::C) | (1 << RegisterBit::DC) | (1 << RegisterBit::Z); 3726 return behaviour; 3727 } 3728 3729 3730 QString Instr_xorlw::code() const 3731 { 3732 return QString("xorlw\t%1").arg( m_literal ); 3733 } 3734 3735 void Instr_xorlw::generateLinksAndStates( Code::iterator current ) 3736 { 3737 makeOutputLinks( current ); 3738 m_outputState = m_inputState; 3739 m_outputState.working.value = (m_inputState.working.value ^ m_literal) & 0xff; 3740 m_outputState.working.known = m_inputState.working.known; 3741 m_outputState.status.known &= ~(1 << RegisterBit::Z); 3742 } 3743 3744 ProcessorBehaviour Instr_xorlw::behaviour() const 3745 { 3746 ProcessorBehaviour behaviour; 3747 behaviour.working.depends = 0xff; 3748 behaviour.status.indep = (1 << RegisterBit::Z); 3749 return behaviour; 3750 } 3751 //END Literal and Control Operations 3752 3753 3754 3755 //BEGIN MicrobeApp (non-assembly) Operations 3756 QString Instr_sourceCode::code() const 3757 { 3758 QStringList sourceLines = m_raw.split("\n", Qt::SkipEmptyParts); // QString::split("\n",m_raw); 3759 return ";" + sourceLines.join("\n;"); 3760 } 3761 3762 3763 QString Instr_asm::code() const 3764 { 3765 return "; asm {\n" + m_raw + "\n; }"; 3766 } 3767 3768 3769 QString Instr_raw::code() const 3770 { 3771 return m_raw; 3772 } 3773 //END MicrobeApp (non-assembly) Operations 3774