X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fpcode.h;h=e8cefd86797e2bf19871791945fc19f7f3e8141a;hb=80972b2e54c9b88f11c27b878874fd2a6a681391;hp=cdd4a1a6c1380542a1f10bd50c121ab2b6046329;hpb=4c3872ef27c1263faae7d9b85c1821381646ece8;p=fw%2Fsdcc diff --git a/src/pic/pcode.h b/src/pic/pcode.h index cdd4a1a6..e8cefd86 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -19,7 +19,17 @@ -------------------------------------------------------------------------*/ -//#include "ralloc.h" +#ifndef __PCODE_H__ +#define __PCODE_H__ + +#include "common.h" + +/* When changing these, you must also update the assembler template + * in device/lib/libsdcc/macros.inc */ +#define GPTRTAG_DATA 0x00 +#define GPTRTAG_CODE 0x80 + +/* Cyclic dependency with ralloc.h: */ struct regs; /* @@ -50,20 +60,37 @@ struct regs; movwf t1 movf t1,w ; Can't remove this movf skpz - return + return example3: movwf t1 movf t1,w ; This movf can be removed xorwf t2,w ; since xorwf will over write Z skpz - return + return */ -#ifndef __PCODE_H__ -#define __PCODE_H__ +/*********************************************************************** + * debug stuff + * + * The DFPRINTF macro will call fprintf if PCODE_DEBUG is defined. + * The macro is used like: + * + * DPRINTF(("%s #%d\n","test", 1)); + * + * The double parenthesis (()) are necessary + * + ***********************************************************************/ +//#define PCODE_DEBUG + +#ifdef PCODE_DEBUG +#define DFPRINTF(args) (fprintf args) +#else +#define DFPRINTF(args) ((void)0) +#endif + /*********************************************************************** * PIC status bits - this will move into device dependent headers @@ -71,13 +98,21 @@ struct regs; #define PIC_C_BIT 0 #define PIC_DC_BIT 1 #define PIC_Z_BIT 2 +#define PIC_RP0_BIT 5 /* Register Bank select bits RP1:0 : */ +#define PIC_RP1_BIT 6 /* 00 - bank 0, 01 - bank 1, 10 - bank 2, 11 - bank 3 */ +#define PIC_IRP_BIT 7 /* Indirect register page select */ /*********************************************************************** - * Operand types + * PIC INTCON bits - this will move into device dependent headers ***********************************************************************/ -#define POT_RESULT 0 -#define POT_LEFT 1 -#define POT_RIGHT 2 +#define PIC_RBIF_BIT 0 /* Port B level has changed flag */ +#define PIC_INTF_BIT 1 /* Port B bit 0 interrupt on edge flag */ +#define PIC_T0IF_BIT 2 /* TMR0 has overflowed flag */ +#define PIC_RBIE_BIT 3 /* Port B level has changed - Interrupt Enable */ +#define PIC_INTE_BIT 4 /* Port B bit 0 interrupt on edge - Int Enable */ +#define PIC_T0IE_BIT 5 /* TMR0 overflow Interrupt Enable */ +#define PIC_PIE_BIT 6 /* Peripheral Interrupt Enable */ +#define PIC_GIE_BIT 7 /* Global Interrupt Enable */ /*********************************************************************** @@ -99,55 +134,30 @@ struct regs; typedef enum { - PO_NONE=0, // No operand e.g. NOP - PO_W, // The 'W' register - PO_STATUS, // The 'STATUS' register - PO_FSR, // The "file select register" (in 18c it's one of three) - PO_INDF, // The Indirect register - PO_GPR_REGISTER, // A general purpose register - PO_GPR_TEMP, // A general purpose temporary register - PO_SFR_REGISTER, // A special function register (e.g. PORTA) - PO_LITERAL, // A constant - PO_IMMEDIATE, // (8051 legacy) - PO_DIR, // Direct memory (8051 legacy) - PO_CRY, // bit memory (8051 legacy) - PO_BIT, // bit operand. - PO_STR, // (8051 legacy) - PO_LABEL, - PO_WILD // Wild card operand in peep optimizer + PO_NONE=0, // No operand e.g. NOP + PO_W, // The 'W' register + PO_STATUS, // The 'STATUS' register + PO_FSR, // The "file select register" (in 18c it's one of three) + PO_INDF, // The Indirect register + PO_INTCON, // Interrupt Control register + PO_GPR_REGISTER, // A general purpose register + PO_GPR_BIT, // A bit of a general purpose register + PO_GPR_TEMP, // A general purpose temporary register + PO_GPR_POINTER, // A general purpose pointer + PO_SFR_REGISTER, // A special function register (e.g. PORTA) + PO_PCL, // Program counter Low register + PO_PCLATH, // Program counter Latch high register + PO_LITERAL, // A constant + PO_IMMEDIATE, // (8051 legacy) + PO_DIR, // Direct memory (8051 legacy) + PO_CRY, // bit memory (8051 legacy) + PO_BIT, // bit operand. + PO_STR, // (8051 legacy) + PO_LABEL, + PO_WILD // Wild card operand in peep optimizer } PIC_OPTYPE; -/************************************************* - * pCode conditions: - * - * The "conditions" are bit-mapped flags that describe - * input and/or output conditions that are affected by - * the instructions. For example: - * - * MOVF SOME_REG,W - * - * This instruction depends upon 'SOME_REG'. Consequently - * it has the input condition PCC_REGISTER set to true. - * - * In addition, this instruction affects the Z bit in the - * status register and affects W. Thus the output conditions - * are the logical or: - * PCC_ZERO_BIT | PCC_W - * - * The conditions are intialized when the pCode for an - * instruction is created. They're subsequently used - * by the pCode optimizer determine state information - * in the program flow. - *************************************************/ - -#define PCC_NONE 0 -#define PCC_REGISTER (1<<0) -#define PCC_C (1<<1) -#define PCC_Z (1<<2) -#define PCC_DC (1<<3) -#define PCC_W (1<<4) - /*********************************************************************** * * PIC_OPCODE @@ -159,48 +169,61 @@ typedef enum typedef enum { - POC_WILD=-1, /* Wild card - used in the pCode peep hole optimizer - * to represent ANY pic opcode */ - POC_ADDLW=0, - POC_ADDWF, - POC_ADDFW, - POC_ANDLW, - POC_ANDWF, - POC_ANDFW, - POC_BCF, - POC_BSF, - POC_BTFSC, - POC_BTFSS, - POC_CALL, - POC_COMF, - POC_CLRF, - POC_CLRW, - POC_DECF, - POC_DECFW, - POC_DECFSZ, - POC_DECFSZW, - POC_GOTO, - POC_INCF, - POC_INCFW, - POC_INCFSZ, - POC_INCFSZW, - POC_IORLW, - POC_IORWF, - POC_IORFW, - POC_MOVF, - POC_MOVFW, - POC_MOVLW, - POC_MOVWF, - POC_NEGF, - POC_RETLW, - POC_RETURN, - POC_SUBLW, - POC_SUBWF, - POC_SUBFW, - POC_TRIS, - POC_XORLW, - POC_XORWF, - POC_XORFW + POC_WILD=-1, /* Wild card - used in the pCode peep hole optimizer + * to represent ANY pic opcode */ + POC_ADDLW=0, + POC_ADDWF, + POC_ADDFW, + POC_ANDLW, + POC_ANDWF, + POC_ANDFW, + POC_BCF, + POC_BSF, + POC_BTFSC, + POC_BTFSS, + POC_CALL, + POC_COMF, + POC_COMFW, + POC_CLRF, + POC_CLRW, + POC_CLRWDT, + POC_DECF, + POC_DECFW, + POC_DECFSZ, + POC_DECFSZW, + POC_GOTO, + POC_INCF, + POC_INCFW, + POC_INCFSZ, + POC_INCFSZW, + POC_IORLW, + POC_IORWF, + POC_IORFW, + POC_MOVF, + POC_MOVFW, + POC_MOVLW, + POC_MOVWF, + POC_NOP, + POC_RETLW, + POC_RETURN, + POC_RETFIE, + POC_RLF, + POC_RLFW, + POC_RRF, + POC_RRFW, + POC_SUBLW, + POC_SUBWF, + POC_SUBFW, + POC_SWAPF, + POC_SWAPFW, + POC_TRIS, + POC_XORLW, + POC_XORWF, + POC_XORFW, + POC_BANKSEL, + POC_PAGESEL, + + MAX_PIC14MNEMONICS } PIC_OPCODE; @@ -210,17 +233,27 @@ typedef enum typedef enum { - PC_COMMENT=0, // pCode is a comment - PC_OPCODE, // PORT dependent opcode - PC_LABEL, // assembly label - PC_FUNCTION, // Function start or end - PC_WILD // wildcard - an opcode place holder + PC_COMMENT=0, /* pCode is a comment */ + PC_INLINE, /* user's inline code */ + PC_OPCODE, /* PORT dependent opcode */ + PC_LABEL, /* assembly label */ + PC_FLOW, /* flow analysis */ + PC_FUNCTION, /* Function start or end */ + PC_WILD, /* wildcard - an opcode place holder used + * in the pCode peep hole optimizer */ + PC_CSOURCE, /* C-Source Line */ + PC_ASMDIR, /* Assembler directive */ + PC_BAD /* Mark the pCode object as being bad */ } PC_TYPE; /************************************************/ /*************** Structures ********************/ /************************************************/ +/* These are here as forward references - the + * full definition of these are below */ struct pCode; +struct pCodeWildBlock; +struct pCodeRegLives; /************************************************* pBranch @@ -240,9 +273,9 @@ struct pCode; typedef struct pBranch { - struct pCode *pc; // Next pCode in a branch - struct pBranch *next; /* If more than one branch - * the next one is here */ + struct pCode *pc; // Next pCode in a branch + struct pBranch *next; /* If more than one branch + * the next one is here */ } pBranch; @@ -262,39 +295,75 @@ typedef struct pBranch typedef struct pCodeOp { - PIC_OPTYPE type; - char *name; - -} pCodeOp; + PIC_OPTYPE type; + char *name; -typedef struct pCodeOpBit -{ - pCodeOp pcop; - int bit; - unsigned int inBitSpace: 1; /* True if in bit space, else - just a bit of a register */ -} pCodeOpBit; +} pCodeOp; typedef struct pCodeOpLit { - pCodeOp pcop; - int lit; + pCodeOp pcop; + int lit; } pCodeOpLit; +typedef struct pCodeOpImmd +{ + pCodeOp pcop; + int offset; /* low,med, or high byte of immediate value */ + int index; /* add this to the immediate value */ + unsigned _const:1; /* is in code space */ + unsigned _function:1; /* is a (pointer to a) function */ + + int rIdx; /* If this immd points to a register */ + struct regs *r; /* then this is the reg. */ + +} pCodeOpImmd; + typedef struct pCodeOpLabel { - pCodeOp pcop; - int key; + pCodeOp pcop; + int key; + int offset; /* low or high byte of label */ } pCodeOpLabel; typedef struct pCodeOpReg { - pCodeOp pcop; // Can be either GPR or SFR - int rIdx; // Index into the register table - struct regs *r; - struct pBlock *pb; + pCodeOp pcop; // Can be either GPR or SFR + int rIdx; // Index into the register table + struct regs *r; + int instance; // byte # of Multi-byte registers + struct pBlock *pb; } pCodeOpReg; +typedef struct pCodeOpRegBit +{ + pCodeOpReg pcor; // The Register containing this bit + int bit; // 0-7 bit number. + PIC_OPTYPE subtype; // The type of this register. + unsigned int inBitSpace: 1; /* True if in bit space, else + just a bit of a register */ +} pCodeOpRegBit; + +typedef struct pCodeOpStr /* Only used here for the name of fn being called or jumped to */ +{ + pCodeOp pcop; + unsigned isPublic: 1; /* True if not static ie extern */ +} pCodeOpStr; + +typedef struct pCodeOpWild +{ + pCodeOp pcop; + + struct pCodeWildBlock *pcwb; + + int id; /* index into an array of char *'s that will match + * the wild card. The array is in *pcp. */ + pCodeOp *subtype; /* Pointer to the Operand type into which this wild + * card will be expanded */ + pCodeOp *matched; /* When a wild matches, we'll store a pointer to the + * opcode we matched */ + +} pCodeOpWild; /************************************************* @@ -308,27 +377,23 @@ typedef struct pCodeOpReg typedef struct pCode { - PC_TYPE type; - - struct pCode *prev; // The pCode objects are linked together - struct pCode *next; // in doubly linked lists. + PC_TYPE type; - int seq; // sequence number + struct pCode *prev; // The pCode objects are linked together + struct pCode *next; // in doubly linked lists. - pBranch *from; // pCodes that execute before this one - pBranch *to; // pCodes that execute after - pBranch *label; // pCode instructions that have labels + unsigned id; // unique ID number for all pCodes to assist in debugging + int seq; // sequence number - struct pBlock *pb; // The pBlock that contains this pCode. + struct pBlock *pb; // The pBlock that contains this pCode. - /* "virtual functions" - * The pCode structure is like a base class - * in C++. The subsequent structures that "inherit" - * the pCode structure will initialize these function - * pointers to something useful */ - void (*analyze) (struct pCode *_this); - void (*destruct)(struct pCode *_this); - void (*print) (FILE *of,struct pCode *_this); + /* "virtual functions" + * The pCode structure is like a base class + * in C++. The subsequent structures that "inherit" + * the pCode structure will initialize these function + * pointers to something useful */ + void (*destruct)(struct pCode *_this); + void (*print) (FILE *of,struct pCode *_this); } pCode; @@ -340,12 +405,91 @@ typedef struct pCode typedef struct pCodeComment { - pCode pc; + pCode pc; - char *comment; + char *comment; } pCodeComment; + +/************************************************* + pCodeComment +**************************************************/ + +typedef struct pCodeCSource +{ + + pCode pc; + + int line_number; + char *line; + char *file_name; + +} pCodeCSource; + + +/************************************************* + pCodeFlow + + The Flow object is used as marker to separate + the assembly code into contiguous chunks. In other + words, everytime an instruction cause or potentially + causes a branch, a Flow object will be inserted into + the pCode chain to mark the beginning of the next + contiguous chunk. + +**************************************************/ + +typedef struct pCodeFlow +{ + + pCode pc; + + pCode *end; /* Last pCode in this flow. Note that + the first pCode is pc.next */ + + set *from; /* flow blocks that can send control to this flow block */ + set *to; /* flow blocks to which this one can send control */ + struct pCodeFlow *ancestor; /* The most immediate "single" pCodeFlow object that + * executes prior to this one. In many cases, this + * will be just the previous */ + + int inCond; /* Input conditions - stuff assumed defined at entry */ + int outCond; /* Output conditions - stuff modified by flow block */ + + int firstBank; /* The first and last bank flags are the first and last */ + int lastBank; /* register banks used within one flow object */ + + int FromConflicts; + int ToConflicts; + + set *registers;/* Registers used in this flow */ + +} pCodeFlow; + + +/************************************************* + pCodeFlowLink + + The Flow Link object is used to record information + about how consecutive excutive Flow objects are related. + The pCodeFlow objects demarcate the pCodeInstructions + into contiguous chunks. The FlowLink records conflicts + in the discontinuities. For example, if one Flow object + references a register in bank 0 and the next Flow object + references a register in bank 1, then there is a discontinuity + in the banking registers. + +*/ +typedef struct pCodeFlowLink +{ + pCodeFlow *pcflow; /* pointer to linked pCodeFlow object */ + + int bank_conflict; /* records bank conflicts */ + +} pCodeFlowLink; + + /************************************************* pCodeInstruction @@ -357,24 +501,47 @@ typedef struct pCodeComment typedef struct pCodeInstruction { - pCode pc; + pCode pc; - PIC_OPCODE op; // The opcode of the instruction. + PIC_OPCODE op; // The opcode of the instruction. - char *mnemonic; // Pointer to mnemonic string + char const * const mnemonic; // Pointer to mnemonic string - pCodeOp *pcop; // Operand + pBranch *from; // pCodes that execute before this one + pBranch *to; // pCodes that execute after + pBranch *label; // pCode instructions that have labels - unsigned int num_ops; - unsigned int dest: 1; // If destination is W or F, then 1==F - unsigned int bit_inst: 1; + pCodeOp *pcop; /* Operand, if this instruction has one */ + pCodeFlow *pcflow; /* flow block to which this instruction belongs */ + pCodeCSource *cline; /* C Source from which this instruction was derived */ - unsigned int inCond; // Input conditions for this instruction - unsigned int outCond; // Output conditions for this instruction + unsigned int num_ops; /* Number of operands (0,1,2 for mid range pics) */ + unsigned int isModReg: 1; /* If destination is W or F, then 1==F */ + unsigned int isBitInst: 1; /* e.g. BCF */ + unsigned int isBranch: 1; /* True if this is a branching instruction */ + unsigned int isSkip: 1; /* True if this is a skip instruction */ + unsigned int isLit: 1; /* True if this instruction has an literal operand */ + + PIC_OPCODE inverted_op; /* Opcode of instruction that's the opposite of this one */ + unsigned int inCond; // Input conditions for this instruction + unsigned int outCond; // Output conditions for this instruction } pCodeInstruction; +/************************************************* + pCodeAsmDir +**************************************************/ + +typedef struct pCodeAsmDir +{ + pCodeInstruction pci; + + char *directive; + char *arg; +} pCodeAsmDir; + + /************************************************* pCodeLabel **************************************************/ @@ -382,13 +549,14 @@ typedef struct pCodeInstruction typedef struct pCodeLabel { - pCode pc; + pCode pc; - char *label; - int key; + char *label; + int key; } pCodeLabel; + /************************************************* pCodeFunction **************************************************/ @@ -396,13 +564,20 @@ typedef struct pCodeLabel typedef struct pCodeFunction { - pCode pc; + pCode pc; + + char *modname; + char *fname; /* If NULL, then this is the end of + a function. Otherwise, it's the + start and the name is contained + here */ - char *modname; - char *fname; /* If NULL, then this is the end of - a function. Otherwise, it's the - start and the name is contained - here */ + pBranch *from; // pCodes that execute before this one + pBranch *to; // pCodes that execute after + pBranch *label; // pCode instructions that have labels + + int ncalled; /* Number of times function is called */ + unsigned isPublic:1; /* True if the fn is not static and can be called from another module (ie a another c or asm file) */ } pCodeFunction; @@ -414,15 +589,19 @@ typedef struct pCodeFunction typedef struct pCodeWild { - pCode pc; + pCodeInstruction pci; - int id; /* Index into the wild card array of a peepBlock - * - this wild card will get expanded into that pCode - * that is stored at this index */ + int id; /* Index into the wild card array of a peepBlock + * - this wild card will get expanded into that pCode + * that is stored at this index */ + /* Conditions on wild pcode instruction */ + int mustBeBitSkipInst:1; + int mustNotBeBitSkipInst:1; + int invertBitSkipInst:1; - pCodeOp *operand; // Optional operand - pCodeOp *label; // Optional label + pCodeOp *operand; // Optional operand + pCodeOp *label; // Optional label } pCodeWild; @@ -439,22 +618,23 @@ typedef struct pCodeWild typedef struct pBlock { - memmap *cmemmap; /* The snippet is from this memmap */ - char dbName; /* if cmemmap is NULL, then dbName will identify the block */ - pCode *pcHead; /* A pointer to the first pCode in a link list of pCodes */ - pCode *pcTail; /* A pointer to the last pCode in a link list of pCodes */ + memmap *cmemmap; /* The snippet is from this memmap */ + char dbName; /* if cmemmap is NULL, then dbName will identify the block */ + pCode *pcHead; /* A pointer to the first pCode in a link list of pCodes */ + pCode *pcTail; /* A pointer to the last pCode in a link list of pCodes */ - struct pBlock *next; /* The pBlocks will form a doubly linked list */ - struct pBlock *prev; + struct pBlock *next; /* The pBlocks will form a doubly linked list */ + struct pBlock *prev; - set *function_entries; /* dll of functions in this pblock */ - set *function_exits; - set *function_calls; - set *registers; + set *function_entries; /* dll of functions in this pblock */ + set *function_exits; + set *function_calls; + set *tregisters; - unsigned visited:1; /* set true if traversed in call tree */ + set *FlowTree; + unsigned visited:1; /* set true if traversed in call tree */ - unsigned seq; /* sequence number of this pBlock */ + unsigned seq; /* sequence number of this pBlock */ } pBlock; @@ -471,15 +651,37 @@ typedef struct pBlock typedef struct pFile { - pBlock *pbHead; /* A pointer to the first pBlock */ - pBlock *pbTail; /* A pointer to the last pBlock */ + pBlock *pbHead; /* A pointer to the first pBlock */ + pBlock *pbTail; /* A pointer to the last pBlock */ - pBranch *functions; /* A SLL of functions in this pFile */ + pBranch *functions; /* A SLL of functions in this pFile */ } pFile; +/************************************************* + pCodeWildBlock + + The pCodeWildBlock object keeps track of the wild + variables, operands, and opcodes that exist in + a pBlock. +**************************************************/ +typedef struct pCodeWildBlock { + pBlock *pb; + struct pCodePeep *pcp; // pointer back to ... I don't like this... + + int nvars; // Number of wildcard registers in target. + char **vars; // array of pointers to them + + int nops; // Number of wildcard operands in target. + pCodeOp **wildpCodeOps; // array of pointers to the pCodeOp's. + + int nwildpCodes; // Number of wildcard pCodes in target/replace + pCode **wildpCodes; // array of pointers to the pCode's. + +} pCodeWildBlock; + /************************************************* pCodePeep @@ -492,44 +694,49 @@ typedef struct pFile pCode chain. **************************************************/ typedef struct pCodePeep { + pCodeWildBlock target; // code we'd like to optimize + pCodeWildBlock replace; // and this is what we'll optimize it with. + + /* (Note: a wildcard register is a place holder. Any register + * can be replaced by the wildcard when the pcode is being + * compared to the target. */ + + /* Post Conditions. A post condition is a condition that + * must be either true or false before the peep rule is + * accepted. For example, a certain rule may be accepted + * if and only if the Z-bit is not used as an input to + * the subsequent instructions in a pCode chain. + */ + unsigned int postFalseCond; + unsigned int postTrueCond; - pBlock *target; // code we'd like to optimize - pBlock *replace; // and this is what we'll optimize it with. +} pCodePeep; - int nvars; // Number of wildcard registers in target. - char **vars; // array of pointers to them - int nwildpCodes; // Number of wildcard pCodes in target/replace - pCode **wildpCodes; // array of pointers to the pCodeOp's. +/************************************************* + pCode peep command definitions - /* (Note: a wildcard register is a place holder. Any register - * can be replaced by the wildcard when the pcode is being - * compared to the target. */ + Here are some special commands that control the +way the peep hole optimizer behaves - /* Post Conditions. A post condition is a condition that - * must be either true or false before the peep rule is - * accepted. For example, a certain rule may be accepted - * if and only if the Z-bit is not used as an input to - * the subsequent instructions in a pCode chain. - */ - unsigned int postFalseCond; - unsigned int postTrueCond; +**************************************************/ -} pCodePeep; +enum peepCommandTypes{ + NOTBITSKIP = 0, + BITSKIP, + INVERTBITSKIP, + _LAST_PEEP_COMMAND_ +}; -typedef struct pCodeOpWild -{ - pCodeOp pcop; - //PIC_OPTYPE subtype; Wild get's expanded to this by the optimizer - pCodePeep *pcp; // pointer to the parent peep block - int id; /* index into an array of char *'s that will match - * the wild card. The array is in *pcp. */ - pCodeOp *subtype; /* Pointer to the Operand type into which this wild - * card will be expanded */ - pCodeOp *matched; /* When a wild matches, we'll store a pointer to the - * opcode we matched */ +/************************************************* + peepCommand structure stores the peep commands. -} pCodeOpWild; +**************************************************/ + +typedef struct peepCommand { + int id; + char *cmd; +} peepCommand; /************************************************* pCode Macros @@ -539,71 +746,136 @@ typedef struct pCodeOpWild #define PCI(x) ((pCodeInstruction *)(x)) #define PCL(x) ((pCodeLabel *)(x)) #define PCF(x) ((pCodeFunction *)(x)) +#define PCFL(x) ((pCodeFlow *)(x)) +#define PCFLINK(x)((pCodeFlowLink *)(x)) #define PCW(x) ((pCodeWild *)(x)) +#define PCCS(x) ((pCodeCSource *)(x)) +#define PCAD(x) ((pCodeAsmDir *)(x)) #define PCOP(x) ((pCodeOp *)(x)) -#define PCOB(x) ((pCodeOpBit *)(x)) #define PCOL(x) ((pCodeOpLit *)(x)) +#define PCOI(x) ((pCodeOpImmd *)(x)) #define PCOLAB(x) ((pCodeOpLabel *)(x)) #define PCOR(x) ((pCodeOpReg *)(x)) +#define PCORB(x) ((pCodeOpRegBit *)(x)) +#define PCOS(x) ((pCodeOpStr *)(x)) #define PCOW(x) ((pCodeOpWild *)(x)) #define PBR(x) ((pBranch *)(x)) +#define PCWB(x) ((pCodeWildBlock *)(x)) + +#define isPCOLAB(x) ((PCOP(x)->type) == PO_LABEL) +#define isPCOS(x) ((PCOP(x)->type) == PO_STR) + + +/* + macros for checking pCode types +*/ +#define isPCI(x) ((PCODE(x)->type == PC_OPCODE)) +#define isPCFL(x) ((PCODE(x)->type == PC_FLOW)) +#define isPCF(x) ((PCODE(x)->type == PC_FUNCTION)) +#define isPCL(x) ((PCODE(x)->type == PC_LABEL)) +#define isPCW(x) ((PCODE(x)->type == PC_WILD)) +#define isPCCS(x) ((PCODE(x)->type == PC_CSOURCE)) +#define isPCASMDIR(x) ((PCODE(x)->type == PC_ASMDIR)) + +/* + macros for checking pCodeInstruction types +*/ +#define isCALL(x) (isPCI(x) && (PCI(x)->op == POC_CALL)) +#define isPCI_BRANCH(x) (isPCI(x) && PCI(x)->isBranch) +#define isPCI_SKIP(x) (isPCI(x) && PCI(x)->isSkip) +#define isPCI_LIT(x) (isPCI(x) && PCI(x)->isLit) +#define isPCI_BITSKIP(x)(isPCI_SKIP(x) && PCI(x)->isBitInst) + + +#define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS) + /*-----------------------------------------------------------------* * pCode functions. *-----------------------------------------------------------------*/ pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop); // Create a new pCode given an operand pCode *newpCodeCharP(char *cP); // Create a new pCode given a char * -pCode *newpCodeFunction(char *g, char *f); // Create a new function -pCode *newpCodeLabel(int key); // Create a new label given a key -pCode *newpCodeLabelStr(char *str); // Create a new label given a string +pCode *newpCodeFunction(char *g, char *f,int); // Create a new function +pCode *newpCodeLabel(char *name,int key); // Create a new label given a key +pCode *newpCodeCSource(int ln, char *f, const char *l); // Create a new symbol line +pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label); +pCode *findNextInstruction(pCode *pci); +pCode *findPrevInstruction(pCode *pci); +pCode *findNextpCode(pCode *pc, PC_TYPE pct); +pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert); + pBlock *newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock void printpBlock(FILE *of, pBlock *pb); // Write a pBlock to a file void printpCode(FILE *of, pCode *pc); // Write a pCode to a file void addpCode2pBlock(pBlock *pb, pCode *pc); // Add a pCode to a pBlock void addpBlock(pBlock *pb); // Add a pBlock to a pFile +void unlinkpCode(pCode *pc); void copypCode(FILE *of, char dbName); // Write all pBlocks with dbName to *of void movepBlock2Head(char dbName); // move pBlocks around +void AnalyzeBanking(void); +void ReuseReg(void); void AnalyzepCode(char dbName); -void OptimizepCode(char dbName); -void printCallTree(FILE *of); -void pCodePeepInit(void); - -pCodeOp *newpCodeOpLabel(int key); +void InlinepCode(void); +void pCodeInitRegisters(void); +void pic14initpCodePeepCommands(void); +void pBlockConvert2ISR(pBlock *pb); +void pBlockMergeLabels(pBlock *pb); +void pCodeInsertAfter(pCode *pc1, pCode *pc2); +void pCodeInsertBefore(pCode *pc1, pCode *pc2); +void pCodeDeleteChain(pCode *f,pCode *t); + +pCode *newpCodeAsmDir(char *asdir, char *argfmt, ...); + +pCodeOp *newpCodeOpLabel(char *name, int key); +pCodeOp *newpCodeOpImmd(char *name, int offset, int index, int code_space,int is_func); pCodeOp *newpCodeOpLit(int lit); -pCodeOp *newpCodeOpBit(char *name, int bit); +pCodeOp *newpCodeOpBit(char *name, int bit,int inBitSpace); +pCodeOp *newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype); +pCodeOp *newpCodeOpRegFromStr(char *name); pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p); -extern void pcode_test(void); +pCodeOp *pCodeOpCopy(pCodeOp *pcop); +pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval); +pCodeOp *popCopyReg(pCodeOpReg *pc); + +pBranch *pBranchAppend(pBranch *h, pBranch *n); + +struct regs * getRegFromInstruction(pCode *pc); + +char *get_op(pCodeOp *pcop, char *buff, size_t buf_size); +char *pCode2str(char *str, size_t size, pCode *pc); + +int pCodePeepMatchRule(pCode *pc); + +void pcode_test(void); +void resetpCodeStatistics (void); +void dumppCodeStatistics (FILE *of); /*-----------------------------------------------------------------* * pCode objects. *-----------------------------------------------------------------*/ extern pCodeOpReg pc_status; +extern pCodeOpReg pc_intcon; extern pCodeOpReg pc_indf; extern pCodeOpReg pc_fsr; +extern pCodeOpReg pc_pcl; +extern pCodeOpReg pc_pclath; +extern pCodeOpReg pc_wsave; /* wsave, ssave and psave are used to save W, the Status and PCLATH*/ +extern pCodeOpReg pc_ssave; /* registers during an interrupt */ +extern pCodeOpReg pc_psave; /* registers during an interrupt */ +extern pFile *the_pFile; +extern pCodeInstruction *pic14Mnemonics[MAX_PIC14MNEMONICS]; -//////////////////// DELETE THIS /////////////////// -/*-----------------------------------------------------------------*/ -/* Allocation macros that replace those in SDCCalloc.h */ -/* Why? I dunno. I ran across a bug with those macros that */ -/* I couldn't fix, but I could work around... */ -/*-----------------------------------------------------------------*/ -# define GC_malloc(x) calloc((x), 1) - -#define _ALLOC(x,sz) if (!(x = calloc((sz),1) )) \ - { \ - werror(E_OUT_OF_MEM,__FILE__,(long) sz);\ - exit (1); \ - } - -#define _ALLOC_ATOMIC(x,y) if (!((x) = malloc(y))) \ - { \ - werror(E_OUT_OF_MEM,__FILE__,(long) y); \ - exit (1); \ - } +/* + * From pcodepeep.h: + */ +int getpCode(char *mnem, unsigned dest); +int getpCodePeepCommand(char *cmd); +int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip); #endif // __PCODE_H__ +