From: maartenbrock Date: Mon, 22 Aug 2005 21:00:12 +0000 (+0000) Subject: * as/mcs51/asdata.c: changed ctype['['] to BINOP X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=fbccf8c34a545513634c74ff2218b3e1441b3324;p=fw%2Fsdcc * as/mcs51/asdata.c: changed ctype['['] to BINOP * as/mcs51/asexpr.c (expr): added case '[' for bit access in bdata, (term): abused bit 15 of s_addr to indicate bit-addressable bytes, (oprio): set priority for '[' * as/mcs51/aslink.h: added define R_BIT, and prototypes for adb_bit and adb_24_bit * as/mcs51/asm.h: added defines R_BIT and S_BIT * as/mcs51/lkarea.c (lnksect2): use T for seg BIT_BANK and overlay it * as/mcs51/lkdata.c: changed ctype['['] to BINOP * as/mcs51/lkmain.c (Areas51): rel2 contains 12 (=C) areas now, added overlayable BIT_BANK area * as/mcs51/lkmem.c (summary): add BIT_BANK to BSEG_BYTES in the report, (summary2): explain 'T' in legenda * as/mcs51/lkrloc.c: replaced old K&R style, (relr): added R_BIT processing, (errmsg): added "Bit-addressable relocation error", (adb_bit): added for converting from byte- to bit-addressable space, (adb_24_bit): added for converting from byte- to bit-addressable space * device/include/stdbool.h: changed BOOL to __bit for mcs51 as it can be used in reentrant functions now even as return value * device/lib/_gptrput.c (_gptrput): removed obsolete code * src/SDCCast.c (resultTypePropagate): also propagate AND_OP and OR_OP, (decorateType): case '!', GETHBIT, AND_OP, OR_OP: result in bool or char * src/SDCCglobl.h: added indicator BitBankUsed * src/SDCCglue.c (glue): emit area BIT_BANK with byte 'bits' and equ's for the bit registers b0-b7 * src/SDCCicode.c (operandFromSymbol): removed IS_BITVAR check, (geniCodeCast): fixed bug 1263853, (geniCodeLogicAndOr): put result in bool or char, (geniCodeReceive): added parameter func for accessing the return type, (geniCodeFunctionBody): pass func to geniCodeReceive * src/SDCCmain.c: added indicator BitBankUsed * src/SDCCmem.c (allocLocal): explicitly set sclass for V_BIT * src/SDCCsymt.c (newBoolLink): added for creating a bool/bit, (checkSClass): don't put automatic bool/bit on stack, (checkFunction): removed check on function cannot return bit * src/SDCCsymt.h: added newBoolLink prototype * src/mcs51/gen.c (rb1regs): added bit registers, (movc): created for assigning to carry, (pushReg, popReg): created for pushing registers, (sameRegs): check both AOP_REG and AOP_CRY types, (aopOp): handle bit registers, (aopPut): optimization no self-assign, (saveRegisters): push reg->base (bits) only once for bit registers, and use pushReg, (unsaveRegisters): pop reg->base only once and use popReg, (assignResultValue): added parameter func and return in carry for bits, (genIpush): optimization no reload in A if not changed, (genSend): bit parameters in reentrant functions are passed in bit registers by first assigning to bits in B, then save registers and copy B to bits, (genCall): handle returning in Carry properly, save it in F0 if needed, (genPcall): updated assignResultValue call, this is not safe yet for bit returning function !!! (genFunction): don't generate equ's for bit registers and use pushReg, (genEndFunction): take care of bit returning functions and use popReg, (genRet): return bit in Carry, (genIfx): optimize bit registers and other directly addressable bits, (genReceive): updated assignResultValue call * src/mcs51/main.c (_mcs51_reset_regparm): added regBitParmFlg, (_mcs51_regparm): allow passing of upto 8 bit parameters in bit registers when using stack-auto * src/mcs51/ralloc.c (_G): added allBitregs, (regs8051): added the bit registers, (createStackSpil): use macro IS_BIT, (getRegBit): added to allocate a bit register, else spill, (getRegBitNoSpil): added to allocate a bit register, else a gpr, (updateRegUsage): factored out to ease stepping while debugging, (serialRegAssign): use updateRegUsage, only spill bits if necessary, also allocate bit registers, (fillGaps): handle bit registers, (findAllBitregs): added to create bit vector with all bit registers, (mcs51_allBitregs): returns this bit vector, (mcs51_assignRegisters): when using stack-auto use bit registers for passing parameters and creating local variables * src/mcs51/ralloc.h: added B0_IDX..B7_IDX and prototype mcs51_allBitregs git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3873 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 6d9da3cb..d740f85f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,82 @@ +2005-08-22 Maarten Brock + + * as/mcs51/asdata.c: changed ctype['['] to BINOP + * as/mcs51/asexpr.c (expr): added case '[' for bit access in bdata, + (term): abused bit 15 of s_addr to indicate bit-addressable bytes, + (oprio): set priority for '[' + * as/mcs51/aslink.h: added define R_BIT, and prototypes for adb_bit + and adb_24_bit + * as/mcs51/asm.h: added defines R_BIT and S_BIT + * as/mcs51/lkarea.c (lnksect2): use T for seg BIT_BANK and overlay it + * as/mcs51/lkdata.c: changed ctype['['] to BINOP + * as/mcs51/lkmain.c (Areas51): rel2 contains 12 (=C) areas now, + added overlayable BIT_BANK area + * as/mcs51/lkmem.c (summary): add BIT_BANK to BSEG_BYTES in the report, + (summary2): explain 'T' in legenda + * as/mcs51/lkrloc.c: replaced old K&R style, + (relr): added R_BIT processing, + (errmsg): added "Bit-addressable relocation error", + (adb_bit): added for converting from byte- to bit-addressable space, + (adb_24_bit): added for converting from byte- to bit-addressable space + * device/include/stdbool.h: changed BOOL to __bit for mcs51 as it can be + used in reentrant functions now even as return value + * device/lib/_gptrput.c (_gptrput): removed obsolete code + * src/SDCCast.c (resultTypePropagate): also propagate AND_OP and OR_OP, + (decorateType): case '!', GETHBIT, AND_OP, OR_OP: result in bool or char + * src/SDCCglobl.h: added indicator BitBankUsed + * src/SDCCglue.c (glue): emit area BIT_BANK with byte 'bits' and equ's for + the bit registers b0-b7 + * src/SDCCicode.c (operandFromSymbol): removed IS_BITVAR check, + (geniCodeCast): fixed bug 1263853, + (geniCodeLogicAndOr): put result in bool or char, + (geniCodeReceive): added parameter func for accessing the return type, + (geniCodeFunctionBody): pass func to geniCodeReceive + * src/SDCCmain.c: added indicator BitBankUsed + * src/SDCCmem.c (allocLocal): explicitly set sclass for V_BIT + * src/SDCCsymt.c (newBoolLink): added for creating a bool/bit, + (checkSClass): don't put automatic bool/bit on stack, + (checkFunction): removed check on function cannot return bit + * src/SDCCsymt.h: added newBoolLink prototype + * src/mcs51/gen.c (rb1regs): added bit registers, + (movc): created for assigning to carry, + (pushReg, popReg): created for pushing registers, + (sameRegs): check both AOP_REG and AOP_CRY types, + (aopOp): handle bit registers, + (aopPut): optimization no self-assign, + (saveRegisters): push reg->base (bits) only once for bit registers, + and use pushReg, + (unsaveRegisters): pop reg->base only once and use popReg, + (assignResultValue): added parameter func and return in carry for bits, + (genIpush): optimization no reload in A if not changed, + (genSend): bit parameters in reentrant functions are passed in bit + registers by first assigning to bits in B, then save registers and + copy B to bits, + (genCall): handle returning in Carry properly, save it in F0 if needed, + (genPcall): updated assignResultValue call, this is not safe yet for bit + returning function !!! + (genFunction): don't generate equ's for bit registers and use pushReg, + (genEndFunction): take care of bit returning functions and use popReg, + (genRet): return bit in Carry, + (genIfx): optimize bit registers and other directly addressable bits, + (genReceive): updated assignResultValue call + * src/mcs51/main.c (_mcs51_reset_regparm): added regBitParmFlg, + (_mcs51_regparm): allow passing of upto 8 bit parameters in bit + registers when using stack-auto + * src/mcs51/ralloc.c (_G): added allBitregs, + (regs8051): added the bit registers, + (createStackSpil): use macro IS_BIT, + (getRegBit): added to allocate a bit register, else spill, + (getRegBitNoSpil): added to allocate a bit register, else a gpr, + (updateRegUsage): factored out to ease stepping while debugging, + (serialRegAssign): use updateRegUsage, only spill bits if necessary, + also allocate bit registers, + (fillGaps): handle bit registers, + (findAllBitregs): added to create bit vector with all bit registers, + (mcs51_allBitregs): returns this bit vector, + (mcs51_assignRegisters): when using stack-auto use bit registers for + passing parameters and creating local variables + * src/mcs51/ralloc.h: added B0_IDX..B7_IDX and prototype mcs51_allBitregs + 2005-08-22 Borut Razem * device/lib/Makefile.in: replaced find option -or with -o @@ -18,7 +97,7 @@ * sim/ucsim/libtool: regenerated on sparc-solaris * sim/ucsim/avr.src/Makefile.in, sim/ucsim/hc08.src/Makefile.in, sim/ucsim/s51.src/Makefile.in, sim/ucsim/xa.src/Makefile.in, - sim/ucsim/z80.src/Makefile.in: removed GNU ld specific linker options + sim/ucsim/z80.src/Makefile.in: removed GNU ld specific linker options -Wl,--start-group and -Wl,--end-group to enable ucsim compilation on sparc-solaris, which doesn't use GNU ld linker * device/lib/Makefile.in: cp on sparc-solaris (SunOS) does not support -u option diff --git a/as/mcs51/asdata.c b/as/mcs51/asdata.c index 16657520..be5dd3d6 100644 --- a/as/mcs51/asdata.c +++ b/as/mcs51/asdata.c @@ -8,8 +8,8 @@ * 721 Berkeley St. * Kent, Ohio 44240 * - * 28-Oct-97 JLH: - * - change s_id from [NCPS] to pointer (comment) + * 28-Oct-97 JLH: + * - change s_id from [NCPS] to pointer (comment) * 2-Nov-97 JLH: * - add jflag for debug control */ @@ -19,271 +19,271 @@ #include #include "asm.h" -/*)Module asdata.c +/*)Module asdata.c * - * The module asdata.c contains the global constants, - * structures, and variables used in the assembler. + * The module asdata.c contains the global constants, + * structures, and variables used in the assembler. */ -int aserr; /* ASxxxx error counter - */ -jmp_buf jump_env; /* compiler dependent structure - * used by setjmp() and longjmp() - */ -int inpfil; /* count of assembler - * input files specified - */ -int incfil; /* current file handle index - * for include files - */ -int cfile; /* current file handle index - * of input assembly files - */ -int flevel; /* IF-ELSE-ENDIF flag will be non - * zero for false conditional case - */ -int tlevel; /* current conditional level - */ -int ifcnd[MAXIF+1]; /* array of IF statement condition - * values (0 = FALSE) indexed by tlevel - */ -int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel - * values indexed by tlevel - */ +int aserr; /* ASxxxx error counter + */ +jmp_buf jump_env; /* compiler dependent structure + * used by setjmp() and longjmp() + */ +int inpfil; /* count of assembler + * input files specified + */ +int incfil; /* current file handle index + * for include files + */ +int cfile; /* current file handle index + * of input assembly files + */ +int flevel; /* IF-ELSE-ENDIF flag will be non + * zero for false conditional case + */ +int tlevel; /* current conditional level + */ +int ifcnd[MAXIF+1]; /* array of IF statement condition + * values (0 = FALSE) indexed by tlevel + */ +int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel + * values indexed by tlevel + */ -char afn[PATH_MAX]; /* afile temporary file name - */ -char srcfn[MAXFIL][PATH_MAX]; /* array of source file names - */ -int srcline[MAXFIL]; /* source line number - */ -char incfn[MAXINC][PATH_MAX]; /* array of include file names - */ -int incline[MAXINC]; /* include line number - */ +char afn[PATH_MAX]; /* afile temporary file name + */ +char srcfn[MAXFIL][PATH_MAX];/* array of source file names + */ +int srcline[MAXFIL]; /* source line number + */ +char incfn[MAXINC][PATH_MAX];/* array of include file names + */ +int incline[MAXINC]; /* include line number + */ -int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -int line; /* current assembler source - * line number - */ -int page; /* current page number - */ -int lop; /* current line number on page - */ -int pass; /* assembler pass number - */ -int lflag; /* -l, generate listing flag - */ -int cflag; /* -lc, generate sdcdb debug info - */ -int gflag; /* -g, make undefined symbols global flag - */ -int aflag; /* -a, make all symbols global flag - */ -int jflag; /* -j, generate debug information flag - */ -int oflag; /* -o, generate relocatable output flag - */ -int sflag; /* -s, generate symbol table flag - */ -int pflag; /* -p, enable listing pagination - */ -int xflag; /* -x, listing radix flag - */ -int fflag; /* -f(f), relocations flagged flag - */ -Addr_T laddr; /* address of current assembler line - * or value of .if argument - */ -Addr_T fuzz; /* tracks pass to pass changes in the - * address of symbols caused by - * variable length instruction formats - */ -int lmode; /* listing mode - */ -char *ep; /* pointer into error list - * array eb[NERR] - */ -char eb[NERR]; /* array of generated error codes - */ -char *ip; /* pointer into the assembler-source - * text line in ib[] - */ -char ib[NINPUT]; /* assembler-source text line - */ -char *cp; /* pointer to assembler output - * array cb[] - */ -char cb[NCODE]; /* array of assembler output values - */ -int *cpt; /* pointer to assembler relocation type - * output array cbt[] - */ -int cbt[NCODE]; /* array of assembler relocation types - * describing the data in cb[] - */ -char tb[NTITL]; /* Title string buffer - */ -char stb[NSBTL]; /* Subtitle string buffer - */ -char optsdcc[NINPUT]; /* sdcc compile options - */ -int flat24Mode; /* non-zero if we are using DS390 24 bit - * flat mode (via .flat24 directive). - */ +int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +int line; /* current assembler source + * line number + */ +int page; /* current page number + */ +int lop; /* current line number on page + */ +int pass; /* assembler pass number + */ +int lflag; /* -l, generate listing flag + */ +int cflag; /* -lc, generate sdcdb debug info + */ +int gflag; /* -g, make undefined symbols global flag + */ +int aflag; /* -a, make all symbols global flag + */ +int jflag; /* -j, generate debug information flag + */ +int oflag; /* -o, generate relocatable output flag + */ +int sflag; /* -s, generate symbol table flag + */ +int pflag; /* -p, enable listing pagination + */ +int xflag; /* -x, listing radix flag + */ +int fflag; /* -f(f), relocations flagged flag + */ +Addr_T laddr; /* address of current assembler line + * or value of .if argument + */ +Addr_T fuzz; /* tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + */ +int lmode; /* listing mode + */ +char *ep; /* pointer into error list + * array eb[NERR] + */ +char eb[NERR]; /* array of generated error codes + */ +char *ip; /* pointer into the assembler-source + * text line in ib[] + */ +char ib[NINPUT]; /* assembler-source text line + */ +char *cp; /* pointer to assembler output + * array cb[] + */ +char cb[NCODE]; /* array of assembler output values + */ +int *cpt; /* pointer to assembler relocation type + * output array cbt[] + */ +int cbt[NCODE]; /* array of assembler relocation types + * describing the data in cb[] + */ +char tb[NTITL]; /* Title string buffer + */ +char stb[NSBTL]; /* Subtitle string buffer + */ +char optsdcc[NINPUT]; /* sdcc compile options + */ +int flat24Mode; /* non-zero if we are using DS390 24 bit + * flat mode (via .flat24 directive). + */ -char symtbl[] = { "Symbol Table" }; -char aretbl[] = { "Area Table" }; +char symtbl[] = { "Symbol Table" }; +char aretbl[] = { "Area Table" }; -char module[NCPS]; /* module name string - */ +char module[NCPS]; /* module name string + */ /* - * The mne structure is a linked list of the assembler - * mnemonics and directives. The list of mnemonics and - * directives contained in the device dependent file - * xxxpst.c are hashed and linked into NHASH lists in - * module assym.c by syminit(). The structure contains - * the mnemonic/directive name, a subtype which directs - * the evaluation of this mnemonic/directive, a flag which - * is used to detect the end of the mnemonic/directive - * list in xxxpst.c, and a value which is normally - * associated with the assembler mnemonic base instruction - * value. + * The mne structure is a linked list of the assembler + * mnemonics and directives. The list of mnemonics and + * directives contained in the device dependent file + * xxxpst.c are hashed and linked into NHASH lists in + * module assym.c by syminit(). The structure contains + * the mnemonic/directive name, a subtype which directs + * the evaluation of this mnemonic/directive, a flag which + * is used to detect the end of the mnemonic/directive + * list in xxxpst.c, and a value which is normally + * associated with the assembler mnemonic base instruction + * value. * - * struct mne - * { - * struct mne *m_mp; Hash link - * char m_id[NCPS]; Mnemonic - * char m_type; Mnemonic subtype - * char m_flag; Mnemonic flags - * Addr_T m_valu; Value - * }; + * struct mne + * { + * struct mne *m_mp; Hash link + * char m_id[NCPS]; Mnemonic + * char m_type; Mnemonic subtype + * char m_flag; Mnemonic flags + * Addr_T m_valu; Value + * }; */ -struct mne *mnehash[NHASH]; +struct mne *mnehash[NHASH]; /* - * The sym structure is a linked list of symbols defined - * in the assembler source files. The first symbol is "." - * defined here. The entry 'struct tsym *s_tsym' - * links any temporary symbols following this symbol and - * preceeding the next normal symbol. The structure also - * contains the symbol's name, type (USER or NEW), flag - * (global, assigned, and multiply defined), a pointer - * to the area structure defining where the symbol is - * located, a reference number assigned by outgsd() in - * asout.c, and the symbols address relative to the base - * address of the area where the symbol is located. + * The sym structure is a linked list of symbols defined + * in the assembler source files. The first symbol is "." + * defined here. The entry 'struct tsym *s_tsym' + * links any temporary symbols following this symbol and + * preceeding the next normal symbol. The structure also + * contains the symbol's name, type (USER or NEW), flag + * (global, assigned, and multiply defined), a pointer + * to the area structure defining where the symbol is + * located, a reference number assigned by outgsd() in + * asout.c, and the symbols address relative to the base + * address of the area where the symbol is located. * - * struct sym - * { - * struct sym *s_sp; Hash link - * struct tsym *s_tsym; Temporary symbol link - * char *s_id; Symbol (JLH) - * char s_type; Symbol subtype - * char s_flag; Symbol flags - * struct area *s_area; Area line, 0 if absolute - * int s_ref; Ref. number - * Addr_T s_addr; Address - * }; + * struct sym + * { + * struct sym *s_sp; Hash link + * struct tsym *s_tsym; Temporary symbol link + * char *s_id; Symbol (JLH) + * char s_type; Symbol subtype + * char s_flag; Symbol flags + * struct area *s_area; Area line, 0 if absolute + * int s_ref; Ref. number + * Addr_T s_addr; Address + * }; */ -struct sym sym[] = { - {NULL, NULL, ".", S_USER, S_END, NULL, 0, 0} +struct sym sym[] = { + {NULL, NULL, ".", S_USER, S_END, NULL, 0, 0} }; -struct sym *symp; /* pointer to a symbol structure - */ -struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ +struct sym *symp; /* pointer to a symbol structure + */ +struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ /* - * The area structure contains the parameter values for a - * specific program or data section. The area structure - * is a linked list of areas. The initial default area - * is "_CODE" defined here, the next area structure - * will be linked to this structure through the structure - * element 'struct area *a_ep'. The structure contains the - * area name, area reference number ("_CODE" is 0) determined - * by the order of .area directives, area size determined - * from the total code and/or data in an area, area fuzz is - * an variable used to track pass to pass changes in the - * area size caused by variable length instruction formats, - * and area flags which specify the area's relocation type. + * The area structure contains the parameter values for a + * specific program or data section. The area structure + * is a linked list of areas. The initial default area + * is "_CODE" defined here, the next area structure + * will be linked to this structure through the structure + * element 'struct area *a_ep'. The structure contains the + * area name, area reference number ("_CODE" is 0) determined + * by the order of .area directives, area size determined + * from the total code and/or data in an area, area fuzz is + * an variable used to track pass to pass changes in the + * area size caused by variable length instruction formats, + * and area flags which specify the area's relocation type. * - * struct area - * { - * struct area *a_ap; Area link - * char a_id[NCPS]; Area Name - * int a_ref; Reference number - * Addr_T a_size; Area size - * Addr_T a_fuzz; Area fuzz - * int a_flag; Area flags - * }; + * struct area + * { + * struct area *a_ap; Area link + * char a_id[NCPS]; Area Name + * int a_ref; Reference number + * Addr_T a_size; Area size + * Addr_T a_fuzz; Area fuzz + * int a_flag; Area flags + * }; */ -struct area area[] = { - {NULL, "_CODE", 0, 0, 0, A_CON|A_REL} +struct area area[] = { + {NULL, "_CODE", 0, 0, 0, A_CON|A_REL} }; -struct area *areap; /* pointer to an area structure - */ +struct area *areap; /* pointer to an area structure + */ -FILE *lfp; /* list output file handle - */ -FILE *ofp; /* relocation output file handle - */ -FILE *tfp; /* symbol table output file handle - */ -FILE *sfp[MAXFIL]; /* array of assembler-source file handles - */ -FILE *ifp[MAXINC]; /* array of include-file file handles - */ +FILE *lfp; /* list output file handle + */ +FILE *ofp; /* relocation output file handle + */ +FILE *tfp; /* symbol table output file handle + */ +FILE *sfp[MAXFIL]; /* array of assembler-source file handles + */ +FILE *ifp[MAXINC]; /* array of include-file file handles + */ /* - * array of character types, one per - * ASCII character + * array of character types, one per + * ASCII character */ -unsigned char ctype[128] = { -/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, -/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, -/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, -/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, -/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, -/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*X*/ LETTER, LETTER, LETTER, ETC, ETC, ETC, BINOP, LETTER, -/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC +unsigned char ctype[128] = { +/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, +/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, +/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, +/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, +/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, +/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*X*/ LETTER, LETTER, LETTER, BINOP, ETC, ETC, BINOP, LETTER, +/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC }; /* - * an array of characters which - * perform the case translation function + * an array of characters which + * perform the case translation function */ -char ccase[128] = { -/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', -/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', -/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', -/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', -/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', -/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', -/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', -/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', -/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', -/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' -}; +char ccase[128] = { +/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', +/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', +/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', +/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', +/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', +/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', +/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', +/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', +/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', +/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' +}; diff --git a/as/mcs51/asexpr.c b/as/mcs51/asexpr.c index 8eb5519f..4bef5594 100644 --- a/as/mcs51/asexpr.c +++ b/as/mcs51/asexpr.c @@ -1,4 +1,4 @@ - /* asexpr.c */ +/* asexpr.c */ /* * (C) Copyright 1989-1995 @@ -88,7 +88,7 @@ expr(register struct expr *esp, int n) term(esp); while (ctype[c = getnb()] & BINOP) { /* - * Handle binary operators + - * / & | % ^ << >> + * Handle binary operators + - * / & | % ^ << >> [ */ if ((p = oprio(c)) <= n) break; @@ -217,6 +217,21 @@ expr(register struct expr *esp, int n) abscheck(esp); esp->e_addr >>= re.e_addr; break; + case '[': + /* MB added [ for bit access in bdata */ + abscheck(&re); + if (getnb() != ']') + qerr(); + + /* if the left is a relative address then */ + if (esp->e_base.e_ap) { + esp->e_addr |= (re.e_addr | 0x80) << 8; + break; + } + else if ((esp->e_addr & 0x87) == 0x80) { + esp->e_addr |= re.e_addr; + break; + } default: qerr(); @@ -505,6 +520,11 @@ term(register struct expr *esp) esp->e_mode = sp->s_type; esp->e_addr = sp->s_addr; esp->e_base.e_ap = sp->s_area; + /* MB: abused bit 15 of s_addr to indicate bit-addressable bytes */ + if ((sp->s_addr & 0x8000) && sp->s_area && + (!strcmp(sp->s_area->a_id, "BSEG_BYTES") || !strcmp(sp->s_area->a_id, "BIT_BANK"))) { + esp->e_rlcf |= R_BIT | R_BYT2; + } } return; } @@ -658,6 +678,8 @@ is_abs (register struct expr *esp) int oprio(register int c) { + if (c == '[') + return (12); if (c == '*' || c == '/' || c == '%') return (10); if (c == '+' || c == '-') diff --git a/as/mcs51/aslink.h b/as/mcs51/aslink.h index ace467ef..79a84969 100644 --- a/as/mcs51/aslink.h +++ b/as/mcs51/aslink.h @@ -8,87 +8,87 @@ * 721 Berkeley St. * Kent, Ohio 44240 * - * 28-Oct-97 JLH: - * - add proto for StoreString - * - change s_id from [NCPS] to pointer - * - change NCPS to 80 + * 28-Oct-97 JLH: + * - add proto for StoreString + * - change s_id from [NCPS] to pointer + * - change NCPS to 80 * - case sensitive * - add R_J11 for 8051 assembler - * 31-Oct-97 JLH: + * 31-Oct-97 JLH: * - add jflag and jfp for NoICE output * 30-Jan-98 JLH: * - add memory space flags to a_flag for 8051 */ -#define VERSION "V01.70 + NoICE + SDCC Feb 1999" +#define VERSION "V01.70 + NoICE + SDCC Feb 1999" /* * Case Sensitivity Flag */ -#define CASE_SENSITIVE 1 +#define CASE_SENSITIVE 1 -/*)Module asmlnk.h +/*)Module asmlnk.h * - * The module asmlnk.h contains the definitions for constants, - * structures, global variables, and LKxxxx functions - * contained in the LKxxxx.c files. + * The module asmlnk.h contains the definitions for constants, + * structures, global variables, and LKxxxx functions + * contained in the LKxxxx.c files. */ /*)BUILD - $(PROGRAM) = ASLINK - $(INCLUDE) = ASLINK.H - $(FILES) = { - LKMAIN.C - LKLEX.C - LKAREA.C - LKHEAD.C - LKSYM.C - LKEVAL.C - LKDATA.C - LKLIST.C - LKRLOC.C - LKLIBR.C - LKS19.C - LKIHX.C - } - $(STACK) = 2000 + $(PROGRAM) = ASLINK + $(INCLUDE) = ASLINK.H + $(FILES) = { + LKMAIN.C + LKLEX.C + LKAREA.C + LKHEAD.C + LKSYM.C + LKEVAL.C + LKDATA.C + LKLIST.C + LKRLOC.C + LKLIBR.C + LKS19.C + LKIHX.C + } + $(STACK) = 2000 */ /* DECUS C void definition */ /* File/extension seperator */ -#ifdef decus -#define VOID char -#define FSEPX '.' +#ifdef decus +#define VOID char +#define FSEPX '.' #endif /* PDOS C void definition */ /* File/extension seperator */ -#ifdef PDOS -#define VOID char -#define FSEPX ':' +#ifdef PDOS +#define VOID char +#define FSEPX ':' #endif /* Default void definition */ /* File/extension seperator */ -#ifndef VOID -#define VOID void -#define FSEPX '.' -#define OTHERSYSTEM +#ifndef VOID +#define VOID void +#define FSEPX '.' +#define OTHERSYSTEM #endif /* * PATH_MAX */ #include -#ifndef PATH_MAX /* POSIX, but not required */ +#ifndef PATH_MAX /* POSIX, but not required */ #if defined(__BORLANDC__) || defined(_MSC_VER) #include - #define PATH_MAX _MAX_PATH + #define PATH_MAX _MAX_PATH #else - #define PATH_MAX 255 /* define a reasonable value */ + #define PATH_MAX 255 /* define a reasonable value */ #endif #endif @@ -97,60 +97,64 @@ * relocatable binary file. */ -#define NCPS 80 /* characters per symbol (JLH: change from 8) */ -#define NDATA 16 /* actual data */ -#define NINPUT PATH_MAX /* Input buffer size */ -#define NHASH 64 /* Buckets in hash table */ -#define HMASK 077 /* Hash mask */ -#define NLPP 60 /* Lines per page */ -#define NTXT 16 /* T values */ +#define NCPS 80 /* characters per symbol (JLH: change from 8) */ +#define NDATA 16 /* actual data */ +#define NINPUT PATH_MAX /* Input buffer size */ +#define NHASH 64 /* Buckets in hash table */ +#define HMASK 077 /* Hash mask */ +#define NLPP 60 /* Lines per page */ +#define NTXT 16 /* T values */ /* - * The "R_" relocation constants define values used in - * generating the assembler relocation output data for - * areas, symbols, and code. + * The "R_" relocation constants define values used in + * generating the assembler relocation output data for + * areas, symbols, and code. * * - * Relocation types. + * Relocation types. * - * 7 6 5 4 3 2 1 0 - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT | - * +-----+-----+-----+-----+-----+-----+-----+-----+ + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT | + * +-----+-----+-----+-----+-----+-----+-----+-----+ */ -#define R_WORD 0x00 /* 16 bit */ -#define R_BYTE 0x01 /* 8 bit */ +#define R_WORD 0x00 /* 16 bit */ +#define R_BYTE 0x01 /* 8 bit */ -#define R_AREA 0x00 /* Base type */ -#define R_SYM 0x02 +#define R_AREA 0x00 /* Base type */ +#define R_SYM 0x02 -#define R_NORM 0x00 /* PC adjust */ -#define R_PCR 0x04 +#define R_NORM 0x00 /* PC adjust */ +#define R_PCR 0x04 -#define R_BYT1 0x00 /* Byte count for R_BYTE = 1 */ -#define R_BYT2 0x08 /* Byte count for R_BYTE = 2 */ +#define R_BYT1 0x00 /* Byte count for R_BYTE = 1 */ +#define R_BYT2 0x08 /* Byte count for R_BYTE = 2 */ -#define R_SGND 0x00 /* Signed Byte */ -#define R_USGN 0x10 /* Unsigned Byte */ +#define R_SGND 0x00 /* Signed Byte */ +#define R_USGN 0x10 /* Unsigned Byte */ -#define R_NOPAG 0x00 /* Page Mode */ -#define R_PAG0 0x20 /* Page '0' */ -#define R_PAG 0x40 /* Page 'nnn' */ +#define R_NOPAG 0x00 /* Page Mode */ +#define R_PAG0 0x20 /* Page '0' */ +#define R_PAG 0x40 /* Page 'nnn' */ -#define R_LSB 0x00 /* low byte */ -#define R_MSB 0x80 /* high byte */ +#define R_LSB 0x00 /* low byte */ +#define R_MSB 0x80 /* high byte */ -#define R_BYT3 0x100 /* if R_BYTE is set, this is a - * 3 byte address, of which - * the linker must select one byte. - */ -#define R_HIB 0x200 /* If R_BYTE & R_BYT3 are set, linker - * will select byte 3 of the relocated - * 24 bit address. - */ +#define R_BYT3 0x100 /* if R_BYTE is set, this is a + * 3 byte address, of which + * the linker must select one byte. + */ +#define R_HIB 0x200 /* If R_BYTE & R_BYT3 are set, linker + * will select byte 3 of the relocated + * 24 bit address. + */ -#define R_J11 (R_WORD|R_BYT2) /* JLH: 11 bit JMP and CALL (8051) */ +#define R_BIT 0x400 /* Linker will convert from byte-addressable + * space to bit-addressable space. + */ + +#define R_J11 (R_WORD|R_BYT2) /* JLH: 11 bit JMP and CALL (8051) */ #define R_J19 (R_WORD|R_BYT2|R_MSB) /* 19 bit JMP/CALL (DS80C390) */ #define R_C24 (R_WORD|R_BYT1|R_MSB) /* 24 bit address (DS80C390) */ #define R_J19_MASK (R_BYTE|R_BYT2|R_MSB) @@ -159,616 +163,618 @@ #define IS_R_J11(x) (((x) & R_J19_MASK) == R_J11) #define IS_C24(x) (((x) & R_J19_MASK) == R_C24) -#define R_ESCAPE_MASK 0xf0 /* Used to escape relocation modes - * greater than 0xff in the .rel - * file. - */ +#define R_ESCAPE_MASK 0xf0 /* Used to escape relocation modes + * greater than 0xff in the .rel + * file. + */ /* * Global symbol types. */ -#define S_REF 1 /* referenced */ -#define S_DEF 2 /* defined */ +#define S_REF 1 /* referenced */ +#define S_DEF 2 /* defined */ /* * Area type flags */ -#define A_CON 0000 /* concatenate */ -#define A_OVR 0004 /* overlay */ -#define A_REL 0000 /* relocatable */ -#define A_ABS 0010 /* absolute */ -#define A_NOPAG 0000 /* non-paged */ -#define A_PAG 0020 /* paged */ +#define A_CON 0000 /* concatenate */ +#define A_OVR 0004 /* overlay */ +#define A_REL 0000 /* relocatable */ +#define A_ABS 0010 /* absolute */ +#define A_NOPAG 0000 /* non-paged */ +#define A_PAG 0020 /* paged */ /* Additional flags for 8051 address spaces */ -#define A_DATA 0000 /* data space (default)*/ -#define A_CODE 0040 /* code space */ -#define A_XDATA 0100 /* external data space */ -#define A_BIT 0200 /* bit addressable space */ +#define A_DATA 0000 /* data space (default)*/ +#define A_CODE 0040 /* code space */ +#define A_XDATA 0100 /* external data space */ +#define A_BIT 0200 /* bit addressable space */ /* * File types */ -#define F_STD 1 /* stdin */ -#define F_LNK 2 /* File.lnk */ -#define F_REL 3 /* File.rel */ +#define F_STD 1 /* stdin */ +#define F_LNK 2 /* File.lnk */ +#define F_REL 3 /* File.rel */ /* - * General assembler address type + * General assembler address type */ typedef unsigned int Addr_T; /* - * The structures of head, area, areax, and sym are created - * as the REL files are read during the first pass of the - * linker. The struct head is created upon encountering a - * H directive in the REL file. The structure contains a - * link to a link file structure (struct lfile) which describes - * the file containing the H directive, the number of data/code - * areas contained in this header segment, the number of - * symbols referenced/defined in this header segment, a pointer - * to an array of pointers to areax structures (struct areax) - * created as each A directive is read, and a pointer to an - * array of pointers to symbol structures (struct sym) for - * all referenced/defined symbols. As H directives are read - * from the REL files a linked list of head structures is - * created by placing a link to the new head structure - * in the previous head structure. + * The structures of head, area, areax, and sym are created + * as the REL files are read during the first pass of the + * linker. The struct head is created upon encountering a + * H directive in the REL file. The structure contains a + * link to a link file structure (struct lfile) which describes + * the file containing the H directive, the number of data/code + * areas contained in this header segment, the number of + * symbols referenced/defined in this header segment, a pointer + * to an array of pointers to areax structures (struct areax) + * created as each A directive is read, and a pointer to an + * array of pointers to symbol structures (struct sym) for + * all referenced/defined symbols. As H directives are read + * from the REL files a linked list of head structures is + * created by placing a link to the new head structure + * in the previous head structure. */ -struct head +struct head { - struct head *h_hp; /* Header link */ - struct lfile *h_lfile;/* Associated file */ - int h_narea; /* # of areas */ - struct areax **a_list; /* Area list */ - int h_nglob; /* # of global symbols */ - struct sym **s_list; /* Globle symbol list */ - char m_id[NCPS]; /* Module name */ + struct head *h_hp; /* Header link */ + struct lfile *h_lfile;/* Associated file */ + int h_narea; /* # of areas */ + struct areax **a_list; /* Area list */ + int h_nglob; /* # of global symbols */ + struct sym **s_list; /* Globle symbol list */ + char m_id[NCPS]; /* Module name */ }; /* - * A structure area is created for each 'unique' data/code - * area definition found as the REL files are read. The - * struct area contains the name of the area, a flag byte - * which contains the area attributes (REL/CON/OVR/ABS), - * an area subtype (not used in this assembler), and the - * area base address and total size which will be filled - * in at the end of the first pass through the REL files. - * As A directives are read from the REL files a linked - * list of unique area structures is created by placing a - * link to the new area structure in the previous area structure. + * A structure area is created for each 'unique' data/code + * area definition found as the REL files are read. The + * struct area contains the name of the area, a flag byte + * which contains the area attributes (REL/CON/OVR/ABS), + * an area subtype (not used in this assembler), and the + * area base address and total size which will be filled + * in at the end of the first pass through the REL files. + * As A directives are read from the REL files a linked + * list of unique area structures is created by placing a + * link to the new area structure in the previous area structure. */ -struct area +struct area { - struct area *a_ap; /* Area link */ - struct areax *a_axp; /* Area extension link */ - Addr_T a_addr; /* Beginning address of area */ - Addr_T a_size; /* Total size of the area */ - Addr_T a_unaloc; /* Total number of unalocated bytes, for error reporting */ - char a_type; /* Area subtype */ - char a_flag; /* Flag byte */ - char a_id[NCPS]; /* Name */ + struct area *a_ap; /* Area link */ + struct areax *a_axp; /* Area extension link */ + Addr_T a_addr; /* Beginning address of area */ + Addr_T a_size; /* Total size of the area */ + Addr_T a_unaloc; /* Total number of unalocated bytes, for error reporting */ + char a_type; /* Area subtype */ + char a_flag; /* Flag byte */ + char a_id[NCPS]; /* Name */ }; /* - * An areax structure is created for every A directive found - * while reading the REL files. The struct areax contains a - * link to the 'unique' area structure referenced by the A - * directive and to the head structure this area segment is - * a part of. The size of this area segment as read from the - * A directive is placed in the areax structure. The beginning - * address of this segment will be filled in at the end of the - * first pass through the REL files. As A directives are read - * from the REL files a linked list of areax structures is - * created for each unique area. The final areax linked - * list has at its head the 'unique' area structure linked - * to the linked areax structures (one areax structure for - * each A directive for this area). + * An areax structure is created for every A directive found + * while reading the REL files. The struct areax contains a + * link to the 'unique' area structure referenced by the A + * directive and to the head structure this area segment is + * a part of. The size of this area segment as read from the + * A directive is placed in the areax structure. The beginning + * address of this segment will be filled in at the end of the + * first pass through the REL files. As A directives are read + * from the REL files a linked list of areax structures is + * created for each unique area. The final areax linked + * list has at its head the 'unique' area structure linked + * to the linked areax structures (one areax structure for + * each A directive for this area). */ -struct areax +struct areax { - struct areax *a_axp; /* Area extension link */ - struct area *a_bap; /* Base area link */ - struct head *a_bhp; /* Base header link */ - Addr_T a_addr; /* Beginning address of section */ - Addr_T a_size; /* Size of the area in section */ + struct areax *a_axp; /* Area extension link */ + struct area *a_bap; /* Base area link */ + struct head *a_bhp; /* Base header link */ + Addr_T a_addr; /* Beginning address of section */ + Addr_T a_size; /* Size of the area in section */ }; /* - * A sym structure is created for every unique symbol - * referenced/defined while reading the REL files. The - * struct sym contains the symbol's name, a flag value - * (not used in this linker), a symbol type denoting - * referenced/defined, and an address which is loaded - * with the relative address within the area in which - * the symbol was defined. The sym structure also - * contains a link to the area where the symbol was defined. - * The sym structures are linked into linked lists using - * the symbol link element. + * A sym structure is created for every unique symbol + * referenced/defined while reading the REL files. The + * struct sym contains the symbol's name, a flag value + * (not used in this linker), a symbol type denoting + * referenced/defined, and an address which is loaded + * with the relative address within the area in which + * the symbol was defined. The sym structure also + * contains a link to the area where the symbol was defined. + * The sym structures are linked into linked lists using + * the symbol link element. */ -struct sym +struct sym { - struct sym *s_sp; /* Symbol link */ - struct areax *s_axp; /* Symbol area link */ - char s_type; /* Symbol subtype */ - char s_flag; /* Flag byte */ - Addr_T s_addr; /* Address */ - char *s_id; /* Name: JLH change from [NCPS] */ + struct sym *s_sp; /* Symbol link */ + struct areax *s_axp; /* Symbol area link */ + char s_type; /* Symbol subtype */ + char s_flag; /* Flag byte */ + Addr_T s_addr; /* Address */ + char *s_id; /* Name: JLH change from [NCPS] */ }; /* - * The structure lfile contains a pointer to a - * file specification string, the file type, and - * a link to the next lfile structure. + * The structure lfile contains a pointer to a + * file specification string, the file type, and + * a link to the next lfile structure. */ -struct lfile +struct lfile { - struct lfile *f_flp; /* lfile link */ - int f_type; /* File type */ - char *f_idp; /* Pointer to file spec */ + struct lfile *f_flp; /* lfile link */ + int f_type; /* File type */ + char *f_idp; /* Pointer to file spec */ }; /* - * The struct base contains a pointer to a - * base definition string and a link to the next - * base structure. + * The struct base contains a pointer to a + * base definition string and a link to the next + * base structure. */ -struct base +struct base { - struct base *b_base; /* Base link */ - char *b_strp; /* String pointer */ + struct base *b_base; /* Base link */ + char *b_strp; /* String pointer */ }; /* - * The struct globl contains a pointer to a - * global definition string and a link to the next - * global structure. + * The struct globl contains a pointer to a + * global definition string and a link to the next + * global structure. */ -struct globl +struct globl { - struct globl *g_globl; /* Global link */ - char *g_strp; /* String pointer */ + struct globl *g_globl; /* Global link */ + char *g_strp; /* String pointer */ }; /* - * A structure sdp is created for each 'unique' paged - * area definition found as the REL files are read. - * As P directives are read from the REL files a linked - * list of unique sdp structures is created by placing a - * link to the new sdp structure in the previous area structure. + * A structure sdp is created for each 'unique' paged + * area definition found as the REL files are read. + * As P directives are read from the REL files a linked + * list of unique sdp structures is created by placing a + * link to the new sdp structure in the previous area structure. */ -struct sdp +struct sdp { - struct area *s_area; /* Paged Area link */ - struct areax *s_areax; /* Paged Area Extension Link */ - Addr_T s_addr; /* Page address offset */ + struct area *s_area; /* Paged Area link */ + struct areax *s_areax; /* Paged Area Extension Link */ + Addr_T s_addr; /* Page address offset */ }; /* - * The structure rerr is loaded with the information - * required to report an error during the linking - * process. The structure contains an index value - * which selects the areax structure from the header - * areax structure list, a mode value which selects - * symbol or area relocation, the base address in the - * area section, an area/symbol list index value, and - * an area/symbol offset value. + * The structure rerr is loaded with the information + * required to report an error during the linking + * process. The structure contains an index value + * which selects the areax structure from the header + * areax structure list, a mode value which selects + * symbol or area relocation, the base address in the + * area section, an area/symbol list index value, and + * an area/symbol offset value. */ -struct rerr +struct rerr { - int aindex; /* Linking area */ - int mode; /* Relocation mode */ - Addr_T rtbase; /* Base address in section */ - int rindex; /* Area/Symbol reloaction index */ - Addr_T rval; /* Area/Symbol offset value */ + int aindex; /* Linking area */ + int mode; /* Relocation mode */ + Addr_T rtbase; /* Base address in section */ + int rindex; /* Area/Symbol reloaction index */ + Addr_T rval; /* Area/Symbol offset value */ }; /* - * The structure lbpath is created for each library - * path specification input by the -k option. The - * lbpath structures are linked into a list using - * the next link element. + * The structure lbpath is created for each library + * path specification input by the -k option. The + * lbpath structures are linked into a list using + * the next link element. */ struct lbpath { - struct lbpath *next; - char *path; + struct lbpath *next; + char *path; }; /* - * The structure lbname is created for all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file. The element path points to - * the path string, element libfil points to the library - * file string, and the element libspc is the concatenation - * of the valid path and libfil strings. + * The structure lbname is created for all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file. The element path points to + * the path string, element libfil points to the library + * file string, and the element libspc is the concatenation + * of the valid path and libfil strings. * - * The lbpath structures are linked into a list - * using the next link element. + * The lbpath structures are linked into a list + * using the next link element. * - * Each library file contains a list of object files - * that are contained in the particular library. e.g.: + * Each library file contains a list of object files + * that are contained in the particular library. e.g.: * - * \iolib\termio - * \inilib\termio + * \iolib\termio + * \inilib\termio * - * Only one specification per line is allowed. + * Only one specification per line is allowed. */ struct lbname { - struct lbname *next; - char *path; - char *libfil; - char *libspc; + struct lbname *next; + char *path; + char *libfil; + char *libspc; }; /* - * The function fndsym() searches through all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file for a symbol definition. + * The function fndsym() searches through all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file for a symbol definition. * - * The structure lbfile is created for the first library - * object file which contains the definition for the - * specified undefined symbol. + * The structure lbfile is created for the first library + * object file which contains the definition for the + * specified undefined symbol. * - * The element libspc points to the library file path specification - * and element relfil points to the object file specification string. - * The element filspc is the complete path/file specification for - * the library file to be imported into the linker. The - * file specicifation may be formed in one of two ways: + * The element libspc points to the library file path specification + * and element relfil points to the object file specification string. + * The element filspc is the complete path/file specification for + * the library file to be imported into the linker. The + * file specicifation may be formed in one of two ways: * - * (1) If the library file contained an absolute - * path/file specification then this becomes filspc. - * (i.e. C:\...) + * (1) If the library file contained an absolute + * path/file specification then this becomes filspc. + * (i.e. C:\...) * - * (2) If the library file contains a relative path/file - * specification then the concatenation of the path - * and this file specification becomes filspc. - * (i.e. \...) + * (2) If the library file contains a relative path/file + * specification then the concatenation of the path + * and this file specification becomes filspc. + * (i.e. \...) * - * The lbpath structures are linked into a list - * using the next link element. + * The lbpath structures are linked into a list + * using the next link element. */ struct lbfile { - struct lbfile *next; - char *libspc; - char *relfil; - char *filspc; - long offset; /*>=0 if rel file is embedded in a lib file at this offset*/ + struct lbfile *next; + char *libspc; + char *relfil; + char *filspc; + long offset; /*>=0 if rel file is embedded in a lib file at this offset*/ }; /* - * External Definitions for all Global Variables + * External Definitions for all Global Variables */ -extern char *_abs_; /* = { ". .ABS." }; - */ -extern int lkerr; /* ASLink error flag - */ -extern char *ip; /* pointer into the REL file - * text line in ib[] - */ -extern char ib[NINPUT]; /* REL file text line - */ -extern char *rp; /* pointer into the LST file - * text line in rb[] - */ -extern char rb[NINPUT]; /* LST file text line being - * address relocated - */ -extern unsigned char ctype[]; /* array of character types, one per - * ASCII character - */ +extern char *_abs_; /* = { ". .ABS." }; + */ +extern int lkerr; /* ASLink error flag + */ +extern char *ip; /* pointer into the REL file + * text line in ib[] + */ +extern char ib[NINPUT]; /* REL file text line + */ +extern char *rp; /* pointer into the LST file + * text line in rb[] + */ +extern char rb[NINPUT]; /* LST file text line being + * address relocated + */ +extern unsigned char ctype[]; /* array of character types, one per + * ASCII character + */ extern char sdccopt[NINPUT]; extern char sdccopt_module[NINPUT]; extern char curr_module[NINPUT]; /* - * Character Type Definitions + * Character Type Definitions */ -#define SPACE 0000 -#define ETC 0000 -#define LETTER 0001 -#define DIGIT 0002 -#define BINOP 0004 -#define RAD2 0010 -#define RAD8 0020 -#define RAD10 0040 -#define RAD16 0100 -#define ILL 0200 - -#define DGT2 DIGIT|RAD16|RAD10|RAD8|RAD2 -#define DGT8 DIGIT|RAD16|RAD10|RAD8 -#define DGT10 DIGIT|RAD16|RAD10 -#define LTR16 LETTER|RAD16 - -#if CASE_SENSITIVE +#define SPACE 0000 +#define ETC 0000 +#define LETTER 0001 +#define DIGIT 0002 +#define BINOP 0004 +#define RAD2 0010 +#define RAD8 0020 +#define RAD10 0040 +#define RAD16 0100 +#define ILL 0200 + +#define DGT2 DIGIT|RAD16|RAD10|RAD8|RAD2 +#define DGT8 DIGIT|RAD16|RAD10|RAD8 +#define DGT10 DIGIT|RAD16|RAD10 +#define LTR16 LETTER|RAD16 + +#if CASE_SENSITIVE #else -extern char ccase[]; /* an array of characters which - * perform the case translation function - */ +extern char ccase[]; /* an array of characters which + * perform the case translation function + */ #endif -extern struct lfile *filep; /* The pointers (lfile *) filep, - * (lfile *) cfp, and (FILE *) sfp - * are used in conjunction with - * the routine getline() to read - * asmlnk commands from - * (1) the standard input or - * (2) or a command file - * and to read the REL files - * sequentially as defined by the - * asmlnk input commands. - * - * The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - */ -extern struct lfile *cfp; /* The pointer *cfp points to the - * current lfile structure - */ -extern struct lfile *startp;/* asmlnk startup file structure - */ -extern struct lfile *linkp; /* pointer to first lfile structure - * containing an input REL file - * specification - */ -extern struct lfile *lfp; /* pointer to current lfile structure - * being processed by parse() - */ -extern struct head *headp; /* The pointer to the first - * head structure of a linked list - */ -extern struct head *hp; /* Pointer to the current - * head structure - */ -extern struct area *areap; /* The pointer to the first - * area structure of a linked list - */ -extern struct area *ap; /* Pointer to the current - * area structure - */ -extern struct areax *axp; /* Pointer to the current - * areax structure - */ -extern struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ -extern struct base *basep; /* The pointer to the first - * base structure - */ -extern struct base *bsp; /* Pointer to the current - * base structure - */ -extern struct globl *globlp;/* The pointer to the first - * globl structure - */ -extern struct globl *gsp; /* Pointer to the current - * globl structure - */ -extern struct sdp sdp; /* Base Paged structure - */ -extern struct rerr rerr; /* Structure containing the - * linker error information - */ -extern FILE *ofp; /* Linker Output file handle - */ -extern FILE *mfp; /* Map output file handle - */ -extern FILE *jfp; /* NoICE output file handle - */ -extern FILE *rfp; /* File handle for output - * address relocated ASxxxx - * listing file - */ -extern FILE *sfp; /* The file handle sfp points to the - * currently open file - */ -extern FILE *tfp; /* File handle for input - * ASxxxx listing file - */ +extern struct lfile *filep; /* The pointers (lfile *) filep, + * (lfile *) cfp, and (FILE *) sfp + * are used in conjunction with + * the routine getline() to read + * asmlnk commands from + * (1) the standard input or + * (2) or a command file + * and to read the REL files + * sequentially as defined by the + * asmlnk input commands. + * + * The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + */ +extern struct lfile *cfp; /* The pointer *cfp points to the + * current lfile structure + */ +extern struct lfile *startp;/* asmlnk startup file structure + */ +extern struct lfile *linkp; /* pointer to first lfile structure + * containing an input REL file + * specification + */ +extern struct lfile *lfp; /* pointer to current lfile structure + * being processed by parse() + */ +extern struct head *headp; /* The pointer to the first + * head structure of a linked list + */ +extern struct head *hp; /* Pointer to the current + * head structure + */ +extern struct area *areap; /* The pointer to the first + * area structure of a linked list + */ +extern struct area *ap; /* Pointer to the current + * area structure + */ +extern struct areax *axp; /* Pointer to the current + * areax structure + */ +extern struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ +extern struct base *basep; /* The pointer to the first + * base structure + */ +extern struct base *bsp; /* Pointer to the current + * base structure + */ +extern struct globl *globlp;/* The pointer to the first + * globl structure + */ +extern struct globl *gsp; /* Pointer to the current + * globl structure + */ +extern struct sdp sdp; /* Base Paged structure + */ +extern struct rerr rerr; /* Structure containing the + * linker error information + */ +extern FILE *ofp; /* Linker Output file handle + */ +extern FILE *mfp; /* Map output file handle + */ +extern FILE *jfp; /* NoICE output file handle + */ +extern FILE *rfp; /* File handle for output + * address relocated ASxxxx + * listing file + */ +extern FILE *sfp; /* The file handle sfp points to the + * currently open file + */ +extern FILE *tfp; /* File handle for input + * ASxxxx listing file + */ extern FILE *dfp; /* File handle for debug info output - */ + */ extern int dflag; /* Output debug information flag - */ -extern int oflag; /* Output file type flag - */ -extern int mflag; /* Map output flag - */ -extern int sflag; /* JCF: Memory usage output flag - */ -extern int packflag; /* Pack data memory flag - */ -extern int stacksize; /* Pack data memory flag - */ -extern int jflag; /* NoICE output flag - */ -extern int xflag; /* Map file radix type flag - */ -extern int pflag; /* print linker command file flag - */ -extern int uflag; /* Listing relocation flag - */ -extern int rflag; /* Extended linear address record flag. - */ -extern int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -extern int line; /* current line number - */ -extern int page; /* current page number - */ -extern int lop; /* current line number on page - */ -extern int pass; /* linker pass number - */ -extern int rtcnt; /* count of elements in the - * rtval[] and rtflg[] arrays - */ -extern Addr_T rtval[]; /* data associated with relocation - */ -extern int rtflg[]; /* indicates if rtval[] value is - * to be sent to the output file. - * (always set in this linker) - */ -extern int hilo; /* REL file byte ordering - */ -extern int gline; /* LST file relocation active - * for current line - */ -extern int gcntr; /* LST file relocation active - * counter - */ -extern struct lbpath *lbphead; /* pointer to the first - * library path structure - */ -extern struct lbname *lbnhead; /* pointer to the first - * library name structure - */ -extern struct lbfile *lbfhead; /* pointer to the first - * library file structure - */ -extern Addr_T iram_size; /* internal ram size - */ -extern long xram_size; /* external ram size - */ -extern long code_size; /* code size - */ + */ +extern int oflag; /* Output file type flag + */ +extern int mflag; /* Map output flag + */ +extern int sflag; /* JCF: Memory usage output flag + */ +extern int packflag; /* Pack data memory flag + */ +extern int stacksize; /* Pack data memory flag + */ +extern int jflag; /* NoICE output flag + */ +extern int xflag; /* Map file radix type flag + */ +extern int pflag; /* print linker command file flag + */ +extern int uflag; /* Listing relocation flag + */ +extern int rflag; /* Extended linear address record flag. + */ +extern int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +extern int line; /* current line number + */ +extern int page; /* current page number + */ +extern int lop; /* current line number on page + */ +extern int pass; /* linker pass number + */ +extern int rtcnt; /* count of elements in the + * rtval[] and rtflg[] arrays + */ +extern Addr_T rtval[]; /* data associated with relocation + */ +extern int rtflg[]; /* indicates if rtval[] value is + * to be sent to the output file. + * (always set in this linker) + */ +extern int hilo; /* REL file byte ordering + */ +extern int gline; /* LST file relocation active + * for current line + */ +extern int gcntr; /* LST file relocation active + * counter + */ +extern struct lbpath *lbphead; /* pointer to the first + * library path structure + */ +extern struct lbname *lbnhead; /* pointer to the first + * library name structure + */ +extern struct lbfile *lbfhead; /* pointer to the first + * library file structure + */ +extern Addr_T iram_size; /* internal ram size + */ +extern long xram_size; /* external ram size + */ +extern long code_size; /* code size + */ /* C Library function definitions */ /* for reference only -extern VOID exit(); -extern int fclose(); -extern char * fgets(); -extern FILE * fopen(); -extern int fprintf(); -extern VOID free(); -extern VOID * malloc(); -extern char putc(); -extern char * strcpy(); -extern int strlen(); -extern char * strncpy(); +extern VOID exit(); +extern int fclose(); +extern char * fgets(); +extern FILE * fopen(); +extern int fprintf(); +extern VOID free(); +extern VOID * malloc(); +extern char putc(); +extern char * strcpy(); +extern int strlen(); +extern char * strncpy(); */ /* Program function definitions */ /* lkmain.c */ -extern FILE * afile(); -extern VOID bassav(); -extern VOID gblsav(); -extern VOID iramsav(); -extern VOID xramsav(); -extern VOID codesav(); -extern VOID iramcheck(); -extern VOID link_main(); -extern VOID lkexit(); -extern int main(); -extern VOID map(); -extern int parse(); -extern VOID setbas(); -extern VOID setgbl(); -extern VOID usage(); +extern FILE * afile(); +extern VOID bassav(); +extern VOID gblsav(); +extern VOID iramsav(); +extern VOID xramsav(); +extern VOID codesav(); +extern VOID iramcheck(); +extern VOID link_main(); +extern VOID lkexit(); +extern int main(); +extern VOID map(); +extern int parse(); +extern VOID setbas(); +extern VOID setgbl(); +extern VOID usage(); extern VOID copyfile(); /* lklex.c */ -extern char endline(); -extern char get(); -extern VOID getfid(); -extern VOID getid(); -extern VOID getSid(); -extern int getline(); -extern int getmap(); -extern char getnb(); -extern int more(); -extern VOID skip(); -extern VOID unget(); -extern VOID chop_crlf(); +extern char endline(); +extern char get(); +extern VOID getfid(); +extern VOID getid(); +extern VOID getSid(); +extern int getline(); +extern int getmap(); +extern char getnb(); +extern int more(); +extern VOID skip(); +extern VOID unget(); +extern VOID chop_crlf(); /* lkarea.c */ -extern VOID lkparea(); -extern VOID lnkarea(); -extern VOID lnkarea2(); -extern VOID lnksect(); -extern VOID newarea(); +extern VOID lkparea(); +extern VOID lnkarea(); +extern VOID lnkarea2(); +extern VOID lnksect(); +extern VOID newarea(); /* lkhead.c */ -extern VOID module(); -extern VOID newhead(); +extern VOID module(); +extern VOID newhead(); /* lksym.c */ -extern int hash(); -extern struct sym * lkpsym(); -extern VOID * new(); -extern struct sym * newsym(); -extern VOID symdef(); -extern int symeq(); -extern VOID syminit(); -extern VOID symmod(); -extern Addr_T symval(); +extern int hash(); +extern struct sym * lkpsym(); +extern VOID * new(); +extern struct sym * newsym(); +extern VOID symdef(); +extern int symeq(); +extern VOID syminit(); +extern VOID symmod(); +extern Addr_T symval(); /* lkeval.c */ -extern int digit(); -extern Addr_T eval(); -extern Addr_T expr(); -extern int oprio(); -extern Addr_T term(); +extern int digit(); +extern Addr_T eval(); +extern Addr_T expr(); +extern int oprio(); +extern Addr_T term(); /* lklist.c */ -extern int dgt(); -extern VOID lkulist(); -extern VOID lkalist(); -extern VOID lkglist(); -extern VOID lstarea(); -extern VOID newpag(); -extern VOID slew(); +extern int dgt(); +extern VOID lkulist(); +extern VOID lkalist(); +extern VOID lkglist(); +extern VOID lstarea(); +extern VOID newpag(); +extern VOID slew(); /* lkrloc.c */ -extern Addr_T adb_b(); -extern Addr_T adb_hi(); -extern Addr_T adb_lo(); -extern Addr_T adb_24_hi(Addr_T v, int i); -extern Addr_T adb_24_mid(Addr_T v, int i); -extern Addr_T adb_24_lo(Addr_T v, int i); -extern Addr_T adw_w(); -extern Addr_T adw_24(Addr_T, int); -extern Addr_T adw_hi(); -extern Addr_T adw_lo(); -extern Addr_T evword(); -extern VOID rele(); -extern VOID reloc(); -extern VOID relt(); -extern VOID relr(); -extern VOID relp(); -extern VOID relerr(); -extern char * errmsg[]; -extern VOID errdmp(); -extern VOID relerp(); -extern VOID erpdmp(); -extern VOID prntval(); -extern int lastExtendedAddress; +extern Addr_T adb_b(); +extern Addr_T adb_bit(); +extern Addr_T adb_hi(); +extern Addr_T adb_lo(); +extern Addr_T adb_24_bit(Addr_T v, int i); +extern Addr_T adb_24_hi(Addr_T v, int i); +extern Addr_T adb_24_mid(Addr_T v, int i); +extern Addr_T adb_24_lo(Addr_T v, int i); +extern Addr_T adw_w(); +extern Addr_T adw_24(Addr_T, int); +extern Addr_T adw_hi(); +extern Addr_T adw_lo(); +extern Addr_T evword(); +extern VOID rele(); +extern VOID reloc(); +extern VOID relt(); +extern VOID relr(); +extern VOID relp(); +extern VOID relerr(); +extern char * errmsg[]; +extern VOID errdmp(); +extern VOID relerp(); +extern VOID erpdmp(); +extern VOID prntval(); +extern int lastExtendedAddress; /* lklibr.c */ -extern int addfile(); -extern VOID addlib(); -extern VOID addpath(); -extern int fndsym(); -extern VOID library(); -extern VOID loadfile(); -extern VOID search(); +extern int addfile(); +extern VOID addlib(); +extern VOID addpath(); +extern int fndsym(); +extern VOID library(); +extern VOID loadfile(); +extern VOID search(); /* lks19.c */ -extern VOID s19(); +extern VOID s19(); /* lkihx.c */ -extern VOID ihx(); -extern VOID ihxEntendedLinearAddress(Addr_T); -extern VOID newArea(); +extern VOID ihx(); +extern VOID ihxEntendedLinearAddress(Addr_T); +extern VOID newArea(); /* lkstore.c */ -extern char *StoreString( char *str ); +extern char *StoreString( char *str ); /* lknoice.c */ extern void DefineNoICE( char *name, Addr_T value, int page ); diff --git a/as/mcs51/asm.h b/as/mcs51/asm.h index c81374ab..415250be 100644 --- a/as/mcs51/asm.h +++ b/as/mcs51/asm.h @@ -8,11 +8,11 @@ * 721 Berkeley St. * Kent, Ohio 44240 * - * 28-Oct-97 JLH: - * - add proto for StoreString - * - change s_id from [NCPS] to pointer - * - change m_id from [NCPS] to pointer - * - change NCPS to 80 + * 28-Oct-97 JLH: + * - add proto for StoreString + * - change s_id from [NCPS] to pointer + * - change m_id from [NCPS] to pointer + * - change NCPS to 80 * - case sensitive * - add R_J11 for 8051 assembler * - add outr11 prototype for 8051 assembler @@ -24,10 +24,10 @@ * - add memory space flags to a_flag for 8051 * * 3-Feb-00 KV: - * - add DS80C390 flat mode support. + * - add DS80C390 flat mode support. */ -#define VERSION "V01.70 + NoICE + SDCC mods + Flat24 Feb-1999" +#define VERSION "V01.70 + NoICE + SDCC mods + Flat24 Feb-1999" #if !defined(__BORLANDC__) && !defined(_MSC_VER) #include @@ -36,628 +36,633 @@ /* * Case Sensitivity Flag */ -#define CASE_SENSITIVE 1 +#define CASE_SENSITIVE 1 -/*)Module asm.h +/*)Module asm.h * - * The module asm.h contains the definitions for constants, - * structures, global variables, and ASxxxx functions - * contained in the ASxxxx.c files. The two functions - * and three global variables from the machine dependent - * files are also defined. + * The module asm.h contains the definitions for constants, + * structures, global variables, and ASxxxx functions + * contained in the ASxxxx.c files. The two functions + * and three global variables from the machine dependent + * files are also defined. */ /* - * compiler/operating system specific definitions + * compiler/operating system specific definitions */ /* DECUS C void definition */ /* File/extension seperator */ -#ifdef decus -#define VOID char -#define FSEPX '.' +#ifdef decus +#define VOID char +#define FSEPX '.' #endif /* PDOS C void definition */ /* File/extension seperator */ -#ifdef PDOS -#define VOID char -#define FSEPX ':' +#ifdef PDOS +#define VOID char +#define FSEPX ':' #endif /* Default void definition */ /* File/extension seperator */ -#ifndef VOID -#define VOID void -#define FSEPX '.' -#define OTHERSYSTEM +#ifndef VOID +#define VOID void +#define FSEPX '.' +#define OTHERSYSTEM #endif /* * PATH_MAX */ #include -#ifndef PATH_MAX /* POSIX, but not required */ +#ifndef PATH_MAX /* POSIX, but not required */ #if defined(_MSC_VER) || defined(__BORLANDC__) /* Microsoft C or Borland C*/ #include -#define PATH_MAX _MAX_PATH +#define PATH_MAX _MAX_PATH #else -#define PATH_MAX /* define a reasonable value */ +#define PATH_MAX /* define a reasonable value */ #endif #endif /* * Assembler definitions. */ -#define LFTERM '(' /* Left expression delimeter */ -#define RTTERM ')' /* Right expression delimeter */ - -#define NCPS 80 /* Chars. per symbol (JLH: change from 8) */ -#define HUGE 1000 /* A huge number */ -#define NERR 3 /* Errors per line */ -#define NINPUT 1024 /* Input buffer size (icodes need space) */ -#define NCODE 128 /* Listing code buffer size */ -#define NTITL 64 /* Title buffer size */ -#define NSBTL 64 /* SubTitle buffer size */ -#define NHASH 64 /* Buckets in hash table */ -#define HMASK 077 /* Hash mask */ -#define NLPP 60 /* Lines per page */ -#define MAXFIL 6 /* Maximum command line input files */ -#define MAXINC 6 /* Maximum nesting of include files */ -#define MAXIF 10 /* Maximum nesting of if/else/endif */ - -#define NLIST 0 /* No listing */ -#define SLIST 1 /* Source only */ -#define ALIST 2 /* Address only */ -#define BLIST 3 /* Address only with allocation */ -#define CLIST 4 /* Code */ -#define ELIST 5 /* Equate only */ - -#define dot sym[0] /* Dot, current loc */ -#define dca area[0] /* Dca, default code area */ +#define LFTERM '(' /* Left expression delimeter */ +#define RTTERM ')' /* Right expression delimeter */ + +#define NCPS 80 /* Chars. per symbol (JLH: change from 8) */ +#define HUGE 1000 /* A huge number */ +#define NERR 3 /* Errors per line */ +#define NINPUT 1024 /* Input buffer size (icodes need space) */ +#define NCODE 128 /* Listing code buffer size */ +#define NTITL 64 /* Title buffer size */ +#define NSBTL 64 /* SubTitle buffer size */ +#define NHASH 64 /* Buckets in hash table */ +#define HMASK 077 /* Hash mask */ +#define NLPP 60 /* Lines per page */ +#define MAXFIL 6 /* Maximum command line input files */ +#define MAXINC 6 /* Maximum nesting of include files */ +#define MAXIF 10 /* Maximum nesting of if/else/endif */ + +#define NLIST 0 /* No listing */ +#define SLIST 1 /* Source only */ +#define ALIST 2 /* Address only */ +#define BLIST 3 /* Address only with allocation */ +#define CLIST 4 /* Code */ +#define ELIST 5 /* Equate only */ + +#define dot sym[0] /* Dot, current loc */ +#define dca area[0] /* Dca, default code area */ /* NB: for Flat24 extentions to work, Addr_T must be at least 24 - * bits. This is checked at runtime when the .flat24 directive + * bits. This is checked at runtime when the .flat24 directive * is processed. */ -typedef unsigned int Addr_T; +typedef unsigned int Addr_T; /* - * The area structure contains the parameter values for a - * specific program or data section. The area structure - * is a linked list of areas. The initial default area - * is "_CODE" defined in asdata.c, the next area structure - * will be linked to this structure through the structure - * element 'struct area *a_ap'. The structure contains the - * area name, area reference number ("_CODE" is 0) determined - * by the order of .area directives, area size determined - * from the total code and/or data in an area, area fuzz is - * a variable used to track pass to pass changes in the - * area size caused by variable length instruction formats, - * and area flags which specify the area's relocation type. + * The area structure contains the parameter values for a + * specific program or data section. The area structure + * is a linked list of areas. The initial default area + * is "_CODE" defined in asdata.c, the next area structure + * will be linked to this structure through the structure + * element 'struct area *a_ap'. The structure contains the + * area name, area reference number ("_CODE" is 0) determined + * by the order of .area directives, area size determined + * from the total code and/or data in an area, area fuzz is + * a variable used to track pass to pass changes in the + * area size caused by variable length instruction formats, + * and area flags which specify the area's relocation type. */ -struct area +struct area { - struct area *a_ap; /* Area link */ - char a_id[NCPS]; /* Area Name */ - int a_ref; /* Ref. number */ - Addr_T a_size; /* Area size */ - Addr_T a_fuzz; /* Area fuzz */ - int a_flag; /* Area flags */ + struct area *a_ap; /* Area link */ + char a_id[NCPS]; /* Area Name */ + int a_ref; /* Ref. number */ + Addr_T a_size; /* Area size */ + Addr_T a_fuzz; /* Area fuzz */ + int a_flag; /* Area flags */ }; /* - * The "A_" area constants define values used in - * generating the assembler area output data. + * The "A_" area constants define values used in + * generating the assembler area output data. * * Area flags * - * 7 6 5 4 3 2 1 0 - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | BIT |XDATA|DATA | PAG | ABS | OVR | | | - * +-----+-----+-----+-----+-----+-----+-----+-----+ + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | BIT |XDATA|DATA | PAG | ABS | OVR | | | + * +-----+-----+-----+-----+-----+-----+-----+-----+ */ -#define A_CON 0000 /* Concatenating */ -#define A_OVR 0004 /* Overlaying */ -#define A_REL 0000 /* Relocatable */ -#define A_ABS 0010 /* absolute */ -#define A_NOPAG 0000 /* Non-Paged */ -#define A_PAG 0020 /* Paged */ +#define A_CON 0000 /* Concatenating */ +#define A_OVR 0004 /* Overlaying */ +#define A_REL 0000 /* Relocatable */ +#define A_ABS 0010 /* absolute */ +#define A_NOPAG 0000 /* Non-Paged */ +#define A_PAG 0020 /* Paged */ /* Additional flags for 8051 address spaces */ -#define A_DATA 0000 /* data space (default)*/ -#define A_CODE 0040 /* code space */ -#define A_XDATA 0100 /* external data space */ -#define A_BIT 0200 /* bit addressable space */ +#define A_DATA 0000 /* data space (default)*/ +#define A_CODE 0040 /* code space */ +#define A_XDATA 0100 /* external data space */ +#define A_BIT 0200 /* bit addressable space */ /* - * The "R_" relocation constants define values used in - * generating the assembler relocation output data for - * areas, symbols, and code. + * The "R_" relocation constants define values used in + * generating the assembler relocation output data for + * areas, symbols, and code. * * Relocation flags * - * 7 6 5 4 3 2 1 0 - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT | - * +-----+-----+-----+-----+-----+-----+-----+-----+ + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT | + * +-----+-----+-----+-----+-----+-----+-----+-----+ */ -#define R_WORD 0x00 /* 16 bit */ -#define R_BYTE 0x01 /* 8 bit */ +#define R_WORD 0x00 /* 16 bit */ +#define R_BYTE 0x01 /* 8 bit */ -#define R_AREA 0x00 /* Base type */ -#define R_SYM 0x02 +#define R_AREA 0x00 /* Base type */ +#define R_SYM 0x02 -#define R_NORM 0x00 /* PC adjust */ -#define R_PCR 0x04 +#define R_NORM 0x00 /* PC adjust */ +#define R_PCR 0x04 -#define R_BYT1 0x00 /* Byte count for R_BYTE = 1 */ -#define R_BYT2 0x08 /* Byte count for R_BYTE = 2 */ +#define R_BYT1 0x00 /* Byte count for R_BYTE = 1 */ +#define R_BYT2 0x08 /* Byte count for R_BYTE = 2 */ -#define R_SGND 0x00 /* Signed Byte */ -#define R_USGN 0x10 /* Unsigned Byte */ +#define R_SGND 0x00 /* Signed Byte */ +#define R_USGN 0x10 /* Unsigned Byte */ -#define R_NOPAG 0x00 /* Page Mode */ -#define R_PAG0 0x20 /* Page '0' */ -#define R_PAG 0x40 /* Page 'nnn' */ +#define R_NOPAG 0x00 /* Page Mode */ +#define R_PAG0 0x20 /* Page '0' */ +#define R_PAG 0x40 /* Page 'nnn' */ -#define R_LSB 0x00 /* low byte */ -#define R_MSB 0x80 /* high byte */ +#define R_LSB 0x00 /* low byte */ +#define R_MSB 0x80 /* high byte */ -#define R_BYT3 0x100 /* if R_BYTE is set, this is a - * 3 byte address, of which - * the linker must select one byte. - */ -#define R_HIB 0x200 /* If R_BYTE & R_BYT3 are set, linker - * will select byte 3 of the relocated - * 24 bit address. - */ +#define R_BYT3 0x100 /* if R_BYTE is set, this is a + * 3 byte address, of which + * the linker must select one byte. + */ +#define R_HIB 0x200 /* If R_BYTE & R_BYT3 are set, linker + * will select byte 3 of the relocated + * 24 bit address. + */ -#define R_J11 (R_WORD|R_BYT2) /* JLH: 11 bit JMP and CALL (8051) */ -#define R_J19 (R_WORD|R_BYT2|R_MSB) /* 19 bit JMP/CALL (DS80C390) */ -#define R_C24 (R_WORD|R_BYT1|R_MSB) /* 24 bit address (DS80C390) */ +#define R_BIT 0x400 /* Linker will convert from byte-addressable + * space to bit-addressable space. + */ + +#define R_J11 (R_WORD|R_BYT2) /* JLH: 11 bit JMP and CALL (8051) */ +#define R_J19 (R_WORD|R_BYT2|R_MSB) /* 19 bit JMP/CALL (DS80C390) */ +#define R_C24 (R_WORD|R_BYT1|R_MSB) /* 24 bit address (DS80C390) */ #define R_J19_MASK (R_BYTE|R_BYT2|R_MSB) #define IS_R_J19(x) (((x) & R_J19_MASK) == R_J19) #define IS_R_J11(x) (((x) & R_J19_MASK) == R_J11) #define IS_C24(x) (((x) & R_J19_MASK) == R_C24) -#define R_ESCAPE_MASK 0xf0 /* Used to escape relocation modes - * greater than 0xff in the .rel - * file. - */ +#define R_ESCAPE_MASK 0xf0 /* Used to escape relocation modes + * greater than 0xff in the .rel + * file. + */ /* * Listing Control Flags */ -#define R_HIGH 0040000 /* High Byte */ -#define R_RELOC 0100000 /* Relocation */ +#define R_HIGH 0040000 /* High Byte */ +#define R_RELOC 0100000 /* Relocation */ -#define R_DEF 00 /* Global def. */ -#define R_REF 01 /* Global ref. */ -#define R_REL 00 /* Relocatable */ -#define R_ABS 02 /* Absolute */ -#define R_GBL 00 /* Global */ -#define R_LCL 04 /* Local */ +#define R_DEF 00 /* Global def. */ +#define R_REF 01 /* Global ref. */ +#define R_REL 00 /* Relocatable */ +#define R_ABS 02 /* Absolute */ +#define R_GBL 00 /* Global */ +#define R_LCL 04 /* Local */ /* - * The mne structure is a linked list of the assembler - * mnemonics and directives. The list of mnemonics and - * directives contained in the device dependent file - * xxxpst.c are hashed and linked into NHASH lists in - * module assym.c by syminit(). The structure contains - * the mnemonic/directive name, a subtype which directs - * the evaluation of this mnemonic/directive, a flag which - * is used to detect the end of the mnemonic/directive - * list in xxxpst.c, and a value which is normally - * associated with the assembler mnemonic base instruction - * value. + * The mne structure is a linked list of the assembler + * mnemonics and directives. The list of mnemonics and + * directives contained in the device dependent file + * xxxpst.c are hashed and linked into NHASH lists in + * module assym.c by syminit(). The structure contains + * the mnemonic/directive name, a subtype which directs + * the evaluation of this mnemonic/directive, a flag which + * is used to detect the end of the mnemonic/directive + * list in xxxpst.c, and a value which is normally + * associated with the assembler mnemonic base instruction + * value. */ -struct mne +struct mne { - struct mne *m_mp; /* Hash link */ - char *m_id; /* Mnemonic JLH: change from [NCPS] */ - char m_type; /* Mnemonic subtype */ - char m_flag; /* Mnemonic flags */ - Addr_T m_valu; /* Value */ + struct mne *m_mp; /* Hash link */ + char *m_id; /* Mnemonic JLH: change from [NCPS] */ + char m_type; /* Mnemonic subtype */ + char m_flag; /* Mnemonic flags */ + Addr_T m_valu; /* Value */ }; /* - * The sym structure is a linked list of symbols defined - * in the assembler source files. The first symbol is "." - * defined in asdata.c. The entry 'struct tsym *s_tsym' - * links any temporary symbols following this symbol and - * preceeding the next normal symbol. The structure also - * contains the symbol's name, type (USER or NEW), flag - * (global, assigned, and multiply defined), a pointer - * to the area structure defining where the symbol is - * located, a reference number assigned by outgsd() in - * asout.c, and the symbols address relative to the base - * address of the area where the symbol is located. + * The sym structure is a linked list of symbols defined + * in the assembler source files. The first symbol is "." + * defined in asdata.c. The entry 'struct tsym *s_tsym' + * links any temporary symbols following this symbol and + * preceeding the next normal symbol. The structure also + * contains the symbol's name, type (USER or NEW), flag + * (global, assigned, and multiply defined), a pointer + * to the area structure defining where the symbol is + * located, a reference number assigned by outgsd() in + * asout.c, and the symbols address relative to the base + * address of the area where the symbol is located. */ -struct sym +struct sym { - struct sym *s_sp; /* Hash link */ - struct tsym *s_tsym; /* Temporary symbol link */ - char *s_id; /* Symbol: JLH change from [NCPS] */ - char s_type; /* Symbol subtype */ - char s_flag; /* Symbol flags */ - struct area *s_area; /* Area line, 0 if absolute */ - int s_ref; /* Ref. number */ - Addr_T s_addr; /* Address */ + struct sym *s_sp; /* Hash link */ + struct tsym *s_tsym; /* Temporary symbol link */ + char *s_id; /* Symbol: JLH change from [NCPS] */ + char s_type; /* Symbol subtype */ + char s_flag; /* Symbol flags */ + struct area *s_area; /* Area line, 0 if absolute */ + int s_ref; /* Ref. number */ + Addr_T s_addr; /* Address */ }; -#define S_GBL 01 /* Global */ -#define S_ASG 02 /* Assigned */ -#define S_MDF 04 /* Mult. def */ -#define S_END 010 /* End mark for pst. */ - -#define S_NEW 0 /* New name */ -#define S_USER 1 /* User name */ - /* unused slot */ - /* unused slot */ - /* unused slot */ - -#define S_BYTE 5 /* .byte */ -#define S_WORD 6 /* .word */ -#define S_ASCII 7 /* .ascii */ -#define S_ASCIZ 8 /* .asciz */ -#define S_BLK 9 /* .blkb or .blkw */ -#define S_INCL 10 /* .include */ -#define S_DAREA 11 /* .area */ -#define S_ATYP 12 /* .area type */ -#define S_AREA 13 /* .area name */ -#define S_GLOBL 14 /* .globl */ -#define S_PAGE 15 /* .page */ -#define S_TITLE 16 /* .title */ -#define S_SBTL 17 /* .sbttl */ -#define S_IF 18 /* .if */ -#define S_ELSE 19 /* .else */ -#define S_ENDIF 20 /* .endif */ -#define S_EVEN 21 /* .even */ -#define S_ODD 22 /* .odd */ -#define S_RADIX 23 /* .radix */ -#define S_ORG 24 /* .org */ -#define S_MODUL 25 /* .module */ -#define S_ASCIS 26 /* .ascis */ -#define S_FLAT24 27 /* .flat24 */ -#define S_OPTSDCC 28 /* .optsdcc */ +#define S_GBL 01 /* Global */ +#define S_ASG 02 /* Assigned */ +#define S_MDF 04 /* Mult. def */ +#define S_END 010 /* End mark for pst. */ +#define S_BIT 020 /* address of bit in byte memory */ + +#define S_NEW 0 /* New name */ +#define S_USER 1 /* User name */ + /* unused slot */ + /* unused slot */ + /* unused slot */ + +#define S_BYTE 5 /* .byte */ +#define S_WORD 6 /* .word */ +#define S_ASCII 7 /* .ascii */ +#define S_ASCIZ 8 /* .asciz */ +#define S_BLK 9 /* .blkb or .blkw */ +#define S_INCL 10 /* .include */ +#define S_DAREA 11 /* .area */ +#define S_ATYP 12 /* .area type */ +#define S_AREA 13 /* .area name */ +#define S_GLOBL 14 /* .globl */ +#define S_PAGE 15 /* .page */ +#define S_TITLE 16 /* .title */ +#define S_SBTL 17 /* .sbttl */ +#define S_IF 18 /* .if */ +#define S_ELSE 19 /* .else */ +#define S_ENDIF 20 /* .endif */ +#define S_EVEN 21 /* .even */ +#define S_ODD 22 /* .odd */ +#define S_RADIX 23 /* .radix */ +#define S_ORG 24 /* .org */ +#define S_MODUL 25 /* .module */ +#define S_ASCIS 26 /* .ascis */ +#define S_FLAT24 27 /* .flat24 */ +#define S_OPTSDCC 28 /* .optsdcc */ /* - * The tsym structure is a linked list of temporary - * symbols defined in the assembler source files following - * a normal symbol. The structure contains the temporary - * symbols number, a flag (multiply defined), a pointer to the - * area structure defining where the temporary structure - * is located, and the temporary symbol's address relative - * to the base address of the area where the symbol - * is located. + * The tsym structure is a linked list of temporary + * symbols defined in the assembler source files following + * a normal symbol. The structure contains the temporary + * symbols number, a flag (multiply defined), a pointer to the + * area structure defining where the temporary structure + * is located, and the temporary symbol's address relative + * to the base address of the area where the symbol + * is located. */ -struct tsym +struct tsym { - struct tsym *t_lnk; /* Link to next */ + struct tsym *t_lnk; /* Link to next */ /* sandeep changed to 'int' from 'char' */ /* this will increase the number temp symbols that can be defined from 255 to INT_MAX */ - int t_num; /* 0-INT_MAX$ */ - int t_flg; /* flags */ + int t_num; /* 0-INT_MAX$ */ + int t_flg; /* flags */ - struct area *t_area; /* Area */ - Addr_T t_addr; /* Address */ + struct area *t_area; /* Area */ + Addr_T t_addr; /* Address */ }; /* - * External Definitions for all Global Variables + * External Definitions for all Global Variables */ -extern int aserr; /* ASxxxx error counter - */ -extern jmp_buf jump_env; /* compiler dependent structure - * used by setjmp() and longjmp() - */ -extern int inpfil; /* count of assembler - * input files specified - */ -extern int incfil; /* current file handle index - * for include files - */ -extern int cfile; /* current file handle index - * of input assembly files - */ -extern int flevel; /* IF-ELSE-ENDIF flag will be non - * zero for false conditional case - */ -extern int tlevel; /* current conditional level - */ -extern int ifcnd[MAXIF+1]; /* array of IF statement condition - * values (0 = FALSE) indexed by tlevel - */ -extern int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel - * values indexed by tlevel - */ -extern char - afn[PATH_MAX]; /* afile() temporary filespec - */ -extern char - srcfn[MAXFIL][PATH_MAX]; /* array of source file names - */ -extern int - srcline[MAXFIL]; /* current source file line - */ -extern char - incfn[MAXINC][PATH_MAX]; /* array of include file names - */ -extern int - incline[MAXINC]; /* current include file line - */ -extern int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -extern int line; /* current assembler source - * line number - */ -extern int page; /* current page number - */ -extern int lop; /* current line number on page - */ -extern int pass; /* assembler pass number - */ -extern int lflag; /* -l, generate listing flag - */ -extern int cflag; /* -c, generate sdcdb debug information - */ -extern int gflag; /* -g, make undefined symbols global flag - */ -extern int aflag; /* -a, make all symbols global flag - */ -extern int jflag; /* -j, generate debug information flag - */ -extern int oflag; /* -o, generate relocatable output flag - */ -extern int sflag; /* -s, generate symbol table flag - */ -extern int pflag; /* -p, enable listing pagination - */ -extern int xflag; /* -x, listing radix flag - */ -extern int fflag; /* -f(f), relocations flagged flag - */ -extern Addr_T laddr; /* address of current assembler line - * or value of .if argument - */ -extern Addr_T fuzz; /* tracks pass to pass changes in the - * address of symbols caused by - * variable length instruction formats - */ -extern int lmode; /* listing mode - */ -extern struct area area[]; /* array of 1 area - */ -extern struct area *areap; /* pointer to an area structure - */ -extern struct sym sym[]; /* array of 1 symbol - */ -extern struct sym *symp; /* pointer to a symbol structure - */ -extern struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ -extern struct mne *mnehash[NHASH]; /* array of pointers to NHASH - * linked mnemonic/directive lists - */ -extern char *ep; /* pointer into error list - * array eb[NERR] - */ -extern char eb[NERR]; /* array of generated error codes - */ -extern char *ip; /* pointer into the assembler-source - * text line in ib[] - */ -extern char ib[NINPUT]; /* assembler-source text line - */ -extern char *cp; /* pointer to assembler output - * array cb[] - */ -extern char cb[NCODE]; /* array of assembler output values - */ -extern int *cpt; /* pointer to assembler relocation type - * output array cbt[] - */ -extern int cbt[NCODE]; /* array of assembler relocation types - * describing the data in cb[] - */ -extern char tb[NTITL]; /* Title string buffer - */ -extern char stb[NSBTL]; /* Subtitle string buffer - */ -extern char optsdcc[NINPUT]; /* sdcc compile options - */ -extern int flat24Mode; /* non-zero if we are using DS390 24 bit - * flat mode (via .flat24 directive). - */ -extern char symtbl[]; /* string "Symbol Table" - */ -extern char aretbl[]; /* string "Area Table" - */ -extern char module[NCPS]; /* module name string - */ -extern FILE *lfp; /* list output file handle - */ -extern FILE *ofp; /* relocation output file handle - */ -extern FILE *tfp; /* symbol table output file handle - */ -extern FILE *sfp[MAXFIL]; /* array of assembler-source file handles - */ -extern FILE *ifp[MAXINC]; /* array of include-file file handles - */ -extern unsigned char ctype[128]; /* array of character types, one per - * ASCII character - */ - -extern char ccase[128]; /* an array of characters which - * perform the case translation function - */ +extern int aserr; /* ASxxxx error counter + */ +extern jmp_buf jump_env; /* compiler dependent structure + * used by setjmp() and longjmp() + */ +extern int inpfil; /* count of assembler + * input files specified + */ +extern int incfil; /* current file handle index + * for include files + */ +extern int cfile; /* current file handle index + * of input assembly files + */ +extern int flevel; /* IF-ELSE-ENDIF flag will be non + * zero for false conditional case + */ +extern int tlevel; /* current conditional level + */ +extern int ifcnd[MAXIF+1]; /* array of IF statement condition + * values (0 = FALSE) indexed by tlevel + */ +extern int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel + * values indexed by tlevel + */ +extern char + afn[PATH_MAX]; /* afile() temporary filespec + */ +extern char + srcfn[MAXFIL][PATH_MAX]; /* array of source file names + */ +extern int + srcline[MAXFIL]; /* current source file line + */ +extern char + incfn[MAXINC][PATH_MAX]; /* array of include file names + */ +extern int + incline[MAXINC]; /* current include file line + */ +extern int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +extern int line; /* current assembler source + * line number + */ +extern int page; /* current page number + */ +extern int lop; /* current line number on page + */ +extern int pass; /* assembler pass number + */ +extern int lflag; /* -l, generate listing flag + */ +extern int cflag; /* -c, generate sdcdb debug information + */ +extern int gflag; /* -g, make undefined symbols global flag + */ +extern int aflag; /* -a, make all symbols global flag + */ +extern int jflag; /* -j, generate debug information flag + */ +extern int oflag; /* -o, generate relocatable output flag + */ +extern int sflag; /* -s, generate symbol table flag + */ +extern int pflag; /* -p, enable listing pagination + */ +extern int xflag; /* -x, listing radix flag + */ +extern int fflag; /* -f(f), relocations flagged flag + */ +extern Addr_T laddr; /* address of current assembler line + * or value of .if argument + */ +extern Addr_T fuzz; /* tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + */ +extern int lmode; /* listing mode + */ +extern struct area area[]; /* array of 1 area + */ +extern struct area *areap; /* pointer to an area structure + */ +extern struct sym sym[]; /* array of 1 symbol + */ +extern struct sym *symp; /* pointer to a symbol structure + */ +extern struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ +extern struct mne *mnehash[NHASH]; /* array of pointers to NHASH + * linked mnemonic/directive lists + */ +extern char *ep; /* pointer into error list + * array eb[NERR] + */ +extern char eb[NERR]; /* array of generated error codes + */ +extern char *ip; /* pointer into the assembler-source + * text line in ib[] + */ +extern char ib[NINPUT]; /* assembler-source text line + */ +extern char *cp; /* pointer to assembler output + * array cb[] + */ +extern char cb[NCODE]; /* array of assembler output values + */ +extern int *cpt; /* pointer to assembler relocation type + * output array cbt[] + */ +extern int cbt[NCODE]; /* array of assembler relocation types + * describing the data in cb[] + */ +extern char tb[NTITL]; /* Title string buffer + */ +extern char stb[NSBTL]; /* Subtitle string buffer + */ +extern char optsdcc[NINPUT]; /* sdcc compile options + */ +extern int flat24Mode; /* non-zero if we are using DS390 24 bit + * flat mode (via .flat24 directive). + */ +extern char symtbl[]; /* string "Symbol Table" + */ +extern char aretbl[]; /* string "Area Table" + */ +extern char module[NCPS]; /* module name string + */ +extern FILE *lfp; /* list output file handle + */ +extern FILE *ofp; /* relocation output file handle + */ +extern FILE *tfp; /* symbol table output file handle + */ +extern FILE *sfp[MAXFIL]; /* array of assembler-source file handles + */ +extern FILE *ifp[MAXINC]; /* array of include-file file handles + */ +extern unsigned char ctype[128]; /* array of character types, one per + * ASCII character + */ + +extern char ccase[128]; /* an array of characters which + * perform the case translation function + */ /* * Definitions for Character Types */ -#define SPACE 0000 -#define ETC 0000 -#define LETTER 0001 -#define DIGIT 0002 -#define BINOP 0004 -#define RAD2 0010 -#define RAD8 0020 -#define RAD10 0040 -#define RAD16 0100 -#define ILL 0200 - -#define DGT2 DIGIT|RAD16|RAD10|RAD8|RAD2 -#define DGT8 DIGIT|RAD16|RAD10|RAD8 -#define DGT10 DIGIT|RAD16|RAD10 -#define LTR16 LETTER|RAD16 +#define SPACE 0000 +#define ETC 0000 +#define LETTER 0001 +#define DIGIT 0002 +#define BINOP 0004 +#define RAD2 0010 +#define RAD8 0020 +#define RAD10 0040 +#define RAD16 0100 +#define ILL 0200 + +#define DGT2 DIGIT|RAD16|RAD10|RAD8|RAD2 +#define DGT8 DIGIT|RAD16|RAD10|RAD8 +#define DGT10 DIGIT|RAD16|RAD10 +#define LTR16 LETTER|RAD16 /* - * The exp structure is used to return the evaluation - * of an expression. The structure supports three valid - * cases: - * (1) The expression evaluates to a constant, - * mode = S_USER, flag = 0, addr contains the - * constant, and base = NULL. - * (2) The expression evaluates to a defined symbol - * plus or minus a constant, mode = S_USER, - * flag = 0, addr contains the constant, and - * base = pointer to area symbol. - * (3) The expression evaluates to a external - * global symbol plus or minus a constant, - * mode = S_NEW, flag = 1, addr contains the - * constant, and base = pointer to symbol. + * The exp structure is used to return the evaluation + * of an expression. The structure supports three valid + * cases: + * (1) The expression evaluates to a constant, + * mode = S_USER, flag = 0, addr contains the + * constant, and base = NULL. + * (2) The expression evaluates to a defined symbol + * plus or minus a constant, mode = S_USER, + * flag = 0, addr contains the constant, and + * base = pointer to area symbol. + * (3) The expression evaluates to a external + * global symbol plus or minus a constant, + * mode = S_NEW, flag = 1, addr contains the + * constant, and base = pointer to symbol. */ -struct expr +struct expr { - char e_mode; /* Address mode */ - char e_flag; /* Symbol flag */ - Addr_T e_addr; /* Address */ - union { - struct area *e_ap; - struct sym *e_sp; - } e_base; /* Rel. base */ - int e_rlcf; /* Rel. flags */ + char e_mode; /* Address mode */ + char e_flag; /* Symbol flag */ + Addr_T e_addr; /* Address */ + union { + struct area *e_ap; + struct sym *e_sp; + } e_base; /* Rel. base */ + int e_rlcf; /* Rel. flags */ }; /* C Library functions */ /* for reference only -extern VOID exit(); -extern int fclose(); -extern char * fgets(); -extern FILE * fopen(); -extern int fprintf(); -extern VOID longjmp(); -extern VOID * malloc(); -extern int printf(); -extern char putc(); -extern int rewind(); -extern int setjmp(); -extern int strcmp(); -extern char * strcpy(); -extern int strlen(); -extern char * strncpy(); +extern VOID exit(); +extern int fclose(); +extern char * fgets(); +extern FILE * fopen(); +extern int fprintf(); +extern VOID longjmp(); +extern VOID * malloc(); +extern int printf(); +extern char putc(); +extern int rewind(); +extern int setjmp(); +extern int strcmp(); +extern char * strcpy(); +extern int strlen(); +extern char * strncpy(); */ /* Machine independent functions */ /* asmain.c */ -extern FILE * afile(); -extern VOID asexit(); -extern VOID asmbl(); -extern int main(); -extern VOID newdot(); -extern VOID phase(); -extern VOID usage(); +extern FILE * afile(); +extern VOID asexit(); +extern VOID asmbl(); +extern int main(); +extern VOID newdot(); +extern VOID phase(); +extern VOID usage(); /* aslex.c */ -extern char endline(); -extern char get(); -extern VOID getid(); -extern int getline(); -extern int getmap(); -extern char getnb(); -extern VOID getst(); -extern int more(); -extern VOID unget(); -extern VOID chop_crlf(); +extern char endline(); +extern char get(); +extern VOID getid(); +extern int getline(); +extern int getmap(); +extern char getnb(); +extern VOID getst(); +extern int more(); +extern VOID unget(); +extern VOID chop_crlf(); /* assym.c */ -extern struct area * alookup(); -extern struct mne * mlookup(); -extern int hash(); -extern struct sym * lookup(); -extern VOID * new(); -extern int symeq(); -extern VOID syminit(); -extern VOID symglob(); -extern VOID allglob(); +extern struct area * alookup(); +extern struct mne * mlookup(); +extern int hash(); +extern struct sym * lookup(); +extern VOID * new(); +extern int symeq(); +extern VOID syminit(); +extern VOID symglob(); +extern VOID allglob(); /* assubr.c */ -extern VOID aerr(); -extern VOID diag(); -extern VOID err(); -extern VOID warnBanner(void); -extern char * geterr(); -extern VOID qerr(); -extern VOID rerr(); +extern VOID aerr(); +extern VOID diag(); +extern VOID err(); +extern VOID warnBanner(void); +extern char * geterr(); +extern VOID qerr(); +extern VOID rerr(); /* asexpr.c */ -extern VOID abscheck(); -extern Addr_T absexpr(); -extern VOID clrexpr(); -extern int digit(); -extern int is_abs(); -extern VOID expr(); -extern int oprio(); -extern VOID term(); +extern VOID abscheck(); +extern Addr_T absexpr(); +extern VOID clrexpr(); +extern int digit(); +extern int is_abs(); +extern VOID expr(); +extern int oprio(); +extern VOID term(); /* aslist.c */ -extern VOID list(); -extern VOID list1(); -extern VOID list2(); -extern VOID lstsym(); -extern VOID slew(); +extern VOID list(); +extern VOID list1(); +extern VOID list2(); +extern VOID lstsym(); +extern VOID slew(); /* asout.c */ -extern int hibyte(); -extern int lobyte(); -extern int byte3(int); -extern VOID out(); -extern VOID outab(); -extern VOID outarea(); -extern VOID outaw(); -extern VOID outall(); -extern VOID outdot(); -extern VOID outbuf(); -extern VOID outchk(); -extern VOID outgsd(); -extern VOID outrb(); -extern VOID outrw(struct expr *, int); -extern VOID outr24(struct expr *, int); -extern VOID outsym(); -extern VOID out_lb(); -extern VOID out_lw(); -extern VOID out_l24(int, int); -extern VOID out_rw(); -extern VOID out_tw(); -extern VOID out_t24(int); -extern VOID outr11(); /* JLH */ -extern VOID outr19(struct expr *, int, int); +extern int hibyte(); +extern int lobyte(); +extern int byte3(int); +extern VOID out(); +extern VOID outab(); +extern VOID outarea(); +extern VOID outaw(); +extern VOID outall(); +extern VOID outdot(); +extern VOID outbuf(); +extern VOID outchk(); +extern VOID outgsd(); +extern VOID outrb(); +extern VOID outrw(struct expr *, int); +extern VOID outr24(struct expr *, int); +extern VOID outsym(); +extern VOID out_lb(); +extern VOID out_lw(); +extern VOID out_l24(int, int); +extern VOID out_rw(); +extern VOID out_tw(); +extern VOID out_t24(int); +extern VOID outr11(); /* JLH */ +extern VOID outr19(struct expr *, int, int); /* asstore.c */ extern char *StoreString( char *str ); @@ -668,12 +673,12 @@ extern void DefineCDB_Line(); /* Machine dependent variables */ -extern char * cpu; -extern char * dsft; -extern int hilo; -extern struct mne mne[]; +extern char * cpu; +extern char * dsft; +extern int hilo; +extern struct mne mne[]; /* Machine dependent functions */ -extern VOID minit(); +extern VOID minit(); extern VOID machine(struct mne *); diff --git a/as/mcs51/lkarea.c b/as/mcs51/lkarea.c index 1be337af..608e3e15 100644 --- a/as/mcs51/lkarea.c +++ b/as/mcs51/lkarea.c @@ -647,6 +647,8 @@ void lnksect2 (struct area *tap, int rloc) fchar='3'; else if(!strcmp(tap->a_id, "BSEG_BYTES")) fchar='B'; + else if(!strcmp(tap->a_id, "BIT_BANK")) + fchar='T'; else fchar=' ';/*???*/ } @@ -747,6 +749,69 @@ void lnksect2 (struct area *tap, int rloc) } } } + else if (fchar=='T') /*Bit addressable bytes in internal RAM*/ + { + /*Find the size of the space currently used for this areax overlay*/ + for(j=0x20, size=0; j<0x30; j++) + if(idatamap[j]==fchar) size++; + + /*If more space required, release the previously allocated areax in + internal RAM and search for a bigger one*/ + if((int)taxp->a_size>size) + { + size=(int)taxp->a_size; + + for(j=0x20; j<0x30; j++) + if(idatamap[j]==fchar) idatamap[j]=' '; + + /*Search for a space large enough in data memory for this overlay areax*/ + for(j=0x20, k=0; j<0x30; j++) + { + if(idatamap[j]==' ') + k++; + else + k=0; + if(k==(int)taxp->a_size) break; + } + + if(k==(int)taxp->a_size) + { + taxp->a_addr = j-k+1; + if(addr<(unsigned int)0x30) + { + for(j=0x2F; (j>=0x20)&&(idatamap[j]==' '); j--); + if(j>=0x20) addr=j+1; + } + } + + /*Mark the memory used for overlay*/ + if(k==(int)taxp->a_size) + { + for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<0x30); j++) + idatamap[j]=fchar; + + /*Set the new size of the data memory area*/ + size=ramlimit-addr; + } + else /*Couldn't find a chunk big enough: report the problem.*/ + { + tap->a_unaloc=taxp->a_size; + fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id); + lkerr++; + } + } + + for(j=0x20; j<0x30; j++) + { + if (idatamap[j]==fchar) + { + addr=j; + tap->a_addr=addr; + taxp->a_addr=addr; + break; + } + } + } else /*Overlay areas not in internal ram*/ { taxp->a_addr = addr; diff --git a/as/mcs51/lkdata.c b/as/mcs51/lkdata.c index 660c22af..5edb74a6 100644 --- a/as/mcs51/lkdata.c +++ b/as/mcs51/lkdata.c @@ -8,9 +8,9 @@ * 721 Berkeley St. * Kent, Ohio 44240 * - * 28-Oct-97 JLH: - * - change s_id from [NCPS] to pointer (comment) - * 31-Oct-97 JLH: + * 28-Oct-97 JLH: + * - change s_id from [NCPS] to pointer (comment) + * 31-Oct-97 JLH: * - add jflag and jfp for NoICE output */ @@ -18,478 +18,478 @@ #include #include "aslink.h" -/*)Module lkdata.c +/*)Module lkdata.c * - * The module lkdata contains the global variables - * and structures used in the linker aslink. + * The module lkdata contains the global variables + * and structures used in the linker aslink. */ /* - * Definitions for all Global Variables + * Definitions for all Global Variables */ -char *_abs_ = { ". .ABS." }; +char *_abs_ = { ". .ABS." }; -int lkerr; /* Linker error flag - */ -char *ip; /* Pointer into the REL file text line in ib[] - */ -char ib[NINPUT]; /* REL file text line - */ -char *rp; /* pointer into the LST file - * text line in rb[] - */ -char rb[NINPUT]; /* LST file text line being - * address relocated - */ +int lkerr; /* Linker error flag + */ +char *ip; /* Pointer into the REL file text line in ib[] + */ +char ib[NINPUT]; /* REL file text line + */ +char *rp; /* pointer into the LST file + * text line in rb[] + */ +char rb[NINPUT]; /* LST file text line being + * address relocated + */ char sdccopt[NINPUT]=""; char sdccopt_module[NINPUT]=""; char curr_module[NINPUT]=""; int dflag; /* Debug information output flag - */ -int oflag; /* Output file type flag - */ -int mflag; /* Map output flag - */ -int sflag; /* JCF: Memory usage output flag - */ -int packflag=0; /* JCF: Pack internal memory flag - */ -int stacksize=0; /* JCF: Stack size - */ -int aflag; /* Overlapping area warning flag - */ -int jflag; /* NoICE output flag - */ -int xflag; /* Map file radix type flag - */ -int pflag; /* print linker command file flag - */ -int uflag; /* Listing relocation flag - */ -int rflag; /* Extended linear address record flag. - */ -int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -int line; /* current line number - */ -int page; /* current page number - */ -int lop; /* current line number on page - */ -int pass; /* linker pass number - */ -int rtcnt; /* count of elements in the - * rtval[] and rtflg[] arrays - */ -Addr_T rtval[NTXT]; /* data associated with relocation - */ -int rtflg[NTXT]; /* indicates if rtval[] value is - * to be sent to the output file. - * (always set in this linker) - */ -int hilo; /* REL file byte ordering - */ -int gline; /* LST file relocation active - * for current line - */ -int gcntr; /* LST file relocation active - * counter - */ -Addr_T iram_size; /* internal ram size - */ -long xram_size=-1; /* external ram size - */ -long code_size=-1; /* code size - */ + */ +int oflag; /* Output file type flag + */ +int mflag; /* Map output flag + */ +int sflag; /* JCF: Memory usage output flag + */ +int packflag=0; /* JCF: Pack internal memory flag + */ +int stacksize=0; /* JCF: Stack size + */ +int aflag; /* Overlapping area warning flag + */ +int jflag; /* NoICE output flag + */ +int xflag; /* Map file radix type flag + */ +int pflag; /* print linker command file flag + */ +int uflag; /* Listing relocation flag + */ +int rflag; /* Extended linear address record flag. + */ +int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +int line; /* current line number + */ +int page; /* current page number + */ +int lop; /* current line number on page + */ +int pass; /* linker pass number + */ +int rtcnt; /* count of elements in the + * rtval[] and rtflg[] arrays + */ +Addr_T rtval[NTXT]; /* data associated with relocation + */ +int rtflg[NTXT]; /* indicates if rtval[] value is + * to be sent to the output file. + * (always set in this linker) + */ +int hilo; /* REL file byte ordering + */ +int gline; /* LST file relocation active + * for current line + */ +int gcntr; /* LST file relocation active + * counter + */ +Addr_T iram_size; /* internal ram size + */ +long xram_size=-1; /* external ram size + */ +long code_size=-1; /* code size + */ /* - * The structure lfile contains a pointer to a - * file specification string, the file type, and - * a link to the next lfile structure. + * The structure lfile contains a pointer to a + * file specification string, the file type, and + * a link to the next lfile structure. * - * struct lfile - * { - * struct lfile *f_flp; lfile link - * int f_type; File type - * char *f_idp; Pointer to file spec - * }; + * struct lfile + * { + * struct lfile *f_flp; lfile link + * int f_type; File type + * char *f_idp; Pointer to file spec + * }; */ -struct lfile *filep; /* The pointers (lfile *) filep, - * (lfile *) cfp, and (FILE *) sfp - * are used in conjunction with - * the routine getline() to read - * asmlnk commands from - * (1) the standard input or - * (2) or a command file - * and to read the REL files - * sequentially as defined by the - * asmlnk input commands. - * - * The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - */ -struct lfile *cfp; /* The pointer *cfp points to the - * current lfile structure - */ -struct lfile *startp;/* asmlnk startup file structure - */ -struct lfile *linkp; /* pointer to first lfile structure - * containing an input REL file - * specification - */ -struct lfile *lfp; /* pointer to current lfile structure - * being processed by parse() - */ -FILE *ofp; /* Output file handle - * for word formats - */ -FILE *mfp; /* Map output file handle - */ -FILE *jfp; /* NoICE output file handle - */ -FILE *rfp; /* File handle for output - * address relocated ASxxxx - * listing file - */ -FILE *sfp; /* The file handle sfp points to the - * currently open file - */ -FILE *tfp; /* File handle for input - * ASxxxx listing file - */ +struct lfile *filep; /* The pointers (lfile *) filep, + * (lfile *) cfp, and (FILE *) sfp + * are used in conjunction with + * the routine getline() to read + * asmlnk commands from + * (1) the standard input or + * (2) or a command file + * and to read the REL files + * sequentially as defined by the + * asmlnk input commands. + * + * The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + */ +struct lfile *cfp; /* The pointer *cfp points to the + * current lfile structure + */ +struct lfile *startp;/* asmlnk startup file structure + */ +struct lfile *linkp; /* pointer to first lfile structure + * containing an input REL file + * specification + */ +struct lfile *lfp; /* pointer to current lfile structure + * being processed by parse() + */ +FILE *ofp; /* Output file handle + * for word formats + */ +FILE *mfp; /* Map output file handle + */ +FILE *jfp; /* NoICE output file handle + */ +FILE *rfp; /* File handle for output + * address relocated ASxxxx + * listing file + */ +FILE *sfp; /* The file handle sfp points to the + * currently open file + */ +FILE *tfp; /* File handle for input + * ASxxxx listing file + */ FILE *dfp = NULL ; /* - * File handle for debug - * information output file - */ + * File handle for debug + * information output file + */ /* - * The structures of head, area, areax, and sym are created - * as the REL files are read during the first pass of the - * linker. The struct head is created upon encountering a - * H directive in the REL file. The structure contains a - * link to a link file structure (struct lfile) which describes - * the file containing the H directive, the number of data/code - * areas contained in this header segment, the number of - * symbols referenced/defined in this header segment, a pointer - * to an array of pointers to areax structures (struct areax) - * created as each A directive is read, and a pointer to an - * array of pointers to symbol structures (struct sym) for - * all referenced/defined symbols. As H directives are read - * from the REL files a linked list of head structures is - * created by placing a link to the new head structure - * in the previous head structure. + * The structures of head, area, areax, and sym are created + * as the REL files are read during the first pass of the + * linker. The struct head is created upon encountering a + * H directive in the REL file. The structure contains a + * link to a link file structure (struct lfile) which describes + * the file containing the H directive, the number of data/code + * areas contained in this header segment, the number of + * symbols referenced/defined in this header segment, a pointer + * to an array of pointers to areax structures (struct areax) + * created as each A directive is read, and a pointer to an + * array of pointers to symbol structures (struct sym) for + * all referenced/defined symbols. As H directives are read + * from the REL files a linked list of head structures is + * created by placing a link to the new head structure + * in the previous head structure. * - * struct head - * { - * struct head *h_hp; Header link - * struct lfile *h_lfile; Associated file - * int h_narea; # of areas - * struct areax **a_list; Area list - * int h_nglob; # of global symbols - * struct sym **s_list; Global symbol list - * char m_id[NCPS]; Module name - * }; + * struct head + * { + * struct head *h_hp; Header link + * struct lfile *h_lfile; Associated file + * int h_narea; # of areas + * struct areax **a_list; Area list + * int h_nglob; # of global symbols + * struct sym **s_list; Global symbol list + * char m_id[NCPS]; Module name + * }; */ -struct head *headp; /* The pointer to the first - * head structure of a linked list - */ -struct head *hp; /* Pointer to the current - * head structure - */ +struct head *headp; /* The pointer to the first + * head structure of a linked list + */ +struct head *hp; /* Pointer to the current + * head structure + */ /* - * A structure area is created for each 'unique' data/code - * area definition found as the REL files are read. The - * struct area contains the name of the area, a flag byte - * which contains the area attributes (REL/CON/OVR/ABS), - * an area subtype (not used in this assembler), and the - * area base address and total size which will be filled - * in at the end of the first pass through the REL files. - * As A directives are read from the REL files a linked - * list of unique area structures is created by placing a - * link to the new area structure in the previous area structure. + * A structure area is created for each 'unique' data/code + * area definition found as the REL files are read. The + * struct area contains the name of the area, a flag byte + * which contains the area attributes (REL/CON/OVR/ABS), + * an area subtype (not used in this assembler), and the + * area base address and total size which will be filled + * in at the end of the first pass through the REL files. + * As A directives are read from the REL files a linked + * list of unique area structures is created by placing a + * link to the new area structure in the previous area structure. * - * struct area - * { - * struct area *a_ap; Area link - * struct areax *a_axp; Area extension link - * Addr_T a_addr; Beginning address of area - * Addr_T a_size; Total size of the area - * char a_type; Area subtype - * char a_flag; Flag byte - * char a_id[NCPS]; Name - * }; + * struct area + * { + * struct area *a_ap; Area link + * struct areax *a_axp; Area extension link + * Addr_T a_addr; Beginning address of area + * Addr_T a_size; Total size of the area + * char a_type; Area subtype + * char a_flag; Flag byte + * char a_id[NCPS]; Name + * }; */ -struct area *areap; /* The pointer to the first - * area structure of a linked list - */ -struct area *ap; /* Pointer to the current - * area structure - */ +struct area *areap; /* The pointer to the first + * area structure of a linked list + */ +struct area *ap; /* Pointer to the current + * area structure + */ /* - * An areax structure is created for every A directive found - * while reading the REL files. The struct areax contains a - * link to the 'unique' area structure referenced by the A - * directive and to the head structure this area segment is - * a part of. The size of this area segment as read from the - * A directive is placed in the areax structure. The beginning - * address of this segment will be filled in at the end of the - * first pass through the REL files. As A directives are read - * from the REL files a linked list of areax structures is - * created for each unique area. The final areax linked - * list has at its head the 'unique' area structure linked - * to the linked areax structures (one areax structure for - * each A directive for this area). + * An areax structure is created for every A directive found + * while reading the REL files. The struct areax contains a + * link to the 'unique' area structure referenced by the A + * directive and to the head structure this area segment is + * a part of. The size of this area segment as read from the + * A directive is placed in the areax structure. The beginning + * address of this segment will be filled in at the end of the + * first pass through the REL files. As A directives are read + * from the REL files a linked list of areax structures is + * created for each unique area. The final areax linked + * list has at its head the 'unique' area structure linked + * to the linked areax structures (one areax structure for + * each A directive for this area). * - * struct areax - * { - * struct areax *a_axp; Area extension link - * struct area *a_bap; Base area link - * struct head *a_bhp; Base header link - * Addr_T a_addr; Beginning address of section - * Addr_T a_size; Size of the area in section - * }; + * struct areax + * { + * struct areax *a_axp; Area extension link + * struct area *a_bap; Base area link + * struct head *a_bhp; Base header link + * Addr_T a_addr; Beginning address of section + * Addr_T a_size; Size of the area in section + * }; */ -struct areax *axp; /* Pointer to the current - * areax structure - */ +struct areax *axp; /* Pointer to the current + * areax structure + */ /* - * A sym structure is created for every unique symbol - * referenced/defined while reading the REL files. The - * struct sym contains the symbol's name, a flag value - * (not used in this linker), a symbol type denoting - * referenced/defined, and an address which is loaded - * with the relative address within the area in which - * the symbol was defined. The sym structure also - * contains a link to the area where the symbol was defined. - * The sym structures are linked into linked lists using - * the symbol link element. + * A sym structure is created for every unique symbol + * referenced/defined while reading the REL files. The + * struct sym contains the symbol's name, a flag value + * (not used in this linker), a symbol type denoting + * referenced/defined, and an address which is loaded + * with the relative address within the area in which + * the symbol was defined. The sym structure also + * contains a link to the area where the symbol was defined. + * The sym structures are linked into linked lists using + * the symbol link element. * - * struct sym - * { - * struct sym *s_sp; Symbol link - * struct areax *s_axp; Symbol area link - * char s_type; Symbol subtype - * char s_flag; Flag byte - * Addr_T s_addr; Address - * char *s_id; Name (JLH) - * }; + * struct sym + * { + * struct sym *s_sp; Symbol link + * struct areax *s_axp; Symbol area link + * char s_type; Symbol subtype + * char s_flag; Flag byte + * Addr_T s_addr; Address + * char *s_id; Name (JLH) + * }; */ -struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ +struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ /* - * The struct base contains a pointer to a - * base definition string and a link to the next - * base structure. + * The struct base contains a pointer to a + * base definition string and a link to the next + * base structure. * - * struct base - * { - * struct base *b_base; Base link - * char *b_strp; String pointer - * }; + * struct base + * { + * struct base *b_base; Base link + * char *b_strp; String pointer + * }; */ -struct base *basep; /* The pointer to the first - * base structure - */ -struct base *bsp; /* Pointer to the current - * base structure - */ +struct base *basep; /* The pointer to the first + * base structure + */ +struct base *bsp; /* Pointer to the current + * base structure + */ /* - * The struct globl contains a pointer to a - * global definition string and a link to the next - * global structure. + * The struct globl contains a pointer to a + * global definition string and a link to the next + * global structure. * - * struct globl - * { - * struct globl *g_globl; Global link - * char *g_strp; String pointer - * }; + * struct globl + * { + * struct globl *g_globl; Global link + * char *g_strp; String pointer + * }; */ -struct globl *globlp;/* The pointer to the first - * globl structure - */ -struct globl *gsp; /* Pointer to the current - * globl structure - */ +struct globl *globlp;/* The pointer to the first + * globl structure + */ +struct globl *gsp; /* Pointer to the current + * globl structure + */ /* - * A structure sdp is created for each 'unique' paged - * area definition found as the REL files are read. - * As P directives are read from the REL files a linked - * list of unique sdp structures is created by placing a - * link to the new sdp structure in the previous area structure. + * A structure sdp is created for each 'unique' paged + * area definition found as the REL files are read. + * As P directives are read from the REL files a linked + * list of unique sdp structures is created by placing a + * link to the new sdp structure in the previous area structure. * - * struct sdp - * { - * struct area *s_area; Paged Area link - * struct areax *s_areax; Paged Area Extension Link - * Addr_T s_addr; Page address offset - * }; + * struct sdp + * { + * struct area *s_area; Paged Area link + * struct areax *s_areax; Paged Area Extension Link + * Addr_T s_addr; Page address offset + * }; */ -struct sdp sdp; /* Base Page Structure */ +struct sdp sdp; /* Base Page Structure */ /* - * The structure rerr is loaded with the information - * required to report an error during the linking - * process. The structure contains an index value - * which selects the areax structure from the header - * areax structure list, a mode value which selects - * symbol or area relocation, the base address in the - * area section, an area/symbol list index value, and - * an area/symbol offset value. + * The structure rerr is loaded with the information + * required to report an error during the linking + * process. The structure contains an index value + * which selects the areax structure from the header + * areax structure list, a mode value which selects + * symbol or area relocation, the base address in the + * area section, an area/symbol list index value, and + * an area/symbol offset value. * - * struct rerr - * { - * int aindex; Linking area - * int mode; Relocation mode - * Addr_T rtbase; Base address in section - * int rindex; Area/Symbol reloaction index - * Addr_T rval; Area/Symbol offset value - * }; + * struct rerr + * { + * int aindex; Linking area + * int mode; Relocation mode + * Addr_T rtbase; Base address in section + * int rindex; Area/Symbol reloaction index + * Addr_T rval; Area/Symbol offset value + * }; */ -struct rerr rerr; /* Structure containing the - * linker error information - */ +struct rerr rerr; /* Structure containing the + * linker error information + */ /* - * The structure lbpath is created for each library - * path specification input by the -k option. The - * lbpath structures are linked into a list using - * the next link element. + * The structure lbpath is created for each library + * path specification input by the -k option. The + * lbpath structures are linked into a list using + * the next link element. * - * struct lbpath { - * struct lbpath *next; - * char *path; - * }; + * struct lbpath { + * struct lbpath *next; + * char *path; + * }; */ -struct lbpath *lbphead; /* pointer to the first - * library path structure - */ +struct lbpath *lbphead; /* pointer to the first + * library path structure + */ /* - * The structure lbname is created for all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file. The element path points to - * the path string, element libfil points to the library - * file string, and the element libspc is the concatenation - * of the valid path and libfil strings. + * The structure lbname is created for all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file. The element path points to + * the path string, element libfil points to the library + * file string, and the element libspc is the concatenation + * of the valid path and libfil strings. * - * The lbpath structures are linked into a list - * using the next link element. + * The lbpath structures are linked into a list + * using the next link element. * - * Each library file contains a list of object files - * that are contained in the particular library. e.g.: + * Each library file contains a list of object files + * that are contained in the particular library. e.g.: * - * \iolib\termio - * \inilib\termio + * \iolib\termio + * \inilib\termio * - * Only one specification per line is allowed. + * Only one specification per line is allowed. * - * struct lbname { - * struct lbname *next; - * char *path; - * char *libfil; - * char *libspc; - * }; + * struct lbname { + * struct lbname *next; + * char *path; + * char *libfil; + * char *libspc; + * }; */ -struct lbname *lbnhead; /* pointer to the first - * library name structure - */ +struct lbname *lbnhead; /* pointer to the first + * library name structure + */ /* - * The function fndsym() searches through all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file for a symbol definition. + * The function fndsym() searches through all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file for a symbol definition. * - * The structure lbfile is created for the first library - * object file which contains the definition for the - * specified undefined symbol. + * The structure lbfile is created for the first library + * object file which contains the definition for the + * specified undefined symbol. * - * The element libspc points to the library file path specification - * and element relfil points to the object file specification string. - * The element filspc is the complete path/file specification for - * the library file to be imported into the linker. The - * file specicifation may be formed in one of two ways: + * The element libspc points to the library file path specification + * and element relfil points to the object file specification string. + * The element filspc is the complete path/file specification for + * the library file to be imported into the linker. The + * file specicifation may be formed in one of two ways: * - * (1) If the library file contained an absolute - * path/file specification then this becomes filspc. - * (i.e. C:\...) + * (1) If the library file contained an absolute + * path/file specification then this becomes filspc. + * (i.e. C:\...) * - * (2) If the library file contains a relative path/file - * specification then the concatenation of the path - * and this file specification becomes filspc. - * (i.e. \...) + * (2) If the library file contains a relative path/file + * specification then the concatenation of the path + * and this file specification becomes filspc. + * (i.e. \...) * - * The lbpath structures are linked into a list - * using the next link element. + * The lbpath structures are linked into a list + * using the next link element. * - * struct lbfile { - * struct lbfile *next; - * char *libspc; - * char *relfil; - * char *filspc; - * }; + * struct lbfile { + * struct lbfile *next; + * char *libspc; + * char *relfil; + * char *filspc; + * }; */ -struct lbfile *lbfhead; /* pointer to the first - * library file structure - */ +struct lbfile *lbfhead; /* pointer to the first + * library file structure + */ /* - * array of character types, one per - * ASCII character + * array of character types, one per + * ASCII character */ -unsigned char ctype[128] = { -/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, -/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, -/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, -/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, -/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, -/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*X*/ LETTER, LETTER, LETTER, ETC, ETC, ETC, BINOP, LETTER, -/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC +unsigned char ctype[128] = { +/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, +/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, +/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, +/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, +/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, +/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*X*/ LETTER, LETTER, LETTER, BINOP, ETC, ETC, BINOP, LETTER, +/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC }; /* - * an array of characters which - * perform the case translation function + * an array of characters which + * perform the case translation function */ -#if CASE_SENSITIVE +#if CASE_SENSITIVE #else -char ccase[128] = { -/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', -/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', -/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', -/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', -/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', -/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', -/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', -/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', -/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', -/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' -}; +char ccase[128] = { +/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', +/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', +/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', +/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', +/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', +/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', +/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', +/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', +/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', +/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' +}; #endif diff --git a/as/mcs51/lkmain.c b/as/mcs51/lkmain.c index 843f707c..f7d1537f 100644 --- a/as/mcs51/lkmain.c +++ b/as/mcs51/lkmain.c @@ -92,7 +92,7 @@ void Areas51 (void) char * rel2[]={ "XH", - "H B areas 0 global symbols", + "H C areas 0 global symbols", "A _CODE size 0 flags 0", /*Each .rel has one, so...*/ "A REG_BANK_0 size 0 flags 4", /*Register banks are overlayable*/ "A REG_BANK_1 size 0 flags 4", @@ -100,6 +100,7 @@ void Areas51 (void) "A REG_BANK_3 size 0 flags 4", "A BSEG size 0 flags 80", /*BSEG must be just before BITS*/ "A BSEG_BYTES size 0 flags 0", /*Size will be obtained from BSEG in lnkarea()*/ + "A BIT_BANK size 0 flags 4", /*Bit register bank is overlayable*/ "A DSEG size 0 flags 0", "A OSEG size 0 flags 4", "A ISEG size 0 flags 0", diff --git a/as/mcs51/lkmem.c b/as/mcs51/lkmem.c index d330f055..4447c2ba 100644 --- a/as/mcs51/lkmem.c +++ b/as/mcs51/lkmem.c @@ -143,7 +143,11 @@ int summary(struct area * areap) } else if (EQ(xp->a_id, "BSEG_BYTES")) { - Ram[4].Size=xp->a_size; + Ram[4].Size+=xp->a_size; + } + else if (EQ(xp->a_id, "BIT_BANK")) + { + Ram[4].Size+=xp->a_size; } else if(xp->a_flag & A_CODE) @@ -479,7 +483,7 @@ int summary2(struct area * areap) if(j%16==0) fprintf(of, "\n0x%02x:|", j); fprintf(of, "%c|", idatamap[j]); } - fprintf(of, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n"); + fprintf(of, "\n0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n"); for(j=0; j<256; j++) { diff --git a/as/mcs51/lkrloc.c b/as/mcs51/lkrloc.c index baa05649..2771ec50 100644 --- a/as/mcs51/lkrloc.c +++ b/as/mcs51/lkrloc.c @@ -9,8 +9,8 @@ * Kent, Ohio 44240 * * 29-Oct-97 JLH: - * - errdmp: show s_id as string rather than array [NCPS] - * - relr: add support for 11 bit 8051 addressing + * - errdmp: show s_id as string rather than array [NCPS] + * - relr: add support for 11 bit 8051 addressing * 02-Apr-98 JLH: don't output empty hex records */ @@ -18,31 +18,31 @@ #include #include "aslink.h" -/*)Module lkrloc.c - * - * The module lkrloc.c contains the functions which - * perform the relocation calculations. - * - * lkrloc.c contains the following functions: - * Addr_T adb_b() - * Addr_T adb_lo() - * Addr_T adb_hi() - * Addr_T adw_w() - * Addr_T adw_lo() - * Addr_T adw_hi() - * VOID erpdmp() - * VOID errdmp() - * Addr_T evword() - * VOID prntval() - * VOID rele() - * VOID relerr() - * VOID relerp() - * VOID reloc() - * VOID relp() - * VOID relr() - * VOID relt() - * - * lkrloc.c the local variable errmsg[]. +/*)Module lkrloc.c + * + * The module lkrloc.c contains the functions which + * perform the relocation calculations. + * + * lkrloc.c contains the following functions: + * Addr_T adb_b() + * Addr_T adb_lo() + * Addr_T adb_hi() + * Addr_T adw_w() + * Addr_T adw_lo() + * Addr_T adw_hi() + * VOID erpdmp() + * VOID errdmp() + * Addr_T evword() + * VOID prntval() + * VOID rele() + * VOID relerr() + * VOID relerp() + * VOID reloc() + * VOID relp() + * VOID relr() + * VOID relt() + * + * lkrloc.c the local variable errmsg[]. * */ @@ -56,366 +56,368 @@ int lastExtendedAddress=-1; */ static int lastAreaIndex = -1; -/*)Function VOID reloc(c) +/*)Function VOID reloc(c) * - * char c process code + * char c process code * - * The function reloc() calls a particular relocation - * function determined by the process code. + * The function reloc() calls a particular relocation + * function determined by the process code. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int lkerr error flag + * global variables: + * int lkerr error flag * - * called functions: - * int fprintf() c_library - * VOID rele() lkrloc.c - * VOID relp() lkrloc.c - * VOID relr() lkrloc.c - * VOId relt() lkrloc.c + * called functions: + * int fprintf() c_library + * VOID rele() lkrloc.c + * VOID relp() lkrloc.c + * VOID relr() lkrloc.c + * VOId relt() lkrloc.c * - * side effects: - * Refer to the called relocation functions. + * side effects: + * Refer to the called relocation functions. * */ -VOID -reloc(c) -char c; +VOID reloc(char c) { - switch(c) { + switch(c) { - case 'T': - relt(); - break; + case 'T': + relt(); + break; - case 'R': - relr(); - break; + case 'R': + relr(); + break; - case 'P': - relp(); - break; + case 'P': + relp(); + break; - case 'E': - rele(); - break; + case 'E': + rele(); + break; - default: - fprintf(stderr, "Undefined Relocation Operation\n"); - lkerr++; - break; + default: + fprintf(stderr, "Undefined Relocation Operation\n"); + lkerr++; + break; - } + } } -/*)Function VOID relt() +/*)Function VOID relt() * - * The function relt() evaluates a T line read by - * the linker. Each byte value read is saved in the - * rtval[] array, rtflg[] is set, and the number of - * evaluations is maintained in rtcnt. + * The function relt() evaluates a T line read by + * the linker. Each byte value read is saved in the + * rtval[] array, rtflg[] is set, and the number of + * evaluations is maintained in rtcnt. * - * T Line + * T Line * - * T xx xx nn nn nn nn nn ... + * T xx xx nn nn nn nn nn ... * * - * In: "T n0 n1 n2 n3 ... nn" + * In: "T n0 n1 n2 n3 ... nn" * - * Out: 0 1 2 .. rtcnt - * +----+----+----+----+----+ - * rtval | n0 | n1 | n2 | .. | nn | - * +----+----+----+----+----+ - * rtflag| 1 | 1 | 1 | 1 | 1 | + * Out: 0 1 2 .. rtcnt + * +----+----+----+----+----+ + * rtval | n0 | n1 | n2 | .. | nn | + * +----+----+----+----+----+ + * rtflag| 1 | 1 | 1 | 1 | 1 | * +----+----+----+----+----+ * - * The T line contains the assembled code output by the assem- - * bler with xx xx being the offset address from the current area - * base address and nn being the assembled instructions and data in - * byte format. + * The T line contains the assembled code output by the assem- + * bler with xx xx being the offset address from the current area + * base address and nn being the assembled instructions and data in + * byte format. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int rtcnt number of values evaluated - * int rtflg[] array of evaluation flags - * int rtval[] array of evaluation values + * global variables: + * int rtcnt number of values evaluated + * int rtflg[] array of evaluation flags + * int rtval[] array of evaluation values * - * called functions: - * int eval() lkeval.c - * int more() lklex.c + * called functions: + * int eval() lkeval.c + * int more() lklex.c * - * side effects: - * Linker input T line evaluated. + * side effects: + * Linker input T line evaluated. * */ -VOID -relt() +VOID relt(VOID) { - rtcnt = 0; - while (more()) { - if (rtcnt < NTXT) { - rtval[rtcnt] = eval(); - rtflg[rtcnt] = 1; - rtcnt++; - } - } + rtcnt = 0; + while (more()) { + if (rtcnt < NTXT) { + rtval[rtcnt] = eval(); + rtflg[rtcnt] = 1; + rtcnt++; + } + } } -/*)Function VOID relr() - * - * The function relr() evaluates a R line read by - * the linker. The R line data is combined with the - * previous T line data to perform the relocation of - * code and data bytes. The S19 / IHX output and - * translation of the LST files to RST files may be - * performed. - * - * R Line - * - * R 0 0 nn nn n1 n2 xx xx ... - * - * The R line provides the relocation information to the linker. - * The nn nn value is the current area index, i.e. which area the - * current values were assembled. Relocation information is en- - * coded in groups of 4 bytes: - * - * 1. n1 is the relocation mode and object format - * 1. bit 0 word(0x00)/byte(0x01) - * 2. bit 1 relocatable area(0x00)/symbol(0x02) - * 3. bit 2 normal(0x00)/PC relative(0x04) relocation - * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for - * byte data - * 5. bit 4 signed(0x00)/unsigned(0x10) byte data - * 6. bit 5 normal(0x00)/page '0'(0x20) reference - * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference - * - * 2. n2 is a byte index into the corresponding (i.e. pre- - * ceeding) T line data (i.e. a pointer to the data to be - * updated by the relocation). The T line data may be - * 1-byte or 2-byte byte data format or 2-byte word - * format. - * - * 3. xx xx is the area/symbol index for the area/symbol be- - * ing referenced. the corresponding area/symbol is found - * in the header area/symbol lists. - * - * The groups of 4 bytes are repeated for each item requiring relo- - * cation in the preceeding T line. - * - * local variable: - * areax **a pointer to array of area pointers - * int aindex area index - * char *errmsg[] array of pointers to error strings - * int error error code - * int lkerr error flag - * int mode relocation mode - * adrr_t paga paging base area address - * Addr_T pags paging symbol address - * Addr_T pc relocated base address - * Addr_T r PCR relocation value - * Addr_T reli relocation initial value - * Addr_T relv relocation final value - * int rindex symbol / area index - * Addr_T rtbase base code address - * Addr_T rtofst rtval[] index offset - * int rtp index into T data - * sym **s pointer to array of symbol pointers - * - * global variables: - * head *hp pointer to the head structure - * rerr rerr linker error structure - * FILE *stderr standard error device - * - * called functions: - * Addr_T adb_b() lkrloc.c - * Addr_T adb_lo() lkrloc.c - * Addr_T adb_hi() lkrloc.c - * Addr_T adw_w() lkrloc.c - * Addr_T evword() lkrloc.c - * int eval() lkeval.c - * int fprintf() c_library - * VOID ihx() lkihx.c - * int lkulist lklist.c - * int more() lklex.c - * VOID relerr() lkrloc.c - * VOID s19() lks19.c - * int symval() lksym.c - * - * side effects: - * The R and T lines are combined to produce - * relocated code and data. Output S19 / IHX - * and relocated listing files may be produced. +/*)Function VOID relr() + * + * The function relr() evaluates a R line read by + * the linker. The R line data is combined with the + * previous T line data to perform the relocation of + * code and data bytes. The S19 / IHX output and + * translation of the LST files to RST files may be + * performed. + * + * R Line + * + * R 0 0 nn nn n1 n2 xx xx ... + * + * The R line provides the relocation information to the linker. + * The nn nn value is the current area index, i.e. which area the + * current values were assembled. Relocation information is en- + * coded in groups of 4 bytes: + * + * 1. n1 is the relocation mode and object format + * 1. bit 0 word(0x00)/byte(0x01) + * 2. bit 1 relocatable area(0x00)/symbol(0x02) + * 3. bit 2 normal(0x00)/PC relative(0x04) relocation + * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for + * byte data + * 5. bit 4 signed(0x00)/unsigned(0x10) byte data + * 6. bit 5 normal(0x00)/page '0'(0x20) reference + * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference + * + * 2. n2 is a byte index into the corresponding (i.e. pre- + * ceeding) T line data (i.e. a pointer to the data to be + * updated by the relocation). The T line data may be + * 1-byte or 2-byte byte data format or 2-byte word + * format. + * + * 3. xx xx is the area/symbol index for the area/symbol be- + * ing referenced. the corresponding area/symbol is found + * in the header area/symbol lists. + * + * The groups of 4 bytes are repeated for each item requiring relo- + * cation in the preceeding T line. + * + * local variable: + * areax **a pointer to array of area pointers + * int aindex area index + * char *errmsg[] array of pointers to error strings + * int error error code + * int lkerr error flag + * int mode relocation mode + * adrr_t paga paging base area address + * Addr_T pags paging symbol address + * Addr_T pc relocated base address + * Addr_T r PCR relocation value + * Addr_T reli relocation initial value + * Addr_T relv relocation final value + * int rindex symbol / area index + * Addr_T rtbase base code address + * Addr_T rtofst rtval[] index offset + * int rtp index into T data + * sym **s pointer to array of symbol pointers + * + * global variables: + * head *hp pointer to the head structure + * rerr rerr linker error structure + * FILE *stderr standard error device + * + * called functions: + * Addr_T adb_b() lkrloc.c + * Addr_T adb_lo() lkrloc.c + * Addr_T adb_hi() lkrloc.c + * Addr_T adw_w() lkrloc.c + * Addr_T evword() lkrloc.c + * int eval() lkeval.c + * int fprintf() c_library + * VOID ihx() lkihx.c + * int lkulist lklist.c + * int more() lklex.c + * VOID relerr() lkrloc.c + * VOID s19() lks19.c + * int symval() lksym.c + * + * side effects: + * The R and T lines are combined to produce + * relocated code and data. Output S19 / IHX + * and relocated listing files may be produced. * */ -VOID -relr() +VOID relr(VOID) { - register int mode; - register Addr_T reli, relv; - int aindex, rindex, rtp, error; - Addr_T r, rtbase, rtofst, paga, pags, pc; - struct areax **a; - struct sym **s; - - /* - * Get area and symbol lists - */ - a = hp->a_list; - s = hp->s_list; - - /* - * Verify Area Mode - */ - if (eval() != (R_WORD | R_AREA) || eval()) { - fprintf(stderr, "R input error\n"); - lkerr++; - } - - /* - * Get area pointer - */ - aindex = evword(); - if (aindex >= hp->h_narea) { - fprintf(stderr, "R area error\n"); - lkerr++; - return; - } - - /* - * Base values - */ - rtbase = adw_w(0, 0); - rtofst = 2; - - /* - * Relocate address - */ - pc = adw_w(a[aindex]->a_addr, 0); - - #if 0 - printf("area %d base address: 0x%x size: 0x%x rtbase: 0x%x\n", aindex, - a[aindex]->a_addr, a[aindex]->a_size, rtbase); - #endif - /* - * Do remaining relocations - */ - while (more()) { - error = 0; - mode = eval(); - - if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK) - { - mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval(); - /* printf("unescaping rmode\n"); */ - } - - rtp = eval(); - rindex = evword(); - - /* - * R_SYM or R_AREA references - */ - if (mode & R_SYM) { - if (rindex >= hp->h_nglob) { - fprintf(stderr, "R symbol error\n"); - lkerr++; - return; - } - reli = symval(s[rindex]); - } else { - if (rindex >= hp->h_narea) { - fprintf(stderr, "R area error\n"); - lkerr++; - return; - } - reli = a[rindex]->a_addr; - } - - /* - * R_PCR addressing - */ - if (mode & R_PCR) { - if (mode & R_BYTE) { - reli -= (pc + (rtp-rtofst) + 1); - } else { - reli -= (pc + (rtp-rtofst) + 2); - } - } - - /* - * R_PAG0 or R_PAG addressing - */ - if (mode & (R_PAG0 | R_PAG)) { - paga = sdp.s_area->a_addr; - pags = sdp.s_addr; - reli -= paga + pags; - } - - /* - * R_BYTE or R_WORD operation - */ - if (mode & R_BYTE) { - if (mode & R_BYT3) - { - /* This is a three byte address, of which - * we will select one byte. - */ - if (mode & R_HIB) - { - /* printf("24 bit address selecting hi byte.\n"); */ - relv = adb_24_hi(reli, rtp); - } - else if (mode & R_MSB) - { - /* Note that in 24 bit mode, R_MSB - * is really the middle byte, not - * the most significant byte. - * - * This is ugly and I can only apologize - * for any confusion. - */ - /* printf("24 bit address selecting middle byte.\n"); */ - relv = adb_24_mid(reli, rtp); - } - else - { - /* printf("24 bit address selecting lo byte.\n"); */ - relv = adb_24_lo(reli, rtp); - } - } - else if (mode & R_BYT2) { - /* This is a two byte address, of - * which we will select one byte. - */ - if (mode & R_MSB) { - relv = adb_hi(reli, rtp); - } else { - relv = adb_lo(reli, rtp); - } - } else { - relv = adb_b(reli, rtp); - } - } else if (IS_R_J11(mode)) { - /* JLH: 11 bit jump destination for 8051. Forms - / two byte instruction with op-code bits - / in the MIDDLE! - / rtp points at 3 byte locus: first two - / will get the instructiion. third one - / has raw op-code. - */ - - /* Calculate absolute destination - / relv must be on same 2K page as pc - */ - relv = adw_w(reli, rtp); + register int mode; + register Addr_T reli, relv; + int aindex, rindex, rtp, error; + Addr_T r, rtbase, rtofst, paga, pags, pc; + struct areax **a; + struct sym **s; + + /* + * Get area and symbol lists + */ + a = hp->a_list; + s = hp->s_list; + + /* + * Verify Area Mode + */ + if (eval() != (R_WORD | R_AREA) || eval()) { + fprintf(stderr, "R input error\n"); + lkerr++; + } + + /* + * Get area pointer + */ + aindex = evword(); + if (aindex >= hp->h_narea) { + fprintf(stderr, "R area error\n"); + lkerr++; + return; + } + + /* + * Base values + */ + rtbase = adw_w(0, 0); + rtofst = 2; + + /* + * Relocate address + */ + pc = adw_w(a[aindex]->a_addr, 0); + + #if 0 + printf("area %d base address: 0x%x size: 0x%x rtbase: 0x%x\n", aindex, + a[aindex]->a_addr, a[aindex]->a_size, rtbase); + #endif + /* + * Do remaining relocations + */ + while (more()) { + error = 0; + mode = eval(); + + if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK) + { + mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval(); + /* printf("unescaping rmode\n"); */ + } + + rtp = eval(); + rindex = evword(); + + /* + * R_SYM or R_AREA references + */ + if (mode & R_SYM) { + if (rindex >= hp->h_nglob) { + fprintf(stderr, "R symbol error\n"); + lkerr++; + return; + } + reli = symval(s[rindex]); + } else { + if (rindex >= hp->h_narea) { + fprintf(stderr, "R area error\n"); + lkerr++; + return; + } + reli = a[rindex]->a_addr; + } + + /* + * R_PCR addressing + */ + if (mode & R_PCR) { + if (mode & R_BYTE) { + reli -= (pc + (rtp-rtofst) + 1); + } else { + reli -= (pc + (rtp-rtofst) + 2); + } + } + + /* + * R_PAG0 or R_PAG addressing + */ + if (mode & (R_PAG0 | R_PAG)) { + paga = sdp.s_area->a_addr; + pags = sdp.s_addr; + reli -= paga + pags; + } + + /* + * R_BYTE or R_WORD operation + */ + if (mode & R_BYTE) { + if (mode & R_BYT3) + { + /* This is a three byte address, of which + * we will select one byte. + */ + if (mode & R_BIT) + { + relv = adb_24_bit(reli, rtp); + } + else if (mode & R_HIB) + { + /* printf("24 bit address selecting hi byte.\n"); */ + relv = adb_24_hi(reli, rtp); + } + else if (mode & R_MSB) + { + /* Note that in 24 bit mode, R_MSB + * is really the middle byte, not + * the most significant byte. + * + * This is ugly and I can only apologize + * for any confusion. + */ + /* printf("24 bit address selecting middle byte.\n"); */ + relv = adb_24_mid(reli, rtp); + } + else + { + /* printf("24 bit address selecting lo byte.\n"); */ + relv = adb_24_lo(reli, rtp); + } + } + else if (mode & R_BYT2) { + /* This is a two byte address, of + * which we will select one byte. + */ + if (mode & R_BIT) { + relv = adb_bit(reli, rtp); + } else if (mode & R_MSB) { + relv = adb_hi(reli, rtp); + } else { + relv = adb_lo(reli, rtp); + } + } else { + relv = adb_b(reli, rtp); + } + } else if (IS_R_J11(mode)) { + /* JLH: 11 bit jump destination for 8051. Forms + / two byte instruction with op-code bits + / in the MIDDLE! + / rtp points at 3 byte locus: first two + / will get the instructiion. third one + / has raw op-code. + */ + + /* Calculate absolute destination + / relv must be on same 2K page as pc + */ + relv = adw_w(reli, rtp); if ((relv & ~0x7ff) != ((pc + rtp - rtofst) & ~0x7ff)) { error = 2; @@ -426,1045 +428,1096 @@ relr() */ rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+2]; rtflg[rtp+2] = 0; - rtofst += 1; - } - else if (IS_R_J19(mode)) { - /* 19 bit jump destination for DS80C390. Forms - / three byte instruction with op-code bits - / in the MIDDLE! - / rtp points at 4 byte locus: first three - / will get the instructiion. fourth one - / has raw op-code. - */ - - /* Calculate absolute destination - / relv must be on same 512K page as pc - */ - relv = adw_24(reli, rtp); + rtofst += 1; + } + else if (IS_R_J19(mode)) { + /* 19 bit jump destination for DS80C390. Forms + / three byte instruction with op-code bits + / in the MIDDLE! + / rtp points at 4 byte locus: first three + / will get the instructiion. fourth one + / has raw op-code. + */ + + /* Calculate absolute destination + / relv must be on same 512K page as pc + */ + relv = adw_24(reli, rtp); if ((relv & ~0x7ffff) != ((pc + rtp - rtofst) & ~0x7ffff)) { - error = 2; - } + error = 2; + } /* Merge MSB (byte 0) with op-code, ignoring / top 5 bits of address. Then hide the op-code */ rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+3]; rtflg[rtp+3] = 0; - rtofst += 1; - } - else if (IS_C24(mode)) - { - /* 24 bit address */ - relv = adw_24(reli, rtp); - } - else - { - /* 16 bit address. */ - relv = adw_w(reli, rtp); - } - - /* - * R_BYTE with R_BYT2 offset adjust - */ - if (mode & R_BYTE) { - if (mode & R_BYT2) { - rtofst += 1; - } - } - - /* - * Unsigned Byte Checking - */ - if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF) - error = 1; - - /* - * PCR Relocation Error Checking - */ - if (mode & R_PCR && mode & R_BYTE) { - r = relv & ~0x7F; - if (r != (Addr_T) ~0x7F && r != 0) - error = 2; - } - - /* - * Page Relocation Error Checking - */ - /* if (mode & R_PAG0 && (relv & ~0xFF || paga || pags)) - error = 3;*/ - if (mode & R_PAG && (relv & ~0xFF)) - error = 4; - - /* - * Error Processing - */ - if (error) { - rerr.aindex = aindex; - rerr.mode = mode; - rerr.rtbase = rtbase + rtp - rtofst - 1; - rerr.rindex = rindex; - rerr.rval = relv - reli; - relerr(errmsg[error-1]); - } - } - if (uflag != 0) { - lkulist(1); - } - - /* JLH: output only if data (beyond two byte address) */ - if ((oflag == 1) && (rtcnt > 2)) { - int extendedAddress = (a[aindex]->a_addr >> 16) & 0xffff; - - /* Boy, is this a hack: for ABS sections, the - * base address is stored as zero, and the T records - * indicate the offset from zero. - * - * Since T records can only indicate a 16 bit offset, this - * obviously creates a problem for ABS segments located - * above 64K (this is only meaningful in flat24 mode). - * - * However, the size of an ABS area is stored as - * base address + section size (I suspect this is a bug, - * but it's a handy one right now). So the upper 8 bits of - * the 24 bit address are stored in the size record. - * Thus we add it in. - * - * This is another reason why we can't have areas greater - * than 64K yet, even in flat24 mode. - */ - // extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff); - // commented out by jr - - if (lastAreaIndex != aindex) { - lastAreaIndex = aindex; - newArea(); - } - - if (extendedAddress != lastExtendedAddress) - { - - if (lastExtendedAddress!=-1) { - printf("output extended linear address record 0x%x 0x%x\n", - extendedAddress, lastExtendedAddress); - } - - if (rflag) - { - ihxEntendedLinearAddress(extendedAddress); - } - else if (extendedAddress) - { - /* Not allowed to generate extended address records, - * but one is called for here... - */ - fprintf(stderr, - "warning: extended linear address encountered; " - "you probably want the -r flag.\n"); - } - lastExtendedAddress = extendedAddress; - } - ihx(1); - } else - if ((oflag == 2) && (rtcnt > 2)) { - s19(1); - } + rtofst += 1; + } + else if (IS_C24(mode)) + { + /* 24 bit address */ + relv = adw_24(reli, rtp); + } + else + { + /* 16 bit address. */ + relv = adw_w(reli, rtp); + } + + /* + * R_BYTE with R_BYT2 offset adjust + */ + if (mode & R_BYTE) { + if (mode & R_BYT2) { + rtofst += 1; + } + } + + /* + * Unsigned Byte Checking + */ + if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF) + error = 1; + + /* + * PCR Relocation Error Checking + */ + if (mode & R_PCR && mode & R_BYTE) { + r = relv & ~0x7F; + if (r != (Addr_T) ~0x7F && r != 0) + error = 2; + } + + /* + * Page Relocation Error Checking + */ + /* if (mode & R_PAG0 && (relv & ~0xFF || paga || pags)) + error = 3;*/ + if (mode & R_PAG && (relv & ~0xFF)) + error = 4; + if ((mode & R_BIT) && (relv & ~0x87FF)) + error = 5; + + /* + * Error Processing + */ + if (error) { + rerr.aindex = aindex; + rerr.mode = mode; + rerr.rtbase = rtbase + rtp - rtofst - 1; + rerr.rindex = rindex; + rerr.rval = relv - reli; + relerr(errmsg[error-1]); + } + } + if (uflag != 0) { + lkulist(1); + } + + /* JLH: output only if data (beyond two byte address) */ + if ((oflag == 1) && (rtcnt > 2)) { + int extendedAddress = (a[aindex]->a_addr >> 16) & 0xffff; + + /* Boy, is this a hack: for ABS sections, the + * base address is stored as zero, and the T records + * indicate the offset from zero. + * + * Since T records can only indicate a 16 bit offset, this + * obviously creates a problem for ABS segments located + * above 64K (this is only meaningful in flat24 mode). + * + * However, the size of an ABS area is stored as + * base address + section size (I suspect this is a bug, + * but it's a handy one right now). So the upper 8 bits of + * the 24 bit address are stored in the size record. + * Thus we add it in. + * + * This is another reason why we can't have areas greater + * than 64K yet, even in flat24 mode. + */ + // extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff); + // commented out by jr + + if (lastAreaIndex != aindex) { + lastAreaIndex = aindex; + newArea(); + } + + if (extendedAddress != lastExtendedAddress) + { + + if (lastExtendedAddress!=-1) { + printf("output extended linear address record 0x%x 0x%x\n", + extendedAddress, lastExtendedAddress); + } + + if (rflag) + { + ihxEntendedLinearAddress(extendedAddress); + } + else if (extendedAddress) + { + /* Not allowed to generate extended address records, + * but one is called for here... + */ + fprintf(stderr, + "warning: extended linear address encountered; " + "you probably want the -r flag.\n"); + } + lastExtendedAddress = extendedAddress; + } + ihx(1); + } else + if ((oflag == 2) && (rtcnt > 2)) { + s19(1); + } } char *errmsg[] = { - "Unsigned Byte error", - "Byte PCR relocation error", - "Page0 relocation error", - "Page Mode relocation error" + "Unsigned Byte error", + "Byte PCR relocation error", + "Page0 relocation error", + "Page Mode relocation error", + "Bit-addressable relocation error" }; -/*)Function VOID relp() - * - * The function relp() evaluates a P line read by - * the linker. The P line data is combined with the - * previous T line data to set the base page address - * and test the paging boundary and length. - * - * P Line - * - * P 0 0 nn nn n1 n2 xx xx - * - * The P line provides the paging information to the linker as - * specified by a .setdp directive. The format of the relocation - * information is identical to that of the R line. The correspond- - * ing T line has the following information: - * T xx xx aa aa bb bb - * - * Where aa aa is the area reference number which specifies the - * selected page area and bb bb is the base address of the page. - * bb bb will require relocation processing if the 'n1 n2 xx xx' is - * specified in the P line. The linker will verify that the base - * address is on a 256 byte boundary and that the page length of an - * area defined with the PAG type is not larger than 256 bytes. - * - * local variable: - * areax **a pointer to array of area pointers - * int aindex area index - * int mode relocation mode - * Addr_T relv relocation value - * int rindex symbol / area index - * int rtp index into T data - * sym **s pointer to array of symbol pointers - * - * global variables: - * head *hp pointer to the head structure - * int lkerr error flag - * sdp sdp base page structure - * FILE *stderr standard error device - * - * called functions: - * Addr_T adw_w() lkrloc.c - * Addr_T evword() lkrloc.c - * int eval() lkeval.c - * int fprintf() c_library - * int more() lklex.c - * int symval() lksym.c - * - * side effects: - * The P and T lines are combined to set - * the base page address and report any - * paging errors. +/*)Function VOID relp() + * + * The function relp() evaluates a P line read by + * the linker. The P line data is combined with the + * previous T line data to set the base page address + * and test the paging boundary and length. + * + * P Line + * + * P 0 0 nn nn n1 n2 xx xx + * + * The P line provides the paging information to the linker as + * specified by a .setdp directive. The format of the relocation + * information is identical to that of the R line. The correspond- + * ing T line has the following information: + * T xx xx aa aa bb bb + * + * Where aa aa is the area reference number which specifies the + * selected page area and bb bb is the base address of the page. + * bb bb will require relocation processing if the 'n1 n2 xx xx' is + * specified in the P line. The linker will verify that the base + * address is on a 256 byte boundary and that the page length of an + * area defined with the PAG type is not larger than 256 bytes. + * + * local variable: + * areax **a pointer to array of area pointers + * int aindex area index + * int mode relocation mode + * Addr_T relv relocation value + * int rindex symbol / area index + * int rtp index into T data + * sym **s pointer to array of symbol pointers + * + * global variables: + * head *hp pointer to the head structure + * int lkerr error flag + * sdp sdp base page structure + * FILE *stderr standard error device + * + * called functions: + * Addr_T adw_w() lkrloc.c + * Addr_T evword() lkrloc.c + * int eval() lkeval.c + * int fprintf() c_library + * int more() lklex.c + * int symval() lksym.c + * + * side effects: + * The P and T lines are combined to set + * the base page address and report any + * paging errors. * */ -VOID -relp() +VOID relp(VOID) { - register int aindex, rindex; - int mode, rtp; - Addr_T relv; - struct areax **a; - struct sym **s; - - /* - * Get area and symbol lists - */ - a = hp->a_list; - s = hp->s_list; - - /* - * Verify Area Mode - */ - if (eval() != (R_WORD | R_AREA) || eval()) { - fprintf(stderr, "P input error\n"); - lkerr++; - } - - /* - * Get area pointer - */ - aindex = evword(); - if (aindex >= hp->h_narea) { - fprintf(stderr, "P area error\n"); - lkerr++; - return; - } - - /* - * Do remaining relocations - */ - while (more()) { - mode = eval(); - rtp = eval(); - rindex = evword(); - - /* - * R_SYM or R_AREA references - */ - if (mode & R_SYM) { - if (rindex >= hp->h_nglob) { - fprintf(stderr, "P symbol error\n"); - lkerr++; - return; - } - relv = symval(s[rindex]); - } else { - if (rindex >= hp->h_narea) { - fprintf(stderr, "P area error\n"); - lkerr++; - return; - } - relv = a[rindex]->a_addr; - } - adw_w(relv, rtp); - } - - /* - * Paged values - */ - aindex = adw_w(0,2); - if (aindex >= hp->h_narea) { - fprintf(stderr, "P area error\n"); - lkerr++; - return; - } - sdp.s_areax = a[aindex]; - sdp.s_area = sdp.s_areax->a_bap; - sdp.s_addr = adw_w(0,4); - if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF) - relerp("Page Definition Boundary Error"); + register int aindex, rindex; + int mode, rtp; + Addr_T relv; + struct areax **a; + struct sym **s; + + /* + * Get area and symbol lists + */ + a = hp->a_list; + s = hp->s_list; + + /* + * Verify Area Mode + */ + if (eval() != (R_WORD | R_AREA) || eval()) { + fprintf(stderr, "P input error\n"); + lkerr++; + } + + /* + * Get area pointer + */ + aindex = evword(); + if (aindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + + /* + * Do remaining relocations + */ + while (more()) { + mode = eval(); + rtp = eval(); + rindex = evword(); + + /* + * R_SYM or R_AREA references + */ + if (mode & R_SYM) { + if (rindex >= hp->h_nglob) { + fprintf(stderr, "P symbol error\n"); + lkerr++; + return; + } + relv = symval(s[rindex]); + } else { + if (rindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + relv = a[rindex]->a_addr; + } + adw_w(relv, rtp); + } + + /* + * Paged values + */ + aindex = adw_w(0,2); + if (aindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + sdp.s_areax = a[aindex]; + sdp.s_area = sdp.s_areax->a_bap; + sdp.s_addr = adw_w(0,4); + if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF) + relerp("Page Definition Boundary Error"); } -/*)Function VOID rele() +/*)Function VOID rele() * - * The function rele() closes all open output files - * at the end of the linking process. + * The function rele() closes all open output files + * at the end of the linking process. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int oflag output type flag - * int uflag relocation listing flag + * global variables: + * int oflag output type flag + * int uflag relocation listing flag * - * called functions: - * VOID ihx() lkihx.c - * VOID lkulist() lklist.c - * VOID s19() lks19.c + * called functions: + * VOID ihx() lkihx.c + * VOID lkulist() lklist.c + * VOID s19() lks19.c * - * side effects: - * All open output files are closed. + * side effects: + * All open output files are closed. * */ -VOID -rele() +VOID rele(VOID) { - if (uflag != 0) { - lkulist(0); - } - if (oflag == 1) { - ihx(0); - } else - if (oflag == 2) { - s19(0); - } + if (uflag != 0) { + lkulist(0); + } + if (oflag == 1) { + ihx(0); + } else + if (oflag == 2) { + s19(0); + } } -/*)Function Addr_T evword() +/*)Function Addr_T evword() + * + * The function evword() combines two byte values + * into a single word value. + * + * local variable: + * Addr_T v temporary evaluation variable + * + * global variables: + * hilo byte ordering parameter + * + * called functions: + * int eval() lkeval.c + * + * side effects: + * Relocation text line is scanned to combine + * two byte values into a single word value. + * + */ + +Addr_T evword(VOID) +{ + register Addr_T v; + + if (hilo) { + v = (eval() << 8); + v += eval(); + } else { + v = eval(); + v += (eval() << 8); + } + return(v); +} + +/*)Function Addr_T adb_b(v, i) + * + * int v value to add to byte + * int i rtval[] index + * + * The function adb_b() adds the value of v to + * the single byte value contained in rtval[i]. + * The new value of rtval[i] is returned. + * + * local variable: + * none + * + * global variables: + * none + * + * called functions: + * none + * + * side effects: + * The value of rtval[] is changed. + * + */ + +Addr_T adb_b(register Addr_T v, register int i) +{ + return(rtval[i] += v); +} + +/*)Function Addr_T adb_bit(v, i) + * + * int v value to add to byte + * int i rtval[] index * - * The function evword() combines two byte values - * into a single word value. + * The function adb_bit() converts the single + * byte address value contained in rtval[i] to bit- + * addressable space and adds the value of v to it. + * The new value of rtval[i] is returned. * - * local variable: - * Addr_T v temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * none * - * called functions: - * int eval() lkeval.c + * called functions: + * none * - * side effects: - * Relocation text line is scanned to combine - * two byte values into a single word value. + * side effects: + * The value of rtval[] is changed. * */ -Addr_T -evword() +Addr_T adb_bit(register Addr_T v, register int i) { - register Addr_T v; - - if (hilo) { - v = (eval() << 8); - v += eval(); - } else { - v = eval(); - v += (eval() << 8); - } - return(v); + register Addr_T j; + + j = adb_lo(v, i) & 0xFF; + if ((j >= 0x20) && (j <= 0x2F)) { + j = (j - 0x20) * 8; + } else if ((j < 0x80) || ((j & 0x07) != 0)) { + return(0x100);//error + } + + if (hilo) { + j = rtval[i+1] = j + (rtval[i] & 0x07); + } else { + j = rtval[i] = j + (rtval[i+1] & 0x07); + } + return(j); } -/*)Function Addr_T adb_b(v, i) +/*)Function Addr_T adb_lo(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_b() adds the value of v to - * the single byte value contained in rtval[i]. - * The new value of rtval[i] is returned. + * The function adb_lo() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB rtflg[] is cleared. * - * local variable: - * none + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * none + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. + * side effects: + * The value of rtval[] is changed. + * The rtflg[] value corresponding to the + * MSB of the word value is cleared to reflect + * the fact that the LSB is the selected byte. * */ -Addr_T -adb_b(v, i) -register Addr_T v; -register int i; +Addr_T adb_lo(Addr_T v, int i) { - return(rtval[i] += v); + register Addr_T j; + + j = adw_w(v, i); + /* + * Remove Hi byte + */ + if (hilo) { + rtflg[i] = 0; + } else { + rtflg[i+1] = 0; + } + return (j); } -/*)Function Addr_T adb_lo(v, i) +/*)Function Addr_T adb_hi(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_lo() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB rtflg[] is cleared. + * The function adb_hi() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The LSB rtflg[] is cleared. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The rtflg[] value corresponding to the - * MSB of the word value is cleared to reflect - * the fact that the LSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The rtflg[] value corresponding to the + * LSB of the word value is cleared to reflect + * the fact that the MSB is the selected byte. * */ -Addr_T -adb_lo(v, i) -Addr_T v; -int i; +Addr_T adb_hi(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * Remove Hi byte - */ - if (hilo) { - rtflg[i] = 0; - } else { - rtflg[i+1] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * Remove Lo byte + */ + if (hilo) { + rtflg[i+1] = 0; + } else { + rtflg[i] = 0; + } + return (j); } -/*)Function Addr_T adb_hi(v, i) +/*)Function Addr_T adb_24_bit(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_hi() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The LSB rtflg[] is cleared. + * The function adb_24_bit() converts the single + * byte address value contained in rtval[i] to bit- + * addressable space and adds the value of v to it. + * The new value of rtval[i] is returned. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * none * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The rtflg[] value corresponding to the - * LSB of the word value is cleared to reflect - * the fact that the MSB is the selected byte. + * side effects: + * The value of rtval[] is changed. * */ -Addr_T -adb_hi(v, i) -Addr_T v; -int i; +Addr_T adb_24_bit(register Addr_T v, register int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * Remove Lo byte - */ - if (hilo) { - rtflg[i+1] = 0; - } else { - rtflg[i] = 0; - } - return (j); + register Addr_T j; + + j = adb_24_lo(v, i) & 0xFF; + if ((j >= 0x20) && (j <= 0x2F)) { + j = (j - 0x20) * 8; + } else if ((j < 0x80) || ((j & 0x07) != 0)) { + return(0x100);//error + } + + if (hilo) { + j = rtval[i+2] = j + (rtval[i+1] & 0x07); + } else { + j = rtval[i] = j + (rtval[i+1] & 0x07); + } + return(j); } -/*)Function Addr_T adb_24_hi(v, i) +/*)Function Addr_T adb_24_hi(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_24_hi() adds the value of v to the - * 24 bit value contained in rtval[i] - rtval[i+2]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The LSB & middle byte rtflg[] is cleared. + * The function adb_24_hi() adds the value of v to the + * 24 bit value contained in rtval[i] - rtval[i+2]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The LSB & middle byte rtflg[] is cleared. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The rtflg[] value corresponding to the - * LSB & middle byte of the word value is cleared to - * reflect the fact that the MSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The rtflg[] value corresponding to the + * LSB & middle byte of the word value is cleared to + * reflect the fact that the MSB is the selected byte. * */ -Addr_T -adb_24_hi(Addr_T v, int i) +Addr_T adb_24_hi(Addr_T v, int i) { - register Addr_T j; - - j = adw_24(v, i); - - /* Remove the lower two bytes. */ - if (hilo) - { - rtflg[i+2] = 0; - } - else - { - rtflg[i] = 0; - } - rtflg[i+1] = 0; - - return (j); + register Addr_T j; + + j = adw_24(v, i); + + /* Remove the lower two bytes. */ + if (hilo) + { + rtflg[i+2] = 0; + } + else + { + rtflg[i] = 0; + } + rtflg[i+1] = 0; + + return (j); } -/*)Function Addr_T adb_24_mid(v, i) +/*)Function Addr_T adb_24_mid(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_24_mid() adds the value of v to the - * 24 bit value contained in rtval[i] - rtval[i+2]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The LSB & MSB byte rtflg[] is cleared. + * The function adb_24_mid() adds the value of v to the + * 24 bit value contained in rtval[i] - rtval[i+2]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The LSB & MSB byte rtflg[] is cleared. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The rtflg[] value corresponding to the - * LSB & MSB of the 24 bit value is cleared to reflect - * the fact that the middle byte is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The rtflg[] value corresponding to the + * LSB & MSB of the 24 bit value is cleared to reflect + * the fact that the middle byte is the selected byte. * */ -Addr_T -adb_24_mid(Addr_T v, int i) +Addr_T adb_24_mid(Addr_T v, int i) { - register Addr_T j; + register Addr_T j; - j = adw_24(v, i); + j = adw_24(v, i); - /* remove the MSB & LSB. */ - rtflg[i+2] = 0; - rtflg[i] = 0; + /* remove the MSB & LSB. */ + rtflg[i+2] = 0; + rtflg[i] = 0; - return (j); + return (j); } -/*)Function Addr_T adb_24_lo(v, i) +/*)Function Addr_T adb_24_lo(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_24_lo() adds the value of v to the - * 24 bit value contained in rtval[i] - rtval[i+2]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB & middle byte rtflg[] is cleared. + * The function adb_24_lo() adds the value of v to the + * 24 bit value contained in rtval[i] - rtval[i+2]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB & middle byte rtflg[] is cleared. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The rtflg[] value corresponding to the - * MSB & middle byte of the word value is cleared to - * reflect the fact that the LSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The rtflg[] value corresponding to the + * MSB & middle byte of the word value is cleared to + * reflect the fact that the LSB is the selected byte. * */ -Addr_T -adb_24_lo(Addr_T v, int i) +Addr_T adb_24_lo(Addr_T v, int i) { - register Addr_T j; - - j = adw_24(v, i); - - /* Remove the upper two bytes. */ - if (hilo) - { - rtflg[i] = 0; - } - else - { - rtflg[i+2] = 0; - } - rtflg[i+1] = 0; - - return (j); + register Addr_T j; + + j = adw_24(v, i); + + /* Remove the upper two bytes. */ + if (hilo) + { + rtflg[i] = 0; + } + else + { + rtflg[i+2] = 0; + } + rtflg[i+1] = 0; + + return (j); } -/*)Function Addr_T adw_w(v, i) +/*)Function Addr_T adw_w(v, i) * - * int v value to add to word - * int i rtval[] index + * int v value to add to word + * int i rtval[] index * - * The function adw_w() adds the value of v to the - * word value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. + * The function adw_w() adds the value of v to the + * word value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The word value of rtval[] is changed. + * side effects: + * The word value of rtval[] is changed. * */ -Addr_T -adw_w(v, i) -register Addr_T v; -register int i; +Addr_T adw_w(register Addr_T v, register int i) { - register Addr_T j; - - if (hilo) { - j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff); - rtval[i] = (j >> 8) & 0xff; - rtval[i+1] = j & 0xff; - } else { - j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8); - rtval[i] = j & 0xff; - rtval[i+1] = (j >> 8) & 0xff; - } - return(j); + register Addr_T j; + + if (hilo) { + j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff); + rtval[i] = (j >> 8) & 0xff; + rtval[i+1] = j & 0xff; + } else { + j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8); + rtval[i] = j & 0xff; + rtval[i+1] = (j >> 8) & 0xff; + } + return(j); } -/*)Function Addr_T adw_24(v, i) +/*)Function Addr_T adw_24(v, i) * - * int v value to add to word - * int i rtval[] index + * int v value to add to word + * int i rtval[] index * - * The function adw_w() adds the value of v to the - * 24 bit value contained in rtval[i] - rtval[i+2]. - * The new value of rtval[i] - rtval[i+2] is returned. + * The function adw_w() adds the value of v to the + * 24 bit value contained in rtval[i] - rtval[i+2]. + * The new value of rtval[i] - rtval[i+2] is returned. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The word value of rtval[] is changed. + * side effects: + * The word value of rtval[] is changed. * */ -Addr_T -adw_24(Addr_T v, int i) +Addr_T adw_24(Addr_T v, int i) { - register Addr_T j; - - if (hilo) { - j = v + ((rtval[i] & 0xff) << 16) - + ((rtval[i+1] & 0xff) << 8) - + (rtval[i+2] & 0xff); - rtval[i] = (j >> 16) & 0xff; - rtval[i+1] = (j >> 8) & 0xff; - rtval[i+2] = j & 0xff; - } else { - j = v + (rtval[i] & 0xff) - + ((rtval[i+1] & 0xff) << 8) - + ((rtval[i+2] & 0xff) << 16); - rtval[i] = j & 0xff; - rtval[i+1] = (j >> 8) & 0xff; - rtval[i+2] = (j >> 16) & 0xff; - } - return(j); + register Addr_T j; + + if (hilo) { + j = v + ((rtval[i] & 0xff) << 16) + + ((rtval[i+1] & 0xff) << 8) + + (rtval[i+2] & 0xff); + rtval[i] = (j >> 16) & 0xff; + rtval[i+1] = (j >> 8) & 0xff; + rtval[i+2] = j & 0xff; + } else { + j = v + (rtval[i] & 0xff) + + ((rtval[i+1] & 0xff) << 8) + + ((rtval[i+2] & 0xff) << 16); + rtval[i] = j & 0xff; + rtval[i+1] = (j >> 8) & 0xff; + rtval[i+2] = (j >> 16) & 0xff; + } + return(j); } -/*)Function Addr_T adw_lo(v, i) +/*)Function Addr_T adw_lo(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adw_lo() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB rtval[] is zeroed. + * The function adw_lo() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB rtval[] is zeroed. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The MSB of the word value is cleared to reflect - * the fact that the LSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The MSB of the word value is cleared to reflect + * the fact that the LSB is the selected byte. * */ -Addr_T -adw_lo(v, i) -Addr_T v; -int i; +Addr_T adw_lo(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * Clear Hi byte - */ - if (hilo) { - rtval[i] = 0; - } else { - rtval[i+1] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * Clear Hi byte + */ + if (hilo) { + rtval[i] = 0; + } else { + rtval[i+1] = 0; + } + return (j); } -/*)Function Addr_T adw_hi(v, i) +/*)Function Addr_T adw_hi(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adw_hi() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB and LSB values are interchanged. - * The MSB rtval[] is zeroed. + * The function adw_hi() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB and LSB values are interchanged. + * The MSB rtval[] is zeroed. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The MSB and LSB values are interchanged and - * then the MSB cleared. + * side effects: + * The value of rtval[] is changed. + * The MSB and LSB values are interchanged and + * then the MSB cleared. * */ -Addr_T -adw_hi(v, i) -Addr_T v; -int i; +Addr_T adw_hi(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * LSB = MSB, Clear MSB - */ - if (hilo) { - rtval[i+1] = rtval[i]; - rtval[i] = 0; - } else { - rtval[i] = rtval[i+1]; - rtval[i+1] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * LSB = MSB, Clear MSB + */ + if (hilo) { + rtval[i+1] = rtval[i]; + rtval[i] = 0; + } else { + rtval[i] = rtval[i+1]; + rtval[i+1] = 0; + } + return (j); } -/*)Function VOID relerr(str) +/*)Function VOID relerr(str) * - * char *str error string + * char *str error string * - * The function relerr() outputs the error string to - * stderr and to the map file (if it is open). + * The function relerr() outputs the error string to + * stderr and to the map file (if it is open). * - * local variable: - * none + * local variable: + * none * - * global variables: - * FILE *mfp handle for the map file + * global variables: + * FILE *mfp handle for the map file * - * called functions: - * VOID errdmp() lkrloc.c + * called functions: + * VOID errdmp() lkrloc.c * - * side effects: - * Error message inserted into map file. + * side effects: + * Error message inserted into map file. * */ -VOID -relerr(str) -char *str; +VOID relerr(char *str) { - errdmp(stderr, str); - if (mfp) - errdmp(mfp, str); + errdmp(stderr, str); + if (mfp) + errdmp(mfp, str); } -/*)Function VOID errdmp(fptr, str) +/*)Function VOID errdmp(fptr, str) * - * FILE *fptr output file handle - * char *str error string + * FILE *fptr output file handle + * char *str error string * - * The function errdmp() outputs the error string str - * to the device specified by fptr. Additional information - * is output about the definition and referencing of - * the symbol / area error. + * The function errdmp() outputs the error string str + * to the device specified by fptr. Additional information + * is output about the definition and referencing of + * the symbol / area error. * - * local variable: - * int mode error mode - * int aindex area index - * int lkerr error flag - * int rindex error index - * sym **s pointer to array of symbol pointers - * areax **a pointer to array of area pointers - * areax *raxp error area extension pointer + * local variable: + * int mode error mode + * int aindex area index + * int lkerr error flag + * int rindex error index + * sym **s pointer to array of symbol pointers + * areax **a pointer to array of area pointers + * areax *raxp error area extension pointer * - * global variables: - * sdp sdp base page structure + * global variables: + * sdp sdp base page structure * - * called functions: - * int fprintf() c_library - * VOID prntval() lkrloc.c + * called functions: + * int fprintf() c_library + * VOID prntval() lkrloc.c * - * side effects: - * Error reported. + * side effects: + * Error reported. * */ -VOID -errdmp(fptr, str) -FILE *fptr; -char *str; +VOID errdmp(FILE *fptr, char *str) { - int mode, aindex, rindex; - struct sym **s; - struct areax **a; - struct areax *raxp; - - a = hp->a_list; - s = hp->s_list; - - mode = rerr.mode; - aindex = rerr.aindex; - rindex = rerr.rindex; - - /* - * Print Error - */ - fprintf(fptr, "\n?ASlink-Warning-%s", str); - lkerr++; - - /* - * Print symbol if symbol based - */ - if (mode & R_SYM) { - fprintf(fptr, " for symbol %s\n", - &s[rindex]->s_id[0]); - } else { - fprintf(fptr, "\n"); - } - - /* - * Print Ref Info - */ - fprintf(fptr, - " file module area offset\n"); - fprintf(fptr, - " Refby %-8.8s %-8.8s %-8.8s ", - hp->h_lfile->f_idp, - &hp->m_id[0], - &a[aindex]->a_bap->a_id[0]); - prntval(fptr, rerr.rtbase); - - /* - * Print Def Info - */ - if (mode & R_SYM) { - raxp = s[rindex]->s_axp; - } else { - raxp = a[rindex]; - } - fprintf(fptr, - " Defin %-8.8s %-8.8s %-8.8s ", - raxp->a_bhp->h_lfile->f_idp, - &raxp->a_bhp->m_id[0], - &raxp->a_bap->a_id[0]); - if (mode & R_SYM) { - prntval(fptr, s[rindex]->s_addr); - } else { - prntval(fptr, rerr.rval); - } + int mode, aindex, rindex; + struct sym **s; + struct areax **a; + struct areax *raxp; + + a = hp->a_list; + s = hp->s_list; + + mode = rerr.mode; + aindex = rerr.aindex; + rindex = rerr.rindex; + + /* + * Print Error + */ + fprintf(fptr, "\n?ASlink-Warning-%s", str); + lkerr++; + + /* + * Print symbol if symbol based + */ + if (mode & R_SYM) { + fprintf(fptr, " for symbol %s\n", + &s[rindex]->s_id[0]); + } else { + fprintf(fptr, "\n"); + } + + /* + * Print Ref Info + */ + fprintf(fptr, + " file module area offset\n"); + fprintf(fptr, + " Refby %-8.8s %-8.8s %-8.8s ", + hp->h_lfile->f_idp, + &hp->m_id[0], + &a[aindex]->a_bap->a_id[0]); + prntval(fptr, rerr.rtbase); + + /* + * Print Def Info + */ + if (mode & R_SYM) { + raxp = s[rindex]->s_axp; + } else { + raxp = a[rindex]; + } + fprintf(fptr, + " Defin %-8.8s %-8.8s %-8.8s ", + raxp->a_bhp->h_lfile->f_idp, + &raxp->a_bhp->m_id[0], + &raxp->a_bap->a_id[0]); + if (mode & R_SYM) { + prntval(fptr, s[rindex]->s_addr); + } else { + prntval(fptr, rerr.rval); + } } -/*)Function VOID prntval(fptr, v) +/*)Function VOID prntval(fptr, v) * - * FILE *fptr output file handle - * Addr_T v value to output + * FILE *fptr output file handle + * Addr_T v value to output * - * The function prntval() outputs the value v, in the - * currently selected radix, to the device specified - * by fptr. + * The function prntval() outputs the value v, in the + * currently selected radix, to the device specified + * by fptr. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int xflag current radix + * global variables: + * int xflag current radix * - * called functions: - * int fprintf() c_library + * called functions: + * int fprintf() c_library * - * side effects: - * none + * side effects: + * none * */ -VOID -prntval(fptr, v) -FILE *fptr; -Addr_T v; +VOID prntval(FILE *fptr, Addr_T v) { - if (xflag == 0) { - fprintf(fptr, "%04X\n", v); - } else - if (xflag == 1) { - fprintf(fptr, "%06o\n", v); - } else - if (xflag == 2) { - fprintf(fptr, "%05u\n", v); - } + if (xflag == 0) { + fprintf(fptr, "%04X\n", v); + } else + if (xflag == 1) { + fprintf(fptr, "%06o\n", v); + } else + if (xflag == 2) { + fprintf(fptr, "%05u\n", v); + } } -/*)Function VOID relerp(str) +/*)Function VOID relerp(str) * - * char *str error string + * char *str error string * - * The function relerp() outputs the paging error string to - * stderr and to the map file (if it is open). + * The function relerp() outputs the paging error string to + * stderr and to the map file (if it is open). * - * local variable: - * none + * local variable: + * none * - * global variables: - * FILE *mfp handle for the map file + * global variables: + * FILE *mfp handle for the map file * - * called functions: - * VOID erpdmp() lkrloc.c + * called functions: + * VOID erpdmp() lkrloc.c * - * side effects: - * Error message inserted into map file. + * side effects: + * Error message inserted into map file. * */ -VOID -relerp(str) -char *str; +VOID relerp(char *str) { - erpdmp(stderr, str); - if (mfp) - erpdmp(mfp, str); + erpdmp(stderr, str); + if (mfp) + erpdmp(mfp, str); } -/*)Function VOID erpdmp(fptr, str) +/*)Function VOID erpdmp(fptr, str) * - * FILE *fptr output file handle - * char *str error string + * FILE *fptr output file handle + * char *str error string * - * The function erpdmp() outputs the error string str - * to the device specified by fptr. + * The function erpdmp() outputs the error string str + * to the device specified by fptr. * - * local variable: - * head *thp pointer to head structure + * local variable: + * head *thp pointer to head structure * - * global variables: - * int lkerr error flag - * sdp sdp base page structure + * global variables: + * int lkerr error flag + * sdp sdp base page structure * - * called functions: - * int fprintf() c_library - * VOID prntval() lkrloc.c + * called functions: + * int fprintf() c_library + * VOID prntval() lkrloc.c * - * side effects: - * Error reported. + * side effects: + * Error reported. * */ -VOID -erpdmp(fptr, str) -FILE *fptr; -char *str; +VOID erpdmp(FILE *fptr, char *str) { - register struct head *thp; - - thp = sdp.s_areax->a_bhp; - - /* - * Print Error - */ - fprintf(fptr, "\n?ASlink-Warning-%s\n", str); - lkerr++; - - /* - * Print PgDef Info - */ - fprintf(fptr, - " file module pgarea pgoffset\n"); - fprintf(fptr, - " PgDef %-8.8s %-8.8s %-8.8s ", - thp->h_lfile->f_idp, - &thp->m_id[0], - &sdp.s_area->a_id[0]); - prntval(fptr, sdp.s_area->a_addr + sdp.s_addr); + register struct head *thp; + + thp = sdp.s_areax->a_bhp; + + /* + * Print Error + */ + fprintf(fptr, "\n?ASlink-Warning-%s\n", str); + lkerr++; + + /* + * Print PgDef Info + */ + fprintf(fptr, + " file module pgarea pgoffset\n"); + fprintf(fptr, + " PgDef %-8.8s %-8.8s %-8.8s ", + thp->h_lfile->f_idp, + &thp->m_id[0], + &sdp.s_area->a_id[0]); + prntval(fptr, sdp.s_area->a_addr + sdp.s_addr); } diff --git a/device/include/stdbool.h b/device/include/stdbool.h index 8d7d01b2..2bf0be28 100644 --- a/device/include/stdbool.h +++ b/device/include/stdbool.h @@ -28,8 +28,7 @@ #define false 0 #define __bool_true_false_are_defined 1 -#if defined (SDCC_STACK_AUTO) || defined (SDCC_hc08) || defined (SDCC_z80) - //as long as bit/bool cannot be used reentrant +#if defined (SDCC_hc08) || defined (SDCC_z80) || defined (SDCC_gbz80) #define BOOL char #else #define BOOL __bit diff --git a/device/lib/_gptrput.c b/device/lib/_gptrput.c index fe30a845..cc374ce0 100644 --- a/device/lib/_gptrput.c +++ b/device/lib/_gptrput.c @@ -70,9 +70,6 @@ _gptrput (char *gptr, char c) _naked pdataptr$: movx @r0,a ; 1 sjmp dataptrrestore$ ; 2 - mov r0,dph ; restore r0 ; 2 - mov dph,#0 ; restore dph ; 2 - ret ; 1 ; ; store into far space ; diff --git a/src/SDCCast.c b/src/SDCCast.c index 990f43fe..1d65bc7d 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -2148,6 +2148,9 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType) { switch (tree->opval.op) { + case AND_OP: + case OR_OP: + return resultType; case '=': case '?': case ':': @@ -3402,7 +3405,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) return tree; } LRVAL (tree) = 1; - TTYPE (tree) = TETYPE (tree) = newCharLink (); + TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); return tree; /*------------------------------------------------------------------*/ @@ -3417,7 +3420,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) return tree; case GETHBIT: - TTYPE (tree) = TETYPE (tree) = newCharLink (); + TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); return tree; case LEFT_OP: @@ -3735,7 +3738,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) return tree; } LRVAL (tree) = RRVAL (tree) = 1; - TTYPE (tree) = TETYPE (tree) = newCharLink (); + TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink(); return tree; /*------------------------------------------------------------------*/ diff --git a/src/SDCCglobl.h b/src/SDCCglobl.h index 51174ae3..1b34d11a 100644 --- a/src/SDCCglobl.h +++ b/src/SDCCglobl.h @@ -288,6 +288,7 @@ extern int reentrant; /* /X flag has been sent SDCC.y */ extern char buffer[PATH_MAX * 2];/* general buffer SDCCmain.c */ extern int currRegBank; /* register bank being used SDCCgens.c */ extern int RegBankUsed[4]; /* JCF: register banks used SDCCmain.c */ +extern int BitBankUsed; /* MB: overlayable bit bank SDCCmain.c */ extern struct symbol *currFunc; /* current function SDCCgens.c */ extern int cNestLevel; /* block nest level SDCCval.c */ extern int currBlockno; /* sequentail block number */ diff --git a/src/SDCCglue.c b/src/SDCCglue.c index dd1f99a4..7ec4ad69 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -1713,6 +1713,22 @@ glue (void) if(RegBankUsed[3]) fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n"); } + if(BitBankUsed) + { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; overlayable bit register bank\n"); + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n"); + fprintf (asmFile, "bits:\n\t.ds 1\n"); + fprintf (asmFile, "\tb0 = bits[0]\n"); + fprintf (asmFile, "\tb1 = bits[1]\n"); + fprintf (asmFile, "\tb2 = bits[2]\n"); + fprintf (asmFile, "\tb3 = bits[3]\n"); + fprintf (asmFile, "\tb4 = bits[4]\n"); + fprintf (asmFile, "\tb5 = bits[5]\n"); + fprintf (asmFile, "\tb6 = bits[6]\n"); + fprintf (asmFile, "\tb7 = bits[7]\n"); + } } /* copy the data segment */ diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 1989aceb..26dbaab3 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -40,8 +40,8 @@ int block; int scopeLevel; int seqPoint; -symbol *returnLabel; /* function return label */ -symbol *entryLabel; /* function entry label */ +symbol *returnLabel; /* function return label */ +symbol *entryLabel; /* function entry label */ /*-----------------------------------------------------------------*/ /* forward definition of some functions */ @@ -137,7 +137,7 @@ iCodeTable codeTable[] = */ void checkConstantRange(sym_link *ltype, value *val, char *msg, - int pedantic) { + int pedantic) { double max; int warnings=0; int negative=0; @@ -196,8 +196,8 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, #if 0 // temporary disabled, leaving the warning as a reminder if (warnings) { SNPRINTF (message, sizeof(message), "for %s %s in %s", - IS_UNSIGNED(ltype) ? "unsigned" : "signed", - nounName(ltype), msg); + IS_UNSIGNED(ltype) ? "unsigned" : "signed", + nounName(ltype), msg); werror (W_CONST_RANGE, message); if (pedantic>1) @@ -229,62 +229,62 @@ printOperand (operand * op, FILE * file) case VALUE: opetype = getSpec (operandType (op)); if (IS_FLOAT (opetype)) - fprintf (file, "%g {", SPEC_CVAL (opetype).v_float); + fprintf (file, "%g {", SPEC_CVAL (opetype).v_float); if (IS_FIXED16X16 (opetype)) fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16)); else - fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand)); + fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand)); printTypeChain (operandType (op), file); fprintf (file, "}"); break; case SYMBOL: #define REGA 1 -//#if REGA /* { */ +//#if REGA /* { */ if(REGA && !getenv("PRINT_SHORT_OPERANDS")) { - fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ - (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name), - op->key, - OP_LIVEFROM (op), OP_LIVETO (op), - OP_SYMBOL (op)->stack, - op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv, - OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc, - OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr - ); + fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ + (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name), + op->key, + OP_LIVEFROM (op), OP_LIVETO (op), + OP_SYMBOL (op)->stack, + op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv, + OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc, + OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr + ); { - fprintf (file, "{"); - printTypeChain (operandType (op), file); - if (SPIL_LOC (op) && IS_ITEMP (op)) - fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname); - fprintf (file, "}"); + fprintf (file, "{"); + printTypeChain (operandType (op), file); + if (SPIL_LOC (op) && IS_ITEMP (op)) + fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname); + fprintf (file, "}"); } /* if assigned to registers */ if (OP_SYMBOL (op)->nRegs) - { - if (OP_SYMBOL (op)->isspilt) - { - if (!OP_SYMBOL (op)->remat) - if (OP_SYMBOL (op)->usl.spillLoc) - fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? - OP_SYMBOL (op)->usl.spillLoc->rname : - OP_SYMBOL (op)->usl.spillLoc->name)); - else - fprintf (file, "[err]"); - else - fprintf (file, "[remat]"); - } - else - { - int i; - fprintf (file, "["); - for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) - fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); - fprintf (file, "]"); - } - } -//#else /* } else { */ + { + if (OP_SYMBOL (op)->isspilt) + { + if (!OP_SYMBOL (op)->remat) + if (OP_SYMBOL (op)->usl.spillLoc) + fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? + OP_SYMBOL (op)->usl.spillLoc->rname : + OP_SYMBOL (op)->usl.spillLoc->name)); + else + fprintf (file, "[err]"); + else + fprintf (file, "[remat]"); + } + else + { + int i; + fprintf (file, "["); + for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) + fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); + fprintf (file, "]"); + } + } +//#else /* } else { */ } else { /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */ fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name)); @@ -292,8 +292,8 @@ printOperand (operand * op, FILE * file) if(getenv("PRINT_SHORT_OPERANDS")[0] < '1') { fprintf (file, "[lr%d:%d so:%d]", - OP_LIVEFROM (op), OP_LIVETO (op), - OP_SYMBOL (op)->stack); + OP_LIVEFROM (op), OP_LIVETO (op), + OP_SYMBOL (op)->stack); } if(getenv("PRINT_SHORT_OPERANDS")[0] < '2') @@ -307,29 +307,29 @@ printOperand (operand * op, FILE * file) /* if assigned to registers */ if (OP_SYMBOL (op)->nRegs) - { - if (OP_SYMBOL (op)->isspilt) - { - if (!OP_SYMBOL (op)->remat) - if (OP_SYMBOL (op)->usl.spillLoc) - fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? - OP_SYMBOL (op)->usl.spillLoc->rname : - OP_SYMBOL (op)->usl.spillLoc->name)); - else - fprintf (file, "[err]"); - else - fprintf (file, "[remat]"); - } - else - { - int i; - fprintf (file, "["); - for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) - fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); - fprintf (file, "]"); - } - } -//#endif /* } */ + { + if (OP_SYMBOL (op)->isspilt) + { + if (!OP_SYMBOL (op)->remat) + if (OP_SYMBOL (op)->usl.spillLoc) + fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? + OP_SYMBOL (op)->usl.spillLoc->rname : + OP_SYMBOL (op)->usl.spillLoc->name)); + else + fprintf (file, "[err]"); + else + fprintf (file, "[remat]"); + } + else + { + int i; + fprintf (file, "["); + for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) + fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); + fprintf (file, "]"); + } + } +//#endif /* } */ } break; @@ -383,9 +383,9 @@ PRINTFUNC (picAddrOf) if (IC_RIGHT (ic)) { if (IS_ITEMP (IC_LEFT (ic))) - fprintf (of, " offsetAdd "); + fprintf (of, " offsetAdd "); else - fprintf (of, " , "); + fprintf (of, " , "); printOperand (IC_RIGHT (ic), of); } if (IS_ITEMP (IC_LEFT (ic))) @@ -497,7 +497,7 @@ PRINTFUNC (picIfx) { fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key); if (IC_FALSE (ic)) - fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name); + fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name); } } @@ -558,15 +558,15 @@ piCode (void *item, FILE * of) icTab = getTableEntry (ic->op); fprintf (of, "%s(%d:%d:%d:%d:%d)\t", - ic->filename, ic->lineno, - ic->seq, ic->key, ic->depth, ic->supportRtn); + ic->filename, ic->lineno, + ic->seq, ic->key, ic->depth, ic->supportRtn); icTab->iCodePrint (of, ic, icTab->printName); return 1; } void PICC(iCode *ic) { - printiCChain(ic,stdout); + printiCChain(ic,stdout); } /*-----------------------------------------------------------------*/ /* printiCChain - prints intermediate code for humans */ @@ -582,13 +582,13 @@ printiCChain (iCode * icChain, FILE * of) for (loop = icChain; loop; loop = loop->next) { if ((icTab = getTableEntry (loop->op))) - { - fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t", - loop->filename, loop->lineno, - loop->seq, loop->key, loop->depth, loop->supportRtn); + { + fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t", + loop->filename, loop->lineno, + loop->seq, loop->key, loop->depth, loop->supportRtn); - icTab->iCodePrint (of, loop, icTab->printName); - } + icTab->iCodePrint (of, loop, icTab->printName); + } } } @@ -635,8 +635,8 @@ newiCode (int op, operand * left, operand * right) /*-----------------------------------------------------------------*/ iCode * newiCodeCondition (operand * condition, - symbol * trueLabel, - symbol * falseLabel) + symbol * trueLabel, + symbol * falseLabel) { iCode *ic; @@ -836,7 +836,7 @@ newiTempOperand (sym_link * type, char throwType) /* copy the type information */ if (type) itmp->etype = getSpec (itmp->type = (throwType ? type : - copyLinkChain (type))); + copyLinkChain (type))); if (IS_LITERAL (itmp->etype)) { SPEC_SCLS (itmp->etype) = S_REGISTER; @@ -868,8 +868,8 @@ operandType (operand * op) return op->operand.typeOperand; default: werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - " operand type not known "); - assert (0); /* should never come here */ + " operand type not known "); + assert (0); /* should never come here */ /* Just to keep the compiler happy */ return (sym_link *) 0; } @@ -888,8 +888,8 @@ isParameterToCall (value * args, operand * op) while (tval) { if (tval->sym && - isSymbolEqual (op->operand.symOperand, tval->sym)) - return 1; + isSymbolEqual (op->operand.symOperand, tval->sym)) + return 1; tval = tval->next; } return 0; @@ -975,9 +975,9 @@ isOperandInFarSpace (operand * op) if (!IS_TRUE_SYMOP (op)) { if (SPIL_LOC (op)) - etype = SPIL_LOC (op)->etype; + etype = SPIL_LOC (op)->etype; else - return FALSE; + return FALSE; } else { @@ -1003,9 +1003,9 @@ isOperandInDirSpace (operand * op) if (!IS_TRUE_SYMOP (op)) { if (SPIL_LOC (op)) - etype = SPIL_LOC (op)->etype; + etype = SPIL_LOC (op)->etype; else - return FALSE; + return FALSE; } else { @@ -1033,9 +1033,9 @@ isOperandInCodeSpace (operand * op) if (!IS_TRUE_SYMOP (op)) { if (SPIL_LOC (op)) - etype = SPIL_LOC (op)->etype; + etype = SPIL_LOC (op)->etype; else - return FALSE; + return FALSE; } else { @@ -1137,11 +1137,11 @@ iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms) *pcount = 0; /* builtin functions uses only SEND for parameters */ while (ic->op != CALL) { - assert(ic->op == SEND && ic->builtinSEND); - ic->generated = 1; /* mark the icode as generated */ - parms[*pcount] = IC_LEFT(ic); - ic = ic->next; - (*pcount)++; + assert(ic->op == SEND && ic->builtinSEND); + ic->generated = 1; /* mark the icode as generated */ + parms[*pcount] = IC_LEFT(ic); + ic = ic->next; + (*pcount)++; } ic->generated = 1; @@ -1157,7 +1157,7 @@ iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms) /*-----------------------------------------------------------------*/ operand * operandOperation (operand * left, operand * right, - int op, sym_link * type) + int op, sym_link * type) { sym_link *let , *ret=NULL; operand *retval = (operand *) 0; @@ -1173,19 +1173,19 @@ operandOperation (operand * left, operand * right, { case '+': retval = operandFromValue (valCastLiteral (type, - operandLitValue (left) + - operandLitValue (right))); + operandLitValue (left) + + operandLitValue (right))); break; case '-': retval = operandFromValue (valCastLiteral (type, - operandLitValue (left) - - operandLitValue (right))); + operandLitValue (left) - + operandLitValue (right))); break; case '*': /* retval = operandFromValue (valCastLiteral (type, - operandLitValue (left) * - operandLitValue (right))); + operandLitValue (left) * + operandLitValue (right))); This could be all we've to do, but with gcc we've to take care about overflows. Two examples: ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least @@ -1200,193 +1200,193 @@ operandOperation (operand * left, operand * right, if (IS_INT (type) || !IS_SPEC (type)) { - /* long is handled here, because it can overflow with double */ - if (IS_LONG (type) || - !IS_SPEC (type)) - /* signed and unsigned mul are the same, as long as the precision - of the result isn't bigger than the precision of the operands. */ - retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD) operandLitValue (left) * - (TYPE_UDWORD) operandLitValue (right))); - else if (IS_UNSIGNED (type)) /* unsigned int */ - { - /* unsigned int is handled here in order to detect overflow */ - TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) * - (TYPE_UWORD) operandLitValue (right); - - retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul)); - if (ul != (TYPE_UWORD) ul) - werror (W_INT_OVL); - } - else /* signed int */ - { - /* signed int is handled here in order to detect overflow */ - TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) * - (TYPE_WORD) operandLitValue (right); - - retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l)); - if (l != (TYPE_WORD) l) - werror (W_INT_OVL); - } - } + /* long is handled here, because it can overflow with double */ + if (IS_LONG (type) || + !IS_SPEC (type)) + /* signed and unsigned mul are the same, as long as the precision + of the result isn't bigger than the precision of the operands. */ + retval = operandFromValue (valCastLiteral (type, + (TYPE_UDWORD) operandLitValue (left) * + (TYPE_UDWORD) operandLitValue (right))); + else if (IS_UNSIGNED (type)) /* unsigned int */ + { + /* unsigned int is handled here in order to detect overflow */ + TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) * + (TYPE_UWORD) operandLitValue (right); + + retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul)); + if (ul != (TYPE_UWORD) ul) + werror (W_INT_OVL); + } + else /* signed int */ + { + /* signed int is handled here in order to detect overflow */ + TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) * + (TYPE_WORD) operandLitValue (right); + + retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l)); + if (l != (TYPE_WORD) l) + werror (W_INT_OVL); + } + } else - /* all others go here: */ - retval = operandFromValue (valCastLiteral (type, - operandLitValue (left) * - operandLitValue (right))); + /* all others go here: */ + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) * + operandLitValue (right))); break; case '/': if ((TYPE_UDWORD) operandLitValue (right) == 0) - { - werror (E_DIVIDE_BY_ZERO); - retval = right; + { + werror (E_DIVIDE_BY_ZERO); + retval = right; - } + } else { - if (IS_UNSIGNED (type)) - { - SPEC_USIGN (let) = 1; - SPEC_USIGN (ret) = 1; - retval = operandFromValue (valCastLiteral (type, - (TYPE_UDWORD) operandLitValue (left) / - (TYPE_UDWORD) operandLitValue (right))); - } - else - { + if (IS_UNSIGNED (type)) + { + SPEC_USIGN (let) = 1; + SPEC_USIGN (ret) = 1; retval = operandFromValue (valCastLiteral (type, - operandLitValue (left) / - operandLitValue (right))); - } - } + (TYPE_UDWORD) operandLitValue (left) / + (TYPE_UDWORD) operandLitValue (right))); + } + else + { + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) / + operandLitValue (right))); + } + } break; case '%': if ((TYPE_UDWORD) operandLitValue (right) == 0) { - werror (E_DIVIDE_BY_ZERO); - retval = right; + werror (E_DIVIDE_BY_ZERO); + retval = right; } else { if (IS_UNSIGNED (type)) - retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) % - (TYPE_UDWORD) operandLitValue (right)); - else - retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) % - (TYPE_DWORD) operandLitValue (right)); + retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) % + (TYPE_UDWORD) operandLitValue (right)); + else + retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) % + (TYPE_DWORD) operandLitValue (right)); } break; case LEFT_OP: /* The number of left shifts is always unsigned. Signed doesn't make - sense here. Shifting by a negative number is impossible. */ + sense here. Shifting by a negative number is impossible. */ retval = operandFromValue (valCastLiteral (type, - ((TYPE_UDWORD) operandLitValue (left) << - (TYPE_UDWORD) operandLitValue (right)))); + ((TYPE_UDWORD) operandLitValue (left) << + (TYPE_UDWORD) operandLitValue (right)))); break; case RIGHT_OP: /* The number of right shifts is always unsigned. Signed doesn't make - sense here. Shifting by a negative number is impossible. */ + sense here. Shifting by a negative number is impossible. */ if (IS_UNSIGNED(let)) /* unsigned: logic shift right */ retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >> - (TYPE_UDWORD) operandLitValue (right)); + (TYPE_UDWORD) operandLitValue (right)); else /* signed: arithmetic shift right */ retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >> - (TYPE_UDWORD) operandLitValue (right)); + (TYPE_UDWORD) operandLitValue (right)); break; case EQ_OP: if (IS_FLOAT (let) || IS_FLOAT (ret)) - { - retval = operandFromLit (operandLitValue (left) == - operandLitValue (right)); - } + { + retval = operandFromLit (operandLitValue (left) == + operandLitValue (right)); + } else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret)) - { - retval = operandFromLit (operandLitValue (left) == - operandLitValue (right)); - } + { + retval = operandFromLit (operandLitValue (left) == + operandLitValue (right)); + } else - { - /* this op doesn't care about signedness */ - TYPE_UDWORD l, r; - - l = (TYPE_UDWORD) operandLitValue (left); - r = (TYPE_UDWORD) operandLitValue (right); - /* In order to correctly compare 'signed int' and 'unsigned int' it's - neccessary to strip them to 16 bit. - Literals are reduced to their cheapest type, therefore left and - right might have different types. It's neccessary to find a - common type: int (used for char too) or long */ - if (!IS_LONG (let) && - !IS_LONG (ret)) - { - r = (TYPE_UWORD) r; - l = (TYPE_UWORD) l; - } - retval = operandFromLit (l == r); - } + { + /* this op doesn't care about signedness */ + TYPE_UDWORD l, r; + + l = (TYPE_UDWORD) operandLitValue (left); + r = (TYPE_UDWORD) operandLitValue (right); + /* In order to correctly compare 'signed int' and 'unsigned int' it's + neccessary to strip them to 16 bit. + Literals are reduced to their cheapest type, therefore left and + right might have different types. It's neccessary to find a + common type: int (used for char too) or long */ + if (!IS_LONG (let) && + !IS_LONG (ret)) + { + r = (TYPE_UWORD) r; + l = (TYPE_UWORD) l; + } + retval = operandFromLit (l == r); + } break; case '<': retval = operandFromLit (operandLitValue (left) < - operandLitValue (right)); + operandLitValue (right)); break; case LE_OP: retval = operandFromLit (operandLitValue (left) <= - operandLitValue (right)); + operandLitValue (right)); break; case NE_OP: retval = operandFromLit (operandLitValue (left) != - operandLitValue (right)); + operandLitValue (right)); break; case '>': retval = operandFromLit (operandLitValue (left) > - operandLitValue (right)); + operandLitValue (right)); break; case GE_OP: retval = operandFromLit (operandLitValue (left) >= - operandLitValue (right)); + operandLitValue (right)); break; case BITWISEAND: retval = operandFromValue (valCastLiteral (type, (TYPE_UDWORD)operandLitValue(left) & - (TYPE_UDWORD)operandLitValue(right))); + (TYPE_UDWORD)operandLitValue(right))); break; case '|': retval = operandFromValue (valCastLiteral (type, (TYPE_UDWORD)operandLitValue(left) | - (TYPE_UDWORD)operandLitValue(right))); + (TYPE_UDWORD)operandLitValue(right))); break; case '^': retval = operandFromValue (valCastLiteral (type, (TYPE_UDWORD)operandLitValue(left) ^ - (TYPE_UDWORD)operandLitValue(right))); + (TYPE_UDWORD)operandLitValue(right))); break; case AND_OP: retval = operandFromLit (operandLitValue (left) && - operandLitValue (right)); + operandLitValue (right)); break; case OR_OP: retval = operandFromLit (operandLitValue (left) || - operandLitValue (right)); + operandLitValue (right)); break; case RRC: { - TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left); + TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left); - retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) | - (i << 1)); + retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) | + (i << 1)); } break; case RLC: { - TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left); + TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left); - retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) | - (i >> 1)); + retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) | + (i >> 1)); } break; @@ -1407,7 +1407,7 @@ operandOperation (operand * left, operand * right, default: werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - " operandOperation invalid operator "); + " operandOperation invalid operator "); assert (0); } @@ -1440,7 +1440,7 @@ isOperandEqual (operand * left, operand * right) { case SYMBOL: return isSymbolEqual (left->operand.symOperand, - right->operand.symOperand); + right->operand.symOperand); case VALUE: return (compareType (left->operand.valOperand->type, right->operand.valOperand->type) && @@ -1448,8 +1448,8 @@ isOperandEqual (operand * left, operand * right) floatFromVal (right->operand.valOperand))); case TYPE: if (compareType (left->operand.typeOperand, - right->operand.typeOperand) == 1) - return 1; + right->operand.typeOperand) == 1) + return 1; } return 0; @@ -1475,22 +1475,22 @@ isiCodeEqual (iCode * left, iCode * right) /* compare all the elements depending on type */ if (left->op != IFX) - { - if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right))) - return 0; - if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right))) - return 0; + { + if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right))) + return 0; + if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right))) + return 0; - } + } else - { - if (!isOperandEqual (IC_COND (left), IC_COND (right))) - return 0; - if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right))) - return 0; - if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right))) - return 0; - } + { + if (!isOperandEqual (IC_COND (left), IC_COND (right))) + return 0; + if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right))) + return 0; + if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right))) + return 0; + } return 1; } @@ -1613,16 +1613,15 @@ operandFromSymbol (symbol * sym) options.stackAuto == 0) ok = 0; - if (!IS_AGGREGATE (sym->type) && /* not an aggregate */ - !IS_FUNC (sym->type) && /* not a function */ - !sym->_isparm && /* not a parameter */ - IS_AUTO (sym) && /* is a local auto variable */ - !sym->addrtaken && /* whose address has not been taken */ - !sym->reqv && /* does not already have a reg equivalence */ - !IS_VOLATILE (sym->etype) && /* not declared as volatile */ - !sym->islbl && /* not a label */ - ok && /* farspace check */ - !IS_BITVAR (sym->etype) /* not a bit variable */ + if (!IS_AGGREGATE (sym->type) && /* not an aggregate */ + !IS_FUNC (sym->type) && /* not a function */ + !sym->_isparm && /* not a parameter */ + IS_AUTO (sym) && /* is a local auto variable */ + !sym->addrtaken && /* whose address has not been taken */ + !sym->reqv && /* does not already have a reg equivalence */ + !IS_VOLATILE (sym->etype) && /* not declared as volatile */ + !sym->islbl && /* not a label */ + ok /* farspace check */ ) { @@ -1770,18 +1769,18 @@ setOperandType (operand * op, sym_link * type) case VALUE: op->operand.valOperand->etype = - getSpec (op->operand.valOperand->type = - copyLinkChain (type)); + getSpec (op->operand.valOperand->type = + copyLinkChain (type)); return; case SYMBOL: if (op->operand.symOperand->isitmp) - op->operand.symOperand->etype = - getSpec (op->operand.symOperand->type = - copyLinkChain (type)); + op->operand.symOperand->etype = + getSpec (op->operand.symOperand->type = + copyLinkChain (type)); else - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "attempt to modify type of source"); + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "attempt to modify type of source"); return; case TYPE: @@ -1809,25 +1808,25 @@ getArraySizePtr (operand * op) { sym_link *letype = getSpec(ltype); switch (PTR_TYPE (SPEC_OCLS (letype))) - { - case IPOINTER: - case PPOINTER: - case POINTER: - return (PTRSIZE); - case EEPPOINTER: - case FPOINTER: - case CPOINTER: - case FUNCTION: - return (FPTRSIZE); - case GPOINTER: + { + case IPOINTER: + case PPOINTER: + case POINTER: + return (PTRSIZE); + case EEPPOINTER: + case FPOINTER: + case CPOINTER: + case FUNCTION: + return (FPTRSIZE); + case GPOINTER: if (GPTRSIZE > FPTRSIZE) - return (GPTRSIZE-1); + return (GPTRSIZE-1); else - return (FPTRSIZE); + return (FPTRSIZE); - default: - return (FPTRSIZE); - } + default: + return (FPTRSIZE); + } } return (FPTRSIZE); } @@ -1842,10 +1841,10 @@ usualUnaryConversions (operand * op) if (IS_INTEGRAL (operandType (op))) { if (getSize (operandType (op)) < (unsigned int) INTSIZE) - { - /* Widen to int. */ - return geniCodeCast (INTTYPE, op, TRUE); - } + { + /* Widen to int. */ + return geniCodeCast (INTTYPE, op, TRUE); + } } return op; } @@ -1870,14 +1869,14 @@ usualBinaryConversions (operand ** op1, operand ** op2, case '*': case '/': case '%': - if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype))) - { - /* one byte operations: keep signedness for code generator */ - return ctype; - } - break; + if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype))) + { + /* one byte operations: keep signedness for code generator */ + return ctype; + } + break; default: - break; + break; } *op1 = geniCodeCast (ctype, *op1, TRUE); @@ -1977,71 +1976,71 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype)) { return operandFromValue (valCastLiteral (type, - operandLitValue (op))); + operandLitValue (op))); } /* if casting to/from pointers, do some checking */ if (IS_PTR(type)) { // to a pointer if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer if (IS_INTEGRAL(optype)) { - // maybe this is NULL, than it's ok. - if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) { - if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) { - // no way to set the storage - if (IS_LITERAL(optype)) { - werror(E_LITERAL_GENERIC); - errors++; - } else { - werror(E_NONPTR2_GENPTR); - errors++; - } - } else if (implicit) { - werror(W_INTEGRAL2PTR_NOCAST); - errors++; - } - } - } else { - // shouldn't do that with float, array or structure unless to void - if (!IS_VOID(getSpec(type)) && - !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { - werror(E_INCOMPAT_TYPES); - errors++; - } + // maybe this is NULL, than it's ok. + if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) { + if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) { + // no way to set the storage + if (IS_LITERAL(optype)) { + werror(E_LITERAL_GENERIC); + errors++; + } else { + werror(E_NONPTR2_GENPTR); + errors++; + } + } else if (implicit) { + werror(W_INTEGRAL2PTR_NOCAST); + errors++; + } + } + } else { + // shouldn't do that with float, array or structure unless to void + if (!IS_VOID(getSpec(type)) && + !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { + werror(E_INCOMPAT_TYPES); + errors++; + } } } else { // from a pointer to a pointer if (IS_GENPTR(type) && IS_VOID(type->next)) - { // cast to void* is always allowed - } + { // cast to void* is always allowed + } else if (IS_GENPTR(optype) && IS_VOID(optype->next)) - { // cast from void* is always allowed - } + { // cast from void* is always allowed + } else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) { - // if not a pointer to a function - if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { - if (implicit) { // if not to generic, they have to match - if (!IS_GENPTR(type) && + // if not a pointer to a function + if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { + if (implicit) { // if not to generic, they have to match + if (!IS_GENPTR(type) && !((DCL_TYPE(optype) == DCL_TYPE(type)) || ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER)) ) ) { - werror(E_INCOMPAT_PTYPES); - errors++; - } - } - } + werror(E_INCOMPAT_PTYPES); + errors++; + } + } + } } } } else { // to a non pointer if (IS_PTR(optype)) { // from a pointer if (implicit) { // sneaky - if (IS_INTEGRAL(type)) { - werror(W_PTR2INTEGRAL_NOCAST); - errors++; - } else { // shouldn't do that with float, array or structure - werror(E_INCOMPAT_TYPES); - errors++; - } + if (IS_INTEGRAL(type)) { + werror(W_PTR2INTEGRAL_NOCAST); + errors++; + } else { // shouldn't do that with float, array or structure + werror(E_INCOMPAT_TYPES); + errors++; + } } } } @@ -2069,14 +2068,14 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) { ic = newiCode ('=', NULL, op); IC_RESULT (ic) = newiTempOperand (type, 0); - SPIL_LOC (IC_RESULT (ic)) = - (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL); + if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype)) + SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op); IC_RESULT (ic)->isaddr = 0; } else { ic = newiCode (CAST, operandFromLink (type), - geniCodeRValue (op, FALSE)); + geniCodeRValue (op, FALSE)); IC_RESULT (ic) = newiTempOperand (type, 0); } @@ -2132,7 +2131,7 @@ geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType) /* if they are both literal then we know the result */ if (IS_LITERAL (letype) && IS_LITERAL (retype)) return operandFromValue (valMult (left->operand.valOperand, - right->operand.valOperand)); + right->operand.valOperand)); if (IS_LITERAL(retype)) { p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand)); @@ -2158,19 +2157,19 @@ geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType) && strcmp (port->target, "pic14") != 0) { if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))) - { - /* LEFT_OP need same size for left and result, */ - left = geniCodeCast (resType, left, TRUE); - ltype = operandType (left); - } + { + /* LEFT_OP need same size for left and result, */ + left = geniCodeCast (resType, left, TRUE); + ltype = operandType (left); + } ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */ } else { - ic = newiCode ('*', left, right); /* normal multiplication */ + ic = newiCode ('*', left, right); /* normal multiplication */ /* if the size left or right > 1 then support routine */ if (getSize (ltype) > 1 || getSize (rtype) > 1) - ic->supportRtn = 1; + ic->supportRtn = 1; } IC_RESULT (ic) = newiTempOperand (resType, 1); @@ -2203,15 +2202,15 @@ geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType) !IS_FIXED (letype) && IS_UNSIGNED(letype) && (p2 = powof2 ((TYPE_UDWORD) - floatFromVal (right->operand.valOperand)))) { + floatFromVal (right->operand.valOperand)))) { ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */ } else { - ic = newiCode ('/', left, right); /* normal division */ + ic = newiCode ('/', left, right); /* normal division */ /* if the size left or right > 1 then support routine */ if (getSize (ltype) > 1 || getSize (rtype) > 1) - ic->supportRtn = 1; + ic->supportRtn = 1; } IC_RESULT (ic) = newiTempOperand (resType, 0); @@ -2231,7 +2230,7 @@ geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType) /* if they are both literal then we know the result */ if (IS_LITERAL (letype) && IS_LITERAL (retype)) return operandFromValue (valMod (left->operand.valOperand, - right->operand.valOperand)); + right->operand.valOperand)); resType = usualBinaryConversions (&left, &right, resultType, '%'); @@ -2261,7 +2260,7 @@ geniCodePtrPtrSubtract (operand * left, operand * right) if (IS_LITERAL (letype) && IS_LITERAL (retype)) { result = operandFromValue (valMinus (left->operand.valOperand, - right->operand.valOperand)); + right->operand.valOperand)); goto subtractExit; } @@ -2277,8 +2276,8 @@ subtractExit: // should we really do this? is this ANSI? return geniCodeDivision (result, - operandFromLit (getSize (ltype->next)), - FALSE); + operandFromLit (getSize (ltype->next)), + FALSE); } /*-----------------------------------------------------------------*/ @@ -2301,21 +2300,21 @@ geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType) if (IS_LITERAL (letype) && IS_LITERAL (retype) && left->isLiteral && right->isLiteral) return operandFromValue (valMinus (left->operand.valOperand, - right->operand.valOperand)); + right->operand.valOperand)); /* if left is an array or pointer */ if (IS_PTR (ltype) || IS_ARRAY (ltype)) { isarray = left->isaddr; right = geniCodeMultiply (right, - operandFromLit (getSize (ltype->next)), - (getArraySizePtr(left) >= INTSIZE) ? - RESULT_TYPE_INT : - RESULT_TYPE_CHAR); + operandFromLit (getSize (ltype->next)), + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR); resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype); } else - { /* make them the same size */ + { /* make them the same size */ resType = usualBinaryConversions (&left, &right, resultType, '-'); } @@ -2362,20 +2361,20 @@ geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl) // there is no need to multiply with 1 if (getSize (ltype->next) != 1) { - size = operandFromLit (getSize (ltype->next)); - SPEC_USIGN (getSpec (operandType (size))) = 1; - indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); - right = geniCodeMultiply (right, - size, - (getArraySizePtr(left) >= INTSIZE) ? - RESULT_TYPE_INT : - RESULT_TYPE_CHAR); - /* Even if right is a 'unsigned char', - the result will be a 'signed int' due to the promotion rules. - It doesn't make sense when accessing arrays, so let's fix it here: */ - if (indexUnsigned) - SPEC_USIGN (getSpec (operandType (right))) = 1; - } + size = operandFromLit (getSize (ltype->next)); + SPEC_USIGN (getSpec (operandType (size))) = 1; + indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); + right = geniCodeMultiply (right, + size, + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR); + /* Even if right is a 'unsigned char', + the result will be a 'signed int' due to the promotion rules. + It doesn't make sense when accessing arrays, so let's fix it here: */ + if (indexUnsigned) + SPEC_USIGN (getSpec (operandType (right))) = 1; + } resType = copyLinkChain (ltype); } else @@ -2387,7 +2386,7 @@ geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl) if (IS_LITERAL (letype) && IS_LITERAL (retype) && left->isLiteral && right->isLiteral) return operandFromValue (valPlus (valFromType (ltype), - valFromType (rtype))); + valFromType (rtype))); ic = newiCode ('+', left, right); @@ -2472,26 +2471,26 @@ geniCodeArray (operand * left, operand * right, int lvl) if (IS_PTR (ltype)) { if (IS_PTR (ltype->next) && left->isaddr) - { - left = geniCodeRValue (left, FALSE); - } + { + left = geniCodeRValue (left, FALSE); + } return geniCodeDerefPtr (geniCodeAdd (left, - right, - (getArraySizePtr(left) >= INTSIZE) ? - RESULT_TYPE_INT : - RESULT_TYPE_CHAR, - lvl), - lvl); + right, + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR, + lvl), + lvl); } size = operandFromLit (getSize (ltype->next)); SPEC_USIGN (getSpec (operandType (size))) = 1; indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); right = geniCodeMultiply (right, - size, - (getArraySizePtr(left) >= INTSIZE) ? - RESULT_TYPE_INT : - RESULT_TYPE_CHAR); + size, + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR); /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules. It doesn't make sense when accessing arrays, so let's fix it here: */ if (indexUnsigned) @@ -2504,17 +2503,17 @@ geniCodeArray (operand * left, operand * right, int lvl) (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype)) { werror (W_IDX_OUT_OF_BOUNDS, - (int) operandLitValue (right) / getSize (ltype->next), - DCL_ELEM (ltype)); + (int) operandLitValue (right) / getSize (ltype->next), + DCL_ELEM (ltype)); } */ ic = newiCode ('+', left, right); IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) && - !IS_AGGREGATE (ltype->next) && - !IS_PTR (ltype->next)) - ? ltype : ltype->next), 0); + !IS_AGGREGATE (ltype->next) && + !IS_PTR (ltype->next)) + ? ltype : ltype->next), 0); if (!IS_AGGREGATE (ltype->next)) { @@ -2537,7 +2536,7 @@ geniCodeStruct (operand * left, operand * right, bool islval) sym_link *etype = getSpec (type); sym_link *retype; symbol *element = getStructElement (SPEC_STRUCT (etype), - right->operand.symOperand); + right->operand.symOperand); wassert(IS_SYMOP(right)); @@ -2574,8 +2573,8 @@ geniCodePostInc (operand * op) sym_link *optype = operandType (op); operand *result; operand *rv = (IS_ITEMP (op) ? - geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : - op); + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); sym_link *rvtype = operandType (rv); int size = 0; @@ -2623,8 +2622,8 @@ geniCodePreInc (operand * op, bool lvalue) iCode *ic; sym_link *optype = operandType (op); operand *rop = (IS_ITEMP (op) ? - geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : - op); + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); sym_link *roptype = operandType (rop); operand *result; int size = 0; @@ -2666,8 +2665,8 @@ geniCodePostDec (operand * op) sym_link *optype = operandType (op); operand *result; operand *rv = (IS_ITEMP (op) ? - geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : - op); + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); sym_link *rvtype = operandType (rv); int size = 0; @@ -2715,8 +2714,8 @@ geniCodePreDec (operand * op, bool lvalue) iCode *ic; sym_link *optype = operandType (op); operand *rop = (IS_ITEMP (op) ? - geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : - op); + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); sym_link *roptype = operandType (rop); operand *result; int size = 0; @@ -2753,7 +2752,7 @@ geniCodePreDec (operand * op, bool lvalue) /*-----------------------------------------------------------------*/ operand * geniCodeBitwise (operand * left, operand * right, - int oper, sym_link * resType) + int oper, sym_link * resType) { iCode *ic; @@ -2895,11 +2894,11 @@ geniCodeDerefPtr (operand * op,int lvl) op->isGptr = IS_GENPTR (optype); op->isaddr = (IS_PTR (rtype) || - IS_STRUCT (rtype) || - IS_INT (rtype) || - IS_CHAR (rtype) || - IS_FLOAT (rtype) || - IS_FIXED (rtype)); + IS_STRUCT (rtype) || + IS_INT (rtype) || + IS_CHAR (rtype) || + IS_FLOAT (rtype) || + IS_FIXED (rtype)); if (!isLvaluereq(lvl)) op = geniCodeRValue (op, TRUE); @@ -2974,7 +2973,7 @@ geniCodeLogic (operand * left, operand * right, int op) if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype)) { checkConstantRange(ltype, - OP_VALUE(right), "compare operation", 1); + OP_VALUE(right), "compare operation", 1); } /* if one operand is a pointer and the other is a literal generic void pointer, @@ -3050,6 +3049,7 @@ static operand * geniCodeLogicAndOr (ast *tree, int lvl) { iCode *ic; + sym_link *type; symbol *falseLabel = newiTempLabel (NULL); symbol *trueLabel = newiTempLabel (NULL); symbol *exitLabel = newiTempLabel (NULL); @@ -3093,7 +3093,8 @@ geniCodeLogicAndOr (ast *tree, int lvl) ADDTOCHAIN (ic); /* store 0 or 1 in result */ - result = newiTempOperand (newCharLink(), 1); + type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink(); + result = newiTempOperand (type, 1); geniCodeLabel (falseLabel); geniCodeAssign (result, operandFromLit (0), 0, 0); @@ -3134,7 +3135,7 @@ geniCodeConditional (ast * tree,int lvl) operand *true, *false, *result; ic = newiCodeCondition (geniCodeRValue (cond, FALSE), - NULL, falseLabel); + NULL, falseLabel); ADDTOCHAIN (ic); true = ast2iCode (tree->right->left,lvl+1); @@ -3179,7 +3180,7 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval) if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype)) { checkConstantRange(ltype, - OP_VALUE(right), "= operation", 0); + OP_VALUE(right), "= operation", 0); } /* if the left & right type don't exactly match */ @@ -3192,7 +3193,7 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval) compareType (ltype, rtype) <= 0) { if (compareType (ltype->next, rtype) < 0) - right = geniCodeCast (ltype->next, right, TRUE); + right = geniCodeCast (ltype->next, right, TRUE); } else if (compareType (ltype, rtype) < 0) right = geniCodeCast (ltype, right, TRUE); @@ -3210,7 +3211,7 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval) symbol *sym = NULL; if (IS_TRUE_SYMOP (right)) - sym = OP_SYMBOL (right); + sym = OP_SYMBOL (right); ic = newiCode ('=', NULL, right); IC_RESULT (ic) = right = newiTempOperand (ltype, 0); SPIL_LOC (right) = sym; @@ -3279,7 +3280,7 @@ geniCodeSEParms (ast * parms,int lvl) parms->type = EX_OPERAND; AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) : - SPEC_ARGREG(parms->ftype); + SPEC_ARGREG(parms->ftype); } /*-----------------------------------------------------------------*/ @@ -3287,7 +3288,7 @@ geniCodeSEParms (ast * parms,int lvl) /*-----------------------------------------------------------------*/ value * geniCodeParms (ast * parms, value *argVals, int *stack, - sym_link * ftype, int lvl) + sym_link * ftype, int lvl) { iCode *ic; operand *pval; @@ -3418,7 +3419,7 @@ geniCodeCall (operand * left, ast * parms,int lvl) /* geniCodeReceive - generate intermediate code for "receive" */ /*-----------------------------------------------------------------*/ static void -geniCodeReceive (value * args) +geniCodeReceive (value * args, operand * func) { unsigned char paramByteCounter = 0; @@ -3427,54 +3428,54 @@ geniCodeReceive (value * args) { int first = 1; if (IS_REGPARM (args->etype)) - { - operand *opr = operandFromValue (args); - operand *opl; - symbol *sym = OP_SYMBOL (opr); - iCode *ic; - - /* we will use it after all optimizations - and before liveRange calculation */ - if (!sym->addrtaken && !IS_VOLATILE (sym->etype)) - { - - if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) && - options.stackAuto == 0 && - (!(options.model == MODEL_FLAT24)) ) - { - } - else - { - opl = newiTempOperand (args->type, 0); - sym->reqv = opl; - sym->reqv->key = sym->key; - OP_SYMBOL (sym->reqv)->key = sym->key; - OP_SYMBOL (sym->reqv)->isreqv = 1; - OP_SYMBOL (sym->reqv)->islocal = 0; - SPIL_LOC (sym->reqv) = sym; - } - } - - ic = newiCode (RECEIVE, NULL, NULL); - ic->argreg = SPEC_ARGREG(args->etype); - if (first) { - currFunc->recvSize = getSize (sym->type); - first = 0; - } - IC_RESULT (ic) = opr; - - /* misuse of parmBytes (normally used for functions) - * to save estimated stack position of this argument. - * Normally this should be zero for RECEIVE iCodes. - * No idea if this causes side effects on other ports. - dw - */ - ic->parmBytes = paramByteCounter; - - /* what stack position do we have? */ - paramByteCounter += getSize (sym->type); - - ADDTOCHAIN (ic); - } + { + operand *opr = operandFromValue (args); + operand *opl; + symbol *sym = OP_SYMBOL (opr); + iCode *ic; + + /* we will use it after all optimizations + and before liveRange calculation */ + if (!sym->addrtaken && !IS_VOLATILE (sym->etype)) + { + + if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) && + options.stackAuto == 0 && + (!(options.model == MODEL_FLAT24)) ) + { + } + else + { + opl = newiTempOperand (args->type, 0); + sym->reqv = opl; + sym->reqv->key = sym->key; + OP_SYMBOL (sym->reqv)->key = sym->key; + OP_SYMBOL (sym->reqv)->isreqv = 1; + OP_SYMBOL (sym->reqv)->islocal = 0; + SPIL_LOC (sym->reqv) = sym; + } + } + + ic = newiCode (RECEIVE, func, NULL); + ic->argreg = SPEC_ARGREG(args->etype); + if (first) { + currFunc->recvSize = getSize (sym->type); + first = 0; + } + IC_RESULT (ic) = opr; + + /* misuse of parmBytes (normally used for functions) + * to save estimated stack position of this argument. + * Normally this should be zero for RECEIVE iCodes. + * No idea if this causes side effects on other ports. - dw + */ + ic->parmBytes = paramByteCounter; + + /* what stack position do we have? */ + paramByteCounter += getSize (sym->type); + + ADDTOCHAIN (ic); + } args = args->next; } @@ -3515,7 +3516,7 @@ geniCodeFunctionBody (ast * tree,int lvl) /* for all parameters that are passed on registers add a "receive" */ - geniCodeReceive (tree->values.args); + geniCodeReceive (tree->values.args, func); /* generate code for the body */ ast2iCode (tree->right,lvl+1); @@ -3567,37 +3568,37 @@ geniCodeIfx (ast * tree,int lvl) if (IS_LITERAL (cetype)) { if (floatFromVal (condition->operand.valOperand)) - { - if (tree->trueLabel) - geniCodeGoto (tree->trueLabel); - else - assert (0); - } + { + if (tree->trueLabel) + geniCodeGoto (tree->trueLabel); + else + assert (0); + } else - { - if (tree->falseLabel) - geniCodeGoto (tree->falseLabel); - else - assert (0); - } + { + if (tree->falseLabel) + geniCodeGoto (tree->falseLabel); + else + assert (0); + } goto exit; } if (tree->trueLabel) { ic = newiCodeCondition (condition, - tree->trueLabel, - NULL); + tree->trueLabel, + NULL); ADDTOCHAIN (ic); if (tree->falseLabel) - geniCodeGoto (tree->falseLabel); + geniCodeGoto (tree->falseLabel); } else { ic = newiCodeCondition (condition, - NULL, - tree->falseLabel); + NULL, + tree->falseLabel); ADDTOCHAIN (ic); } @@ -3748,11 +3749,11 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) /* no need to check the lower bound if the condition is unsigned & minimum value is zero */ if (!(min == 0 && IS_UNSIGNED (cetype))) - { - boundary = geniCodeLogic (cond, operandFromLit (min), '<'); - ic = newiCodeCondition (boundary, falseLabel, NULL); - ADDTOCHAIN (ic); - } + { + boundary = geniCodeLogic (cond, operandFromLit (min), '<'); + ic = newiCodeCondition (boundary, falseLabel, NULL); + ADDTOCHAIN (ic); + } /* now for upper bounds */ boundary = geniCodeLogic (cond, operandFromLit (max), '>'); @@ -3800,7 +3801,7 @@ geniCodeSwitch (ast * tree,int lvl) if (caseVal == switchVal) { SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d", - tree->values.switchVals.swNum, caseVal); + tree->values.switchVals.swNum, caseVal); trueLabel = newiTempLabel (buffer); geniCodeGoto (trueLabel); goto jumpTable; @@ -3828,19 +3829,19 @@ geniCodeSwitch (ast * tree,int lvl) /* if we can make this a jump table */ if (geniCodeJumpTable (cond, caseVals, tree)) - goto jumpTable; /* no need for the comparison */ + goto jumpTable; /* no need for the comparison */ /* for the cases defined do */ while (caseVals) { operand *compare = geniCodeLogic (cond, - operandFromValue (caseVals), - EQ_OP); + operandFromValue (caseVals), + EQ_OP); SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d", - tree->values.switchVals.swNum, - (int) floatFromVal (caseVals)); + tree->values.switchVals.swNum, + (int) floatFromVal (caseVals)); trueLabel = newiTempLabel (buffer); ic = newiCodeCondition (compare, trueLabel, NULL); @@ -3853,11 +3854,11 @@ defaultOrBreak: /* if default is present then goto break else break */ if (tree->values.switchVals.swDefault) { - SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum); + SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum); } else { - SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum); + SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum); } falseLabel = newiTempLabel (buffer); @@ -3974,7 +3975,7 @@ void delLvaluereq() if(lpItem) Safe_free(lpItem); } /*-----------------------------------------------------------------*/ -/* clearLvaluereq - clear lvalreq flag */ +/* clearLvaluereq - clear lvalreq flag */ /*-----------------------------------------------------------------*/ void clearLvaluereq() { @@ -3983,7 +3984,7 @@ void clearLvaluereq() if(lpItem) lpItem->req = 0; } /*-----------------------------------------------------------------*/ -/* getLvaluereq - get the last lvalreq level */ +/* getLvaluereq - get the last lvalreq level */ /*-----------------------------------------------------------------*/ int getLvaluereqLvl() { @@ -3993,7 +3994,7 @@ int getLvaluereqLvl() return 0; } /*-----------------------------------------------------------------*/ -/* isLvaluereq - is lvalreq valid for this level ? */ +/* isLvaluereq - is lvalreq valid for this level ? */ /*-----------------------------------------------------------------*/ int isLvaluereq(int lvl) { @@ -4076,22 +4077,22 @@ ast2iCode (ast * tree,int lvl) left = operandFromAst (tree->left,lvl); delLvaluereq(); if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left)) - left = geniCodeRValue (left, TRUE); + left = geniCodeRValue (left, TRUE); } else { - left = operandFromAst (tree->left,lvl); + left = operandFromAst (tree->left,lvl); } if (tree->opval.op == INC_OP || - tree->opval.op == DEC_OP) + tree->opval.op == DEC_OP) { - addLvaluereq(lvl); - right = operandFromAst (tree->right,lvl); - delLvaluereq(); + addLvaluereq(lvl); + right = operandFromAst (tree->right,lvl); + delLvaluereq(); } else { - right = operandFromAst (tree->right,lvl); + right = operandFromAst (tree->right,lvl); } } @@ -4100,124 +4101,124 @@ ast2iCode (ast * tree,int lvl) switch (tree->opval.op) { - case '[': /* array operation */ + case '[': /* array operation */ { - //sym_link *ltype = operandType (left); - //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE); - left = geniCodeRValue (left, FALSE); - right = geniCodeRValue (right, TRUE); + //sym_link *ltype = operandType (left); + //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE); + left = geniCodeRValue (left, FALSE); + right = geniCodeRValue (right, TRUE); } return geniCodeArray (left, right,lvl); - case '.': /* structure dereference */ + case '.': /* structure dereference */ if (IS_PTR (operandType (left))) - left = geniCodeRValue (left, TRUE); + left = geniCodeRValue (left, TRUE); else - left = geniCodeRValue (left, FALSE); + left = geniCodeRValue (left, FALSE); return geniCodeStruct (left, right, tree->lvalue); - case PTR_OP: /* structure pointer dereference */ + case PTR_OP: /* structure pointer dereference */ { - sym_link *pType; - pType = operandType (left); - left = geniCodeRValue (left, TRUE); + sym_link *pType; + pType = operandType (left); + left = geniCodeRValue (left, TRUE); - setOClass (pType, getSpec (operandType (left))); + setOClass (pType, getSpec (operandType (left))); } return geniCodeStruct (left, right, tree->lvalue); - case INC_OP: /* increment operator */ + case INC_OP: /* increment operator */ if (left) - return geniCodePostInc (left); + return geniCodePostInc (left); else - return geniCodePreInc (right, tree->lvalue); + return geniCodePreInc (right, tree->lvalue); - case DEC_OP: /* decrement operator */ + case DEC_OP: /* decrement operator */ if (left) - return geniCodePostDec (left); + return geniCodePostDec (left); else - return geniCodePreDec (right, tree->lvalue); + return geniCodePreDec (right, tree->lvalue); - case '&': /* bitwise and or address of operator */ + case '&': /* bitwise and or address of operator */ if (right) - { /* this is a bitwise operator */ - left = geniCodeRValue (left, FALSE); - right = geniCodeRValue (right, FALSE); - return geniCodeBitwise (left, right, BITWISEAND, tree->ftype); - } + { /* this is a bitwise operator */ + left = geniCodeRValue (left, FALSE); + right = geniCodeRValue (right, FALSE); + return geniCodeBitwise (left, right, BITWISEAND, tree->ftype); + } else - return geniCodeAddressOf (left); + return geniCodeAddressOf (left); - case '|': /* bitwise or & xor */ + case '|': /* bitwise or & xor */ case '^': return geniCodeBitwise (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE), - tree->opval.op, - tree->ftype); + geniCodeRValue (right, FALSE), + tree->opval.op, + tree->ftype); case '/': return geniCodeDivision (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); case '%': return geniCodeModulus (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); case '*': if (right) - return geniCodeMultiply (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype)); + return geniCodeMultiply (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); else - return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl); + return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl); case '-': if (right) - return geniCodeSubtract (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype)); + return geniCodeSubtract (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); else - return geniCodeUnaryMinus (geniCodeRValue (left, FALSE)); + return geniCodeUnaryMinus (geniCodeRValue (left, FALSE)); case '+': if (right) - return geniCodeAdd (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype), - lvl); + return geniCodeAdd (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype), + lvl); else - return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */ + return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */ case LEFT_OP: return geniCodeLeftShift (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); case RIGHT_OP: return geniCodeRightShift (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE)); case CAST: #if 0 // this indeed needs a second thought { - operand *op; - - // let's keep this simple: get the rvalue we need - op=geniCodeRValue (right, FALSE); - // now cast it to whatever we want - op=geniCodeCast (operandType(left), op, FALSE); - // if this is going to be used as an lvalue, make it so - if (tree->lvalue) { - op->isaddr=1; - } - return op; + operand *op; + + // let's keep this simple: get the rvalue we need + op=geniCodeRValue (right, FALSE); + // now cast it to whatever we want + op=geniCodeCast (operandType(left), op, FALSE); + // if this is going to be used as an lvalue, make it so + if (tree->lvalue) { + op->isaddr=1; + } + return op; } #else // bug #604575, is it a bug ???? return geniCodeCast (operandType (left), - geniCodeRValue (right, FALSE), FALSE); + geniCodeRValue (right, FALSE), FALSE); #endif case '~': @@ -4229,9 +4230,9 @@ ast2iCode (ast * tree,int lvl) case '!': case GETHBIT: { - operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); - setOperandType (op, UCHARTYPE); - return op; + operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); + setOperandType (op, UCHARTYPE); + return op; } case AND_OP: case OR_OP: @@ -4265,126 +4266,126 @@ ast2iCode (ast * tree,int lvl) case '=': { - sym_link *rtype = operandType (right); - sym_link *ltype = operandType (left); - if (IS_PTR (rtype) && IS_ITEMP (right) - && right->isaddr && compareType (rtype->next, ltype) == 1) - right = geniCodeRValue (right, TRUE); - else - right = geniCodeRValue (right, FALSE); - - geniCodeAssign (left, right, 0, 1); - return right; + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); + if (IS_PTR (rtype) && IS_ITEMP (right) + && right->isaddr && compareType (rtype->next, ltype) == 1) + right = geniCodeRValue (right, TRUE); + else + right = geniCodeRValue (right, FALSE); + + geniCodeAssign (left, right, 0, 1); + return right; } case MUL_ASSIGN: return - geniCodeAssign (left, - geniCodeMultiply (geniCodeRValue (operandFromOperand (left), - FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype)), - 0, 1); + geniCodeAssign (left, + geniCodeMultiply (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0, 1); case DIV_ASSIGN: return - geniCodeAssign (left, - geniCodeDivision (geniCodeRValue (operandFromOperand (left), - FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype)), - 0, 1); + geniCodeAssign (left, + geniCodeDivision (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0, 1); case MOD_ASSIGN: return - geniCodeAssign (left, - geniCodeModulus (geniCodeRValue (operandFromOperand (left), - FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype)), - 0, 1); + geniCodeAssign (left, + geniCodeModulus (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0, 1); case ADD_ASSIGN: { - sym_link *rtype = operandType (right); - sym_link *ltype = operandType (left); - if (IS_PTR (rtype) && IS_ITEMP (right) - && right->isaddr && compareType (rtype->next, ltype) == 1) - right = geniCodeRValue (right, TRUE); - else - right = geniCodeRValue (right, FALSE); - - - return geniCodeAssign (left, - geniCodeAdd (geniCodeRValue (operandFromOperand (left), - FALSE), - right, - getResultTypeFromType (tree->ftype), - lvl), - 0, 1); + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); + if (IS_PTR (rtype) && IS_ITEMP (right) + && right->isaddr && compareType (rtype->next, ltype) == 1) + right = geniCodeRValue (right, TRUE); + else + right = geniCodeRValue (right, FALSE); + + + return geniCodeAssign (left, + geniCodeAdd (geniCodeRValue (operandFromOperand (left), + FALSE), + right, + getResultTypeFromType (tree->ftype), + lvl), + 0, 1); } case SUB_ASSIGN: { - sym_link *rtype = operandType (right); - sym_link *ltype = operandType (left); - if (IS_PTR (rtype) && IS_ITEMP (right) - && right->isaddr && compareType (rtype->next, ltype) == 1) - { - right = geniCodeRValue (right, TRUE); - } - else - { - right = geniCodeRValue (right, FALSE); - } - return - geniCodeAssign (left, - geniCodeSubtract (geniCodeRValue (operandFromOperand (left), - FALSE), - right, - getResultTypeFromType (tree->ftype)), - 0, 1); + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); + if (IS_PTR (rtype) && IS_ITEMP (right) + && right->isaddr && compareType (rtype->next, ltype) == 1) + { + right = geniCodeRValue (right, TRUE); + } + else + { + right = geniCodeRValue (right, FALSE); + } + return + geniCodeAssign (left, + geniCodeSubtract (geniCodeRValue (operandFromOperand (left), + FALSE), + right, + getResultTypeFromType (tree->ftype)), + 0, 1); } case LEFT_ASSIGN: return - geniCodeAssign (left, - geniCodeLeftShift (geniCodeRValue (operandFromOperand (left) - ,FALSE), - geniCodeRValue (right, FALSE), - getResultTypeFromType (tree->ftype)), - 0, 1); + geniCodeAssign (left, + geniCodeLeftShift (geniCodeRValue (operandFromOperand (left) + ,FALSE), + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0, 1); case RIGHT_ASSIGN: return - geniCodeAssign (left, - geniCodeRightShift (geniCodeRValue (operandFromOperand (left) - ,FALSE), - geniCodeRValue (right, FALSE)), 0, 1); + geniCodeAssign (left, + geniCodeRightShift (geniCodeRValue (operandFromOperand (left) + ,FALSE), + geniCodeRValue (right, FALSE)), 0, 1); case AND_ASSIGN: return - geniCodeAssign (left, - geniCodeBitwise (geniCodeRValue (operandFromOperand (left), - FALSE), - geniCodeRValue (right, FALSE), - BITWISEAND, - operandType (left)), 0, 1); + geniCodeAssign (left, + geniCodeBitwise (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), + BITWISEAND, + operandType (left)), 0, 1); case XOR_ASSIGN: return - geniCodeAssign (left, - geniCodeBitwise (geniCodeRValue (operandFromOperand (left), - FALSE), - geniCodeRValue (right, FALSE), - '^', - operandType (left)), 0, 1); + geniCodeAssign (left, + geniCodeBitwise (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), + '^', + operandType (left)), 0, 1); case OR_ASSIGN: return - geniCodeAssign (left, - geniCodeBitwise (geniCodeRValue (operandFromOperand (left) - ,FALSE), - geniCodeRValue (right, FALSE), - '|', - operandType (left)), 0, 1); + geniCodeAssign (left, + geniCodeBitwise (geniCodeRValue (operandFromOperand (left) + ,FALSE), + geniCodeRValue (right, FALSE), + '|', + operandType (left)), 0, 1); case ',': return geniCodeRValue (right, FALSE); case CALL: return geniCodeCall (ast2iCode (tree->left,lvl+1), - tree->right,lvl); + tree->right,lvl); case LABEL: geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand); return ast2iCode (tree->right,lvl+1); @@ -4414,11 +4415,11 @@ ast2iCode (ast * tree,int lvl) return NULL; case ARRAYINIT: - geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1)); - return NULL; + geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1)); + return NULL; case CRITICAL: - geniCodeCritical (tree, lvl); + geniCodeCritical (tree, lvl); } return NULL; @@ -4437,7 +4438,7 @@ reverseiCChain () { loop->next = prev; if (prev) - prev->prev = loop; + prev->prev = loop; prev = loop; } @@ -4469,22 +4470,22 @@ static const char *opTypeToStr(OPTYPE op) } -operand *validateOpType(operand *op, - const char *macro, - const char *args, - OPTYPE type, - const char *file, - unsigned line) +operand *validateOpType(operand *op, + const char *macro, + const char *args, + OPTYPE type, + const char *file, + unsigned line) { if (op && op->type == type) { - return op; + return op; } fprintf(stderr, - "Internal error: validateOpType failed in %s(%s) @ %s:%u:" - " expected %s, got %s\n", - macro, args, file, line, - opTypeToStr(type), op ? opTypeToStr(op->type) : "null op"); + "Internal error: validateOpType failed in %s(%s) @ %s:%u:" + " expected %s, got %s\n", + macro, args, file, line, + opTypeToStr(type), op ? opTypeToStr(op->type) : "null op"); exit(-1); return op; // never reached, makes compiler happy. } diff --git a/src/SDCCmain.c b/src/SDCCmain.c index d9896e26..12893d7e 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -64,6 +64,7 @@ char *moduleName; /* module name is same as module name base, but /* non-alphanumeric characters replaced with underscore */ int currRegBank = 0; int RegBankUsed[4] = {1, 0, 0, 0}; /*JCF: Reg Bank 0 used by default*/ +int BitBankUsed; /* MB: overlayable bit bank */ struct optimize optimize; struct options options; int preProcOnly = 0; @@ -76,7 +77,7 @@ set *libPathsSet = NULL; set *relFilesSet = NULL; set *dataDirsSet = NULL; /* list of data search directories */ set *includeDirsSet = NULL; /* list of include search directories */ -set *userIncDirsSet = NULL; /* list of user include directories */ +set *userIncDirsSet = NULL; /* list of user include directories */ set *libDirsSet = NULL; /* list of lib search directories */ /* uncomment JAMIN_DS390 to always override and use ds390 port @@ -175,8 +176,8 @@ optionsTable[] = { { 0, OPTION_STD_SDCC89, NULL, "Use C89 standard with SDCC extensions (default)" }, { 0, OPTION_STD_C99, NULL, "Use C99 standard only (incomplete)" }, { 0, OPTION_STD_SDCC99, NULL, "Use C99 standard with SDCC extensions (incomplete)" }, - - { 0, NULL, NULL, "Code generation options"}, + + { 0, NULL, NULL, "Code generation options"}, { 'm', NULL, NULL, "Set the port to use e.g. -mz80." }, { 'p', NULL, NULL, "Select port specific processor e.g. -mpic14 -p16f84" }, { 0, OPTION_LARGE_MODEL, NULL, "external data space is used" }, @@ -219,7 +220,7 @@ optionsTable[] = { { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8 bits (for old times sake)" }, { 0, OPTION_CODE_SEG, NULL, " use this name for the code segment" }, { 0, OPTION_CONST_SEG, NULL, " use this name for the const segment" }, - + { 0, NULL, NULL, "Optimization options"}, { 0, "--nooverlay", &options.noOverlay, "Disable overlaying leaf function auto variables" }, { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" }, @@ -234,7 +235,7 @@ optionsTable[] = { { 0, OPTION_PEEP_FILE, NULL, " use this extra peephole file" }, { 0, OPTION_OPT_CODE_SPEED, NULL, "Optimize for code speed rather than size" }, { 0, OPTION_OPT_CODE_SIZE, NULL, "Optimize for code size rather than speed" }, - + { 0, NULL, NULL, "Internal debugging options"}, { 0, "--dumpraw", &options.dump_raw, "Dump the internal structure after the initial parse" }, { 0, "--dumpgcse", &options.dump_gcse, NULL }, @@ -246,7 +247,7 @@ optionsTable[] = { { 0, "--dumptree", &options.dump_tree, "dump front-end AST before generating iCode" }, { 0, OPTION_DUMP_ALL, NULL, "Dump the internal structure at all stages" }, { 0, OPTION_ICODE_IN_ASM, &options.iCodeInAsm, "include i-code as comments in the asm file"}, - + { 0, NULL, NULL, "Linker options" }, { 'l', NULL, NULL, "Include the given library in the link" }, { 'L', NULL, NULL, "Add the next field to the library search path" }, @@ -267,7 +268,7 @@ optionsTable[] = { { 0, OPTION_PACK_IRAM, NULL,"MCS51/DS390 - Tells the linker to pack variables in internal ram (default)"}, { 0, OPTION_NO_PACK_IRAM, &options.no_pack_iram,"MCS51/DS390 - Tells the linker not to pack variables in internal ram"}, #endif - + /* End of options */ { 0, NULL } }; @@ -1100,7 +1101,7 @@ parseCmdLine (int argc, char **argv) options.std_sdcc = 0; continue; } - + if (strcmp (argv[i], OPTION_STD_C99) == 0) { options.std_c99 = 1; @@ -1114,7 +1115,7 @@ parseCmdLine (int argc, char **argv) options.std_sdcc = 1; continue; } - + if (strcmp (argv[i], OPTION_STD_SDCC99) == 0) { options.std_c99 = 1; diff --git a/src/SDCCmem.c b/src/SDCCmem.c index 8e0db0dc..ddf5ce66 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -663,9 +663,9 @@ allocLocal (symbol * sym) } /* if this is a bit variable and no storage class */ - if (SPEC_NOUN (sym->etype) == V_BIT - && (SPEC_SCLS (sym->etype) == S_BIT)) + if (SPEC_NOUN (sym->etype) == V_BIT) { + SPEC_SCLS (sym->etype) = S_BIT; SPEC_OCLS (sym->etype) = bit; allocIntoSeg (sym); return; diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 3ea2843f..73f36ab0 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -781,6 +781,20 @@ newIntLink () return p; } +/*------------------------------------------------------------------*/ +/* newBoolLink() - creates an bool type */ +/*------------------------------------------------------------------*/ +sym_link * +newBoolLink () +{ + sym_link *p; + + p = newLink (SPECIFIER); + SPEC_NOUN (p) = V_BIT; + + return p; +} + /*------------------------------------------------------------------*/ /* getSize - returns size of a type chain in bits */ /*------------------------------------------------------------------*/ @@ -1478,16 +1492,18 @@ checkSClass (symbol * sym, int isProto) /* if this is an automatic symbol */ if (sym->level && (options.stackAuto || reentrant)) { - if ((SPEC_SCLS (sym->etype) == S_AUTO || - SPEC_SCLS (sym->etype) == S_FIXED || - SPEC_SCLS (sym->etype) == S_REGISTER || - SPEC_SCLS (sym->etype) == S_STACK || - SPEC_SCLS (sym->etype) == S_XSTACK)) { - SPEC_SCLS (sym->etype) = S_AUTO; - } else { - /* storage class may only be specified for statics */ - if (!IS_STATIC(sym->etype)) { - werror (E_AUTO_ASSUMED, sym->name); + if (SPEC_SCLS (sym->etype) != S_BIT) { + if ((SPEC_SCLS (sym->etype) == S_AUTO || + SPEC_SCLS (sym->etype) == S_FIXED || + SPEC_SCLS (sym->etype) == S_REGISTER || + SPEC_SCLS (sym->etype) == S_STACK || + SPEC_SCLS (sym->etype) == S_XSTACK)) { + SPEC_SCLS (sym->etype) = S_AUTO; + } else { + /* storage class may only be specified for statics */ + if (!IS_STATIC(sym->etype)) { + werror (E_AUTO_ASSUMED, sym->name); + } } } } @@ -2341,13 +2357,6 @@ checkFunction (symbol * sym, symbol *csym) return 0; } - /* function cannot return bit */ - if (IS_BITVAR (sym->type->next)) - { - werror (E_FUNC_BIT, sym->name); - return 0; - } - /* check if this function is defined as calleeSaves then mark it as such */ FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name); diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index df7e0484..7e4a400e 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -1,24 +1,24 @@ /*------------------------------------------------------------------------- - SDCCsymt.h - Header file for Symbols table related structures and MACRO's. - Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) + SDCCsymt.h - Header file for Symbols table related structures and MACRO's. + Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! + what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #ifndef SDCCSYMT_H @@ -30,8 +30,8 @@ #include "SDCChasht.h" #include "SDCCglobl.h" -#define INTNO_MAX 255 /* maximum allowed interrupt number */ -#define INTNO_UNSPEC (INTNO_MAX+1) /* interrupt number unspecified */ +#define INTNO_MAX 255 /* maximum allowed interrupt number */ +#define INTNO_UNSPEC (INTNO_MAX+1) /* interrupt number unspecified */ #define BITVAR_PAD -1 @@ -70,22 +70,22 @@ enum { /* hash table bucket */ typedef struct bucket { - void *sym; /* pointer to the object */ - char name[SDCC_NAME_MAX + 1]; /* name of this symbol */ - int level; /* nest level for this symbol */ - int block; /* belongs to which block */ - struct bucket *prev; /* ptr 2 previous bucket */ - struct bucket *next; /* ptr 2 next bucket */ + void *sym; /* pointer to the object */ + char name[SDCC_NAME_MAX + 1]; /* name of this symbol */ + int level; /* nest level for this symbol */ + int block; /* belongs to which block */ + struct bucket *prev; /* ptr 2 previous bucket */ + struct bucket *next; /* ptr 2 next bucket */ } bucket; typedef struct structdef { - char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */ - unsigned char level; /* Nesting level */ - struct symbol *fields; /* pointer to fields */ - unsigned size; /* sizeof the table in bytes */ - int type; /* STRUCT or UNION */ + char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */ + unsigned char level; /* Nesting level */ + struct symbol *fields; /* pointer to fields */ + unsigned size; /* sizeof the table in bytes */ + int type; /* STRUCT or UNION */ } structdef; @@ -130,53 +130,53 @@ STORAGE_CLASS; /* specifier is the last in the type-chain */ typedef struct specifier { - NOUN noun; /* CHAR INT STRUCTURE LABEL */ - STORAGE_CLASS sclass; /* REGISTER,AUTO,FIX,CONSTANT */ - struct memmap *oclass; /* output storage class */ - unsigned _long:1; /* 1=long */ - unsigned _short:1; /* 1=short int */ - unsigned _unsigned:1; /* 1=unsigned, 0=signed */ - unsigned _signed:1; /* just for sanity checks only*/ - unsigned _static:1; /* 1=static keyword found */ - unsigned _extern:1; /* 1=extern found */ - unsigned _absadr:1; /* absolute address specfied */ - unsigned _volatile:1; /* is marked as volatile */ - unsigned _const:1; /* is a constant */ - unsigned _typedef:1; /* is typedefed */ - unsigned _isregparm:1; /* is the first parameter */ - unsigned _isenum:1; /* is an enumerated type */ - unsigned _addr; /* address of symbol */ - unsigned _stack; /* stack offset for stacked v */ - unsigned _bitStart; /* bit start position */ - int _bitLength; /* bit length */ - int argreg; /* reg no for regparm */ + NOUN noun; /* CHAR INT STRUCTURE LABEL */ + STORAGE_CLASS sclass; /* REGISTER,AUTO,FIX,CONSTANT */ + struct memmap *oclass; /* output storage class */ + unsigned _long:1; /* 1=long */ + unsigned _short:1; /* 1=short int */ + unsigned _unsigned:1; /* 1=unsigned, 0=signed */ + unsigned _signed:1; /* just for sanity checks only*/ + unsigned _static:1; /* 1=static keyword found */ + unsigned _extern:1; /* 1=extern found */ + unsigned _absadr:1; /* absolute address specfied */ + unsigned _volatile:1; /* is marked as volatile */ + unsigned _const:1; /* is a constant */ + unsigned _typedef:1; /* is typedefed */ + unsigned _isregparm:1; /* is the first parameter */ + unsigned _isenum:1; /* is an enumerated type */ + unsigned _addr; /* address of symbol */ + unsigned _stack; /* stack offset for stacked v */ + unsigned _bitStart; /* bit start position */ + int _bitLength; /* bit length */ + int argreg; /* reg no for regparm */ union - { /* Values if constant or enum */ - TYPE_WORD v_int; /* 2 bytes: int and char values */ - char *v_char; /* character string */ - TYPE_UWORD v_uint; /* 2 bytes: unsigned int const value */ - TYPE_DWORD v_long; /* 4 bytes: long constant value */ - TYPE_UDWORD v_ulong; /* 4 bytes: unsigned long constant value */ - double v_float; /* floating point constant value */ - TYPE_UDWORD v_fixed16x16; /* 4 bytes: fixed floating point constant value */ - struct symbol *v_enum; /* ptr 2 enum_list if enum==1 */ + { /* Values if constant or enum */ + TYPE_WORD v_int; /* 2 bytes: int and char values */ + char *v_char; /* character string */ + TYPE_UWORD v_uint; /* 2 bytes: unsigned int const value */ + TYPE_DWORD v_long; /* 4 bytes: long constant value */ + TYPE_UDWORD v_ulong; /* 4 bytes: unsigned long constant value */ + double v_float; /* floating point constant value */ + TYPE_UDWORD v_fixed16x16; /* 4 bytes: fixed floating point constant value */ + struct symbol *v_enum; /* ptr to enum_list if enum==1 */ } const_val; - struct structdef *v_struct; /* structure pointer */ + struct structdef *v_struct; /* structure pointer */ } specifier; /* types of declarators */ typedef enum { - POINTER = 0, /* pointer to near data */ - FPOINTER, /* pointer to far data */ - CPOINTER, /* pointer to code space */ - GPOINTER, /* _generic pointer */ - PPOINTER, /* paged area pointer */ - IPOINTER, /* pointer to upper 128 bytes */ - UPOINTER, /* unknown pointer used only when parsing */ - EEPPOINTER, /* pointer to eeprom */ + POINTER = 0, /* pointer to near data */ + FPOINTER, /* pointer to far data */ + CPOINTER, /* pointer to code space */ + GPOINTER, /* _generic pointer */ + PPOINTER, /* paged area pointer */ + IPOINTER, /* pointer to upper 128 bytes */ + UPOINTER, /* unknown pointer used only when parsing */ + EEPPOINTER, /* pointer to eeprom */ ARRAY, FUNCTION } @@ -184,11 +184,11 @@ DECLARATOR_TYPE; typedef struct declarator { - DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */ - unsigned int num_elem; /* # of elems if type==array */ - unsigned ptr_const:1; /* pointer is constant */ - unsigned ptr_volatile:1; /* pointer is volatile */ - struct sym_link *tspec; /* pointer type specifier */ + DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */ + unsigned int num_elem; /* # of elems if type==array */ + unsigned ptr_const:1; /* pointer is constant */ + unsigned ptr_volatile:1; /* pointer is volatile */ + struct sym_link *tspec; /* pointer type specifier */ } declarator; @@ -200,142 +200,142 @@ typedef enum { typedef struct sym_link { - SYM_LINK_CLASS class; /* DECLARATOR or SPECIFIER */ - unsigned tdef:1; /* current link created by */ + SYM_LINK_CLASS class; /* DECLARATOR or SPECIFIER */ + unsigned tdef:1; /* current link created by */ /* typedef if this flag is set */ union { - specifier s; /* if CLASS == SPECIFIER */ - declarator d; /* if CLASS == DECLARATOR */ + specifier s; /* if CLASS == SPECIFIER */ + declarator d; /* if CLASS == DECLARATOR */ } select; /* function attributes */ struct { - struct value *args; /* the defined arguments */ - unsigned hasVargs:1; /* functions has varargs */ - unsigned calleeSaves:1; /* functions uses callee save */ - unsigned hasbody:1; /* function body defined */ - unsigned hasFcall:1; /* does it call other functions */ - unsigned reent:1; /* function is reentrant */ - unsigned naked:1; /* naked function */ - - unsigned shadowregs:1; /* function uses shadow registers (pic16 port) */ - unsigned wparam:1; /* first byte of arguments is passed via WREG (pic16 port) */ - unsigned nonbanked:1; /* function has the nonbanked attribute */ - unsigned banked:1; /* function has the banked attribute */ - unsigned critical:1; /* critical function */ - unsigned intrtn:1; /* this is an interrupt routine */ - unsigned rbank:1; /* seperate register bank */ - unsigned intno; /* 1=Interrupt svc routine */ - short regbank; /* register bank 2b used */ - unsigned builtin; /* is a builtin function */ - unsigned javaNative; /* is a JavaNative Function (TININative ONLY) */ - unsigned overlay; /* force parameters & locals into overlay segment */ - unsigned hasStackParms; /* function has parameters on stack */ + struct value *args; /* the defined arguments */ + unsigned hasVargs:1; /* functions has varargs */ + unsigned calleeSaves:1; /* functions uses callee save */ + unsigned hasbody:1; /* function body defined */ + unsigned hasFcall:1; /* does it call other functions */ + unsigned reent:1; /* function is reentrant */ + unsigned naked:1; /* naked function */ + + unsigned shadowregs:1; /* function uses shadow registers (pic16 port) */ + unsigned wparam:1; /* first byte of arguments is passed via WREG (pic16 port) */ + unsigned nonbanked:1; /* function has the nonbanked attribute */ + unsigned banked:1; /* function has the banked attribute */ + unsigned critical:1; /* critical function */ + unsigned intrtn:1; /* this is an interrupt routine */ + unsigned rbank:1; /* seperate register bank */ + unsigned intno; /* 1=Interrupt svc routine */ + short regbank; /* register bank 2b used */ + unsigned builtin; /* is a builtin function */ + unsigned javaNative; /* is a JavaNative Function (TININative ONLY) */ + unsigned overlay; /* force parameters & locals into overlay segment */ + unsigned hasStackParms; /* function has parameters on stack */ } funcAttrs; - struct sym_link *next; /* next element on the chain */ + struct sym_link *next; /* next element on the chain */ } sym_link; typedef struct symbol { - char name[SDCC_SYMNAME_MAX + 1]; /* Input Variable Name */ - char rname[SDCC_NAME_MAX + 1]; /* internal name */ + char name[SDCC_SYMNAME_MAX + 1]; /* Input Variable Name */ + char rname[SDCC_NAME_MAX + 1]; /* internal name */ - short level; /* declration lev,fld offset */ - short block; /* sequential block # of defintion */ + short level; /* declration lev,fld offset */ + short block; /* sequential block # of defintion */ int key; - unsigned implicit:1; /* implicit flag */ - unsigned undefined:1; /* undefined variable */ - unsigned _isparm:1; /* is a parameter */ - unsigned ismyparm:1; /* is parameter of the function being generated */ - unsigned isitmp:1; /* is an intermediate temp */ - unsigned islbl:1; /* is a temporary label */ - unsigned isref:1; /* has been referenced */ - unsigned isind:1; /* is a induction variable */ - unsigned isinvariant:1; /* is a loop invariant */ - unsigned cdef:1; /* compiler defined symbol */ - unsigned addrtaken:1; /* address of the symbol was taken */ - unsigned isreqv:1; /* is the register quivalent of a symbol */ - unsigned udChked:1; /* use def checking has been already done */ + unsigned implicit:1; /* implicit flag */ + unsigned undefined:1; /* undefined variable */ + unsigned _isparm:1; /* is a parameter */ + unsigned ismyparm:1; /* is parameter of the function being generated */ + unsigned isitmp:1; /* is an intermediate temp */ + unsigned islbl:1; /* is a temporary label */ + unsigned isref:1; /* has been referenced */ + unsigned isind:1; /* is a induction variable */ + unsigned isinvariant:1; /* is a loop invariant */ + unsigned cdef:1; /* compiler defined symbol */ + unsigned addrtaken:1; /* address of the symbol was taken */ + unsigned isreqv:1; /* is the register quivalent of a symbol */ + unsigned udChked:1; /* use def checking has been already done */ /* following flags are used by the backend for code generation and can be changed if a better scheme for backend is thought of */ - unsigned isLiveFcall:1; /* is live at or across a function call */ - unsigned isspilt:1; /* has to be spilt */ - unsigned spillA:1; /* spilt be register allocator */ - unsigned remat:1; /* can be remateriazed */ - unsigned isptr:1; /* is a pointer */ - unsigned uptr:1; /* used as a pointer */ - unsigned isFree:1; /* used by register allocator */ - unsigned islocal:1; /* is a local variable */ - unsigned blockSpil:1; /* spilt at block level */ - unsigned remainSpil:1; /* spilt because not used in remainder */ - unsigned stackSpil:1; /* has been spilt on temp stack location */ - unsigned onStack:1; /* this symbol allocated on the stack */ - unsigned iaccess:1; /* indirect access */ - unsigned ruonly:1; /* used in return statement only */ - unsigned spildir:1; /* spilt in direct space */ - unsigned ptrreg:1; /* this symbol assigned to a ptr reg */ - unsigned noSpilLoc:1; /* cannot be assigned a spil location */ - unsigned isstrlit; /* is a string literal and it's usage count */ - unsigned accuse; /* can be left in the accumulator - On the Z80 accuse is divided into - ACCUSE_A and ACCUSE_HL as the idea - is quite similar. - */ - unsigned dptr; /* 8051 variants with multiple DPTRS - currently implemented in DS390 only - */ - int allocreq ; /* allocation is required for this variable */ - int stack; /* offset on stack */ - int xstack; /* offset on xternal stack */ - short nRegs; /* number of registers required */ - short regType; /* type of register required */ - - struct regs *regs[4]; /* can have at the most 4 registers */ - struct asmop *aop; /* asmoperand for this symbol */ - struct iCode *fuse; /* furthest use */ - struct iCode *rematiCode; /* rematerialise with which instruction */ - struct operand *reqv; /* register equivalent of a local variable */ - struct symbol *prereqv; /* symbol before register equiv. substituion */ - struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */ + unsigned isLiveFcall:1; /* is live at or across a function call */ + unsigned isspilt:1; /* has to be spilt */ + unsigned spillA:1; /* spilt be register allocator */ + unsigned remat:1; /* can be remateriazed */ + unsigned isptr:1; /* is a pointer */ + unsigned uptr:1; /* used as a pointer */ + unsigned isFree:1; /* used by register allocator */ + unsigned islocal:1; /* is a local variable */ + unsigned blockSpil:1; /* spilt at block level */ + unsigned remainSpil:1; /* spilt because not used in remainder */ + unsigned stackSpil:1; /* has been spilt on temp stack location */ + unsigned onStack:1; /* this symbol allocated on the stack */ + unsigned iaccess:1; /* indirect access */ + unsigned ruonly:1; /* used in return statement only */ + unsigned spildir:1; /* spilt in direct space */ + unsigned ptrreg:1; /* this symbol assigned to a ptr reg */ + unsigned noSpilLoc:1; /* cannot be assigned a spil location */ + unsigned isstrlit; /* is a string literal and it's usage count */ + unsigned accuse; /* can be left in the accumulator + On the Z80 accuse is divided into + ACCUSE_A and ACCUSE_HL as the idea + is quite similar. + */ + unsigned dptr; /* 8051 variants with multiple DPTRS + currently implemented in DS390 only + */ + int allocreq ; /* allocation is required for this variable */ + int stack; /* offset on stack */ + int xstack; /* offset on xternal stack */ + short nRegs; /* number of registers required */ + short regType; /* type of register required */ + + struct regs *regs[4]; /* can have at the most 4 registers */ + struct asmop *aop; /* asmoperand for this symbol */ + struct iCode *fuse; /* furthest use */ + struct iCode *rematiCode; /* rematerialise with which instruction */ + struct operand *reqv; /* register equivalent of a local variable */ + struct symbol *prereqv; /* symbol before register equiv. substituion */ + struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */ union { - struct symbol *spillLoc; /* register spil location */ - struct set *itmpStack; /* symbols spilt @ this stack location */ + struct symbol *spillLoc; /* register spil location */ + struct set *itmpStack; /* symbols spilt @ this stack location */ } usl; - short bitVar; /* this is a bit variable */ - unsigned offset; /* offset from top if struct */ - - int lineDef; /* defined line number */ - char *fileDef; /* defined filename */ - int lastLine; /* for functions the last line */ - struct sym_link *type; /* 1st link to declarator chain */ - struct sym_link *etype; /* last link to declarator chain */ - struct symbol *next; /* crosslink to next symbol */ - struct symbol *localof; /* local variable of which function */ - struct initList *ival; /* ptr to initializer if any */ - struct bitVect *defs; /* bit vector for definitions */ - struct bitVect *uses; /* bit vector for uses */ - struct bitVect *regsUsed; /* for functions registers used */ - int liveFrom; /* live from iCode sequence number */ - int liveTo; /* live to sequence number */ - int used; /* no. of times this was used */ - int recvSize; /* size of first argument */ - struct bitVect *clashes; /* overlaps with what other symbols */ + short bitVar; /* this is a bit variable */ + unsigned offset; /* offset from top if struct */ + + int lineDef; /* defined line number */ + char *fileDef; /* defined filename */ + int lastLine; /* for functions the last line */ + struct sym_link *type; /* 1st link to declarator chain */ + struct sym_link *etype; /* last link to declarator chain */ + struct symbol *next; /* crosslink to next symbol */ + struct symbol *localof; /* local variable of which function */ + struct initList *ival; /* ptr to initializer if any */ + struct bitVect *defs; /* bit vector for definitions */ + struct bitVect *uses; /* bit vector for uses */ + struct bitVect *regsUsed; /* for functions registers used */ + int liveFrom; /* live from iCode sequence number */ + int liveTo; /* live to sequence number */ + int used; /* no. of times this was used */ + int recvSize; /* size of first argument */ + struct bitVect *clashes; /* overlaps with what other symbols */ } symbol; -extern sym_link *validateLink(sym_link *l, - const char *macro, - const char *args, - const char select, - const char *file, - unsigned line); +extern sym_link *validateLink(sym_link *l, + const char *macro, + const char *args, + const char select, + const char *file, + unsigned line); /* Easy Access Macros */ #define DCL_TYPE(l) validateLink(l, "DCL_TYPE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.dcl_type #define DCL_ELEM(l) validateLink(l, "DCL_ELEM", #l, DECLARATOR, __FILE__, __LINE__)->select.d.num_elem @@ -406,9 +406,9 @@ extern sym_link *validateLink(sym_link *l, #define SPEC_BSTR(x) validateLink(x, "SPEC_BSTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart #define SPEC_BLEN(x) validateLink(x, "SPEC_BLEN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitLength -/* Sleaze: SPEC_ISR_SAVED_BANKS is only used on +/* Sleaze: SPEC_ISR_SAVED_BANKS is only used on * function type symbols, which obviously cannot - * be of BIT type. Therefore, we recycle the + * be of BIT type. Therefore, we recycle the * _bitStart field instead of defining a new field. */ #define SPEC_ISR_SAVED_BANKS(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart @@ -420,16 +420,16 @@ extern sym_link *validateLink(sym_link *l, #define SPEC_ARGREG(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.argreg /* type check macros */ -#define IS_DECL(x) ( x && x->class == DECLARATOR ) +#define IS_DECL(x) ( x && x->class == DECLARATOR ) #define IS_SPEC(x) ( x && x->class == SPECIFIER ) #define IS_ARRAY(x) (IS_DECL(x) && DCL_TYPE(x) == ARRAY) #define IS_DATA_PTR(x) (IS_DECL(x) && DCL_TYPE(x) == POINTER) #define IS_PTR(x) (IS_DECL(x) && (DCL_TYPE(x) == POINTER || \ DCL_TYPE(x) == FPOINTER || \ - DCL_TYPE(x) == GPOINTER || \ - DCL_TYPE(x) == IPOINTER || \ - DCL_TYPE(x) == PPOINTER || \ - DCL_TYPE(x) == EEPPOINTER || \ + DCL_TYPE(x) == GPOINTER || \ + DCL_TYPE(x) == IPOINTER || \ + DCL_TYPE(x) == PPOINTER || \ + DCL_TYPE(x) == EEPPOINTER || \ DCL_TYPE(x) == CPOINTER || \ DCL_TYPE(x) == UPOINTER )) #define IS_PTR_CONST(x) (IS_PTR(x) && DCL_PTR_CONST(x)) @@ -453,11 +453,11 @@ extern sym_link *validateLink(sym_link *l, #define IS_INT(x) (IS_SPEC(x) && x->select.s.noun == V_INT) #define IS_VOID(x) (IS_SPEC(x) && x->select.s.noun == V_VOID) #define IS_CHAR(x) (IS_SPEC(x) && x->select.s.noun == V_CHAR) -#define IS_EXTERN(x) (IS_SPEC(x) && x->select.s._extern) +#define IS_EXTERN(x) (IS_SPEC(x) && x->select.s._extern) #define IS_VOLATILE(x) (!x ? 0 : \ - IS_SPEC(x) ? \ - x->select.s._volatile : \ - x->select.d.ptr_volatile) + IS_SPEC(x) ? \ + x->select.s._volatile : \ + x->select.d.ptr_volatile) #define IS_INTEGRAL(x) (IS_SPEC(x) && (x->select.s.noun == V_INT || \ x->select.s.noun == V_CHAR || \ x->select.s.noun == V_BITFIELD || \ @@ -520,12 +520,12 @@ extern symbol *__fp16x16conv[2][4][2]; /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ extern symbol *__rlrr[2][3][2]; -#define CHARTYPE __multypes[0][0] -#define UCHARTYPE __multypes[0][1] -#define INTTYPE __multypes[1][0] -#define UINTTYPE __multypes[1][1] -#define LONGTYPE __multypes[2][0] -#define ULONGTYPE __multypes[2][1] +#define CHARTYPE __multypes[0][0] +#define UCHARTYPE __multypes[0][1] +#define INTTYPE __multypes[1][0] +#define UINTTYPE __multypes[1][1] +#define LONGTYPE __multypes[2][0] +#define ULONGTYPE __multypes[2][1] extern sym_link *floatType; extern sym_link *fixed16x16Type; @@ -534,11 +534,11 @@ extern sym_link *fixed16x16Type; typedef enum { - RESULT_TYPE_NONE = 0, /* operands will be promoted to int */ + RESULT_TYPE_NONE = 0, /* operands will be promoted to int */ RESULT_TYPE_BIT, RESULT_TYPE_CHAR, RESULT_TYPE_INT, - RESULT_TYPE_OTHER, /* operands will be promoted to int */ + RESULT_TYPE_OTHER, /* operands will be promoted to int */ RESULT_TYPE_IFX, } RESULT_TYPE; @@ -573,6 +573,7 @@ unsigned int bitsForType (sym_link *); sym_link *newIntLink (); sym_link *newCharLink (); sym_link *newLongLink (); +sym_link *newBoolLink (); int compareType (sym_link *, sym_link *); int compareTypeExact (sym_link *, sym_link *, int); int checkFunction (symbol *, symbol *); diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 891625a6..6f9f7252 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -81,7 +81,7 @@ static unsigned short rbank = -1; #define SYM_BP(sym) (SPEC_OCLS (sym->etype)->paged ? "_bpx" : "_bp") -#define R0INB _G.bu.bs.r0InB +#define R0INB _G.bu.bs.r0InB #define R1INB _G.bu.bs.r1InB #define OPINB _G.bu.bs.OpInB #define BINUSE _G.bu.BInUse @@ -111,7 +111,8 @@ static struct _G; static char *rb1regs[] = { - "b1_0","b1_1","b1_2","b1_3","b1_4","b1_5","b1_6","b1_7" + "b1_0","b1_1","b1_2","b1_3","b1_4","b1_5","b1_6","b1_7", + "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7" }; extern int mcs51_ptrRegReq; @@ -204,6 +205,24 @@ mova (const char *x) emitcode("mov","a,%s", x); } +/*-----------------------------------------------------------------*/ +/* movc - moves specified value into the carry */ +/*-----------------------------------------------------------------*/ +static void +movc (const char *s) +{ + if (s == zero) + CLRC; + else if (s == one) + SETC; + else if (strcmp (s, "c")) + {/* it's not in carry already */ + MOVA (s); + /* set C, if a >= 1 */ + emitcode ("add", "a,#0xff"); + } +} + /*-----------------------------------------------------------------*/ /* pushB - saves register B if necessary */ /*-----------------------------------------------------------------*/ @@ -241,6 +260,42 @@ popB (bool pushedB) } } +/*-----------------------------------------------------------------*/ +/* pushReg - saves register */ +/*-----------------------------------------------------------------*/ +static bool +pushReg (int index, bool bits_pushed) +{ + regs * reg = mcs51_regWithIdx (index); + if (reg->type == REG_BIT) + { + if (!bits_pushed) + emitcode ("push", "%s", reg->base); + return TRUE; + } + else + emitcode ("push", "%s", reg->dname); + return bits_pushed; +} + +/*-----------------------------------------------------------------*/ +/* popReg - restores register */ +/*-----------------------------------------------------------------*/ +static bool +popReg (int index, bool bits_popped) +{ + regs * reg = mcs51_regWithIdx (index); + if (reg->type == REG_BIT) + { + if (!bits_popped) + emitcode ("pop", "%s", reg->base); + return TRUE; + } + else + emitcode ("pop", "%s", reg->dname); + return bits_popped; +} + /*-----------------------------------------------------------------*/ /* getFreePtr - returns r0 or r1 whichever is free or can be pushed */ /*-----------------------------------------------------------------*/ @@ -761,8 +816,10 @@ sameRegs (asmop * aop1, asmop * aop2) if (aop1 == aop2) return TRUE; - if (aop1->type != AOP_REG || - aop2->type != AOP_REG) + if (aop1->type != AOP_REG && aop1->type != AOP_CRY) + return FALSE; + + if (aop1->type != aop2->type) return FALSE; if (aop1->size != aop2->size) @@ -889,6 +946,16 @@ aopOp (operand * op, iCode * ic, bool result) return; } + /* if the type is a bit register */ + if (sym->regType == REG_BIT) + { + sym->aop = op->aop = aop = newAsmop (AOP_CRY); + aop->size = sym->nRegs;//1??? + aop->aopu.aop_reg[0] = sym->regs[0]; + aop->aopu.aop_dir = sym->regs[0]->name; + return; + } + /* must be in a register */ sym->aop = op->aop = aop = newAsmop (AOP_REG); aop->size = sym->nRegs; @@ -1450,7 +1517,7 @@ aopPut (operand * result, const char *s, int offset, bool bvolatile) emitcode ("setb", "%s", aop->aopu.aop_dir); else if (!strcmp (s, "c")) emitcode ("mov", "%s,c", aop->aopu.aop_dir); - else + else if (strcmp (s, aop->aopu.aop_dir)) { MOVA (s); /* set C, if a >= 1 */ @@ -1918,8 +1985,15 @@ saveRegisters (iCode * lic) if (count == 1) { - i = bitVectFirstBit (rsave); - emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name); + regs * reg = mcs51_regWithIdx (bitVectFirstBit (rsave)); + if (reg->type == REG_BIT) + { + emitcode ("mov", "a,%s", reg->base); + } + else + { + emitcode ("mov", "a,%s", reg->name); + } emitcode ("mov", "r0,%s", spname); emitcode ("inc", "%s", spname);// allocate before use emitcode ("movx", "@r0,a"); @@ -1928,6 +2002,17 @@ saveRegisters (iCode * lic) } else if (count != 0) { + bitVect *rsavebits = bitVectIntersect (bitVectCopy (mcs51_allBitregs ()), rsave); + int nBits = bitVectnBitsOn (rsavebits); + + if (nBits != 0) + { + count = count - nBits + 1; + /* remove all but the first bits as they are pushed all at once */ + rsave = bitVectCplAnd (rsave, rsavebits); + rsave = bitVectSetBit (rsave, bitVectFirstBit (rsavebits)); + } + if (bitVectBitValue (rsave, R0_IDX)) { emitcode ("push", "%s", mcs51_regWithIdx (R0_IDX)->dname); @@ -1940,14 +2025,19 @@ saveRegisters (iCode * lic) { if (bitVectBitValue (rsave, i)) { + regs * reg = mcs51_regWithIdx (i); if (i == R0_IDX) { emitcode ("pop", "acc"); emitcode ("push", "acc"); } + else if (reg->type == REG_BIT) + { + emitcode ("mov", "a,%s", reg->base); + } else { - emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name); + emitcode ("mov", "a,%s", reg->name); } emitcode ("movx", "@r0,a"); if (--count) @@ -1963,10 +2053,15 @@ saveRegisters (iCode * lic) } } else + { + bool bits_pushed = FALSE; for (i = 0; i < mcs51_nRegs; i++) { if (bitVectBitValue (rsave, i)) - emitcode ("push", "%s", mcs51_regWithIdx (i)->dname); + { + bits_pushed = pushReg (i, bits_pushed); + } + } } } @@ -1990,26 +2085,53 @@ unsaveRegisters (iCode * ic) if (count == 1) { + regs * reg = mcs51_regWithIdx (bitVectFirstBit (rsave)); emitcode ("mov", "r0,%s", spname); emitcode ("dec", "r0"); emitcode ("movx", "a,@r0"); - i = bitVectFirstBit (rsave); - emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name); + if (reg->type == REG_BIT) + { + emitcode ("mov", "%s,a", reg->base); + } + else + { + emitcode ("mov", "%s,a", reg->name); + } emitcode ("dec", "%s", spname); } else if (count != 0) { + bitVect *rsavebits = bitVectIntersect (bitVectCopy (mcs51_allBitregs ()), rsave); + int nBits = bitVectnBitsOn (rsavebits); + + if (nBits != 0) + { + count = count - nBits + 1; + /* remove all but the first bits as they are popped all at once */ + rsave = bitVectCplAnd (rsave, rsavebits); + rsave = bitVectSetBit (rsave, bitVectFirstBit (rsavebits)); + } + emitcode ("mov", "r0,%s", spname); for (i = mcs51_nRegs; i >= 0; i--) { if (bitVectBitValue (rsave, i)) { + regs * reg = mcs51_regWithIdx (i); emitcode ("dec", "r0"); emitcode ("movx", "a,@r0"); - if (i != R0_IDX) - emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name); + if (i == R0_IDX) + { + emitcode ("push", "acc"); + } + else if (reg->type == REG_BIT) + { + emitcode ("mov", "%s,a", reg->base); + } else - emitcode ("push", "acc"); + { + emitcode ("mov", "%s,a", reg->name); + } } } emitcode ("mov", "%s,r0", spname); @@ -2020,10 +2142,15 @@ unsaveRegisters (iCode * ic) } } else + { + bool bits_popped = FALSE; for (i = mcs51_nRegs; i >= 0; i--) { if (bitVectBitValue (rsave, i)) - emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname); + { + bits_popped = popReg (i, bits_popped); + } + } } } @@ -2056,12 +2183,18 @@ pushSide (operand * oper, int size) /* assignResultValue - also indicates if acc is in use afterwards */ /*-----------------------------------------------------------------*/ static bool -assignResultValue (operand * oper) +assignResultValue (operand * oper, operand * func) { int offset = 0; int size = AOP_SIZE (oper); bool accuse = FALSE; + if (func && IS_BIT (OP_SYM_ETYPE (func))) + { + outBitC (oper); + return FALSE; + } + while (size--) { accuse |= aopPut (oper, fReturn[offset], offset, isOperandVolatile (oper, FALSE)); @@ -2123,6 +2256,7 @@ genIpush (iCode * ic) { int size, offset = 0; char *l; + char *prev = ""; D(emitcode ("; genIpush","")); @@ -2151,7 +2285,7 @@ genIpush (iCode * ic) return; } - /* this is a paramter push: in this case we call + /* this is a parameter push: in this case we call the routine to find the call and save those registers that need to be saved */ saveRegisters (ic); @@ -2177,11 +2311,15 @@ genIpush (iCode * ic) AOP_TYPE (IC_LEFT (ic)) != AOP_DIR && strcmp (l, "a")) { + if (strcmp (l, prev) || *l == '@') MOVA (l); emitcode ("push", "acc"); } else + { emitcode ("push", "%s", l); + } + prev = l; } freeAsmop (IC_LEFT (ic), NULL, ic, TRUE); @@ -2355,27 +2493,78 @@ unsaveRBank (int bank, iCode * ic, bool popPsw) static void genSend(set *sendSet) { iCode *sic; - int rb1_count = 0 ; + int bit_count = 0; + /* first we do all bit parameters */ for (sic = setFirstItem (sendSet); sic; - sic = setNextItem (sendSet)) { + sic = setNextItem (sendSet)) + { + aopOp (IC_LEFT (sic), sic, FALSE); + + if (sic->argreg > 12) + { + int bit = sic->argreg-13; + + /* if left is a literal then + we know what the value is */ + if (AOP_TYPE (IC_LEFT (sic)) == AOP_LIT) + { + if (((int) operandLitValue (IC_LEFT (sic)))) + emitcode ("setb", "b[%d]", bit); + else + emitcode ("clr", "b[%d]", bit); + } + else if (AOP_TYPE (IC_LEFT (sic)) == AOP_CRY) + { + char *l = AOP (IC_LEFT (sic))->aopu.aop_dir; + if (strcmp (l, "c")) + emitcode ("mov", "c,%s", l); + emitcode ("mov", "b[%d],c", bit); + } + else + { + /* we need to or */ + toBoolean (IC_LEFT (sic)); + /* set C, if a >= 1 */ + emitcode ("add", "a,#0xff"); + emitcode ("mov", "b[%d],c", bit); + } + bit_count++; + } + freeAsmop (IC_LEFT (sic), NULL, sic, TRUE); + } + + if (bit_count) + { + saveRegisters (setFirstItem (sendSet)); + emitcode ("mov", "bits,b"); + } + + /* then we do all other parameters */ + for (sic = setFirstItem (sendSet); sic; + sic = setNextItem (sendSet)) + { int size, offset = 0; aopOp (IC_LEFT (sic), sic, FALSE); size = AOP_SIZE (IC_LEFT (sic)); - if (sic->argreg == 1) { - while (size--) { - char *l = aopGet (IC_LEFT (sic), offset, - FALSE, FALSE); + if (sic->argreg == 1) + { + while (size--) + { + char *l = aopGet (IC_LEFT (sic), offset, FALSE, FALSE); if (strcmp (l, fReturn[offset])) emitcode ("mov", "%s,%s", fReturn[offset], l); offset++; } - rb1_count = 0; - } else { - while (size--) { - emitcode ("mov","b1_%d,%s",rb1_count++, - aopGet (IC_LEFT (sic), offset++,FALSE, FALSE)); + } + else if (sic->argreg <= 12) + { + while (size--) + { + emitcode ("mov","%s,%s", rb1regs[sic->argreg+offset-5], + aopGet (IC_LEFT (sic), offset,FALSE, FALSE)); + offset++; } } freeAsmop (IC_LEFT (sic), NULL, sic, TRUE); @@ -2393,6 +2582,7 @@ genCall (iCode * ic) bool swapBanks = FALSE; bool accuse = FALSE; bool accPushed = FALSE; + bool resultInF0 = FALSE; D(emitcode("; genCall","")); @@ -2458,12 +2648,24 @@ genCall (iCode * ic) if (swapBanks) { - emitcode ("mov", "psw,#0x%02x", - ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff); - } + /* if result is in carry */ + if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic)))) + { + emitcode ("anl", "psw,#0xE7"); + if (FUNC_REGBANK(currFunc->type)) + emitcode ("orl", "psw,#0x%02x", + ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff); + } + else + { + emitcode ("mov", "psw,#0x%02x", + ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff); + } + } /* if we need assign a result value */ if ((IS_ITEMP (IC_RESULT (ic)) && + !IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic))) && (OP_SYMBOL (IC_RESULT (ic))->nRegs || OP_SYMBOL (IC_RESULT (ic))->accuse || OP_SYMBOL (IC_RESULT (ic))->spildir)) || @@ -2474,7 +2676,7 @@ genCall (iCode * ic) aopOp (IC_RESULT (ic), ic, FALSE); _G.accInUse--; - accuse = assignResultValue (IC_RESULT (ic)); + accuse = assignResultValue (IC_RESULT (ic), IC_LEFT (ic)); freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); } @@ -2490,6 +2692,12 @@ genCall (iCode * ic) emitcode ("push", "acc"); accPushed = TRUE; } + if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic))) && + IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic)))) + { + emitcode ("mov", "F0,c"); + resultInF0 = TRUE; + } emitcode ("mov", "a,%s", spname); emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff); @@ -2508,7 +2716,7 @@ genCall (iCode * ic) emitcode ("dec", "%s", spname); } - /* if we hade saved some registers then unsave them */ + /* if we had saved some registers then unsave them */ if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) { if (accuse && !accPushed && options.useXstack) @@ -2524,6 +2732,16 @@ genCall (iCode * ic) // if (restoreBank) // unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE); + if (IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic)))) + { + if (resultInF0) + emitcode ("mov", "c,F0"); + + aopOp (IC_RESULT (ic), ic, FALSE); + assignResultValue (IC_RESULT (ic), IC_LEFT (ic)); + freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); + } + if (accPushed) emitcode ("pop", "acc"); } @@ -2692,7 +2910,7 @@ genPcall (iCode * ic) aopOp (IC_RESULT (ic), ic, FALSE); _G.accInUse--; - assignResultValue (IC_RESULT (ic)); + assignResultValue (IC_RESULT (ic), IC_LEFT (ic)); freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); } @@ -2810,15 +3028,18 @@ genFunction (iCode * ic) rbank = FUNC_REGBANK (ftype); for (i = 0; i < mcs51_nRegs; i++) { - if (strcmp (regs8051[i].base, "0") == 0) - emitcode ("", "%s = 0x%02x", - regs8051[i].dname, - 8 * rbank + regs8051[i].offset); - else - emitcode ("", "%s = %s + 0x%02x", - regs8051[i].dname, - regs8051[i].base, - 8 * rbank + regs8051[i].offset); + if (regs8051[i].type != REG_BIT) + { + if (strcmp (regs8051[i].base, "0") == 0) + emitcode ("", "%s = 0x%02x", + regs8051[i].dname, + 8 * rbank + regs8051[i].offset); + else + emitcode ("", "%s = %s + 0x%02x", + regs8051[i].dname, + regs8051[i].base, + 8 * rbank + regs8051[i].offset); + } } } @@ -2851,11 +3072,12 @@ genFunction (iCode * ic) /* if any registers used */ if (sym->regsUsed) { + bool bits_pushed = FALSE; /* save the registers used */ for (i = 0; i < sym->regsUsed->size; i++) { if (bitVectBitValue (sym->regsUsed, i)) - emitcode ("push", "%s", mcs51_regWithIdx (i)->dname); + bits_pushed = pushReg (i, bits_pushed); } } } @@ -2987,6 +3209,7 @@ genFunction (iCode * ic) /* if any registers used */ if (sym->regsUsed) { + bool bits_pushed = FALSE; /* save the registers used */ for (i = 0; i < sym->regsUsed->size; i++) { @@ -2995,7 +3218,7 @@ genFunction (iCode * ic) /* remember one saved register for later usage */ if (calleesaves_saved_register < 0) calleesaves_saved_register = i; - emitcode ("push", "%s", mcs51_regWithIdx (i)->dname); + bits_pushed = pushReg (i, bits_pushed); _G.nRegsSaved++; } } @@ -3207,8 +3430,18 @@ genEndFunction (iCode * ic) if (IFFUNC_ISCRITICAL (sym->type)) { - emitcode ("pop", "psw"); /* restore ea via c in psw */ - emitcode ("mov", "ea,c"); + if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic)))) + { + emitcode ("rlc", "a"); /* save c in a */ + emitcode ("pop", "psw"); /* restore ea via c in psw */ + emitcode ("mov", "ea,c"); + emitcode ("rrc", "a"); /* restore c from a */ + } + else + { + emitcode ("pop", "psw"); /* restore ea via c in psw */ + emitcode ("mov", "ea,c"); + } } if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) @@ -3269,11 +3502,12 @@ genEndFunction (iCode * ic) /* if any registers used */ if (sym->regsUsed) { + bool bits_popped = FALSE; /* save the registers used */ for (i = sym->regsUsed->size; i >= 0; i--) { if (bitVectBitValue (sym->regsUsed, i)) - emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname); + bits_popped = popReg (i, bits_popped); } } } @@ -3491,6 +3725,13 @@ genRet (iCode * ic) aopOp (IC_LEFT (ic), ic, FALSE); size = AOP_SIZE (IC_LEFT (ic)); + + if (IS_BIT(_G.currentFunc->etype)) + { + movc (aopGet (IC_LEFT (ic), 0, FALSE, FALSE)); + size = 0; + } + while (size--) { char *l; @@ -3511,16 +3752,13 @@ genRet (iCode * ic) } } - if (pushed) + while (pushed) { - while (pushed) - { - pushed--; - if (strcmp (fReturn[pushed], "a")) - emitcode ("pop", fReturn[pushed]); - else - emitcode ("pop", "acc"); - } + pushed--; + if (strcmp (fReturn[pushed], "a")) + emitcode ("pop", fReturn[pushed]); + else + emitcode ("pop", "acc"); } freeAsmop (IC_LEFT (ic), NULL, ic, TRUE); @@ -9803,6 +10041,7 @@ genIfx (iCode * ic, iCode * popIc) { operand *cond = IC_COND (ic); int isbit = 0; + char *dup = NULL; D(emitcode ("; genIfx","")); @@ -9812,8 +10051,12 @@ genIfx (iCode * ic, iCode * popIc) if (AOP_TYPE (cond) != AOP_CRY) toBoolean (cond); else - isbit = 1; - /* the result is now in the accumulator */ + { + isbit = 1; + if (AOP(cond)->aopu.aop_dir) + dup = Safe_strdup(AOP(cond)->aopu.aop_dir); + } + /* the result is now in the accumulator or a directly addressable bit */ freeAsmop (cond, NULL, ic, TRUE); /* if there was something to be popped then do it */ @@ -9821,7 +10064,9 @@ genIfx (iCode * ic, iCode * popIc) genIpop (popIc); /* if the condition is a bit variable */ - if (isbit && IS_ITEMP (cond) && SPIL_LOC (cond)) + if (isbit && dup) + genIfxJump(ic, dup, NULL, NULL, NULL); + else if (isbit && IS_ITEMP (cond) && SPIL_LOC (cond)) genIfxJump (ic, SPIL_LOC (cond)->rname, NULL, NULL, NULL); else if (isbit && !IS_ITEMP (cond)) genIfxJump (ic, OP_SYMBOL (cond)->rname, NULL, NULL, NULL); @@ -10422,6 +10667,7 @@ genReceive (iCode * ic) { int size = getSize (operandType (IC_RESULT (ic))); int offset = 0; + D(emitcode ("; genReceive","")); if (ic->argreg == 1) { /* first parameter */ @@ -10487,7 +10733,7 @@ genReceive (iCode * ic) _G.accInUse++; aopOp (IC_RESULT (ic), ic, FALSE); _G.accInUse--; - assignResultValue (IC_RESULT (ic)); + assignResultValue (IC_RESULT (ic), NULL); } } else { /* second receive onwards */ int rb1off ; diff --git a/src/mcs51/main.c b/src/mcs51/main.c index bed2b95e..a8854a78 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -53,6 +53,7 @@ static char *_mcs51_keywords[] = void mcs51_assignRegisters (ebbIndex *); static int regParmFlg = 0; /* determine if we can register a parameter */ +static int regBitParmFlg = 0; /* determine if we can register a bit parameter */ static void _mcs51_init (void) @@ -64,13 +65,20 @@ static void _mcs51_reset_regparm (void) { regParmFlg = 0; + regBitParmFlg = 0; } static int _mcs51_regparm (sym_link * l) { - if (IS_SPEC(l) && (SPEC_NOUN(l) == V_BIT)) + if (IS_SPEC(l) && (SPEC_NOUN(l) == V_BIT)) { + /* bit parameters go to b0 thru b7 */ + if (options.stackAuto && (regBitParmFlg < 8)) { + regBitParmFlg++; + return 12 + regBitParmFlg; + } return 0; + } if (options.parms_in_bank1 == 0) { /* simple can pass only the first parameter in a register */ if (regParmFlg) @@ -712,7 +720,7 @@ PORT mcs51_port = 1, 2, 2, 4, 1, 2, 3, 1, 4, 4 }, { - "XSTK (PAG,XDATA)", // xstack_name + "XSTK (PAG,XDATA)", // xstack_name "STACK (DATA)", // istack_name "CSEG (CODE)", // code_name "DSEG (DATA)", // data_name diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 96a431ce..9251cd32 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -51,6 +51,7 @@ static struct bitVect *funcrUsed; /* registers used in a function */ int stackExtend; int dataExtend; + bitVect *allBitregs; /* all bit registers */ } _G; @@ -69,6 +70,14 @@ regs regs8051[] = {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1}, {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1}, {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1}, + {REG_BIT, B0_IDX, REG_BIT, "b0", "b0", "bits", 0, 1}, + {REG_BIT, B1_IDX, REG_BIT, "b1", "b1", "bits", 1, 1}, + {REG_BIT, B2_IDX, REG_BIT, "b2", "b2", "bits", 2, 1}, + {REG_BIT, B3_IDX, REG_BIT, "b3", "b3", "bits", 3, 1}, + {REG_BIT, B4_IDX, REG_BIT, "b4", "b4", "bits", 4, 1}, + {REG_BIT, B5_IDX, REG_BIT, "b5", "b5", "bits", 5, 1}, + {REG_BIT, B6_IDX, REG_BIT, "b6", "b6", "bits", 6, 1}, + {REG_BIT, B7_IDX, REG_BIT, "b7", "b7", "bits", 7, 1}, {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1}, {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1}, {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 1}, @@ -80,7 +89,7 @@ regs regs8051[] = {0, B_IDX, 0, "b", "b", "0xf0", 0, 0}, {0, A_IDX, 0, "a", "acc", "0xe0", 0, 0}, }; -int mcs51_nRegs = 17; +int mcs51_nRegs = 16; static void spillThis (symbol *); static void freeAllRegs (); @@ -505,7 +514,7 @@ createStackSpil (symbol * sym) /* set the type to the spilling symbol */ sloc->type = copyLinkChain (sym->type); sloc->etype = getSpec (sloc->type); - if (SPEC_SCLS (sloc->etype) != S_BIT) + if (!IS_BIT (sloc->etype)) { SPEC_SCLS (sloc->etype) = S_DATA; } @@ -865,6 +874,21 @@ tryAgain: goto tryAgain; } +/*-----------------------------------------------------------------*/ +/* getRegBit - will try for Bit if not spill this */ +/*-----------------------------------------------------------------*/ +static regs *getRegBit (symbol * sym) +{ + regs *reg; + + /* try for a bit type */ + if ((reg = allocReg (REG_BIT))) + return reg; + + spillThis (sym); + return 0; +} + /*-----------------------------------------------------------------*/ /* getRegPtrNoSpil - get it cannot be spilt */ /*-----------------------------------------------------------------*/ @@ -906,6 +930,27 @@ static regs *getRegGprNoSpil() return 0; } +/*-----------------------------------------------------------------*/ +/* getRegBitNoSpil - get it cannot be spilt */ +/*-----------------------------------------------------------------*/ +static regs *getRegBitNoSpil() +{ + regs *reg; + + /* try for a ptr type */ + if ((reg = allocReg (REG_BIT))) + return reg; + + /* try for gpr type */ + if ((reg = allocReg (REG_GPR))) + return reg; + + assert(0); + + /* just to make the compiler happy */ + return 0; +} + /*-----------------------------------------------------------------*/ /* symHasReg - symbol has a given register */ /*-----------------------------------------------------------------*/ @@ -921,6 +966,28 @@ symHasReg (symbol * sym, regs * reg) return FALSE; } +/*-----------------------------------------------------------------*/ +/* updateRegUsage - update the registers in use at the start of */ +/* this icode */ +/*-----------------------------------------------------------------*/ +static void +updateRegUsage (iCode * ic) +{ + int reg; + + for (reg=0; regriu &= ~(1<riu |= (1<sch; ic; ic = ic->next) { -#if 1 - int reg; - - // update the registers in use at the start of this icode - for (reg=0; regriu &= ~(1<riu |= (1<op == IPOP) @@ -1246,10 +1303,11 @@ serialRegAssign (eBBlock ** ebbs, int count) continue; } + willCS = willCauseSpill (sym->nRegs, sym->regType); /* if this is a bit variable then don't use precious registers along with expensive bit-to-char conversions but just spill it */ - if (SPEC_NOUN(sym->etype) == V_BIT) { + if (willCS && SPEC_NOUN(sym->etype) == V_BIT) { spillThis (sym); continue; } @@ -1258,7 +1316,6 @@ serialRegAssign (eBBlock ** ebbs, int count) a spill and there is nothing to spill or this one is rematerializable then spill this one */ - willCS = willCauseSpill (sym->nRegs, sym->regType); spillable = computeSpillable (ic); if (sym->remat || (willCS && bitVectIsZero (spillable))) { spillThis (sym); @@ -1323,13 +1380,15 @@ serialRegAssign (eBBlock ** ebbs, int count) sym->regs[j] = NULL; if (sym->regType == REG_PTR) sym->regs[j] = getRegPtr (ic, ebbs[i], sym); + else if (sym->regType == REG_BIT) + sym->regs[j] = getRegBit (sym); else { if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) { symbol * right = OP_SYMBOL (IC_RIGHT (ic)); - if (right->regs[j]) + if (right->regs[j] && (right->regType != REG_BIT)) sym->regs[j] = allocThisReg (right->regs[j]); } if (!sym->regs[j]) @@ -1468,6 +1527,8 @@ static void fillGaps() for (i=0; i < sym->nRegs ; i++ ) { if (sym->regType == REG_PTR) sym->regs[i] = getRegPtrNoSpil (); + else if (sym->regType == REG_BIT) + sym->regs[i] = getRegBitNoSpil (); else { sym->regs[i] = NULL; @@ -1576,6 +1637,33 @@ static void fillGaps() } } +/*-----------------------------------------------------------------*/ +/* findAllBitregs :- returns bit vector of all bit registers */ +/*-----------------------------------------------------------------*/ +static bitVect * +findAllBitregs (void) +{ + bitVect *rmask = newBitVect (mcs51_nRegs); + int j; + + for (j = 0; j < mcs51_nRegs; j++) + { + if (regs8051[j].type == REG_BIT) + rmask = bitVectSetBit (rmask, regs8051[j].rIdx); + } + + return rmask; +} + +/*-----------------------------------------------------------------*/ +/* mcs51_allBitregs :- returns bit vector of all bit registers */ +/*-----------------------------------------------------------------*/ +bitVect * +mcs51_allBitregs (void) +{ + return _G.allBitregs; +} + /*-----------------------------------------------------------------*/ /* rUmaskForOp :- returns register mask for an operand */ /*-----------------------------------------------------------------*/ @@ -2365,7 +2453,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) /* this routine will mark the a symbol as used in one instruction use only && if the defintion is local (ie. within the basic block) && has only one definition && - that definiion is either a return value from a + that definition is either a return value from a function or does not contain any variables in far space */ if (bitVectnBitsOn (OP_USES (op)) > 1) @@ -3144,7 +3232,17 @@ mcs51_assignRegisters (ebbIndex * ebbi) setToNull ((void *) &_G.regAssigned); setToNull ((void *) &_G.totRegAssigned); mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; + if (options.stackAuto) + { + mcs51_nRegs = 16; + BitBankUsed = 1; + } + else + { mcs51_nRegs = 8; + } + _G.allBitregs = findAllBitregs (); + /* change assignments this will remove some live ranges reducing some register pressure */ diff --git a/src/mcs51/ralloc.h b/src/mcs51/ralloc.h index cd92de4f..27601075 100644 --- a/src/mcs51/ralloc.h +++ b/src/mcs51/ralloc.h @@ -31,6 +31,8 @@ enum { R2_IDX = 0, R3_IDX, R4_IDX, R5_IDX, R6_IDX, R7_IDX, R0_IDX, R1_IDX, + B0_IDX, B1_IDX, B2_IDX, B3_IDX, + B4_IDX, B5_IDX, B6_IDX, B7_IDX, X8_IDX, X9_IDX, X10_IDX, X11_IDX, X12_IDX, CND_IDX, DPL_IDX, DPH_IDX, B_IDX, A_IDX, @@ -61,5 +63,6 @@ extern regs regs8051[]; regs *mcs51_regWithIdx (int); bitVect *mcs51_rUmaskForOp (operand * op); +bitVect *mcs51_allBitregs (void); #endif