File indexing completed on 2024-04-21 05:43:18

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