1 /***************************************************************************
2  *   Copyright (C) 2004-2005 by Daniel Clarke <daniel.jc@gmail.com>        *
3  *                      2005 by David Saxton <david@bluehaze.org>          *
4  *									   *
5  *   24-04-2007                                                            *
6  *   Modified to add pic 16f877,16f627 and 16f628 			   *
7  *   by george john george@space-kerala.org 				   *
8  *   supported by SPACE www.space-kerala.org	 			   *
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  *   This program is distributed in the hope that it will be useful,       *
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  *   GNU General Public License for more details.                          *
19  *                                                                         *
20  *   You should have received a copy of the GNU General Public License     *
21  *   along with this program; if not, write to the                         *
22  *   Free Software Foundation, Inc.,                                       *
23  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  ***************************************************************************/
25 
26 #ifndef INSTRUCTION_H
27 #define INSTRUCTION_H
28 
29 #include <QMap>
30 #include <QString>
31 #include <QStringList>
32 #include <QList>
33 
34 class Code;
35 class CodeIterator;
36 class CodeConstIterator;
37 class Instruction;
38 class PIC14;
39 
40 typedef QList<Instruction*> InstructionList;
41 
42 
43 /**
44 Abstraction for a Register - should be used instead of a register name. Contains
45 info like whether or not the adressing of the register depends on the bank
46 selection.
47 
48 @author David Saxton
49 */
50 class Register
51 {
52 	public:
53 		enum Type
54 		{
55 			TMR0,
56 			OPTION_REG,
57 			PCL,
58 			STATUS,
59 			FSR,
60 			PORTA,
61 			TRISA,
62 			PORTB,
63 			TRISB,
64 			EEDATA,
65 			EECON1,
66 			EEADR,
67 			EECON2,
68 			PCLATH,
69 			INTCON,
70 //modification start
71 			PORTC,
72 			PORTD,
73 			PORTE,
74 			TRISC,
75 			TRISD,
76 			TRISE,
77 			ADCON0,
78 			ADCON1,
79 //modification end
80 			// The following three are "special"
81 			WORKING, // Not a register that is addressable by an address
82 			GPR, // Refers to the collection of General Purpose Registers
83 //modification start
84 			PIR1,
85 			PIR2,
86 			TMR1L,
87 			TMR1H,
88 			T1CON,
89 			TMR2,
90 			T2CON,
91 			RCSTA,
92 			TXREG,
93 			RCREG,
94 			ADRESH,
95 			PIE1,
96 			TXSTA,
97 			ADRESL,
98 			EEDATH,
99 			EEADRH,
100 			SSPBUF,
101 			SSPCON,
102 			CCPR1L,
103 			CCPR1H,
104 			CCP1CON,
105 			CCPR2L,
106 			CCPR2H,
107 			CCP2CON,
108 			PIE2,
109 			PCON,
110 			SSPCON2,
111 			PR2,
112 			SSPADD,
113 			SSPSTAT,
114 			SPBRG,
115 			VRCON,
116 			CMCON,
117 
118 //modification end
119 			none // used in default constructor
120 //TODO
121 //SSPBUF:SSPCON:CCPR1L:CCPR1H:CCP1CON:CCPR2L:CCPR2H:CCP2CON:--FOR BANK0
122 //PIE2:PCON:SSPCON2:PR2:SSPADD:SSPSTAT:SPBRG:--------FOR BANK1
123 		};
124 
125 		// These banks are used for ORing together in the banks() function
126 		enum Banks
127 		{
128 			Bank0 = 1 << 0,
129 			Bank1 = 1 << 1
130 		};
131 
132 		/**
133 		 * Creates a register of the given type, giving it the appropriate name.
134 		 * Note that this constructor should not be used for GPR.
135 		 */
136 		Register( Type type = none );
137 		/**
138 		 * Construct a Register with the given name. If the name is not
139 		 * recognized, then it is assumed to be a GPR register.
140 		 */
141 		Register( const QString & name );
142 		/**
143 		 * Construct a Register with the given name. If the name is not
144 		 * recognized, then it is assumed to be a GPR register.
145 		 */
146 		Register( const char * name );
147 		/**
148 		 * @return less-than-equality between registers; name is only compared
149 		 * if both registers have type GPR.
150 		 */
151 		bool operator < ( const Register & reg ) const;
152 		/**
153 		 * @return equality between registers; name is only compared if both
154 		 * registers have type GPR.
155 		 */
156 		bool operator == ( const Register & reg ) const;
157 		/**
158 		 * @return 0x1 and 0x2 for being addressable from banks 0 and 1
159 		 * respectively, OR'ed together.
160 		 */
161 		uchar banks() const;
162 		/**
163 		 * Convenience function.
164 		 * @see banks
165 		 */
166 		bool bankDependent() const;
167 		/**
168 		 * Returns the name of the register, or the alias for the GPR.
169 		 */
name()170 		QString name() const { return m_name; }
171 		/**
172 		 * @return the type of register.
173 		 */
type()174 		Type type() const { return m_type; }
175 		/**
176 		 * From the Optimizer's perspective, it is OK to remove, change or add
177 		 * any instruction so long as there are no visible external changes that
178 		 * go against the original intention of the microbe source (a general
179 		 * guiding principle). Therefore, this function returns true for PORT
180 		 * and TRIS registers, false for everything else.
181 		 */
182 		bool affectsExternal() const;
183 
184 	protected:
185 		QString m_name;
186 		Type m_type;
187 };
188 
189 
190 
191 class RegisterBit
192 {
193 	public:
194 		enum STATUS_bits
195 		{
196 			C			= 0, // Carry
197 			DC			= 1, // Digit carry
198 			Z			= 2, // Zero
199 			NOT_PD		= 3, // Power-down
200 			NOT_TO		= 4, // Time-out
201 			RP0			= 5, // Bank Select
202 			RP1			= 6,
203 			IRP			= 7
204 		};
205 
206 		enum INTCON_bits
207 		{
208 			RBIF		= 0,
209 			INTF		= 1,
210 			T0IF		= 2,
211 			RBIE		= 3,
212 			INTE		= 4,
213 			T0IE		= 5,
214 			EEIE		= 6,
215 			GIE		= 7
216 		};
217 
218 		enum OPTION_bits
219 		{
220 			PS0		= 0,
221 			PS1		= 1,
222 			PS2		= 2,
223 			PSA		= 3,
224 			T0SE		= 4,
225 			T0CS		= 5,
226 			INTEDG		= 6,
227 			NOT_RBPU	= 7
228 		};
229 
230 		enum EECON1_bits
231 		{
232 			RD		= 0,
233 			WR		= 1,
234 			WREN		= 2,
235 			WRERR		= 3,
236 			EEIF		= 4,
237 			EEPGD           = 7
238 		};
239 		/**
240 		 * Constructs a bit of the given register type at the given position.
241 		 */
242 		RegisterBit( uchar bitPos = 0, Register::Type reg = Register::none );
243 		/**
244 		 * Construct a register bit with the given name.
245 		 */
246 		RegisterBit( const QString & name );
247 		/**
248 		 * Construct a register bit with the given name.
249 		 */
250 		RegisterBit( const char * name );
251 		/**
252 		 * @warning do not trust this value! actually, this function should be
253 		 * removed, or the constructors fixed so that this value can be trusted.
254 		 * @return the register type that the bit belongs to.
255 		 */
registerType()256 		Register::Type registerType() const { return m_registerType; }
257 		/**
258 		 * @return the position of the bit, e.g. "5" for RP0.
259 		 */
bitPos()260 		uchar bitPos() const { return m_bitPos; }
261 		/**
262 		 * @return the bit, e.g. "0x20" for Z.
263 		 */
bit()264 		uchar bit() const { return (1 << m_bitPos); }
265 		/**
266 		 * @return the name of the bit, e.g. "Z" for Z.
267 		 */
name()268 		QString name() const { return m_name; }
269 
270 
271 	protected:
272 		/**
273 		 * Determines the register type and bit pos from the bit name (m_name).
274 		 */
275 		void initFromName();
276 
277 		Register::Type m_registerType;
278 		uchar m_bitPos:3;
279 		QString m_name;
280 };
281 
282 
283 
284 
285 /**
286 Contains information on the state of a register before an instruction is
287 executed.
288 
289 Note that all the "uchar" values in this class should be considered as the 8
290 bits of a register. So for example, if known=0x2, then only the second bit of
291 the register is known, and its value is given in the second bit of value.
292 
293 @author David Saxton
294 */
295 class RegisterState
296 {
297 	public:
298 		RegisterState();
299 
300 		/**
301 		 * Merges the known and values together, (possibly) reducing what is
302 		 * known.
303 		 */
304 		void merge( const RegisterState & state );
305 		/**
306 		 * Sets known to unknown and value to zero.
307 		 */
308 		void reset();
309 		/**
310 		 * Returns the bits that are definitely zero.
311 		 */
definiteZeros()312 		uchar definiteZeros() const { return (~value) & known; }
313 		/**
314 		 * Returns the bits that are definitely one.
315 		 */
definiteOnes()316 		uchar definiteOnes() const { return value & known; }
317 		/**
318 		 * Returns the bits that are unknown.
319 		 */
unknown()320 		uchar unknown() const { return ~known; }
321 		/**
322 		 * @return the largest possible value that this register might be
323 		 * storing, based on which bits are known and the value of those bits.
324 		 */
maxValue()325 		uchar maxValue() const { return (value & known) | (~known); }
326 		/**
327 		 * @return the smallest possible value that this register might be
328 		 * storing, based on which bits are known and the value of those bits.
329 		 */
minValue()330 		uchar minValue() const { return (value & known); }
331 		/**
332 		 * @return whether the known and value uchars are equal
333 		 */
334 		bool operator == ( const RegisterState & state ) const;
335 		/**
336 		 * @return whether either of the known and value uchars are not equal.
337 		 */
338 		bool operator != ( const RegisterState & state ) const { return !( *this == state ); }
339 		/**
340 		 * Prints known and value.
341 		 */
342 		void print();
343 
344 		/// Whether or not the value is known (for each bit).
345 		uchar known;
346 
347 		/// The value of the register.
348 		uchar value;
349 };
350 
351 
352 /**
353 Setting and dependency information for register bits. See the respective member
354 descriptions for more information.
355 
356 @author David Saxton
357 */
358 class RegisterBehaviour
359 {
360 	public:
361 		RegisterBehaviour();
362 		/**
363 		 * Sets "depends", "indep" and "changes" to 0x0.
364 		 */
365 		void reset();
366 
367 		/**
368 		 * The bits whose value before the instruction is executed will affect
369 		 * the processor state after execution. So for example,
370 		 *   in MOVLW this will be 0x0;
371 		 *   in ANDLW this will be the bits that are non-zero in the literal;
372 		 *   in BTFSC this will be the bit being tested (if this is the register
373 		 *      being tested).
374 		 */
375 		uchar depends;
376 
377 		/**
378 		 * The bits whose value after the instruction is executed is independent
379 		 * of the value before execution. So for example,
380 		 *   in MOVLW, this will be 0xff;
381 		 *   in ANDLW this will be the bits that are zero in the literal;
382 		 *   in BTFSC this will be 0x0.
383 		 */
384 		uchar indep;
385 };
386 
387 
388 
389 /**
390 Contains information on the state of a processor; e.g. register values
391 
392 @author David Saxton
393  */
394 class ProcessorState
395 {
396 	public:
397 		ProcessorState();
398 		/**
399 		 * Calls merge for each RegisterState.
400 		 */
401 		void merge( const ProcessorState & state );
402 		/**
403 		 * Calls reset() for each RegisterState.
404 		 */
405 		void reset();
406 		/**
407 		 * @return state for the given register.
408 		 */
409 		RegisterState & reg( const Register & reg );
410 		/**
411 		 * @return state for the given register.
412 		 */
413 		RegisterState reg( const Register & reg ) const;
414 		/**
415 		 * @return whether all the RegisterStates are identical
416 		 */
417 		bool operator == ( const ProcessorState & state ) const;
418 		/**
419 		 * @return whether any of the RegisterStates are not equal.
420 		 */
421 		bool operator != ( const ProcessorState & state ) const { return !( *this == state ); }
422 		/**
423 		 * Displays each register's name and calls RegisterState::print in turn.
424 		 */
425 		void print();
426 
427 		/// The working register
428 		RegisterState working;
429 
430 		/// The status register
431 		RegisterState status;
432 
433 	protected:
434 		typedef QMap< Register, RegisterState > RegisterMap;
435 		/**
436 		 * All registers other than working and status. Entries are created on
437 		 * calls to reg with a new Register.
438 		 */
439 		RegisterMap m_registers;
440 };
441 
442 
443 /**
444 Contains behavioural information for each register.
445 
446 @author David Saxton
447 */
448 class ProcessorBehaviour
449 {
450 	public:
451 		ProcessorBehaviour();
452 		/**
453 		 * Calls reset() for each RegisterBehaviour.
454 		 */
455 		void reset();
456 		/**
457 		 * @return behaviour for the given register.
458 		 */
459 		RegisterBehaviour & reg( const Register & reg );
460 
461 		/// The working register
462 		RegisterBehaviour working;
463 
464 		/// The status register
465 		RegisterBehaviour status;
466 
467 	protected:
468 		typedef QMap< Register, RegisterBehaviour > RegisterMap;
469 		/**
470 		 * All registers other than working and status. Entries are created on
471 		 * calls to reg with a new Register.
472 		 */
473 		RegisterMap m_registers;
474 };
475 
476 
477 /**
478 Contains information on whether a register is overwritten before its value is
479 used. Each uchar respresents the 8 bits of the register; if the bit is 1, then
480 the corresponding bit of the register is used by the Instruction or one
481 of its outputs before it is overwritten.
482 
483 @author David Saxton
484 */
485 class RegisterDepends
486 {
487 	public:
488 		RegisterDepends();
489 		/**
490 		 * Sets all the depends values to 0x0.
491 		 */
492 		void reset();
493 		/**
494 		 * @return behaviour for the given register.
495 		 */
496 		uchar & reg( const Register & reg );
497 
498 		/// The working register
499 		uchar working;
500 
501 		/// The status register
502 		uchar status;
503 
504 	protected:
505 		typedef QMap< Register, uchar > RegisterMap;
506 		/**
507 		 * All registers other than working and status. Entries are created on
508 		 * calls to reg with a new Register.
509 		 */
510 		RegisterMap m_registers;
511 };
512 
513 
514 
515 /**
516 Holds a program structure; an (ordered) list of blocks of code, each of which
517 contains a list of instructions. The structure is such as to provide easy
518 manipulation of the program, as well as aiding the optimizer.
519 
520 @author David Saxton
521 */
522 class Code
523 {
524 	public:
525 		Code();
526 
527 		typedef CodeIterator iterator;
528 		typedef CodeConstIterator const_iterator;
529 
530 		enum InstructionPosition
531 		{
532 			InterruptHandler	= 0,
533 			LookupTable			= 1,
534 			Middle				= 2, ///< Used for main code
535 			Subroutine			= 3, ///< Used for subroutines
536 
537 			PositionCount		= 4 ///< This must remain the last item and be the number of valid positions
538 		};
539 
540 		CodeIterator begin();
541 		CodeIterator end();
542 		CodeConstIterator begin() const;
543 		CodeConstIterator end() const;
544 
545 		/**
546 		 * Queues a label to be given to the next instruction to be added in the
547 		 * given position
548 		 */
549 		void queueLabel( const QString & label, InstructionPosition position = Middle );
550 		/**
551 		 * Returns the list of queued labels for the given position. This is
552 		 * used in merging code, as we also need to merge any queued labels.
553 		 */
queuedLabels(InstructionPosition position)554 		QStringList queuedLabels( InstructionPosition position ) const { return m_queuedLabels[position]; }
555 		/**
556 		 * Adds the Instruction at the given position.
557 		 */
558 		void append( Instruction * instruction, InstructionPosition position = Middle );
559 		/**
560 		 * @returns the Instruction with the given label (or null if no such
561 		 * Instruction).
562 		 */
563 		Instruction * instruction( const QString & label ) const;
564 		/**
565 		 * Look for an Assembly instruction (other types are ignored).
566 		 * @return an iterator to the current instruction, or end if it wasn't
567 		 * found.
568 		 */
569 		iterator find( Instruction * instruction );
570 		/**
571 		 * Removes the Instruction (regardless of position).
572 		 * @warning You should always use only this function to remove an
573 		 * instruction as this function handles stuff such as pushing labels
574 		 * from this instruction onto the next before deletion.
575 		 */
576 		void removeInstruction( Instruction * instruction );
577 		/**
578 		 * Merges all the blocks output together with other magic such as adding
579 		 * variables, gpasm directives, etc.
580 		 */
581 		QString generateCode( PIC14 * pic ) const;
582 		/**
583 		 * Appends the InstructionLists to the end of the ones in this instance.
584 		 * @param middleInsertionPosition is the position where the middle code
585 		 * blocks of the given code will be merged at.
586 		 */
587 		void merge( Code * code, InstructionPosition middleInsertionPosition = Middle );
588 		/**
589 		 * @returns the InstructionList for the given insertion position.
590 		 */
instructionList(InstructionPosition position)591 		InstructionList * instructionList( InstructionPosition position ) { return & m_instructionLists[position]; }
592 		/**
593 		 * @returns the InstructionList for the given insertion position.
594 		 */
instructionList(InstructionPosition position)595 		const InstructionList * instructionList( InstructionPosition position ) const { return & m_instructionLists[position]; }
596 		/**
597 		 * Calls generateOutputLinks for each Instruction
598 		 */
599 		void generateLinksAndStates();
600 		/**
601 		 * Calls setUsed(false) for all instructions.
602 		 */
603 		void setAllUnused();
604 		/**
605 		 * Does any work that is needed to the code before it can be passed to
606 		 * the optimizer (such as flushing out queued labels). This is called
607 		 * after all the instructions have been added to the code.
608 		 */
609 		void postCompileConstruct();
610 
611 	protected:
612 		/**
613 		 * Used when generating the code. Finds the list of general purpose
614 		 * registers that are referenced and returns their aliases.
615 		 */
616 		QStringList findVariables() const;
617 
618 		InstructionList m_instructionLists[ PositionCount ]; ///< @see InstructionPosition
619 		QStringList m_queuedLabels[ PositionCount ]; ///< @see InstructionPosition
620 
621 	private: // Disable copy constructor and operator=
622 		Code( const Code & );
623 		Code &operator=( const Code & );
624 };
625 
626 
627 /**
628 Iterates over all the instructions, going seamlessly between the different lists
629 and avoiding the non-assembly instructions.
630 
631 @author David Saxton
632  */
633 class CodeIterator
634 {
635 	public:
636 		bool operator != ( const CodeIterator & i ) const { return it != i.it; }
637 		bool operator == ( const CodeIterator & i ) const { return it == i.it; }
638 		CodeIterator & operator ++ ();
639 		Instruction * & operator * () { return *it; }
640 		/**
641 		 * Deletes the instruction that this iterator is currently pointing at
642 		 * (removing it from any lists), and increments the iterator to the next
643 		 * instruction.
644 		 */
645 		CodeIterator & removeAndIncrement();
646 		/**
647 		 * Inserts the given instruction before the instruction pointed at by
648 		 * this iterator.
649 		 */
650 		void insertBefore( Instruction * ins );
651 
652 		InstructionList::iterator it;
653 		InstructionList::iterator listEnd;
654 		Code::InstructionPosition pos;
655 		Code * code;
656 		InstructionList * list;
657 };
658 
659 
660 /**
661 A const version of CodeIterator (cannot change instructions).
662 
663 @author David Saxton
664  */
665 class CodeConstIterator
666 {
667 	public:
668 		bool operator != ( const CodeConstIterator & i ) const { return it != i.it; }
669 		bool operator == ( const CodeConstIterator & i ) const { return it == i.it; }
670 		CodeConstIterator & operator ++ ();
671 		const Instruction * operator * () const { return *it; }
672 
673 		InstructionList::const_iterator it;
674 		InstructionList::const_iterator listEnd;
675 		Code::InstructionPosition pos;
676 		const Code * code;
677 		const InstructionList * list;
678 };
679 
680 
681 /**
682 @author Daniel Clarke
683 @author David Saxton
684 */
685 class Instruction
686 {
687 	public:
688 		enum InstructionType
689 		{
690 			Assembly,
691 			Raw, // User-inserted assembly
692 			Comment
693 		};
694 		/**
695 		 * Used in optimization. Note that this follows roughly, but not
696 		 * exactly, the Microchip classifications of similar categories.
697 		 */
698 		enum AssemblyType
699 		{
700 			/**
701 			 * Writes to a file (which can be obtained by calling outputReg().
702 			 */
703 			FileOriented,
704 
705 			/**
706 			 * Writes to a file bit (so BCF or BSF).
707 			 */
708 			BitOriented,
709 
710 			/**
711 			 * Affects the working register via a literal operation, with no
712 			 * branching (so excludes retlw).
713 			 */
714 			WorkingOriented,
715 
716 			/**
717 			 * Assembly instructions that don't come under the above categories
718 			 * (so control and branching instructions).
719 			 */
720 			Other,
721 
722 			/**
723 			 * The Instruction is not of Assembly InstructionType.
724 			 */
725 			None
726 		};
727 
728 		Instruction();
729 		virtual ~Instruction();
setCode(Code * code)730 		void setCode( Code * code ) { m_pCode = code; }
731 
732 		/**
733 		 * This is used to decide how to output the instruction, and which
734 		 * instructions to avoid while optimizing.
735 		 */
type()736 		virtual InstructionType type() const { return Assembly; }
737 		/**
738 		 * @return the AssemblyType (None for non-Assembly instructions).
739 		 */
740 		virtual AssemblyType assemblyType() const = 0;
741 		/**
742 		 * The text to output to the generated assembly.
743 		 */
744 		virtual QString code() const = 0;
745 		/**
746 		 * The input processor state is used to generate the outputlinks and the
747 		 * output processor state.
748 		 */
setInputState(const ProcessorState & processorState)749 		void setInputState( const ProcessorState & processorState ) { m_inputState = processorState; }
750 		/**
751 		 * By using the ProcessorState, the Instruction should:
752 		 * * Find all instructions that could be executed after this instruction.
753 		 * * Generate the output ProcessorState.
754 		 * The default behaviour of this function is to link to the next
755 		 * sequential instruction, and to generate an unknown ProcessorState.
756 		 * @warning if your instruction depends on any bits, then it must
757 		 * reinherit this function and say so.
758 		 * @param instruction points at this instruction
759 		 */
760 		virtual void generateLinksAndStates( Code::iterator instruction );
761 		/**
762 		 * @return the processor behaviour for this instruction.
763 		 */
764 		virtual ProcessorBehaviour behaviour() const;
765 		/**
766 		 * An input link is an instruction that might be executed immediately
767 		 * before this Instruction.
768 		 */
769 		void addInputLink( Instruction * inputLink );
770 		/**
771 		 * An output link is an instruction that might be executed immediately
772 		 * after this Instruction.
773 		 */
774 		void addOutputLink( Instruction * inputLink );
775 		/**
776 		 * The list of instructions that might be executed immediately before
777 		 * this instruction.
778 		 * @see addInputLink
779 		 */
inputLinks()780 		InstructionList inputLinks() const { return m_inputLinks; }
781 		/**
782 		 * The list of instructions that might be executed immediately after
783 		 * this instruction. Instruction does not generate these links; instead
784 		 * the list is generated Code::generateLinksAndStates function.
785 		 */
outputLinks()786 		InstructionList outputLinks() const { return m_outputLinks; }
787 		/**
788 		 * Remove the given input link from the instruction.
789 		 */
790 		void removeInputLink( Instruction * ins );
791 		/**
792 		 * Remove the given output link from the instruction.
793 		 */
794 		void removeOutputLink( Instruction * ins );
795 		/**
796 		 * Clears all input and output links from this instruction. This does
797 		 * not remove references to this instruction from other instructions.
798 		 */
799 		void clearLinks();
800 		/**
801 		 * An instruction may have zero, or more than zero labels associated
802 		 * with it - these will be printed before the instruction in the
803 		 * assembly output.
804 		 */
labels()805 		QStringList labels() const { return m_labels; }
806 		/**
807 		 * @see labels
808 		 */
809 		void addLabels( const QStringList & labels );
810 		/**
811 		 * @see labels
812 		 */
813 		void setLabels( const QStringList & labels );
814 		/**
815 		 * @see used
816 		 */
setUsed(bool used)817 		void setUsed( bool used ) { m_bUsed = used; }
818 		/**
819 		 * Used for optimization purposes in determining whether the instruction
820 		 * has been examined yet (to avoid infinite loops).
821 		 */
isUsed()822 		bool isUsed() const { return m_bUsed; }
823 		/**
824 		 * Set by the optimizer to indicate whether this instruction or any of
825 		 * its outputs overwrite any of the bits of the given register.
826 		 */
setRegisterDepends(uchar depends,const Register & reg)827 		void setRegisterDepends( uchar depends, const Register & reg ) { m_registerDepends.reg(reg) = depends; }
828 		/**
829 		 * @see setOutputsOverwriteWorking
830 		 */
registerDepends(const Register & reg)831 		uchar registerDepends( const Register & reg ) { return m_registerDepends.reg(reg); }
832 		/**
833 		 * Resets the overwrites.
834 		 */
resetRegisterDepends()835 		void resetRegisterDepends() { m_registerDepends.reset(); }
836 		/**
837 		 * @return the input processor state to this instruction.
838 		 * @see setInputState
839 		 */
inputState()840 		ProcessorState inputState() const { return m_inputState; }
841 		/**
842 		 * @return the output processor state from this instruction.
843 		 * @see generateLinksAndStates.
844 		 */
outputState()845 		ProcessorState outputState() const { return m_outputState; }
846 		/**
847 		 * Only applicable to Instructions that refer to a file.
848 		 */
file()849 		Register file() const { return m_file; }
850 		/**
851 		 * Only applicable to Instructions that refer to a bit (such as BCF).
852 		 */
bit()853 		RegisterBit bit() const { return m_bit; }
854 		/**
855 		 * Only applicable to instructions that refer to a literal (such as
856 		 * XORLW).
857 		 */
literal()858 		uchar literal() const { return m_literal; }
859 		/**
860 		 * Applicable only to instructions that save a result to working or file
861 		 * depending on the destination bit.
862 		 */
outputReg()863 		Register outputReg() const { return (m_dest == 0) ? Register::WORKING : m_file; }
864 		/**
865 		 * Applicable only to instructions that use the destination flag.
866 		 */
dest()867 		unsigned dest() const { return m_dest; }
868 
869 	protected:
870 		/**
871 		 * This function is provided for convenience; it creates links to the
872 		 * first or second instructions after this one, depending on the value
873 		 * of firstOutput and secondOutput.
874 		 * @see generateOutputLinks
875 		 */
876 		void makeOutputLinks( Code::iterator current, bool firstOutput = true, bool secondOutput = false );
877 		/**
878 		 * This function is provided for instructions that jump to a label (i.e.
879 		 * call and goto).
880 		 */
881 		void makeLabelOutputLink( const QString & label );
882 
883 		RegisterDepends m_registerDepends;
884 		bool m_bInputStateChanged;
885 		bool m_bUsed;
886 		bool m_bPositionAffectsBranching;
887 		InstructionList m_inputLinks;
888 		InstructionList m_outputLinks;
889 		QStringList m_labels;
890 		Code * m_pCode;
891 
892 		// Commonly needed member variables for assembly instructions
893 		Register m_file;
894 		RegisterBit m_bit;
895 		QString m_raw; // Used by source code, raw asm, etc
896 		uchar m_literal;
897 		unsigned m_dest:1; // is 0 (W) or 1 (file).
898 		ProcessorState m_inputState;
899 		ProcessorState m_outputState;
900 
901 	private: // Disable copy constructor and operator=
902 		Instruction( const Instruction & );
903 		Instruction &operator=( const Instruction & );
904 };
905 
906 
907 
908 //BEGIN Byte-Oriented File Register Operations
909 class Instr_addwf : public Instruction
910 {
911 	public:
Instr_addwf(const Register & file,int dest)912 		Instr_addwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
913 		QString code() const override;
914 		void generateLinksAndStates( Code::iterator current ) override;
915 		ProcessorBehaviour behaviour() const override;
assemblyType()916 		AssemblyType assemblyType() const override { return FileOriented; }
917 };
918 
919 
920 class Instr_andwf : public Instruction
921 {
922 	public:
Instr_andwf(const Register & file,int dest)923 		Instr_andwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
924 		QString code() const override;
925 		void generateLinksAndStates( Code::iterator current ) override;
926 		ProcessorBehaviour behaviour() const override;
assemblyType()927 		AssemblyType assemblyType() const override { return FileOriented; }
928 };
929 
930 
931 class Instr_clrf : public Instruction
932 {
933 	public:
Instr_clrf(const Register & file)934 		Instr_clrf( const Register & file ) { m_file = file; m_dest = 1; }
935 		QString code() const override;
936 		void generateLinksAndStates( Code::iterator current ) override;
937 		ProcessorBehaviour behaviour() const override;
assemblyType()938 		AssemblyType assemblyType() const override { return FileOriented; }
939 };
940 
941 
942 //TODO CLRW
943 //TODO COMF
944 
945 
946 class Instr_decf : public Instruction
947 {
948 	public:
Instr_decf(const Register & file,int dest)949 		Instr_decf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
950 		QString code() const override;
951 		void generateLinksAndStates( Code::iterator current ) override;
952 		ProcessorBehaviour behaviour() const override;
assemblyType()953 		AssemblyType assemblyType() const override { return FileOriented; }
954 };
955 
956 
957 class Instr_decfsz : public Instruction
958 {
959 	public:
Instr_decfsz(const Register & file,int dest)960 		Instr_decfsz( const Register & file, int dest ) { m_file = file; m_dest = dest; }
961 		QString code() const override;
962 		void generateLinksAndStates( Code::iterator current ) override;
963 		ProcessorBehaviour behaviour() const override;
assemblyType()964 		AssemblyType assemblyType() const override { return FileOriented; }
965 };
966 
967 
968 class Instr_incf : public Instruction
969 {
970 	public:
Instr_incf(const Register & file,int dest)971 		Instr_incf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
972 		QString code() const override;
973 		void generateLinksAndStates( Code::iterator current ) override;
974 		ProcessorBehaviour behaviour() const override;
assemblyType()975 		AssemblyType assemblyType() const override { return FileOriented; }
976 };
977 
978 
979 //TODO INCFSZ
980 
981 
982 class Instr_iorwf : public Instruction
983 {
984 	public:
Instr_iorwf(const Register & file,int dest)985 		Instr_iorwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
986 		QString code() const override;
987 		void generateLinksAndStates( Code::iterator current ) override;
988 		ProcessorBehaviour behaviour() const override;
assemblyType()989 		AssemblyType assemblyType() const override { return FileOriented; }
990 };
991 
992 
993 class Instr_movf : public Instruction
994 {
995 	public:
Instr_movf(const Register & file,int dest)996 		Instr_movf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
997 		QString code() const override;
998 		void generateLinksAndStates( Code::iterator current ) override;
999 		ProcessorBehaviour behaviour() const override;
assemblyType()1000 		AssemblyType assemblyType() const override { return FileOriented; }
1001 };
1002 
1003 
1004 class Instr_movwf : public Instruction
1005 {
1006 	public:
Instr_movwf(const Register & file)1007 		Instr_movwf( const Register & file ) { m_file = file; m_dest = 1; }
1008 		QString code() const override;
1009 		void generateLinksAndStates( Code::iterator current ) override;
1010 		ProcessorBehaviour behaviour() const override;
assemblyType()1011 		AssemblyType assemblyType() const override { return FileOriented; }
1012 };
1013 
1014 
1015 //TODO NOP
1016 
1017 
1018 class Instr_rlf : public Instruction
1019 {
1020 	public:
Instr_rlf(const Register & file,int dest)1021 		Instr_rlf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
1022 		QString code() const override;
1023 		void generateLinksAndStates( Code::iterator current ) override;
1024 		ProcessorBehaviour behaviour() const override;
assemblyType()1025 		AssemblyType assemblyType() const override { return FileOriented; }
1026 };
1027 
1028 
1029 class Instr_rrf : public Instruction
1030 {
1031 	public:
Instr_rrf(const Register & file,int dest)1032 		Instr_rrf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
1033 		QString code() const override;
1034 		void generateLinksAndStates( Code::iterator current ) override;
1035 		ProcessorBehaviour behaviour() const override;
assemblyType()1036 		AssemblyType assemblyType() const override { return FileOriented; }
1037 };
1038 
1039 
1040 class Instr_subwf : public Instruction
1041 {
1042 	public:
Instr_subwf(const Register & file,int dest)1043 		Instr_subwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
1044 		QString code() const override;
1045 		void generateLinksAndStates( Code::iterator current ) override;
1046 		ProcessorBehaviour behaviour() const override;
assemblyType()1047 		AssemblyType assemblyType() const override { return FileOriented; }
1048 };
1049 
1050 
1051 class Instr_swapf : public Instruction
1052 {
1053 	public:
Instr_swapf(const Register & file,int dest)1054 		Instr_swapf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
1055 		QString code() const override;
1056 		void generateLinksAndStates( Code::iterator current ) override;
1057 		ProcessorBehaviour behaviour() const override;
assemblyType()1058 		AssemblyType assemblyType() const override { return FileOriented; }
1059 };
1060 
1061 
1062 class Instr_xorwf : public Instruction
1063 {
1064 	public:
Instr_xorwf(const Register & file,int dest)1065 		Instr_xorwf( const Register & file, int dest ) { m_file = file; m_dest = dest; }
1066 		QString code() const override;
1067 		void generateLinksAndStates( Code::iterator current ) override;
1068 		ProcessorBehaviour behaviour() const override;
assemblyType()1069 		AssemblyType assemblyType() const override { return FileOriented; }
1070 };
1071 //END Byte-Oriented File Register Operations
1072 
1073 
1074 
1075 //BEGIN Bit-Oriented File Register Operations
1076 class Instr_bcf : public Instruction
1077 {
1078 	public:
Instr_bcf(const Register & file,const RegisterBit & bit)1079 		Instr_bcf( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
1080 		QString code() const override;
1081 		void generateLinksAndStates( Code::iterator current ) override;
1082 		ProcessorBehaviour behaviour() const override;
assemblyType()1083 		AssemblyType assemblyType() const override { return BitOriented; }
1084 };
1085 
1086 
1087 class Instr_bsf : public Instruction
1088 {
1089 	public:
Instr_bsf(const Register & file,const RegisterBit & bit)1090 		Instr_bsf( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
1091 		QString code() const override;
1092 		void generateLinksAndStates( Code::iterator current ) override;
1093 		ProcessorBehaviour behaviour() const override;
assemblyType()1094 		AssemblyType assemblyType() const override { return BitOriented; }
1095 };
1096 
1097 
1098 class Instr_btfsc : public Instruction
1099 {
1100 	public:
Instr_btfsc(const Register & file,const RegisterBit & bit)1101 		Instr_btfsc( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
1102 		QString code() const override;
1103 		void generateLinksAndStates( Code::iterator current ) override;
1104 		ProcessorBehaviour behaviour() const override;
assemblyType()1105 		AssemblyType assemblyType() const override { return Other; }
1106 };
1107 
1108 
1109 class Instr_btfss : public Instruction
1110 {
1111 	public:
Instr_btfss(const Register & file,const RegisterBit & bit)1112 		Instr_btfss( const Register & file, const RegisterBit & bit ) { m_file = file; m_bit = bit; }
1113 		QString code() const override;
1114 		void generateLinksAndStates( Code::iterator current ) override;
1115 		ProcessorBehaviour behaviour() const override;
assemblyType()1116 		AssemblyType assemblyType() const override { return Other; }
1117 };
1118 //END Bit-Oriented File Register Operations
1119 
1120 
1121 
1122 //BEGIN Literal and Control Operations
1123 class Instr_addlw : public Instruction
1124 {
1125 	public:
Instr_addlw(int literal)1126 		Instr_addlw( int literal ) { m_literal = literal; }
1127 		QString code() const override;
1128 		void generateLinksAndStates( Code::iterator current ) override;
1129 		ProcessorBehaviour behaviour() const override;
assemblyType()1130 		AssemblyType assemblyType() const override { return WorkingOriented; }
1131 };
1132 
1133 
1134 
1135 class Instr_andlw : public Instruction
1136 {
1137 	public:
Instr_andlw(int literal)1138 		Instr_andlw( int literal ) { m_literal = literal; }
1139 		QString code() const override;
1140 		void generateLinksAndStates( Code::iterator current ) override;
1141 		ProcessorBehaviour behaviour() const override;
assemblyType()1142 		AssemblyType assemblyType() const override { return WorkingOriented; }
1143 };
1144 
1145 
1146 class Instr_call : public Instruction
1147 {
1148 	public:
Instr_call(const QString & label)1149 		Instr_call( const QString & label ) { m_label = label; }
1150 		QString code() const override;
1151 		void generateLinksAndStates( Code::iterator current ) override;
1152 		ProcessorBehaviour behaviour() const override;
assemblyType()1153 		AssemblyType assemblyType() const override { return Other; }
1154 		/**
1155 		 * Called from Code after all the output links have been generated. The
1156 		 * instruction that is called has its output links followed, and any
1157 		 * returns encountered are linked back to the instruction after this
1158 		 * one.
1159 		 * @param next the instruction after this one which the return points
1160 		 * will be linked to.
1161 		 */
1162 		void makeReturnLinks( Instruction * next );
1163 
label()1164 		QString label() const { return m_label; }
setLabel(const QString & label)1165 		void setLabel( const QString & label ) { m_label = label; }
1166 
1167 	protected:
1168 		/**
1169 		 * Used by makeReturnLinks. Recursively follows the instruction's output
1170 		 * links, until a return is found - then, link the return point back to
1171 		 * the instruction after this one. Call instructions found while
1172 		 * following the output are ignored.
1173 		 * @param returnPoint the instruction to link back to on finding a
1174 		 * return.
1175 		 */
1176 		void linkReturns( Instruction * current, Instruction * returnPoint );
1177 
1178 		QString m_label;
1179 };
1180 
1181 
1182 //TODO CLRWDT
1183 
1184 
1185 class Instr_goto : public Instruction
1186 {
1187 	public:
Instr_goto(const QString & label)1188 		Instr_goto( const QString & label ) { m_label = label; }
1189 		QString code() const override;
1190 		void generateLinksAndStates( Code::iterator current ) override;
1191 		ProcessorBehaviour behaviour() const override;
assemblyType()1192 		AssemblyType assemblyType() const override { return Other; }
1193 
label()1194 		QString label() const { return m_label; }
setLabel(const QString & label)1195 		void setLabel( const QString & label ) { m_label = label; }
1196 
1197 	protected:
1198 		QString m_label;
1199 };
1200 
1201 
1202 class Instr_iorlw : public Instruction
1203 {
1204 	public:
Instr_iorlw(int literal)1205 		Instr_iorlw( int literal ) { m_literal = literal; }
1206 		QString code() const override;
1207 		void generateLinksAndStates( Code::iterator current ) override;
1208 		ProcessorBehaviour behaviour() const override;
assemblyType()1209 		AssemblyType assemblyType() const override { return WorkingOriented; }
1210 };
1211 
1212 
1213 class Instr_movlw : public Instruction
1214 {
1215 	public:
Instr_movlw(int literal)1216 		Instr_movlw( int literal ) { m_literal = literal; }
1217 		QString code() const override;
1218 		void generateLinksAndStates( Code::iterator current ) override;
1219 		ProcessorBehaviour behaviour() const override;
assemblyType()1220 		AssemblyType assemblyType() const override { return WorkingOriented; }
1221 };
1222 
1223 
1224 class Instr_retfie : public Instruction
1225 {
1226 	public:
Instr_retfie()1227 		Instr_retfie() {};
1228 		QString code() const override;
1229 		void generateLinksAndStates( Code::iterator current ) override;
1230 		ProcessorBehaviour behaviour() const override;
assemblyType()1231 		AssemblyType assemblyType() const override { return Other; }
1232 };
1233 
1234 
1235 class Instr_retlw : public Instruction
1236 {
1237 	public:
Instr_retlw(int literal)1238 		Instr_retlw( int literal ) { m_literal = literal; }
1239 		QString code() const override;
1240 		void generateLinksAndStates( Code::iterator current ) override;
1241 		ProcessorBehaviour behaviour() const override;
assemblyType()1242 		AssemblyType assemblyType() const override { return Other; }
1243 };
1244 
1245 
1246 class Instr_return : public Instruction
1247 {
1248 	public:
Instr_return()1249 		Instr_return() {};
1250 		QString code() const override;
1251 		void generateLinksAndStates( Code::iterator current ) override;
1252 		ProcessorBehaviour behaviour() const override;
assemblyType()1253 		AssemblyType assemblyType() const override { return Other; }
1254 };
1255 
1256 
1257 class Instr_sleep : public Instruction
1258 {
1259 	public:
Instr_sleep()1260 		Instr_sleep() {};
1261 		QString code() const override;
1262 		void generateLinksAndStates( Code::iterator current ) override;
1263 		ProcessorBehaviour behaviour() const override;
assemblyType()1264 		AssemblyType assemblyType() const override { return Other; }
1265 };
1266 
1267 
1268 class Instr_sublw : public Instruction
1269 {
1270 	public:
Instr_sublw(int literal)1271 		Instr_sublw( int literal ) { m_literal = literal; }
1272 		QString code() const override;
1273 		void generateLinksAndStates( Code::iterator current ) override;
1274 		ProcessorBehaviour behaviour() const override;
assemblyType()1275 		AssemblyType assemblyType() const override { return WorkingOriented; }
1276 };
1277 
1278 
1279 class Instr_xorlw : public Instruction
1280 {
1281 	public:
Instr_xorlw(int literal)1282 		Instr_xorlw( int literal ) { m_literal = literal; }
1283 		QString code() const override;
1284 		void generateLinksAndStates( Code::iterator current ) override;
1285 		ProcessorBehaviour behaviour() const override;
assemblyType()1286 		AssemblyType assemblyType() const override { return WorkingOriented; }
1287 };
1288 //END Literal and Control Operations
1289 
1290 
1291 
1292 //BEGIN Microbe (non-assembly) Operations
1293 class Instr_sourceCode : public Instruction
1294 {
1295 	public:
Instr_sourceCode(const QString & source)1296 		Instr_sourceCode( const QString & source ) { m_raw = source; }
1297 		QString code() const override;
type()1298 		InstructionType type() const override { return Comment; }
assemblyType()1299 		AssemblyType assemblyType() const override { return None; }
1300 };
1301 
1302 
1303 class Instr_asm : public Instruction
1304 {
1305 	public:
Instr_asm(const QString & raw)1306 		Instr_asm( const QString & raw ) { m_raw = raw; }
1307 		QString code() const override;
type()1308 		InstructionType type() const override { return Raw; }
assemblyType()1309 		AssemblyType assemblyType() const override { return None; }
1310 };
1311 
1312 
1313 // Like Instr_asm, but does not put ;asm {} in, used
1314 // for internal things like gpasm directives etc...
1315 class Instr_raw : public Instruction
1316 {
1317 	public:
Instr_raw(const QString & raw)1318 		Instr_raw( const QString & raw ) { m_raw = raw; }
1319 		QString code() const override;
type()1320 		InstructionType type() const override { return Raw; }
assemblyType()1321 		AssemblyType assemblyType() const override { return None; }
1322 };
1323 //END Microbe (non-assembly) Operations
1324 
1325 
1326 
1327 #endif
1328