+2005-08-22 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * 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 <borut.razem AT siol.net>
* device/lib/Makefile.in: replaced find option -or with -o
* 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
* 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
*/
#include <string.h>
#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'
+};
- /* asexpr.c */
+/* asexpr.c */
/*
* (C) Copyright 1989-1995
term(esp);
while (ctype[c = getnb()] & BINOP) {
/*
- * Handle binary operators + - * / & | % ^ << >>
+ * Handle binary operators + - * / & | % ^ << >> [
*/
if ((p = oprio(c)) <= n)
break;
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();
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;
}
int
oprio(register int c)
{
+ if (c == '[')
+ return (12);
if (c == '*' || c == '/' || c == '%')
return (10);
if (c == '+' || c == '-')
* 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 <limits.h>
-#ifndef PATH_MAX /* POSIX, but not required */
+#ifndef PATH_MAX /* POSIX, but not required */
#if defined(__BORLANDC__) || defined(_MSC_VER)
#include <stdlib.h>
- #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
* 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)
#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 );
* 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
* - 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 <unistd.h>
/*
* 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 <limits.h>
-#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 <stdlib.h>
-#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 );
/* 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 *);
fchar='3';
else if(!strcmp(tap->a_id, "BSEG_BYTES"))
fchar='B';
+ else if(!strcmp(tap->a_id, "BIT_BANK"))
+ fchar='T';
else
fchar=' ';/*???*/
}
}
}
}
+ 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;
* 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
*/
#include <string.h>
#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
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",
"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",
}
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)
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++)
{
* 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
*/
#include <string.h>
#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[].
*
*/
*/
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;
*/
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);
}
#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
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
;
{
switch (tree->opval.op)
{
+ case AND_OP:
+ case OR_OP:
+ return resultType;
case '=':
case '?':
case ':':
return tree;
}
LRVAL (tree) = 1;
- TTYPE (tree) = TETYPE (tree) = newCharLink ();
+ TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
return tree;
/*------------------------------------------------------------------*/
return tree;
case GETHBIT:
- TTYPE (tree) = TETYPE (tree) = newCharLink ();
+ TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
return tree;
case LEFT_OP:
return tree;
}
LRVAL (tree) = RRVAL (tree) = 1;
- TTYPE (tree) = TETYPE (tree) = newCharLink ();
+ TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
return tree;
/*------------------------------------------------------------------*/
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 */
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 */
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 */
*/
void checkConstantRange(sym_link *ltype, value *val, char *msg,
- int pedantic) {
+ int pedantic) {
double max;
int warnings=0;
int negative=0;
#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)
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));
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')
/* 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;
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)))
{
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);
}
}
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 */
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);
+ }
}
}
/*-----------------------------------------------------------------*/
iCode *
newiCodeCondition (operand * condition,
- symbol * trueLabel,
- symbol * falseLabel)
+ symbol * trueLabel,
+ symbol * falseLabel)
{
iCode *ic;
/* 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;
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;
}
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;
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
{
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
{
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
{
*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;
/*-----------------------------------------------------------------*/
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;
{
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
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;
default:
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- " operandOperation invalid operator ");
+ " operandOperation invalid operator ");
assert (0);
}
{
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) &&
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;
/* 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;
}
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 */
)
{
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:
{
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);
}
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;
}
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);
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++;
+ }
}
}
}
{
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);
}
/* 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));
&& 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);
!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);
/* 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, '%');
if (IS_LITERAL (letype) && IS_LITERAL (retype))
{
result = operandFromValue (valMinus (left->operand.valOperand,
- right->operand.valOperand));
+ right->operand.valOperand));
goto subtractExit;
}
// should we really do this? is this ANSI?
return geniCodeDivision (result,
- operandFromLit (getSize (ltype->next)),
- FALSE);
+ operandFromLit (getSize (ltype->next)),
+ FALSE);
}
/*-----------------------------------------------------------------*/
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, '-');
}
// 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
if (IS_LITERAL (letype) && IS_LITERAL (retype)
&& left->isLiteral && right->isLiteral)
return operandFromValue (valPlus (valFromType (ltype),
- valFromType (rtype)));
+ valFromType (rtype)));
ic = newiCode ('+', left, right);
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)
(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))
{
sym_link *etype = getSpec (type);
sym_link *retype;
symbol *element = getStructElement (SPEC_STRUCT (etype),
- right->operand.symOperand);
+ right->operand.symOperand);
wassert(IS_SYMOP(right));
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;
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;
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;
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;
/*-----------------------------------------------------------------*/
operand *
geniCodeBitwise (operand * left, operand * right,
- int oper, sym_link * resType)
+ int oper, sym_link * resType)
{
iCode *ic;
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);
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,
geniCodeLogicAndOr (ast *tree, int lvl)
{
iCode *ic;
+ sym_link *type;
symbol *falseLabel = newiTempLabel (NULL);
symbol *trueLabel = newiTempLabel (NULL);
symbol *exitLabel = newiTempLabel (NULL);
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);
operand *true, *false, *result;
ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
- NULL, falseLabel);
+ NULL, falseLabel);
ADDTOCHAIN (ic);
true = ast2iCode (tree->right->left,lvl+1);
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 */
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);
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;
parms->type = EX_OPERAND;
AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
- SPEC_ARGREG(parms->ftype);
+ SPEC_ARGREG(parms->ftype);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
value *
geniCodeParms (ast * parms, value *argVals, int *stack,
- sym_link * ftype, int lvl)
+ sym_link * ftype, int lvl)
{
iCode *ic;
operand *pval;
/* geniCodeReceive - generate intermediate code for "receive" */
/*-----------------------------------------------------------------*/
static void
-geniCodeReceive (value * args)
+geniCodeReceive (value * args, operand * func)
{
unsigned char paramByteCounter = 0;
{
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;
}
/* 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);
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);
}
/* 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), '>');
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;
/* 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);
/* 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);
if(lpItem) Safe_free(lpItem);
}
/*-----------------------------------------------------------------*/
-/* clearLvaluereq - clear lvalreq flag */
+/* clearLvaluereq - clear lvalreq flag */
/*-----------------------------------------------------------------*/
void clearLvaluereq()
{
if(lpItem) lpItem->req = 0;
}
/*-----------------------------------------------------------------*/
-/* getLvaluereq - get the last lvalreq level */
+/* getLvaluereq - get the last lvalreq level */
/*-----------------------------------------------------------------*/
int getLvaluereqLvl()
{
return 0;
}
/*-----------------------------------------------------------------*/
-/* isLvaluereq - is lvalreq valid for this level ? */
+/* isLvaluereq - is lvalreq valid for this level ? */
/*-----------------------------------------------------------------*/
int isLvaluereq(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);
}
}
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 '~':
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:
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);
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;
{
loop->next = prev;
if (prev)
- prev->prev = loop;
+ prev->prev = loop;
prev = loop;
}
}
-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.
}
/* 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;
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
{ 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" },
{ 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8 bits (for old times sake)" },
{ 0, OPTION_CODE_SEG, NULL, "<name> use this name for the code segment" },
{ 0, OPTION_CONST_SEG, NULL, "<name> 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" },
{ 0, OPTION_PEEP_FILE, NULL, "<file> 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 },
{ 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" },
{ 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 }
};
options.std_sdcc = 0;
continue;
}
-
+
if (strcmp (argv[i], OPTION_STD_C99) == 0)
{
options.std_c99 = 1;
options.std_sdcc = 1;
continue;
}
-
+
if (strcmp (argv[i], OPTION_STD_SDCC99) == 0)
{
options.std_c99 = 1;
}
/* 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;
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 */
/*------------------------------------------------------------------*/
/* 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);
+ }
}
}
}
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);
/*-------------------------------------------------------------------------
- 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
#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
/* 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;
/* 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
}
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;
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
#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
#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))
#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 || \
/* 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;
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;
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 *);
#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
_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;
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 */
/*-----------------------------------------------------------------*/
}
}
+/*-----------------------------------------------------------------*/
+/* 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 */
/*-----------------------------------------------------------------*/
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)
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;
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 */
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");
}
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);
{
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)
}
}
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);
+ }
+ }
}
}
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);
}
}
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);
+ }
+ }
}
}
/* 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));
{
int size, offset = 0;
char *l;
+ char *prev = "";
D(emitcode ("; genIpush",""));
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);
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);
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);
bool swapBanks = FALSE;
bool accuse = FALSE;
bool accPushed = FALSE;
+ bool resultInF0 = FALSE;
D(emitcode("; genCall",""));
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)) ||
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);
}
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);
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)
// 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");
}
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);
}
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);
+ }
}
}
/* 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);
}
}
}
/* if any registers used */
if (sym->regsUsed)
{
+ bool bits_pushed = FALSE;
/* save the registers used */
for (i = 0; i < sym->regsUsed->size; i++)
{
/* 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++;
}
}
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))
/* 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);
}
}
}
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;
}
}
- 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);
{
operand *cond = IC_COND (ic);
int isbit = 0;
+ char *dup = NULL;
D(emitcode ("; genIfx",""));
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 */
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);
{
int size = getSize (operandType (IC_RESULT (ic)));
int offset = 0;
+
D(emitcode ("; genReceive",""));
if (ic->argreg == 1) { /* first parameter */
_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 ;
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)
_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)
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
bitVect *funcrUsed; /* registers used in a function */
int stackExtend;
int dataExtend;
+ bitVect *allBitregs; /* all bit registers */
}
_G;
{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},
{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 ();
/* 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;
}
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 */
/*-----------------------------------------------------------------*/
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 */
/*-----------------------------------------------------------------*/
return FALSE;
}
+/*-----------------------------------------------------------------*/
+/* updateRegUsage - update the registers in use at the start of */
+/* this icode */
+/*-----------------------------------------------------------------*/
+static void
+updateRegUsage (iCode * ic)
+{
+ int reg;
+
+ for (reg=0; reg<mcs51_nRegs; reg++)
+ {
+ if (regs8051[reg].isFree)
+ {
+ ic->riu &= ~(1<<regs8051[reg].offset);
+ }
+ else
+ {
+ ic->riu |= (1<<regs8051[reg].offset);
+ }
+ }
+}
+
/*-----------------------------------------------------------------*/
/* deassignLRs - check the live to and if they have registers & are */
/* not spilt then free up the registers */
/* for all instructions do */
for (ic = ebbs[i]->sch; ic; ic = ic->next)
{
-#if 1
- int reg;
-
- // update the registers in use at the start of this icode
- for (reg=0; reg<mcs51_nRegs; reg++) {
- if (regs8051[reg].isFree) {
- ic->riu &= ~(1<<regs8051[reg].offset);
- } else {
- ic->riu |= (1<<regs8051[reg].offset);
- }
- }
-#endif
+ updateRegUsage(ic);
+
/* if this is an ipop that means some live
range will have to be assigned again */
if (ic->op == IPOP)
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;
}
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);
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])
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;
}
}
+/*-----------------------------------------------------------------*/
+/* 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 */
/*-----------------------------------------------------------------*/
/* 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)
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 */
{
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,
regs *mcs51_regWithIdx (int);
bitVect *mcs51_rUmaskForOp (operand * op);
+bitVect *mcs51_allBitregs (void);
#endif