/* Header file constdivmul.h */ #include #include #include #include #include extern "C" { #include #include } #define MAXINPBITS 32 /* Maximum number of bits in input */ #define MAXOUTBITS 64 /* Maximum number of bits in output */ #define MAXFRCBITS 64 /* Maximum number of bits in fractional part of constant */ #define MAXALGSIZE (MAXOUTBITS - MAXINPBITS + MAXFRCBITS) #define ALGINTSIZE (MAXOUTBITS - MAXINPBITS) /* Size of integral part in algorithm */ //#define MAXREGSIZE ((MAXOUTBITS + MAXFRCBITS) / 8) //maximum register size in bytes #define MAXCODESIZE 65536 #define MAXSNIPSIZE 2048 #define VERSIONDATE "March 21, 2000" //enum RegType {Static, Dynamic}; enum endianType{big, little}; class Reg { public: Reg(); Reg(char *N, char b, endianType endi); char GetSize() //size of reg in bits (leads excluded) { return Bits; } void SetSize(char b, char l); //set size of reg in bits and leads char GetBytes() //how many bytes from GetSize { return (Bits + 7) / 8; } char GetBytesTotal() //including Leads { return (Bits + Leads + 7) / 8; } char *ShiftRight(char Shift); // shift right, truncates fraction part char *ShiftLeft(char Shift); // shift left char *ShowUsedRegs(); //generate code for declaration char *Add(Reg *R2); //add other register (left aligned) char *Sub(Reg *R2); //substract other register(left aligned) char *Neg(); //change sign char *Copy(Reg *R2); char *Name; bool Zero; // Shift will set the flag if result is zero bool Sign; //do sign extension for right shift bool wasUsed; //indicates that the register was accessed for read endianType endian; //big or little protected: void CheckBytesUsed(); //increase used bytes counter if needed void Normalize(Reg *R2); //normalize register to add/substract R2 char Bits, // significant bits number Leads, // number of bits stuffed before bits field BytesUsed; // number of registers for storage char str[MAXSNIPSIZE]; //snippet for code generation functions //big endians: char *ShiftRightBE(char Shift); char *ShiftLeftBE(char Shift); char *AddBE(Reg *R2); char *SubBE(Reg *R2); char *NegBE(); //little endians: char *ShiftRightLE(char Shift); char *ShiftLeftLE(char Shift); char *AddLE(Reg *R2); char *SubLE(Reg *R2); char *NegLE(); void NormalizeBE(Reg *R2); void NormalizeLE(Reg *R2); /* Signed register is represented in twos complement form (-A = ~A + 1) Bits don't include the sign shown by higher bits (Leads), but only the number of significant bits. If Leads = 0 for signed register, the sign bit then is in carry Sign in carry is inverted for PICs, since substraction clears carry flag on borrow. Therefore signed shift left (and right) doesn't put sign in carry, but makes it explicit. */ }; class PIC16 { public: PIC16(); void SetNoteCarry(bool val, Reg *R); //Set vNoteCarry flag void SetValidCarry(bool val, Reg *R); //Set vValidCarry flag bool GetNoteCarry(Reg *R); //Get vNoteCarry flag bool GetValidCarry(Reg *R); //Get vValidCarry flag //member functions to generate code char *TakeCarry(); //Takes care of carry void ClearSnippet(void) { str[0] = 0; } char *GetSnippet(void) { return str; } char *movwf(Reg *File, char Index); //movwf File->Name+'index' char *movfw(Reg *File, char Index); //movf File->Name+'index', w char *swapfw(Reg *File, char Index); char *swapff(Reg *File, char Index); char *movlw(char literal); char *andlw(char literal); char *clrf(Reg *File, char Index); // char *clrw(); char *btfsc(Reg *File, char Index, char Bit); char *btfss(Reg *File, char Index, char Bit); char *bsf(Reg *File, char Index, char Bit); char *comff(Reg *File, char Index); //comf Name, f char *clrc(); char *comc(); //invert carry char *skpc(); char *skpnc(); char *skpnz(); char *rlff(Reg *File, char Index); char *rlfw(Reg *File, char Index); char *rrff(Reg *File, char Index); char *rrfw(Reg *File, char Index); char *addwff(Reg *File, char Index); char *subwff(Reg *File, char Index); char *iorwff(Reg *File, char Index); char *iorlw(char literal); char *incfszw(Reg *File, char Index); char *incff(Reg *File, char Index); char *decff(Reg *File, char Index); Reg *cHolder; //What register holds rights for Carry protected: bool vNoteCarry, //signals if carry contains MSB after addtion vValidCarry; //set if carry can be used as an extension of register char str[MAXSNIPSIZE]; //snippet for code generation functions //w Holder pointer and index Reg *wHolder; char wIndex; bool wValid(Reg *File, char Index); //returns true if w already contains needed register }; void constdivmul(Reg *Acc, Reg *Tmp); void ReportError(char Err); void TimeStamp(); void Banner();