+2004-10-17 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * as/mcs51/lkarea.c: removed old K&R style,
+ (lnksect): changed check on boundary error,
+ (lnksect2): changed check on boundary error,
+ (lnksect2): extend XSTK to end of page if size = 1
+ * as/mcs51/lkmain.c: removed old K&R style,
+ (Areas51): create l_IRAM symbol
+ * as/mcs51/lkmem.c (summary2): added report on PSEG and XSTK
+ * device/lib/Makefile.in: renamed model-mcs51-reentrant to
+ model-mcs51-stack-auto, added model-mcs51-xstack-auto
+ * device/lib/_mullong.c: added version to be compiled with xstack
+ * device/lib/mcs51/crtclear.asm: clear only upto --iram-size
+ * device/lib/mcs51/crtxclear.asm: clear pdata as well
+ * device/lib/mcs51/crtxstack.asm: fixed comment
+ * src/SDCCglue.c: maxInterrupts defaults to 0,
+ (emitMaps): added pdata,
+ (createInterruptVect): (re)moved default,
+ (glue): added pdata,
+ (glue): moved __start__xstack to XSTK with default size 1
+ * src/SDCCmain.c (parseCmdLine): automatically set options.intlong_rent
+ and options.float_rent when options.stackAuto is set,
+ (linkEdit): only write XDATA_NAME if provided on command line
+ * src/SDCCmem.h,
+ * src/SDCCmem.c: added pdata
+ * src/port.h: added pdata_name to PORT
+ * src/mcs51/gen.c (toBoolean): fixed for Acc use of aopGet,
+ (saveRegisters, unsaveRegisters): removed usage of B,
+ (genMinus): fixed accumulator clash,
+ (genJumpTab): added comment, this needs another look
+ * src/mcs51/gen.c: added check for "B in use" paranoia,
+ added pushB() and popB()
+ * src/mcs51/peeph.def: restart after 177.c so 177.a can get a second
+ chance
+ * src/avr/main.c,
+ * src/ds390/main.c,
+ * src/hc08/main.c,
+ * src/mcs51/main.c,
+ * src/pic/main.c,
+ * src/pic16/main.c,
+ * src/xa51/main.c,
+ * src/z80/main.c: (reset_regparms) made void parameter explicit and
+ added PSEG (PAG,XDATA) or NULL to port specifier
+ * src/ds390/main.c (_ds390_genIVT): moved implemented default in here
+ * src/mcs51/main.c (_mcs51_genIVT): moved implemented default in here,
+ (_mcs51_genInitStartup): removed __start__xstack equ,
+ (mcs51_port): moved xstack from XSEG (XDATA) to XSTK (PAG,XDATA)
+ * src/pic16/device.c (pic16_dump_usection, pic16_dump_isection),
+ * src/z80/gen.c (_rleAppend): fixed warnings
+ * support/regression/tests/zeropad.c: added pdata test
+ * .version: bumped to 2.4.6
+
2004-10-17 Borut Razem <borut.razem AT siol.net>
* support/scripts/sdcc.nsi: cross compiling of WIN32 setup.exe on Linux
* 721 Berkeley St.
* Kent, Ohio 44240
*
- * 3-Nov-97 JLH:
+ * 3-Nov-97 JLH:
* - change lkparea to use a_type == 0 as "virgin area" flag
* 02-Apr-98 JLH: add code to link 8051 data spaces
*/
#include <string.h>
#include "aslink.h"
-/*)Module lkarea.c
+/*)Module lkarea.c
*
- * The module lkarea.c contains the functions which
- * create and link together all area definitions read
- * from the .rel file(s).
+ * The module lkarea.c contains the functions which
+ * create and link together all area definitions read
+ * from the .rel file(s).
*
- * lkarea.c contains the following functions:
- * VOID lnkarea()
- * VOID lnksect()
- * VOID lkparea()
- * VOID newarea()
+ * lkarea.c contains the following functions:
+ * VOID lnkarea()
+ * VOID lnksect()
+ * VOID lkparea()
+ * VOID newarea()
*
- * lkarea.c contains no global variables.
+ * lkarea.c contains no global variables.
*/
-/*)Function VOID newarea()
- *
- * The function newarea() creates and/or modifies area
- * and areax structures for each A directive read from
- * the .rel file(s). The function lkparea() is called
- * to find tha area structure associated with this name.
- * If the area does not yet exist then a new area
- * structure is created and linked to any existing
- * linked area structures. The area flags are copied
- * into the area flag variable. For each occurence of
- * an A directive an areax structure is created and
- * linked to the areax structures associated with this
- * area. The size of this area section is placed into
- * the areax structure. The flag value for all subsequent
- * area definitions for the same area are compared and
- * flagged as an error if they are not identical.
- * The areax structure created for every occurence of
- * an A directive is loaded with a pointer to the base
- * area structure and a pointer to the associated
- * head structure. And finally, a pointer to this
- * areax structure is loaded into the list of areax
- * structures in the head structure. Refer to lkdata.c
- * for details of the structures and their linkage.
- *
- * local variables:
- * areax **halp pointer to an array of pointers
- * int i counter, loop variable, value
- * char id[] id string
- * int narea number of areas in this head structure
- * areax * taxp pointer to an areax structure
- * to areax structures
- *
- * global variables:
- * area *ap Pointer to the current
- * area structure
- * areax *axp Pointer to the current
- * areax structure
- * head *hp Pointer to the current
- * head structure
- * int lkerr error flag
- *
- * functions called:
- * Addr_T eval() lkeval.c
- * VOID exit() c_library
- * int fprintf() c_library
- * VOID getid() lklex.c
- * VOID lkparea() lkarea.c
- * VOID skip() lklex.c
- *
- * side effects:
- * The area and areax structures are created and
- * linked with the appropriate head structures.
- * Failure to allocate area or areax structure
- * space will terminate the linker. Other internal
- * errors most likely caused by corrupted .rel
- * files will also terminate the linker.
+/*)Function VOID newarea()
+ *
+ * The function newarea() creates and/or modifies area
+ * and areax structures for each A directive read from
+ * the .rel file(s). The function lkparea() is called
+ * to find tha area structure associated with this name.
+ * If the area does not yet exist then a new area
+ * structure is created and linked to any existing
+ * linked area structures. The area flags are copied
+ * into the area flag variable. For each occurence of
+ * an A directive an areax structure is created and
+ * linked to the areax structures associated with this
+ * area. The size of this area section is placed into
+ * the areax structure. The flag value for all subsequent
+ * area definitions for the same area are compared and
+ * flagged as an error if they are not identical.
+ * The areax structure created for every occurence of
+ * an A directive is loaded with a pointer to the base
+ * area structure and a pointer to the associated
+ * head structure. And finally, a pointer to this
+ * areax structure is loaded into the list of areax
+ * structures in the head structure. Refer to lkdata.c
+ * for details of the structures and their linkage.
+ *
+ * local variables:
+ * areax **halp pointer to an array of pointers
+ * int i counter, loop variable, value
+ * char id[] id string
+ * int narea number of areas in this head structure
+ * areax * taxp pointer to an areax structure
+ * to areax structures
+ *
+ * global variables:
+ * area *ap Pointer to the current
+ * area structure
+ * areax *axp Pointer to the current
+ * areax structure
+ * head *hp Pointer to the current
+ * head structure
+ * int lkerr error flag
+ *
+ * functions called:
+ * Addr_T eval() lkeval.c
+ * VOID exit() c_library
+ * int fprintf() c_library
+ * VOID getid() lklex.c
+ * VOID lkparea() lkarea.c
+ * VOID skip() lklex.c
+ *
+ * side effects:
+ * The area and areax structures are created and
+ * linked with the appropriate head structures.
+ * Failure to allocate area or areax structure
+ * space will terminate the linker. Other internal
+ * errors most likely caused by corrupted .rel
+ * files will also terminate the linker.
*/
/*
VOID
newarea()
{
- register int i, narea;
- struct areax *taxp;
- struct areax **halp;
- char id[NCPS];
-
- /*
- * Create Area entry
- */
- getid(id, -1);
- lkparea(id);
- /*
- * Evaluate area size
- */
- skip(-1);
- axp->a_size = eval();
- /*
- * Evaluate flags
- */
- skip(-1);
- i = 0;
- taxp = ap->a_axp;
- while (taxp->a_axp) {
- ++i;
- taxp = taxp->a_axp;
- }
- if (i == 0) {
- ap->a_flag = eval();
- } else {
- i = eval();
-/* if (i && (ap->a_flag != i)) { */
-/* fprintf(stderr, "Conflicting flags in area %8s\n", id); */
-/* lkerr++; */
-/* } */
- }
- /*
- * Place pointer in header area list
- */
- if (headp == NULL) {
- fprintf(stderr, "No header defined\n");
- lkexit(1);
- }
- narea = hp->h_narea;
- halp = hp->a_list;
- for (i=0; i < narea ;++i) {
- if (halp[i] == NULL) {
- halp[i] = taxp;
- return;
- }
- }
- fprintf(stderr, "Header area list overflow\n");
- lkexit(1);
+ register int i, narea;
+ struct areax *taxp;
+ struct areax **halp;
+ char id[NCPS];
+
+ /*
+ * Create Area entry
+ */
+ getid(id, -1);
+ lkparea(id);
+ /*
+ * Evaluate area size
+ */
+ skip(-1);
+ axp->a_size = eval();
+ /*
+ * Evaluate flags
+ */
+ skip(-1);
+ i = 0;
+ taxp = ap->a_axp;
+ while (taxp->a_axp) {
+ ++i;
+ taxp = taxp->a_axp;
+ }
+ if (i == 0) {
+ ap->a_flag = eval();
+ } else {
+ i = eval();
+/* if (i && (ap->a_flag != i)) { */
+/* fprintf(stderr, "Conflicting flags in area %8s\n", id); */
+/* lkerr++; */
+/* } */
+ }
+ /*
+ * Place pointer in header area list
+ */
+ if (headp == NULL) {
+ fprintf(stderr, "No header defined\n");
+ lkexit(1);
+ }
+ narea = hp->h_narea;
+ halp = hp->a_list;
+ for (i=0; i < narea ;++i) {
+ if (halp[i] == NULL) {
+ halp[i] = taxp;
+ return;
+ }
+ }
+ fprintf(stderr, "Header area list overflow\n");
+ lkexit(1);
}
-/*)Function VOID lkparea(id)
- *
- * char * id pointer to the area name string
- *
- * The function lkparea() searches the linked area structures
- * for a name match. If the name is not found then an area
- * structure is created. An areax structure is created and
- * appended to the areax structures linked to the area structure.
- * The associated base area and head structure pointers are
- * loaded into the areax structure.
- *
- * local variables:
- * area * tap pointer to an area structure
- * areax * taxp pointer to an areax structure
- *
- * global variables:
- * area *ap Pointer to the current
- * area structure
- * area *areap The pointer to the first
- * area structure of a linked list
- * areax *axp Pointer to the current
- * areax structure
- *
- * functions called:
- * VOID * new() lksym()
- * char * strcpy() c_library
- * int symeq() lksym.c
- *
- * side effects:
- * Area and/or areax structures are created.
- * Failure to allocate space for created structures
- * will terminate the linker.
+/*)Function VOID lkparea(id)
+ *
+ * char * id pointer to the area name string
+ *
+ * The function lkparea() searches the linked area structures
+ * for a name match. If the name is not found then an area
+ * structure is created. An areax structure is created and
+ * appended to the areax structures linked to the area structure.
+ * The associated base area and head structure pointers are
+ * loaded into the areax structure.
+ *
+ * local variables:
+ * area * tap pointer to an area structure
+ * areax * taxp pointer to an areax structure
+ *
+ * global variables:
+ * area *ap Pointer to the current
+ * area structure
+ * area *areap The pointer to the first
+ * area structure of a linked list
+ * areax *axp Pointer to the current
+ * areax structure
+ *
+ * functions called:
+ * VOID * new() lksym()
+ * char * strcpy() c_library
+ * int symeq() lksym.c
+ *
+ * side effects:
+ * Area and/or areax structures are created.
+ * Failure to allocate space for created structures
+ * will terminate the linker.
*/
VOID
-lkparea(id)
-char *id;
+lkparea(char *id)
{
- register struct area *tap;
- register struct areax *taxp;
-
- ap = areap;
- axp = (struct areax *) new (sizeof(struct areax));
- while (ap) {
- if (symeq(id, ap->a_id)) {
- taxp = ap->a_axp;
- while (taxp->a_axp)
- taxp = taxp->a_axp;
- taxp->a_axp = axp;
- axp->a_bap = ap;
- axp->a_bhp = hp;
- return;
- }
- ap = ap->a_ap;
- }
- ap = (struct area *) new (sizeof(struct area));
- if (areap == NULL) {
- areap = ap;
- } else {
- tap = areap;
- while (tap->a_ap)
- tap = tap->a_ap;
- tap->a_ap = ap;
- }
- ap->a_axp = axp;
- axp->a_bap = ap;
- axp->a_bhp = hp;
- strncpy(ap->a_id, id, NCPS);
- ap->a_addr = 0;
+ register struct area *tap;
+ register struct areax *taxp;
+
+ ap = areap;
+ axp = (struct areax *) new (sizeof(struct areax));
+ while (ap) {
+ if (symeq(id, ap->a_id)) {
+ taxp = ap->a_axp;
+ while (taxp->a_axp)
+ taxp = taxp->a_axp;
+ taxp->a_axp = axp;
+ axp->a_bap = ap;
+ axp->a_bhp = hp;
+ return;
+ }
+ ap = ap->a_ap;
+ }
+ ap = (struct area *) new (sizeof(struct area));
+ if (areap == NULL) {
+ areap = ap;
+ } else {
+ tap = areap;
+ while (tap->a_ap)
+ tap = tap->a_ap;
+ tap->a_ap = ap;
+ }
+ ap->a_axp = axp;
+ axp->a_bap = ap;
+ axp->a_bhp = hp;
+ strncpy(ap->a_id, id, NCPS);
+ ap->a_addr = 0;
}
-/*)Function VOID lnkarea()
- *
- * The function lnkarea() resolves all area addresses.
- * The function evaluates each area structure (and all
- * the associated areax structures) in sequence. The
- * linking process supports four (4) possible area types:
- *
- * ABS/OVR - All sections (each individual areax
- * section) starts at the identical base
- * area address overlaying all other
- * areax sections for this area. The
- * size of the area is largest of the area
- * sections.
- *
- * ABS/CON - All sections (each individual areax
- * section) are concatenated with the
- * first section starting at the base
- * area address. The size of the area
- * is the sum of the section sizes.
- *
- * NOTE: Multiple absolute (ABS) areas are
- * never concatenated with each other,
- * thus absolute area A and absolute area
- * B will overlay each other if they begin
- * at the same location (the default is
- * always address 0 for absolute areas).
- *
- * REL/OVR - All sections (each individual areax
- * section) starts at the identical base
- * area address overlaying all other
- * areax sections for this area. The
- * size of the area is largest of the area
- * sections.
- *
- * REL/CON - All sections (each individual areax
- * section) are concatenated with the
- * first section starting at the base
- * area address. The size of the area
- * is the sum of the section sizes.
- *
- * NOTE: Relocatable (REL) areas ae always concatenated
- * with each other, thus relocatable area B
- * (defined after area A) will follow
- * relocatable area A independent of the
- * starting address of area A. Within a
- * specific area each areax section may be
- * overlayed or concatenated with other
- * areax sections.
- *
- *
- * If a base address for an area is specified then the
- * area will start at that address. Any relocatable
- * areas defined subsequently will be concatenated to the
- * previous relocatable area if it does not have a base
- * address specified.
- *
- * The names s_<areaname> and l_<areaname> are created to
- * define the starting address and length of each area.
- *
- * local variables:
- * Addr_T rloc ;current relocation address
- * char temp[] ;temporary string
- * struct symbol *sp ;symbol structure
- *
- * global variables:
- * area *ap Pointer to the current
- * area structure
- * area *areap The pointer to the first
- * area structure of a linked list
- *
- * functions called:
- * int fprintf() c_library
- * VOID lnksect() lkarea.c
- * symbol *lkpsym() lksysm.c
- * char * strncpy() c_library
- * int symeq() lksysm.c
- *
- * side effects:
- * All area and areax addresses and sizes are
- * determined and saved in their respective
- * structures.
+/*)Function VOID lnkarea()
+ *
+ * The function lnkarea() resolves all area addresses.
+ * The function evaluates each area structure (and all
+ * the associated areax structures) in sequence. The
+ * linking process supports four (4) possible area types:
+ *
+ * ABS/OVR - All sections (each individual areax
+ * section) starts at the identical base
+ * area address overlaying all other
+ * areax sections for this area. The
+ * size of the area is largest of the area
+ * sections.
+ *
+ * ABS/CON - All sections (each individual areax
+ * section) are concatenated with the
+ * first section starting at the base
+ * area address. The size of the area
+ * is the sum of the section sizes.
+ *
+ * NOTE: Multiple absolute (ABS) areas are
+ * never concatenated with each other,
+ * thus absolute area A and absolute area
+ * B will overlay each other if they begin
+ * at the same location (the default is
+ * always address 0 for absolute areas).
+ *
+ * REL/OVR - All sections (each individual areax
+ * section) starts at the identical base
+ * area address overlaying all other
+ * areax sections for this area. The
+ * size of the area is largest of the area
+ * sections.
+ *
+ * REL/CON - All sections (each individual areax
+ * section) are concatenated with the
+ * first section starting at the base
+ * area address. The size of the area
+ * is the sum of the section sizes.
+ *
+ * NOTE: Relocatable (REL) areas are always concatenated
+ * with each other, thus relocatable area B
+ * (defined after area A) will follow
+ * relocatable area A independent of the
+ * starting address of area A. Within a
+ * specific area each areax section may be
+ * overlayed or concatenated with other
+ * areax sections.
+ *
+ *
+ * If a base address for an area is specified then the
+ * area will start at that address. Any relocatable
+ * areas defined subsequently will be concatenated to the
+ * previous relocatable area if it does not have a base
+ * address specified.
+ *
+ * The names s_<areaname> and l_<areaname> are created to
+ * define the starting address and length of each area.
+ *
+ * local variables:
+ * Addr_T rloc ;current relocation address
+ * char temp[] ;temporary string
+ * struct symbol *sp ;symbol structure
+ *
+ * global variables:
+ * area *ap Pointer to the current
+ * area structure
+ * area *areap The pointer to the first
+ * area structure of a linked list
+ *
+ * functions called:
+ * int fprintf() c_library
+ * VOID lnksect() lkarea.c
+ * symbol *lkpsym() lksym.c
+ * char * strncpy() c_library
+ * int symeq() lksym.c
+ *
+ * side effects:
+ * All area and areax addresses and sizes are
+ * determined and saved in their respective
+ * structures.
*/
/*
VOID
lnkarea()
{
- Addr_T rloc[4];
- int locIndex;
- char temp[NCPS];
- struct sym *sp;
- /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
- struct area *ta[5];
- int j;
-
- rloc[0] = rloc[1] = rloc[2] = rloc[3] = 0;
- ap = areap;
- while (ap) {
- if (ap->a_flag&A_ABS) {
- /*
- * Absolute sections
- */
- lnksect(ap);
- } else {
- /* Determine memory space */
+ Addr_T rloc[4];
+ int locIndex;
+ char temp[NCPS];
+ struct sym *sp;
+ /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
+ struct area *ta[5];
+ int j;
+
+ rloc[0] = rloc[1] = rloc[2] = rloc[3] = 0;
+ ap = areap;
+ while (ap) {
+ if (ap->a_flag&A_ABS) {
+ /*
+ * Absolute sections
+ */
+ lnksect(ap);
+ } else {
+ /* Determine memory space */
locIndex = 0;
if (ap->a_flag & A_CODE) {
locIndex = 1;
if (ap->a_flag & A_BIT) {
locIndex = 3;
}
- /*
- * Relocatable sections
- */
- if (ap->a_type == 0) { /* JLH */
- ap->a_addr = rloc[ locIndex ];
- ap->a_type = 1;
- }
- lnksect(ap);
- rloc[ locIndex ] = ap->a_addr + ap->a_size;
- }
-
- /*
- * Create symbols called:
- * s_<areaname> the start address of the area
- * l_<areaname> the length of the area
- */
-
- if (! symeq(ap->a_id, _abs_)) {
- strncpy(temp+2,ap->a_id,NCPS-2);
- *(temp+1) = '_';
-
- *temp = 's';
- sp = lkpsym(temp, 1);
- sp->s_addr = ap->a_addr ;
- /* sp->s_axp = ap->a_axp; JLH: was NULL; */
- sp->s_type |= S_DEF;
-
- *temp = 'l';
- sp = lkpsym(temp, 1);
- sp->s_addr = ap->a_size;
- sp->s_axp = NULL;
- sp->s_type |= S_DEF;
-
- }
-
- /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
- to compute the byte size of BSEG_BYTES: */
- if (!strcmp(ap->a_id, "BSEG")) {
- ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
- }
- else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
- else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
- else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
- else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
- else if (!strcmp(ap->a_id, "BSEG_BYTES"))
- {
- ta[4]=ap;
- for(j=4; j>1; j--)
- {
- /*If upper register banks are not used roll back the rellocation counter*/
- if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
- {
- rloc[0]-=8;
- }
- else break;
- }
- }
- ap = ap->a_ap;
- }
+ /*
+ * Relocatable sections
+ */
+ if (ap->a_type == 0) { /* JLH */
+ ap->a_addr = rloc[ locIndex ];
+ ap->a_type = 1;
+ }
+ lnksect(ap);
+ rloc[ locIndex ] = ap->a_addr + ap->a_size;
+ }
+
+ /*
+ * Create symbols called:
+ * s_<areaname> the start address of the area
+ * l_<areaname> the length of the area
+ */
+
+ if (! symeq(ap->a_id, _abs_)) {
+ strncpy(temp+2,ap->a_id,NCPS-2);
+ *(temp+1) = '_';
+
+ *temp = 's';
+ sp = lkpsym(temp, 1);
+ sp->s_addr = ap->a_addr ;
+ /* sp->s_axp = ap->a_axp; JLH: was NULL; */
+ sp->s_type |= S_DEF;
+
+ *temp = 'l';
+ sp = lkpsym(temp, 1);
+ sp->s_addr = ap->a_size;
+ sp->s_axp = NULL;
+ sp->s_type |= S_DEF;
+
+ }
+
+ /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
+ to compute the byte size of BSEG_BYTES: */
+ if (!strcmp(ap->a_id, "BSEG")) {
+ ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
+ }
+ else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
+ else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
+ else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
+ else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
+ else if (!strcmp(ap->a_id, "BSEG_BYTES"))
+ {
+ ta[4]=ap;
+ for(j=4; j>1; j--)
+ {
+ /*If upper register banks are not used roll back the relocation counter*/
+ if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
+ {
+ rloc[0]-=8;
+ }
+ else break;
+ }
+ }
+ ap = ap->a_ap;
+ }
}
-/*)Function VOID lnksect()
+/*)Function VOID lnksect()
*
- * area * tap pointer to an area structure
+ * area * tap pointer to an area structure
*
- * The function lnksect() is the function called by
- * lnkarea() to resolve the areax addresses. Refer
- * to the function lnkarea() for more detail. Pageing
- * boundary and length errors will be reported by this
- * function.
+ * The function lnksect() is the function called by
+ * lnkarea() to resolve the areax addresses. Refer
+ * to the function lnkarea() for more detail. Pageing
+ * boundary and length errors will be reported by this
+ * function.
*
- * local variables:
- * Addr_T size size of area
- * Addr_T addr address of area
- * areax * taxp pointer to an areax structure
+ * local variables:
+ * Addr_T size size of area
+ * Addr_T addr address of area
+ * areax * taxp pointer to an areax structure
*
- * global variables:
- * int lkerr error flag
+ * global variables:
+ * int lkerr error flag
*
- * functions called:
- * none
+ * functions called:
+ * none
*
- * side effects:
- * All area and areax addresses and sizes area determined
- * and linked into the structures.
+ * side effects:
+ * All area and areax addresses and sizes area determined
+ * and linked into the structures.
*/
VOID
-lnksect(tap)
-register struct area *tap;
+lnksect(register struct area *tap)
{
- register Addr_T size, addr;
- register struct areax *taxp;
-
- size = 0;
- addr = tap->a_addr;
- if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
- fprintf(stderr,
- "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
- lkerr++;
- }
- taxp = tap->a_axp;
- if (tap->a_flag&A_OVR) {
- /*
- * Overlayed sections
- */
- while (taxp) {
- taxp->a_addr = addr;
- if (taxp->a_size > size)
- size = taxp->a_size;
- taxp = taxp->a_axp;
- }
- } else {
- /*
- * Concatenated sections
- */
- while (taxp) {
- taxp->a_addr = addr;
- addr += taxp->a_size;
- size += taxp->a_size;
- taxp = taxp->a_axp;
- }
- }
- tap->a_size = size;
- if ((tap->a_flag&A_PAG) && (size > 256)) {
- fprintf(stderr,
- "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
- lkerr++;
- }
+ register Addr_T size, addr;
+ register struct areax *taxp;
+
+ size = 0;
+ addr = tap->a_addr;
+#if 0
+ if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
+ fprintf(stderr,
+ "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
+ lkerr++;
+ }
+#endif
+ taxp = tap->a_axp;
+ if (tap->a_flag&A_OVR) {
+ /*
+ * Overlayed sections
+ */
+ while (taxp) {
+ taxp->a_addr = addr;
+ if (taxp->a_size > size)
+ size = taxp->a_size;
+ taxp = taxp->a_axp;
+ }
+ } else {
+ /*
+ * Concatenated sections
+ */
+ while (taxp) {
+ taxp->a_addr = addr;
+ addr += taxp->a_size;
+ size += taxp->a_size;
+ taxp = taxp->a_axp;
+ }
+ }
+ tap->a_size = size;
+ if ((tap->a_flag&A_PAG) && (size > 256)) {
+ fprintf(stderr,
+ "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
+ lkerr++;
+ }
+ if ((tap->a_flag&A_PAG) && (tap->a_size) &&
+ ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
+ {
+ fprintf(stderr,
+ "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
+ lkerr++;
+ }
}
void lnksect2 (struct area *tap, int rloc);
VOID lnkarea2 (void)
{
Addr_T rloc[4]={0, 0, 0, 0};
- int locIndex;
- char temp[NCPS];
- struct sym *sp;
- int j;
+ int locIndex;
+ char temp[NCPS];
+ struct sym *sp;
+ int j;
struct area *dseg_ap=NULL;
- struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL;
+ struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL;
- for(j=0; j<256; j++) idatamap[j]=' ';
+ for(j=0; j<256; j++) idatamap[j]=' ';
- ap = areap;
- while (ap)
- {
- /* Determine memory space */
+ ap = areap;
+ while (ap)
+ {
+ /* Determine memory space */
if (ap->a_flag & A_CODE) locIndex = 1;
else if (ap->a_flag & A_XDATA) locIndex = 2;
else if (ap->a_flag & A_BIT) locIndex = 3;
else locIndex = 0;
if (ap->a_flag&A_ABS) /* Absolute sections */
- {
- lnksect2(ap, locIndex);
- }
- else /* Relocatable sections */
- {
- if (ap->a_type == 0)
+ {
+ lnksect2(ap, locIndex);
+ }
+ else /* Relocatable sections */
+ {
+ if (ap->a_type == 0)
{
- ap->a_addr=rloc[locIndex];
- ap->a_type=1;
- }
-
- lnksect2(ap, locIndex);
- rloc[locIndex] = ap->a_addr + ap->a_size;
- }
-
- /*
- * Create symbols called:
- * s_<areaname> the start address of the area
- * l_<areaname> the length of the area
- */
-
- if (! symeq(ap->a_id, _abs_))
- {
- strncpy(temp+2,ap->a_id,NCPS-2);
- *(temp+1) = '_';
-
- *temp = 's';
- sp = lkpsym(temp, 1);
- sp->s_addr = ap->a_addr ;
- sp->s_type |= S_DEF;
+ ap->a_addr=rloc[locIndex];
+ ap->a_type=1;
+ }
+
+ lnksect2(ap, locIndex);
+ rloc[locIndex] = ap->a_addr + ap->a_size;
+ }
+
+ /*
+ * Create symbols called:
+ * s_<areaname> the start address of the area
+ * l_<areaname> the length of the area
+ */
+
+ if (! symeq(ap->a_id, _abs_))
+ {
+ strncpy(temp+2,ap->a_id,NCPS-2);
+ *(temp+1) = '_';
+
+ *temp = 's';
+ sp = lkpsym(temp, 1);
+ sp->s_addr = ap->a_addr ;
+ sp->s_type |= S_DEF;
if (!strcmp(ap->a_id, "DSEG")) sp_dseg_s=sp;
- *temp = 'l';
- sp = lkpsym(temp, 1);
- sp->s_addr = ap->a_size;
- sp->s_axp = NULL;
- sp->s_type |= S_DEF;
+ *temp = 'l';
+ sp = lkpsym(temp, 1);
+ sp->s_addr = ap->a_size;
+ sp->s_axp = NULL;
+ sp->s_type |= S_DEF;
if (!strcmp(ap->a_id, "DSEG")) sp_dseg_l=sp;
- }
-
- /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
- to compute the byte size of BSEG_BYTES: */
- if (!strcmp(ap->a_id, "BSEG"))
+ }
+
+ /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
+ to compute the byte size of BSEG_BYTES: */
+ if (!strcmp(ap->a_id, "BSEG"))
{
- ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
- }
+ ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
+ }
else if (!strcmp(ap->a_id, "DSEG"))
{
dseg_ap=ap; /*Need it later to set its correct size*/
}
- ap = ap->a_ap;
- }
+ ap = ap->a_ap;
+ }
/*Compute the size of DSEG*/
- if(dseg_ap!=NULL)
- {
- dseg_ap->a_addr=0;
- dseg_ap->a_size=0;
- for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++;
- }
+ if(dseg_ap!=NULL)
+ {
+ dseg_ap->a_addr=0;
+ dseg_ap->a_size=0;
+ for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++;
+ }
if(sp_dseg_s!=NULL) sp_dseg_s->s_addr=0;
if(sp_dseg_l!=NULL) sp_dseg_l->s_addr=dseg_ap->a_size;
#if 0
/*Print the memory map*/
- fprintf(stderr, "Internal RAM layout:\n"
+ fprintf(stderr, "Internal RAM layout:\n"
" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for(j=0; j<256; j++)
- {
- if(j%16==0) fprintf(stderr, "\n0x%02x:|", j);
- fprintf(stderr, "%c|", idatamap[j]);
- }
- fprintf(stderr, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n");
+ {
+ if(j%16==0) fprintf(stderr, "\n0x%02x:|", j);
+ fprintf(stderr, "%c|", idatamap[j]);
+ }
+ fprintf(stderr, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n");
#endif
}
void lnksect2 (struct area *tap, int rloc)
{
- register Addr_T size, addr;
- register struct areax *taxp;
- int j, k, ramlimit;
+ register Addr_T size, addr;
+ register struct areax *taxp;
+ int j, k, ramlimit;
char fchar, dchar='a';
- char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s"
+ char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s"
" in internal RAM for area %s.\n";
tap->a_unaloc=0;
-
+
/*Notice that only ISEG and SSEG can be in the indirectly addressable internal RAM*/
if( (!strcmp(tap->a_id, "ISEG")) || (!strcmp(tap->a_id, "SSEG")) )
{
}
else
{
- ramlimit=0x80;
+ if((iram_size<=0)||(iram_size>0x80))
+ ramlimit=0x80;
+ else
+ ramlimit=iram_size;
}
- size = 0;
- addr = tap->a_addr;
- if ((tap->a_flag&A_PAG) && (addr & 0xFF))
+ size = 0;
+ addr = tap->a_addr;
+#if 0
+ if ((tap->a_flag&A_PAG) && (addr & 0xFF))
{
- fprintf(stderr,
- "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
- lkerr++;
- }
- taxp = tap->a_axp;
+ fprintf(stderr,
+ "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
+ lkerr++;
+ }
+#endif
+ taxp = tap->a_axp;
/*Use a letter to identify each area in the internal RAM layout map*/
if(rloc==0)
{
/**/ if(!strcmp(tap->a_id, "DSEG"))
- fchar='D'; /*It will be converted to letters 'a' to 'z' latter for each areax*/
+ fchar='D'; /*It will be converted to letters 'a' to 'z' later for each areax*/
else if(!strcmp(tap->a_id, "ISEG"))
fchar='I';
else if(!strcmp(tap->a_id, "SSEG"))
fchar=' ';
}
- if (tap->a_flag&A_OVR) /* Overlayed sections */
+ if (tap->a_flag&A_OVR) /* Overlayed sections */
{
while (taxp)
{
stacksize=taxp->a_size;
}
- /*If more space required, release the previously allocated areax in
+ /*If more space required, release the previously allocated areax in
internal RAM and search for a bigger one*/
if((int)taxp->a_size>size)
{
for(j=0; j<ramlimit; j++)
if(idatamap[j]==fchar) idatamap[j]=' ';
-
+
/*Search for a space large enough in data memory for this overlay areax*/
for(j=0, k=0; j<ramlimit; j++)
{
if(j>=0) addr=j+1;
}
}
-
+
/*Mark the memory used for overlay*/
if(k==(int)taxp->a_size)
{
lkerr++;
}
}
-
+
for(j=0; j<ramlimit; j++)
{
if (idatamap[j]==fchar)
{
addr=j;
tap->a_addr=addr;
- taxp->a_addr=addr;
+ taxp->a_addr=addr;
break;
}
}
}
else /*Overlay areas not in internal ram*/
{
- taxp->a_addr = addr;
- if (taxp->a_size > size) size = taxp->a_size;
+ taxp->a_addr = addr;
+ if (taxp->a_size > size) size = taxp->a_size;
}
taxp = taxp->a_axp;
- }
- }
+ }
+ }
else /* Concatenated sections */
{
- while (taxp)
+ while (taxp)
{
- if( (fchar=='D') || (fchar=='I') )
- {
+ if( (fchar=='D') || (fchar=='I') )
+ {
if(taxp->a_size)
{
/*Search for a space large enough in internal RAM for this areax*/
if(j>=0) addr=j+1;
size=ramlimit-addr;
}
-
+
for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
idatamap[j]=(fchar=='D')?dchar:fchar;
if((taxp->a_size>0)&&(fchar=='D'))dchar++;
{
taxp->a_addr = addr;
addr += taxp->a_size;
- size += taxp->a_size;
+ size += taxp->a_size;
tap->a_unaloc+=taxp->a_size;
fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
lkerr++;
}
}
- taxp = taxp->a_axp;
- }
+ taxp = taxp->a_axp;
+ }
else if(fchar=='B')
{
if(taxp->a_size!=0)
idatamap[j]=fchar;
}
- taxp->a_addr = addr;
- addr += taxp->a_size;
- size += taxp->a_size;
- taxp = taxp->a_axp;
+ taxp->a_addr = addr;
+ addr += taxp->a_size;
+ size += taxp->a_size;
+ taxp = taxp->a_axp;
}
else /*For concatenated BIT, CODE, and XRAM areax's*/
{
- taxp->a_addr = addr;
- addr += taxp->a_size;
- size += taxp->a_size;
- taxp = taxp->a_axp;
+ if(!strcmp(tap->a_id, "XSTK") && (taxp->a_size == 1))
+ {
+ taxp->a_size = 256-(addr & 0xFF);
+ }
+ taxp->a_addr = addr;
+ addr += taxp->a_size;
+ size += taxp->a_size;
+ taxp = taxp->a_axp;
}
- }
- }
- tap->a_size = size;
-
- if ((tap->a_flag&A_PAG) && (size > 256))
- {
- fprintf(stderr,
- "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
- lkerr++;
- }
+ }
+ }
+ tap->a_size = size;
+
+ if ((tap->a_flag&A_PAG) && (size > 256))
+ {
+ fprintf(stderr,
+ "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
+ lkerr++;
+ }
+ if ((tap->a_flag&A_PAG) && (tap->a_size) &&
+ ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
+ {
+ fprintf(stderr,
+ "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
+ lkerr++;
+ }
}
*
* 31-Oct-97 JLH:
* - add jflag and jfp to control NoICE output file genration
- * 3-Nov-97 JLH:
+ * 3-Nov-97 JLH:
* - use a_type == 0 as "virgin area" flag: set == 1 if -b
*/
void Timer(int action, char * message)
{
- static double start, end, total=0.0;
+ static double start, end, total=0.0;
static const double secs_per_tick = 1.0 / CLOCKS_PER_SEC;
if(action==0) start=clock()*secs_per_tick;
else if(action==1)
{
- end=clock() * secs_per_tick;
- printf("%s \t%f seconds.\n", message, (end-start));
- total+=end-start;
+ end=clock() * secs_per_tick;
+ printf("%s \t%f seconds.\n", message, (end-start));
+ total+=end-start;
}
else
{
- printf("Total time: \t%f seconds.\n", total);
- total=0.0;
+ printf("Total time: \t%f seconds.\n", total);
+ total=0.0;
}
}
#endif
*/
extern int unlink(const char *);
-/*)Module lkmain.c
- *
- * The module lkmain.c contains the functions which
- * (1) input the linker options, parameters, and specifications
- * (2) perform a two pass link
- * (3) produce the appropriate linked data output and/or
- * link map file and/or relocated listing files.
- *
- * lkmain.c contains the following functions:
- * FILE * afile(fn,ft,wf)
- * VOID bassav()
- * VOID gblsav()
- * VOID link_main()
- * VOID lkexit()
- * VOID main(argc,argv)
- * VOID map()
- * int parse()
- * VOID setbas()
- * VOID setgbl()
- * VOID usage()
- *
- * lkmain.c contains the following local variables:
- * char * usetext[] array of pointers to the
- * command option tect lines
+/*)Module lkmain.c
+ *
+ * The module lkmain.c contains the functions which
+ * (1) input the linker options, parameters, and specifications
+ * (2) perform a two pass link
+ * (3) produce the appropriate linked data output and/or
+ * link map file and/or relocated listing files.
+ *
+ * lkmain.c contains the following functions:
+ * FILE * afile(fn,ft,wf)
+ * VOID bassav()
+ * VOID gblsav()
+ * VOID link_main()
+ * VOID lkexit()
+ * VOID main(argc,argv)
+ * VOID map()
+ * int parse()
+ * VOID setbas()
+ * VOID setgbl()
+ * VOID usage()
+ *
+ * lkmain.c contains the following local variables:
+ * char * usetext[] array of pointers to the
+ * command option tect lines
*
*/
-/*JCF: Creates some of the default areas so they are allocated in the right order.*/
+/*JCF: Creates some of the default areas so they are allocated in the right order.*/
void Areas51 (void)
{
- char * rel[]={
- "XH",
- "H 7 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_2 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()*/
- ""
- };
-
+ char * rel[]={
+ "XH",
+ "H 7 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_2 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()*/
+ ""
+ };
+
char * rel2[]={
- "XH",
- "H B 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_2 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 DSEG size 0 flags 0",
- "A OSEG size 0 flags 4",
- "A ISEG size 0 flags 0",
- "A SSEG size 0 flags 4",
- ""
- };
- int j;
+ "XH",
+ "H B 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_2 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 DSEG size 0 flags 0",
+ "A OSEG size 0 flags 4",
+ "A ISEG size 0 flags 0",
+ "A SSEG size 0 flags 4",
+ ""
+ };
+ int j;
+ struct sym * sp;
if(packflag)
{
- for (j=0; rel2[j][0]!=0; j++)
- {
- ip=rel2[j];
- link_main();
- }
+ for (j=0; rel2[j][0]!=0; j++)
+ {
+ ip=rel2[j];
+ link_main();
+ }
}
else
{
- for (j=0; rel[j][0]!=0; j++)
- {
- ip=rel[j];
- link_main();
- }
+ for (j=0; rel[j][0]!=0; j++)
+ {
+ ip=rel[j];
+ link_main();
+ }
}
-
- /*Set the start address of the default areas:*/
- for(ap=areap; ap; ap=ap->a_ap)
- {
- /**/ if (!strcmp(ap->a_id, "REG_BANK_0")) { ap->a_addr=0x00; ap->a_type=1; }
- else if (!strcmp(ap->a_id, "REG_BANK_1")) { ap->a_addr=0x08; ap->a_type=1; }
- else if (!strcmp(ap->a_id, "REG_BANK_2")) { ap->a_addr=0x10; ap->a_type=1; }
- else if (!strcmp(ap->a_id, "REG_BANK_3")) { ap->a_addr=0x18; ap->a_type=1; }
- else if (!strcmp(ap->a_id, "BSEG_BYTES")) { ap->a_addr=0x20; ap->a_type=1; }
- else if (!strcmp(ap->a_id, "SSEG"))
+
+ /*Set the start address of the default areas:*/
+ for(ap=areap; ap; ap=ap->a_ap)
+ {
+ /**/ if (!strcmp(ap->a_id, "REG_BANK_0")) { ap->a_addr=0x00; ap->a_type=1; }
+ else if (!strcmp(ap->a_id, "REG_BANK_1")) { ap->a_addr=0x08; ap->a_type=1; }
+ else if (!strcmp(ap->a_id, "REG_BANK_2")) { ap->a_addr=0x10; ap->a_type=1; }
+ else if (!strcmp(ap->a_id, "REG_BANK_3")) { ap->a_addr=0x18; ap->a_type=1; }
+ else if (!strcmp(ap->a_id, "BSEG_BYTES")) { ap->a_addr=0x20; ap->a_type=1; }
+ else if (!strcmp(ap->a_id, "SSEG"))
{
if(stacksize) ap->a_axp->a_size=stacksize;
}
- }
+ }
+
+ sp = lkpsym("l_IRAM", 1);
+ sp->s_addr = ((iram_size>0) && (iram_size<=0x100)) ? iram_size : 0x0100;
+ sp->s_axp = NULL;
+ sp->s_type |= S_DEF;
}
-/*)Function VOID main(argc,argv)
- *
- * int argc number of command line arguments + 1
- * char * argv[] array of pointers to the command line
- * arguments
- *
- * The function main() evaluates the command line arguments to
- * determine if the linker parameters are to input through 'stdin'
- * or read from a command file. The functiond getline() and parse()
- * are to input and evaluate the linker parameters. The linking process
- * proceeds by making the first pass through each .rel file in the order
- * presented to the linker. At the end of the first pass the setbase(),
- * lnkarea(), setgbl(), and symdef() functions are called to evaluate
- * the base address terms, link all areas, define global variables,
- * and look for undefined symbols. Following these routines a linker
- * map file may be produced and the linker output files may be opened.
- * The second pass through the .rel files will output the linked data
- * in one of the four supported formats.
- *
- * local variables:
- * char * p pointer to an argument string
- * int c character from argument string
- * int i loop counter
- *
- * global variables:
- * text line in ib[]
- * lfile *cfp The pointer *cfp points to the
- * current lfile structure
- * char ctype[] array of character types, one per
- * ASCII character
- * lfile *filep The pointer *filep points to the
- * beginning of a linked list of
- * lfile structures.
- * head *hp Pointer to the current
- * head structure
- * char ib[NINPUT] .rel file text line
- * char *ip pointer into the .rel file
- * lfile *linkp pointer to first lfile structure
- * containing an input .rel file
- * specification
- * int lkerr error flag
- * int mflag Map output flag
- * int oflag Output file type flag
- * FILE *ofp Output file handle
- * for word formats
- * FILE *ofph Output file handle
- * for high byte format
- * FILE *ofpl Output file handle
- * for low byte format
- * int pass linker pass number
- * int pflag print linker command file flag
- * int radix current number conversion radix
- * FILE *sfp The file handle sfp points to the
- * currently open file
- * lfile *startp asmlnk startup file structure
- * FILE * stdin c_library
- * FILE * stdout c_library
- *
- * functions called:
- * FILE * afile() lkmain.c
- * int fclose() c_library
- * int fprintf() c_library
- * int getline() lklex.c
- * VOID library() lklibr.c
- * VOID link_main() lkmain.c
- * VOID lkexit() lkmain.c
- * VOID lnkarea() lkarea.c
- * VOID map() lkmain.c
- * VOID new() lksym.c
- * int parse() lkmain.c
- * VOID reloc() lkreloc.c
- * VOID search() lklibr.c
- * VOID setbas() lkmain.c
- * VOID setgbl() lkmain.c
- * VOID symdef() lksym.c
- * VOID usage() lkmain.c
- *
- * side effects:
- * Completion of main() completes the linking process
- * and may produce a map file (.map) and/or a linked
- * data files (.ihx or .s19) and/or one or more
- * relocated listing files (.rst).
+/*)Function VOID main(argc,argv)
+ *
+ * int argc number of command line arguments + 1
+ * char * argv[] array of pointers to the command line
+ * arguments
+ *
+ * The function main() evaluates the command line arguments to
+ * determine if the linker parameters are to input through 'stdin'
+ * or read from a command file. The functiond getline() and parse()
+ * are to input and evaluate the linker parameters. The linking process
+ * proceeds by making the first pass through each .rel file in the order
+ * presented to the linker. At the end of the first pass the setbase(),
+ * lnkarea(), setgbl(), and symdef() functions are called to evaluate
+ * the base address terms, link all areas, define global variables,
+ * and look for undefined symbols. Following these routines a linker
+ * map file may be produced and the linker output files may be opened.
+ * The second pass through the .rel files will output the linked data
+ * in one of the four supported formats.
+ *
+ * local variables:
+ * char * p pointer to an argument string
+ * int c character from argument string
+ * int i loop counter
+ *
+ * global variables:
+ * text line in ib[]
+ * lfile *cfp The pointer *cfp points to the
+ * current lfile structure
+ * char ctype[] array of character types, one per
+ * ASCII character
+ * lfile *filep The pointer *filep points to the
+ * beginning of a linked list of
+ * lfile structures.
+ * head *hp Pointer to the current
+ * head structure
+ * char ib[NINPUT] .rel file text line
+ * char *ip pointer into the .rel file
+ * lfile *linkp pointer to first lfile structure
+ * containing an input .rel file
+ * specification
+ * int lkerr error flag
+ * int mflag Map output flag
+ * int oflag Output file type flag
+ * FILE *ofp Output file handle
+ * for word formats
+ * FILE *ofph Output file handle
+ * for high byte format
+ * FILE *ofpl Output file handle
+ * for low byte format
+ * int pass linker pass number
+ * int pflag print linker command file flag
+ * int radix current number conversion radix
+ * FILE *sfp The file handle sfp points to the
+ * currently open file
+ * lfile *startp asmlnk startup file structure
+ * FILE * stdin c_library
+ * FILE * stdout c_library
+ *
+ * functions called:
+ * FILE * afile() lkmain.c
+ * int fclose() c_library
+ * int fprintf() c_library
+ * int getline() lklex.c
+ * VOID library() lklibr.c
+ * VOID link_main() lkmain.c
+ * VOID lkexit() lkmain.c
+ * VOID lnkarea() lkarea.c
+ * VOID map() lkmain.c
+ * VOID new() lksym.c
+ * int parse() lkmain.c
+ * VOID reloc() lkreloc.c
+ * VOID search() lklibr.c
+ * VOID setbas() lkmain.c
+ * VOID setgbl() lkmain.c
+ * VOID symdef() lksym.c
+ * VOID usage() lkmain.c
+ *
+ * side effects:
+ * Completion of main() completes the linking process
+ * and may produce a map file (.map) and/or a linked
+ * data files (.ihx or .s19) and/or one or more
+ * relocated listing files (.rst).
*/
int
-main(argc, argv)
-char *argv[];
+main(int argc, char *argv[])
{
- register char *p;
- register int c, i;
+ register char *p;
+ register int c, i;
#ifdef WIN32T
Timer(0, "");
#endif
- startp = (struct lfile *) new (sizeof (struct lfile));
-
- pflag = 1;
- for (i=1; i<argc; ++i) {
- p = argv[i];
- if (*p == '-') {
- while (ctype[c = *(++p)] & LETTER) {
- switch(c) {
-
- case 'c':
- case 'C':
- startp->f_type = F_STD;
- break;
-
- case 'f':
- case 'F':
- startp->f_type = F_LNK;
- break;
-
- case 'n':
- case 'N':
- pflag = 0;
- break;
-
- case 'p':
- case 'P':
- pflag = 1;
- break;
-
- default:
- usage();
- }
- }
- } else {
- if (startp->f_type == F_LNK) {
- startp->f_idp = p;
- }
- }
- }
- if (startp->f_type == 0)
- usage();
- if (startp->f_type == F_LNK && startp->f_idp == NULL)
- usage();
-
- cfp = NULL;
- sfp = NULL;
- filep = startp;
- while (1) {
- ip = ib;
- if (getline() == 0)
- break;
- if (pflag && sfp != stdin)
- fprintf(stdout, "%s\n", ip);
+ startp = (struct lfile *) new (sizeof (struct lfile));
+
+ pflag = 1;
+ for (i=1; i<argc; ++i) {
+ p = argv[i];
+ if (*p == '-') {
+ while (ctype[c = *(++p)] & LETTER) {
+ switch(c) {
+
+ case 'c':
+ case 'C':
+ startp->f_type = F_STD;
+ break;
+
+ case 'f':
+ case 'F':
+ startp->f_type = F_LNK;
+ break;
+
+ case 'n':
+ case 'N':
+ pflag = 0;
+ break;
+
+ case 'p':
+ case 'P':
+ pflag = 1;
+ break;
+
+ default:
+ usage();
+ }
+ }
+ } else {
+ if (startp->f_type == F_LNK) {
+ startp->f_idp = p;
+ }
+ }
+ }
+ if (startp->f_type == 0)
+ usage();
+ if (startp->f_type == F_LNK && startp->f_idp == NULL)
+ usage();
+
+ cfp = NULL;
+ sfp = NULL;
+ filep = startp;
+ while (1) {
+ ip = ib;
+ if (getline() == 0)
+ break;
+ if (pflag && sfp != stdin)
+ fprintf(stdout, "%s\n", ip);
if (*ip == '\0' || parse())
- break;
- }
-
- if (sfp) {
- fclose(sfp);
- sfp = NULL;
- }
-
- if (linkp == NULL)
- usage();
-
- syminit();
-
- if (dflag){
- //dfp = afile("temp", "cdb", 1);
- SaveLinkedFilePath(linkp->f_idp); //Must be the first one...
- dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002
- if (dfp == NULL)
- lkexit(1);
- }
-
- for (pass=0; pass<2; ++pass) {
- cfp = NULL;
- sfp = NULL;
- filep = linkp;
- hp = NULL;
- radix = 10;
-
- Areas51(); /*JCF: Create the default 8051 areas in the right order*/
-
- while (getline()) {
- ip = ib;
-
- /* pass any "magic comments" to NoICE output */
- if ((ip[0] == ';') && (ip[1] == '!') && jfp) {
- fprintf( jfp, "%s\n", &ip[2] );
- }
- link_main();
- }
- if (pass == 0) {
- /*
- * Search libraries for global symbols
- */
- search();
- /*
- * Set area base addresses.
- */
- setbas();
- /*
- * Link all area addresses.
- */
- if(!packflag)
+ break;
+ }
+
+ if (sfp) {
+ fclose(sfp);
+ sfp = NULL;
+ }
+
+ if (linkp == NULL)
+ usage();
+
+ syminit();
+
+ if (dflag){
+ //dfp = afile("temp", "cdb", 1);
+ SaveLinkedFilePath(linkp->f_idp); //Must be the first one...
+ dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002
+ if (dfp == NULL)
+ lkexit(1);
+ }
+
+ for (pass=0; pass<2; ++pass) {
+ cfp = NULL;
+ sfp = NULL;
+ filep = linkp;
+ hp = NULL;
+ radix = 10;
+
+ Areas51(); /*JCF: Create the default 8051 areas in the right order*/
+
+ while (getline()) {
+ ip = ib;
+
+ /* pass any "magic comments" to NoICE output */
+ if ((ip[0] == ';') && (ip[1] == '!') && jfp) {
+ fprintf( jfp, "%s\n", &ip[2] );
+ }
+ link_main();
+ }
+ if (pass == 0) {
+ /*
+ * Search libraries for global symbols
+ */
+ search();
+ /*
+ * Set area base addresses.
+ */
+ setbas();
+ /*
+ * Link all area addresses.
+ */
+ if(!packflag)
lnkarea();
else
lnkarea2();
- /*
- * Process global definitions.
- */
- setgbl();
- /*
- * Check for undefined globals.
- */
- symdef(stderr);
-
- /* Open NoICE output file if requested */
- if (jflag) {
- jfp = afile(linkp->f_idp, "NOI", 1);
- if (jfp == NULL) {
- lkexit(1);
- }
- }
-
- /*
- * Output Link Map if requested,
- * or if NoICE output requested (since NoICE
- * file is generated in part by map() processing)
- */
- if (mflag || jflag)
- map();
-
- if (sflag) /*JCF: memory usage summary output*/
+ /*
+ * Process global definitions.
+ */
+ setgbl();
+ /*
+ * Check for undefined globals.
+ */
+ symdef(stderr);
+
+ /* Open NoICE output file if requested */
+ if (jflag) {
+ jfp = afile(linkp->f_idp, "NOI", 1);
+ if (jfp == NULL) {
+ lkexit(1);
+ }
+ }
+
+ /*
+ * Output Link Map if requested,
+ * or if NoICE output requested (since NoICE
+ * file is generated in part by map() processing)
+ */
+ if (mflag || jflag)
+ map();
+
+ if (sflag) /*JCF: memory usage summary output*/
{
if(!packflag)
{
- if(summary(areap)) lkexit(1);
+ if(summary(areap)) lkexit(1);
}
else
{
- if(summary2(areap)) lkexit(1);
+ if(summary2(areap)) lkexit(1);
}
}
- if ((iram_size) && (!packflag))
- iramcheck();
-
- /*
- * Open output file
- */
- if (oflag == 1) {
- ofp = afile(linkp->f_idp, "ihx", 1);
- if (ofp == NULL) {
- lkexit(1);
- }
- /* include NoICE command to load hex file */
- if (jfp) fprintf( jfp, "LOAD %s.IHX\n", linkp->f_idp );
-
- } else
- if (oflag == 2) {
- ofp = afile(linkp->f_idp, "S19", 1);
- if (ofp == NULL) {
- lkexit(1);
- }
- /* include NoICE command to load hex file */
- if (jfp) fprintf( jfp, "LOAD %s.S19\n", linkp->f_idp );
- }
- } else {
- /*
- * Link in library files
- */
- library();
- reloc('E');
- }
- }
- //JCF:
- CreateAOMF51();
+ if ((iram_size) && (!packflag))
+ iramcheck();
+
+ /*
+ * Open output file
+ */
+ if (oflag == 1) {
+ ofp = afile(linkp->f_idp, "ihx", 1);
+ if (ofp == NULL) {
+ lkexit(1);
+ }
+ /* include NoICE command to load hex file */
+ if (jfp) fprintf( jfp, "LOAD %s.IHX\n", linkp->f_idp );
+
+ } else
+ if (oflag == 2) {
+ ofp = afile(linkp->f_idp, "S19", 1);
+ if (ofp == NULL) {
+ lkexit(1);
+ }
+ /* include NoICE command to load hex file */
+ if (jfp) fprintf( jfp, "LOAD %s.S19\n", linkp->f_idp );
+ }
+ } else {
+ /*
+ * Link in library files
+ */
+ library();
+ reloc('E');
+ }
+ }
+ //JCF:
+ CreateAOMF51();
#ifdef WIN32T
Timer(1, "Linker execution time");
#endif
- lkexit(lkerr);
- return 0;
+ lkexit(lkerr);
+ return 0;
}
-/*)Function VOID lkexit(i)
+/*)Function VOID lkexit(i)
*
- * int i exit code
+ * int i exit code
*
- * The function lkexit() explicitly closes all open
- * files and then terminates the program.
+ * The function lkexit() explicitly closes all open
+ * files and then terminates the program.
*
- * local variables:
- * none
+ * local variables:
+ * none
*
- * global variables:
- * FILE * mfp file handle for .map
- * FILE * ofp file handle for .ihx/.s19
- * FILE * rfp file hanlde for .rst
- * FILE * sfp file handle for .rel
- * FILE * tfp file handle for .lst
+ * global variables:
+ * FILE * mfp file handle for .map
+ * FILE * ofp file handle for .ihx/.s19
+ * FILE * rfp file hanlde for .rst
+ * FILE * sfp file handle for .rel
+ * FILE * tfp file handle for .lst
*
- * functions called:
- * int fclose() c_library
- * VOID exit() c_library
+ * functions called:
+ * int fclose() c_library
+ * VOID exit() c_library
*
- * side effects:
- * All files closed. Program terminates.
+ * side effects:
+ * All files closed. Program terminates.
*/
VOID
-lkexit(i)
-int i;
+lkexit(int i)
{
- if (mfp != NULL) fclose(mfp);
- if (jfp != NULL) fclose(jfp);
- if (ofp != NULL) fclose(ofp);
- if (rfp != NULL) fclose(rfp);
- if (sfp != NULL) fclose(sfp);
- if (tfp != NULL) fclose(tfp);
- if (dfp != NULL) fclose(dfp);
- /*if (dfp != NULL)
- FILE *xfp = afile(linkp->f_idp,"cdb",1);
- dfp = freopen("temp.cdb","r",dfp);
- copyfile(xfp,dfp);
- fclose(xfp);
- fclose(dfp);
- unlink("temp.cdb");
- }*/
- exit(i);
+ if (mfp != NULL) fclose(mfp);
+ if (jfp != NULL) fclose(jfp);
+ if (ofp != NULL) fclose(ofp);
+ if (rfp != NULL) fclose(rfp);
+ if (sfp != NULL) fclose(sfp);
+ if (tfp != NULL) fclose(tfp);
+ if (dfp != NULL) fclose(dfp);
+ /*if (dfp != NULL)
+ FILE *xfp = afile(linkp->f_idp,"cdb",1);
+ dfp = freopen("temp.cdb","r",dfp);
+ copyfile(xfp,dfp);
+ fclose(xfp);
+ fclose(dfp);
+ unlink("temp.cdb");
+ }*/
+ exit(i);
}
-/*)Function link_main()
- *
- * The function link_main() evaluates the directives for each line of
- * text read from the .rel file(s). The valid directives processed
- * are:
- * X, D, Q, H, M, A, S, T, R, and P.
- *
- * local variables:
- * int c first non blank character of a line
- *
- * global variables:
- * head *headp The pointer to the first
- * head structure of a linked list
- * head *hp Pointer to the current
- * head structure
- * int pass linker pass number
- * int radix current number conversion radix
- *
- * functions called:
- * char endline() lklex.c
- * VOID module() lkhead.c
- * VOID newarea() lkarea.c
- * VOID newhead() lkhead.c
- * sym * newsym() lksym.c
- * VOID reloc() lkreloc.c
- *
- * side effects:
- * Head, area, and symbol structures are created and
- * the radix is set as the .rel file(s) are read.
+/*)Function link_main()
+ *
+ * The function link_main() evaluates the directives for each line of
+ * text read from the .rel file(s). The valid directives processed
+ * are:
+ * X, D, Q, H, M, A, S, T, R, and P.
+ *
+ * local variables:
+ * int c first non blank character of a line
+ *
+ * global variables:
+ * head *headp The pointer to the first
+ * head structure of a linked list
+ * head *hp Pointer to the current
+ * head structure
+ * int pass linker pass number
+ * int radix current number conversion radix
+ *
+ * functions called:
+ * char endline() lklex.c
+ * VOID module() lkhead.c
+ * VOID newarea() lkarea.c
+ * VOID newhead() lkhead.c
+ * sym * newsym() lksym.c
+ * VOID reloc() lkreloc.c
+ *
+ * side effects:
+ * Head, area, and symbol structures are created and
+ * the radix is set as the .rel file(s) are read.
*/
VOID
link_main()
{
- register int c;
+ register int c;
- if ((c=endline()) == 0) { return; }
- switch (c) {
+ if ((c=endline()) == 0) { return; }
+ switch (c) {
case 'O': /*For some important sdcc options*/
if (pass == 0)
{
if(strcmp(sdccopt, &ip[1])!=0)
{
- fprintf(stderr,
- "?ASlink-Warning-Conflicting sdcc options:\n"
+ fprintf(stderr,
+ "?ASlink-Warning-Conflicting sdcc options:\n"
" \"%s\" in module \"%s\" and\n"
" \"%s\" in module \"%s\".\n",
sdccopt, sdccopt_module, &ip[1], curr_module);
- lkerr++;
+ lkerr++;
}
}
}
- break;
-
- case 'X':
- radix = 16;
- break;
-
- case 'D':
- radix = 10;
- break;
-
- case 'Q':
- radix = 8;
- break;
-
- case 'H':
- if (pass == 0) {
- newhead();
- } else {
- if (hp == 0) {
- hp = headp;
- } else {
- hp = hp->h_hp;
- }
- }
- sdp.s_area = NULL;
- sdp.s_areax = NULL;
- sdp.s_addr = 0;
- break;
-
- case 'M':
- if (pass == 0)
+ break;
+
+ case 'X':
+ radix = 16;
+ break;
+
+ case 'D':
+ radix = 10;
+ break;
+
+ case 'Q':
+ radix = 8;
+ break;
+
+ case 'H':
+ if (pass == 0) {
+ newhead();
+ } else {
+ if (hp == 0) {
+ hp = headp;
+ } else {
+ hp = hp->h_hp;
+ }
+ }
+ sdp.s_area = NULL;
+ sdp.s_areax = NULL;
+ sdp.s_addr = 0;
+ break;
+
+ case 'M':
+ if (pass == 0)
{
strcpy(curr_module, &ip[1]);
- module();
+ module();
+ }
+ break;
+
+ case 'A':
+ if (pass == 0)
+ newarea();
+ if (sdp.s_area == NULL) {
+ sdp.s_area = areap;
+ sdp.s_areax = areap->a_axp;
+ sdp.s_addr = 0;
+ }
+ break;
+
+ case 'S':
+ if (pass == 0)
+ newsym();
+ break;
+
+ case 'T':
+ case 'R':
+ case 'P':
+ if (pass == 0)
+ break;
+ reloc(c);
+ break;
+
+ default:
+ break;
+ }
+ if (c == 'X' || c == 'D' || c == 'Q') {
+ if ((c = get()) == 'H') {
+ hilo = 1;
+ } else
+ if (c == 'L') {
+ hilo = 0;
}
- break;
-
- case 'A':
- if (pass == 0)
- newarea();
- if (sdp.s_area == NULL) {
- sdp.s_area = areap;
- sdp.s_areax = areap->a_axp;
- sdp.s_addr = 0;
- }
- break;
-
- case 'S':
- if (pass == 0)
- newsym();
- break;
-
- case 'T':
- case 'R':
- case 'P':
- if (pass == 0)
- break;
- reloc(c);
- break;
-
- default:
- break;
- }
- if (c == 'X' || c == 'D' || c == 'Q') {
- if ((c = get()) == 'H') {
- hilo = 1;
- } else
- if (c == 'L') {
- hilo = 0;
- }
- }
+ }
}
-/*)Function VOID map()
- *
- * The function map() opens the output map file and calls the various
- * routines to
- * (1) output the variables in each area,
- * (2) list the files processed with module names,
- * (3) list the libraries file processed,
- * (4) list base address definitions,
- * (5) list global variable definitions, and
- * (6) list any undefined variables.
- *
- * local variables:
- * int i counter
- * head * hdp pointer to head structure
- * lbfile *lbfh pointer to library file structure
- *
- * global variables:
- * area *ap Pointer to the current
- * area structure
- * area *areap The pointer to the first
- * area structure of a linked list
- * base *basep The pointer to the first
- * base structure
- * base *bsp Pointer to the current
- * base structure
- * lfile *filep The pointer *filep points to the
- * beginning of a linked list of
- * lfile structures.
- * globl *globlp The pointer to the first
- * globl structure
- * globl *gsp Pointer to the current
- * globl structure
- * head *headp The pointer to the first
- * head structure of a linked list
- * lbfile *lbfhead The pointer to the first
- * lbfile structure of a linked list
- * lfile *linkp pointer to first lfile structure
- * containing an input REL file
- * specification
- * int lop current line number on page
- * FILE *mfp Map output file handle
- * int page current page number
- *
- * functions called:
- * FILE * afile() lkmain.c
- * int fprintf() c_library
- * VOID lkexit() lkmain.c
- * VOID lstarea() lklist.c
- * VOID newpag() lklist.c
- * VOID symdef() lksym.c
- *
- * side effects:
- * The map file is created.
+/*)Function VOID map()
+ *
+ * The function map() opens the output map file and calls the various
+ * routines to
+ * (1) output the variables in each area,
+ * (2) list the files processed with module names,
+ * (3) list the libraries file processed,
+ * (4) list base address definitions,
+ * (5) list global variable definitions, and
+ * (6) list any undefined variables.
+ *
+ * local variables:
+ * int i counter
+ * head * hdp pointer to head structure
+ * lbfile *lbfh pointer to library file structure
+ *
+ * global variables:
+ * area *ap Pointer to the current
+ * area structure
+ * area *areap The pointer to the first
+ * area structure of a linked list
+ * base *basep The pointer to the first
+ * base structure
+ * base *bsp Pointer to the current
+ * base structure
+ * lfile *filep The pointer *filep points to the
+ * beginning of a linked list of
+ * lfile structures.
+ * globl *globlp The pointer to the first
+ * globl structure
+ * globl *gsp Pointer to the current
+ * globl structure
+ * head *headp The pointer to the first
+ * head structure of a linked list
+ * lbfile *lbfhead The pointer to the first
+ * lbfile structure of a linked list
+ * lfile *linkp pointer to first lfile structure
+ * containing an input REL file
+ * specification
+ * int lop current line number on page
+ * FILE *mfp Map output file handle
+ * int page current page number
+ *
+ * functions called:
+ * FILE * afile() lkmain.c
+ * int fprintf() c_library
+ * VOID lkexit() lkmain.c
+ * VOID lstarea() lklist.c
+ * VOID newpag() lklist.c
+ * VOID symdef() lksym.c
+ *
+ * side effects:
+ * The map file is created.
*/
VOID
map()
{
- register int i;
- register struct head *hdp;
- register struct lbfile *lbfh;
-
- /*
- * Open Map File
- */
- mfp = afile(linkp->f_idp, "map", 1);
- if (mfp == NULL) {
- lkexit(1);
- }
-
- /*
- * Output Map Area Lists
- */
- page = 0;
- lop = NLPP;
- ap = areap;
- while (ap) {
- lstarea(ap);
- ap = ap->a_ap;
- }
- /*
- * List Linked Files
- */
- newpag(mfp);
- fprintf(mfp, "\nFiles Linked [ module(s) ]\n\n");
- hdp = headp;
- filep = linkp;
- while (filep) {
- fprintf(mfp, "%-16s", filep->f_idp);
- i = 0;
- while ((hdp != NULL) && (hdp->h_lfile == filep)) {
- if (i % 5) {
- fprintf(mfp, ", %8.8s", hdp->m_id);
- } else {
- if (i) {
- fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id);
- } else {
- fprintf(mfp, " [ %8.8s", hdp->m_id);
- }
- }
- hdp = hdp->h_hp;
- i++;
- }
- if (i)
- fprintf(mfp, " ]");
- fprintf(mfp, "\n");
- filep = filep->f_flp;
- }
- /*
- * List Linked Libraries
- */
- if (lbfhead != NULL) {
- fprintf(mfp,
- "\nLibraries Linked [ object file ]\n\n");
- for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) {
- fprintf(mfp, "%-32s [ %16.16s ]\n",
- lbfh->libspc, lbfh->relfil);
- }
- fprintf(mfp, "\n");
- }
- /*
- * List Base Address Definitions
- */
- if (basep) {
- newpag(mfp);
- fprintf(mfp, "\nUser Base Address Definitions\n\n");
- bsp = basep;
- while (bsp) {
- fprintf(mfp, "%s\n", bsp->b_strp);
- bsp = bsp->b_base;
- }
- }
- /*
- * List Global Definitions
- */
- if (globlp) {
- newpag(mfp);
- fprintf(mfp, "\nUser Global Definitions\n\n");
- gsp = globlp;
- while (gsp) {
- fprintf(mfp, "%s\n", gsp->g_strp);
- gsp = gsp->g_globl;
- }
- }
- fprintf(mfp, "\n\f");
- symdef(mfp);
+ register int i;
+ register struct head *hdp;
+ register struct lbfile *lbfh;
+
+ /*
+ * Open Map File
+ */
+ mfp = afile(linkp->f_idp, "map", 1);
+ if (mfp == NULL) {
+ lkexit(1);
+ }
+
+ /*
+ * Output Map Area Lists
+ */
+ page = 0;
+ lop = NLPP;
+ ap = areap;
+ while (ap) {
+ lstarea(ap);
+ ap = ap->a_ap;
+ }
+ /*
+ * List Linked Files
+ */
+ newpag(mfp);
+ fprintf(mfp, "\nFiles Linked [ module(s) ]\n\n");
+ hdp = headp;
+ filep = linkp;
+ while (filep) {
+ fprintf(mfp, "%-16s", filep->f_idp);
+ i = 0;
+ while ((hdp != NULL) && (hdp->h_lfile == filep)) {
+ if (i % 5) {
+ fprintf(mfp, ", %8.8s", hdp->m_id);
+ } else {
+ if (i) {
+ fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id);
+ } else {
+ fprintf(mfp, " [ %8.8s", hdp->m_id);
+ }
+ }
+ hdp = hdp->h_hp;
+ i++;
+ }
+ if (i)
+ fprintf(mfp, " ]");
+ fprintf(mfp, "\n");
+ filep = filep->f_flp;
+ }
+ /*
+ * List Linked Libraries
+ */
+ if (lbfhead != NULL) {
+ fprintf(mfp,
+ "\nLibraries Linked [ object file ]\n\n");
+ for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) {
+ fprintf(mfp, "%-32s [ %16.16s ]\n",
+ lbfh->libspc, lbfh->relfil);
+ }
+ fprintf(mfp, "\n");
+ }
+ /*
+ * List Base Address Definitions
+ */
+ if (basep) {
+ newpag(mfp);
+ fprintf(mfp, "\nUser Base Address Definitions\n\n");
+ bsp = basep;
+ while (bsp) {
+ fprintf(mfp, "%s\n", bsp->b_strp);
+ bsp = bsp->b_base;
+ }
+ }
+ /*
+ * List Global Definitions
+ */
+ if (globlp) {
+ newpag(mfp);
+ fprintf(mfp, "\nUser Global Definitions\n\n");
+ gsp = globlp;
+ while (gsp) {
+ fprintf(mfp, "%s\n", gsp->g_strp);
+ gsp = gsp->g_globl;
+ }
+ }
+ fprintf(mfp, "\n\f");
+ symdef(mfp);
}
-/*)Function int parse()
- *
- * The function parse() evaluates all command line or file input
- * linker directives and updates the appropriate variables.
- *
- * local variables:
- * int c character value
- * char fid[] file id string
- *
- * global variables:
- * char ctype[] array of character types, one per
- * ASCII character
- * lfile *lfp pointer to current lfile structure
- * being processed by parse()
- * lfile *linkp pointer to first lfile structure
- * containing an input REL file
- * specification
- * int mflag Map output flag
- * int oflag Output file type flag
- * int pflag print linker command file flag
- * FILE * stderr c_library
- * int uflag Relocated listing flag
- * int xflag Map file radix type flag
- *
- * Functions called:
- * VOID addlib() lklibr.c
- * VOID addpath() lklibr.c
- * VOID bassav() lkmain.c
- * int fprintf() c_library
- * VOID gblsav() lkmain.c
- * VOID getfid() lklex.c
- * char getnb() lklex.c
- * VOID lkexit() lkmain.c
- * char * strcpy() c_library
- * int strlen() c_library
- *
- * side effects:
- * Various linker flags are updated and the linked
- * structure lfile is created.
+/*)Function int parse()
+ *
+ * The function parse() evaluates all command line or file input
+ * linker directives and updates the appropriate variables.
+ *
+ * local variables:
+ * int c character value
+ * char fid[] file id string
+ *
+ * global variables:
+ * char ctype[] array of character types, one per
+ * ASCII character
+ * lfile *lfp pointer to current lfile structure
+ * being processed by parse()
+ * lfile *linkp pointer to first lfile structure
+ * containing an input REL file
+ * specification
+ * int mflag Map output flag
+ * int oflag Output file type flag
+ * int pflag print linker command file flag
+ * FILE * stderr c_library
+ * int uflag Relocated listing flag
+ * int xflag Map file radix type flag
+ *
+ * Functions called:
+ * VOID addlib() lklibr.c
+ * VOID addpath() lklibr.c
+ * VOID bassav() lkmain.c
+ * int fprintf() c_library
+ * VOID gblsav() lkmain.c
+ * VOID getfid() lklex.c
+ * char getnb() lklex.c
+ * VOID lkexit() lkmain.c
+ * char * strcpy() c_library
+ * int strlen() c_library
+ *
+ * side effects:
+ * Various linker flags are updated and the linked
+ * structure lfile is created.
*/
int
parse()
{
- register int c;
- char fid[NINPUT];
-
- while ((c = getnb()) != 0) {
- if ( c == ';')
- return(0);
- if ( c == '-') {
- while (ctype[c=get()] & LETTER) {
- switch(c) {
-
- case 'i':
- case 'I':
- oflag = 1;
- break;
-
- case 's':
- case 'S':
- oflag = 2;
- break;
-
- case 'm':
- case 'M':
- ++mflag;
- break;
-
- case 'y': /*JCF: memory usage summary output*/
- ++sflag;
- break;
+ register int c;
+ char fid[NINPUT];
+
+ while ((c = getnb()) != 0) {
+ if ( c == ';')
+ return(0);
+ if ( c == '-') {
+ while (ctype[c=get()] & LETTER) {
+ switch(c) {
+
+ case 'i':
+ case 'I':
+ oflag = 1;
+ break;
+
+ case 's':
+ case 'S':
+ oflag = 2;
+ break;
+
+ case 'm':
+ case 'M':
+ ++mflag;
+ break;
+
+ case 'y': /*JCF: memory usage summary output*/
+ ++sflag;
+ break;
case 'Y':
unget(getnb());
if(stacksize>256) stacksize=256;
else if(stacksize<0) stacksize=0;
}
- return(0);
-
- case 'j':
- case 'J':
- jflag = 1;
- break;
-
- case 'u':
- case 'U':
- uflag = 1;
- break;
- case 'r':
- case 'R':
- rflag = 1;
- break;
- case 'x':
- case 'X':
- xflag = 0;
- break;
-
- case 'q':
- case 'Q':
- xflag = 1;
- break;
-
- case 'd':
- case 'D':
- xflag = 2;
- break;
-
- case 'e':
- case 'E':
- return(1);
-
- case 'n':
- case 'N':
- pflag = 0;
- break;
-
- case 'p':
- case 'P':
- pflag = 1;
- break;
-
- case 'b':
- case 'B':
- bassav();
- return(0);
-
- case 'g':
- case 'G':
- gblsav();
- return(0);
-
- case 'k':
- case 'K':
- addpath();
- return(0);
-
- case 'l':
- case 'L':
- addlib();
- return(0);
-
- case 'a':
- iramsav();
- return(0);
-
- case 'v':
- case 'V':
- xramsav();
- return(0);
-
- case 'w':
- case 'W':
- codesav();
- return(0);
-
- case 'z':
+ return(0);
+
+ case 'j':
+ case 'J':
+ jflag = 1;
+ break;
+
+ case 'u':
+ case 'U':
+ uflag = 1;
+ break;
+ case 'r':
+ case 'R':
+ rflag = 1;
+ break;
+ case 'x':
+ case 'X':
+ xflag = 0;
+ break;
+
+ case 'q':
+ case 'Q':
+ xflag = 1;
+ break;
+
+ case 'd':
+ case 'D':
+ xflag = 2;
+ break;
+
+ case 'e':
+ case 'E':
+ return(1);
+
+ case 'n':
+ case 'N':
+ pflag = 0;
+ break;
+
+ case 'p':
+ case 'P':
+ pflag = 1;
+ break;
+
+ case 'b':
+ case 'B':
+ bassav();
+ return(0);
+
+ case 'g':
+ case 'G':
+ gblsav();
+ return(0);
+
+ case 'k':
+ case 'K':
+ addpath();
+ return(0);
+
+ case 'l':
+ case 'L':
+ addlib();
+ return(0);
+
+ case 'a':
+ iramsav();
+ return(0);
+
+ case 'v':
+ case 'V':
+ xramsav();
+ return(0);
+
+ case 'w':
+ case 'W':
+ codesav();
+ return(0);
+
+ case 'z':
case 'Z':
- dflag = 1;
- return(0);
- default:
- fprintf(stderr, "Invalid option\n");
- lkexit(1);
- }
- }
- if ( c == ';')
- return(0);
- } else
+ dflag = 1;
+ return(0);
+ default:
+ fprintf(stderr, "Invalid option\n");
+ lkexit(1);
+ }
+ }
+ if ( c == ';')
+ return(0);
+ } else
if (ctype[c] & ILL) {
fprintf(stderr, "Invalid input");
lkexit(1);
} else {
- if (linkp == NULL) {
- linkp = (struct lfile *)
- new (sizeof (struct lfile));
- lfp = linkp;
- } else {
- lfp->f_flp = (struct lfile *)
- new (sizeof (struct lfile));
- lfp = lfp->f_flp;
- }
- getfid(fid, c);
- lfp->f_idp = (char *) new (strlen(fid)+1);
- strcpy(lfp->f_idp, fid);
- lfp->f_type = F_REL;
- }
- }
- return(0);
+ if (linkp == NULL) {
+ linkp = (struct lfile *)
+ new (sizeof (struct lfile));
+ lfp = linkp;
+ } else {
+ lfp->f_flp = (struct lfile *)
+ new (sizeof (struct lfile));
+ lfp = lfp->f_flp;
+ }
+ getfid(fid, c);
+ lfp->f_idp = (char *) new (strlen(fid)+1);
+ strcpy(lfp->f_idp, fid);
+ lfp->f_type = F_REL;
+ }
+ }
+ return(0);
}
-/*)Function VOID bassav()
+/*)Function VOID bassav()
*
- * The function bassav() creates a linked structure containing
- * the base address strings input to the linker.
+ * The function bassav() creates a linked structure containing
+ * the base address strings input to the linker.
*
- * local variables:
- * none
+ * local variables:
+ * none
*
- * global variables:
- * base *basep The pointer to the first
- * base structure
- * base *bsp Pointer to the current
- * base structure
- * char *ip pointer into the REL file
- * text line in ib[]
+ * global variables:
+ * base *basep The pointer to the first
+ * base structure
+ * base *bsp Pointer to the current
+ * base structure
+ * char *ip pointer into the REL file
+ * text line in ib[]
*
- * functions called:
- * char getnb() lklex.c
- * VOID * new() lksym.c
- * int strlen() c_library
- * char * strcpy() c_library
- * VOID unget() lklex.c
+ * functions called:
+ * char getnb() lklex.c
+ * VOID * new() lksym.c
+ * int strlen() c_library
+ * char * strcpy() c_library
+ * VOID unget() lklex.c
*
- * side effects:
- * The basep structure is created.
+ * side effects:
+ * The basep structure is created.
*/
VOID
bassav()
{
- if (basep == NULL) {
- basep = (struct base *)
- new (sizeof (struct base));
- bsp = basep;
- } else {
- bsp->b_base = (struct base *)
- new (sizeof (struct base));
- bsp = bsp->b_base;
- }
- unget(getnb());
- bsp->b_strp = (char *) new (strlen(ip)+1);
- strcpy(bsp->b_strp, ip);
+ if (basep == NULL) {
+ basep = (struct base *)
+ new (sizeof (struct base));
+ bsp = basep;
+ } else {
+ bsp->b_base = (struct base *)
+ new (sizeof (struct base));
+ bsp = bsp->b_base;
+ }
+ unget(getnb());
+ bsp->b_strp = (char *) new (strlen(ip)+1);
+ strcpy(bsp->b_strp, ip);
}
-/*)Function VOID setbas()
- *
- * The function setbas() scans the base address lines in hte
- * basep structure, evaluates the arguments, and sets beginning
- * address of the specified areas.
- *
- * local variables:
- * int v expression value
- * char id[] base id string
- *
- * global variables:
- * area *ap Pointer to the current
- * area structure
- * area *areap The pointer to the first
- * area structure of a linked list
- * base *basep The pointer to the first
- * base structure
- * base *bsp Pointer to the current
- * base structure
- * char *ip pointer into the REL file
- * text line in ib[]
- * int lkerr error flag
- *
- * functions called:
- * Addr_T expr() lkeval.c
- * int fprintf() c_library
- * VOID getid() lklex.c
- * char getnb() lklex.c
- * int symeq() lksym.c
- *
- * side effects:
- * The base address of an area is set.
+/*)Function VOID setbas()
+ *
+ * The function setbas() scans the base address lines in the
+ * basep structure, evaluates the arguments, and sets beginning
+ * address of the specified areas.
+ *
+ * local variables:
+ * int v expression value
+ * char id[] base id string
+ *
+ * global variables:
+ * area *ap Pointer to the current
+ * area structure
+ * area *areap The pointer to the first
+ * area structure of a linked list
+ * base *basep The pointer to the first
+ * base structure
+ * base *bsp Pointer to the current
+ * base structure
+ * char *ip pointer into the REL file
+ * text line in ib[]
+ * int lkerr error flag
+ *
+ * functions called:
+ * Addr_T expr() lkeval.c
+ * int fprintf() c_library
+ * VOID getid() lklex.c
+ * char getnb() lklex.c
+ * int symeq() lksym.c
+ *
+ * side effects:
+ * The base address of an area is set.
*/
VOID
setbas()
{
- register int v;
- char id[NCPS];
-
- bsp = basep;
- while (bsp) {
- ip = bsp->b_strp;
- getid(id, -1);
- if (getnb() == '=') {
- v = expr(0);
- for (ap = areap; ap != NULL; ap = ap->a_ap) {
- if (symeq(id, ap->a_id))
- break;
- }
- if (ap == NULL) {
- fprintf(stderr,
- "ASlink-Warning-No definition of area %s\n", id);
- lkerr++;
- } else {
- ap->a_addr = v;
- ap->a_type = 1; /* JLH: value set */
- }
- } else {
- fprintf(stderr, "ASlink-Warning-No '=' in base expression");
- lkerr++;
- }
- bsp = bsp->b_base;
- }
+ register int v;
+ char id[NCPS];
+
+ bsp = basep;
+ while (bsp) {
+ ip = bsp->b_strp;
+ getid(id, -1);
+ if (getnb() == '=') {
+ v = expr(0);
+ for (ap = areap; ap != NULL; ap = ap->a_ap) {
+ if (symeq(id, ap->a_id))
+ break;
+ }
+ if (ap == NULL) {
+ fprintf(stderr,
+ "ASlink-Warning-No definition of area %s\n", id);
+ lkerr++;
+ } else {
+ ap->a_addr = v;
+ ap->a_type = 1; /* JLH: value set */
+ }
+ } else {
+ fprintf(stderr, "ASlink-Warning-No '=' in base expression");
+ lkerr++;
+ }
+ bsp = bsp->b_base;
+ }
}
-/*)Function VOID gblsav()
+/*)Function VOID gblsav()
*
- * The function gblsav() creates a linked structure containing
- * the global variable strings input to the linker.
+ * The function gblsav() creates a linked structure containing
+ * the global variable strings input to the linker.
*
- * local variable:
- * none
+ * local variable:
+ * none
*
- * global variables:
- * globl *globlp The pointer to the first
- * globl structure
- * globl *gsp Pointer to the current
- * globl structure
- * char *ip pointer into the REL file
- * text line in ib[]
- * int lkerr error flag
+ * global variables:
+ * globl *globlp The pointer to the first
+ * globl structure
+ * globl *gsp Pointer to the current
+ * globl structure
+ * char *ip pointer into the REL file
+ * text line in ib[]
+ * int lkerr error flag
*
- * functions called:
- * char getnb() lklex.c
- * VOID * new() lksym.c
- * int strlen() c_library
- * char * strcpy() c_library
- * VOID unget() lklex.c
+ * functions called:
+ * char getnb() lklex.c
+ * VOID * new() lksym.c
+ * int strlen() c_library
+ * char * strcpy() c_library
+ * VOID unget() lklex.c
*
- * side effects:
- * The globlp structure is created.
+ * side effects:
+ * The globlp structure is created.
*/
VOID
gblsav()
{
- if (globlp == NULL) {
- globlp = (struct globl *)
- new (sizeof (struct globl));
- gsp = globlp;
- } else {
- gsp->g_globl = (struct globl *)
- new (sizeof (struct globl));
- gsp = gsp->g_globl;
- }
- unget(getnb());
- gsp->g_strp = (char *) new (strlen(ip)+1);
- strcpy(gsp->g_strp, ip);
+ if (globlp == NULL) {
+ globlp = (struct globl *)
+ new (sizeof (struct globl));
+ gsp = globlp;
+ } else {
+ gsp->g_globl = (struct globl *)
+ new (sizeof (struct globl));
+ gsp = gsp->g_globl;
+ }
+ unget(getnb());
+ gsp->g_strp = (char *) new (strlen(ip)+1);
+ strcpy(gsp->g_strp, ip);
}
-
-/*)Function VOID setgbl()
- *
- * The function setgbl() scans the global variable lines in hte
- * globlp structure, evaluates the arguments, and sets a variable
- * to this value.
- *
- * local variables:
- * int v expression value
- * char id[] base id string
- * sym * sp pointer to a symbol structure
- *
- * global variables:
- * char *ip pointer into the REL file
- * text line in ib[]
- * globl *globlp The pointer to the first
- * globl structure
- * globl *gsp Pointer to the current
- * globl structure
- * FILE * stderr c_library
- * int lkerr error flag
- *
- * functions called:
- * Addr_T expr() lkeval.c
- * int fprintf() c_library
- * VOID getid() lklex.c
- * char getnb() lklex.c
- * sym * lkpsym() lksym.c
- *
- * side effects:
- * The value of a variable is set.
+
+/*)Function VOID setgbl()
+ *
+ * The function setgbl() scans the global variable lines in the
+ * globlp structure, evaluates the arguments, and sets a variable
+ * to this value.
+ *
+ * local variables:
+ * int v expression value
+ * char id[] base id string
+ * sym * sp pointer to a symbol structure
+ *
+ * global variables:
+ * char *ip pointer into the REL file
+ * text line in ib[]
+ * globl *globlp The pointer to the first
+ * globl structure
+ * globl *gsp Pointer to the current
+ * globl structure
+ * FILE * stderr c_library
+ * int lkerr error flag
+ *
+ * functions called:
+ * Addr_T expr() lkeval.c
+ * int fprintf() c_library
+ * VOID getid() lklex.c
+ * char getnb() lklex.c
+ * sym * lkpsym() lksym.c
+ *
+ * side effects:
+ * The value of a variable is set.
*/
VOID
setgbl()
{
- register int v;
- register struct sym *sp;
- char id[NCPS];
-
- gsp = globlp;
- while (gsp) {
- ip = gsp->g_strp;
- getid(id, -1);
- if (getnb() == '=') {
- v = expr(0);
- sp = lkpsym(id, 0);
- if (sp == NULL) {
- fprintf(stderr,
- "No definition of symbol %s\n", id);
- lkerr++;
- } else {
- if (sp->s_flag & S_DEF) {
- fprintf(stderr,
- "Redefinition of symbol %s\n", id);
- lkerr++;
- sp->s_axp = NULL;
- }
- sp->s_addr = v;
- sp->s_type |= S_DEF;
- }
- } else {
- fprintf(stderr, "No '=' in global expression");
- lkerr++;
- }
- gsp = gsp->g_globl;
- }
+ register int v;
+ register struct sym *sp;
+ char id[NCPS];
+
+ gsp = globlp;
+ while (gsp) {
+ ip = gsp->g_strp;
+ getid(id, -1);
+ if (getnb() == '=') {
+ v = expr(0);
+ sp = lkpsym(id, 0);
+ if (sp == NULL) {
+ fprintf(stderr,
+ "No definition of symbol %s\n", id);
+ lkerr++;
+ } else {
+ if (sp->s_flag & S_DEF) {
+ fprintf(stderr,
+ "Redefinition of symbol %s\n", id);
+ lkerr++;
+ sp->s_axp = NULL;
+ }
+ sp->s_addr = v;
+ sp->s_type |= S_DEF;
+ }
+ } else {
+ fprintf(stderr, "No '=' in global expression");
+ lkerr++;
+ }
+ gsp = gsp->g_globl;
+ }
}
-/*)Function FILE * afile(fn,, ft, wf)
+/*)Function FILE * afile(fn,, ft, wf)
*
- * char * fn file specification string
- * char * ft file type string
- * int wf read(0)/write(1) flag
+ * char * fn file specification string
+ * char * ft file type string
+ * int wf read(0)/write(1) flag
*
- * The function afile() opens a file for reading or writing.
- * (1) If the file type specification string ft
- * is not NULL then a file specification is
- * constructed with the file path\name in fn
- * and the extension in ft.
- * (2) If the file type specification string ft
- * is NULL then the file specification is
- * constructed from fn. If fn does not have
- * a file type then the default .rel file
- * type is appended to the file specification.
+ * The function afile() opens a file for reading or writing.
+ * (1) If the file type specification string ft
+ * is not NULL then a file specification is
+ * constructed with the file path\name in fn
+ * and the extension in ft.
+ * (2) If the file type specification string ft
+ * is NULL then the file specification is
+ * constructed from fn. If fn does not have
+ * a file type then the default .rel file
+ * type is appended to the file specification.
*
- * afile() returns a file handle for the opened file or aborts
- * the assembler on an open error.
+ * afile() returns a file handle for the opened file or aborts
+ * the assembler on an open error.
*
- * local variables:
- * char fb[] constructed file specification string
- * FILE * fp filehandle for opened file
+ * local variables:
+ * char fb[] constructed file specification string
+ * FILE * fp filehandle for opened file
*
- * global variables:
- * int lkerr error flag
+ * global variables:
+ * int lkerr error flag
*
- * functions called:
- * FILE * fopen() c_library
- * int fprintf() c_library
+ * functions called:
+ * FILE * fopen() c_library
+ * int fprintf() c_library
*
- * side effects:
- * File is opened for read or write.
+ * side effects:
+ * File is opened for read or write.
*/
FILE *
-afile(fn, ft, wf)
-char *fn;
-char *ft;
+afile(char *fn, char *ft, int wf)
{
- FILE *fp;
- char fb[PATH_MAX];
- char *omode = (wf ? (wf == 2 ? "a" : "w") : "r");
- int i;
-
- /*Look backward the name path and get rid of the extension, if any*/
- i=strlen(fn);
- for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--);
- if( (fn[i]=='.') && strcmp(ft, "lnk") )
- {
- strncpy(fb, fn, i);
- fb[i]=0;
- }
- else
- {
- strcpy(fb, fn);
- }
-
- /*Add the extension*/
- if (fb[i] != '.')
- {
- strcat(fb, ".");
- strcat(fb, strlen(ft)?ft:"rel");
- }
-
- fp = fopen(fb, omode);
- if (fp==NULL)
- {
- if (strcmp(ft,"adb"))/*Do not complaint for optional adb files*/
- {
- fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
- lkerr++;
- }
- }
- return (fp);
+ FILE *fp;
+ char fb[PATH_MAX];
+ char *omode = (wf ? (wf == 2 ? "a" : "w") : "r");
+ int i;
+
+ /*Look backward the name path and get rid of the extension, if any*/
+ i=strlen(fn);
+ for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--);
+ if( (fn[i]=='.') && strcmp(ft, "lnk") )
+ {
+ strncpy(fb, fn, i);
+ fb[i]=0;
+ }
+ else
+ {
+ strcpy(fb, fn);
+ }
+
+ /*Add the extension*/
+ if (fb[i] != '.')
+ {
+ strcat(fb, ".");
+ strcat(fb, strlen(ft)?ft:"rel");
+ }
+
+ fp = fopen(fb, omode);
+ if (fp==NULL)
+ {
+ if (strcmp(ft,"adb"))/*Do not complaint for optional adb files*/
+ {
+ fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
+ lkerr++;
+ }
+ }
+ return (fp);
}
-/*)Function VOID iramsav()
+/*)Function VOID iramsav()
*
- * The function iramsav() stores the size of the chip's internal RAM.
- * This is used after linking to check that variable assignment to this
- * dataspace didn't overflow into adjoining segments. Variables in the
- * DSEG, OSEG, and ISEG are assigned to this dataspace.
+ * The function iramsav() stores the size of the chip's internal RAM.
+ * This is used after linking to check that variable assignment to this
+ * dataspace didn't overflow into adjoining segments. Variables in the
+ * DSEG, OSEG, and ISEG are assigned to this dataspace.
*
- * local variables:
- * none
+ * local variables:
+ * none
*
- * global variables:
- * char *ip pointer into the REL file
- * text line in ib[]
- * unsigned int size of chip's internal
- * iram_size RAM segment
+ * global variables:
+ * char *ip pointer into the REL file
+ * text line in ib[]
+ * unsigned int size of chip's internal
+ * iram_size RAM segment
*
- * functions called:
- * char getnb() lklex.c
- * VOID unget() lklex.c
- * Addr_T expr() lkeval.c
+ * functions called:
+ * char getnb() lklex.c
+ * VOID unget() lklex.c
+ * Addr_T expr() lkeval.c
*
- * side effects:
- * The iram_size may be modified.
+ * side effects:
+ * The iram_size may be modified.
*/
VOID
{
unget(getnb());
if (ip && *ip)
- //iram_size = atoi(ip);
- iram_size = expr(0); /* evaluate size expression */
+ iram_size = expr(0); /* evaluate size expression */
else
- iram_size = 128; /* Default is 128 (0x80) bytes */
+ iram_size = 128; /* Default is 128 (0x80) bytes */
+ if ((iram_size<=0) || (iram_size>256))
+ iram_size = 128; /* Default is 128 (0x80) bytes */
}
/*Similar to iramsav but for xram memory*/
{
unget(getnb());
if (ip && *ip)
- xram_size = expr(0); /* evaluate size expression */
+ xram_size = expr(0); /* evaluate size expression */
else
- xram_size = rflag?0x1000000:0x10000;
+ xram_size = rflag?0x1000000:0x10000;
}
/*Similar to iramsav but for code memory*/
{
unget(getnb());
if (ip && *ip)
- code_size = expr(0); /* evaluate size expression */
+ code_size = expr(0); /* evaluate size expression */
else
- code_size = rflag?0x1000000:0x10000;
+ code_size = rflag?0x1000000:0x10000;
}
-/*)Function VOID iramcheck()
+/*)Function VOID iramcheck()
*
- * The function iramcheck() is used at the end of linking to check that
- * the internal RAM area wasn't overflowed by too many variable
- * assignments. Variables in the DSEG, ISEG, and OSEG are assigned to
- * the chip's internal RAM.
+ * The function iramcheck() is used at the end of linking to check that
+ * the internal RAM area wasn't overflowed by too many variable
+ * assignments. Variables in the DSEG, ISEG, and OSEG are assigned to
+ * the chip's internal RAM.
*
- * local variables:
- * none
+ * local variables:
+ * none
*
- * global variables:
- * unsigned int size of chip's internal
- * iram_size RAM segment
- * struct area linked list of memory
- * *areap areas
+ * global variables:
+ * unsigned int size of chip's internal
+ * iram_size RAM segment
+ * struct area linked list of memory
+ * *areap areas
*
- * functions called:
+ * functions called:
*
- * side effects:
+ * side effects:
*/
VOID
{
last_addr = ap->a_addr + ap->a_size - 1;
if (last_addr >= iram_size)
- fprintf(stderr,
- "\nWARNING! Segment %s extends past the end\n"
- " of internal RAM. Check map file.\n",
- ap->a_id);
+ fprintf(stderr,
+ "\nWARNING! Segment %s extends past the end\n"
+ " of internal RAM. Check map file.\n",
+ ap->a_id);
}
}
}
char *usetxt[] = {
- "Startup:",
- " -c Command line input",
- " -f file[LNK] File input",
- " -p Prompt and echo of file[LNK] to stdout (default)",
- " -n No echo of file[LNK] to stdout",
-/* "Usage: [-Options] file [file ...]", */
- "Libraries:",
- " -k Library path specification, one per -k",
- " -l Library file specification, one per -l",
- "Relocation:",
- " -b area base address = expression",
- " -g global symbol = expression",
- "Map format:",
- " -m Map output generated as file[MAP]",
- " -x Hexadecimal (default), -d Decimal, -q Octal",
- "Output:",
- " -i Intel Hex as file[IHX]",
- " -s Motorola S19 as file[S19]",
- " -j Produce NoICE debug as file[NOI]",
- " -z Produce SDCdb debug as file[cdb]",
-/* "List:", */
- " -u Update listing file(s) with link data as file(s)[.RST]",
- "Miscellaneous:\n"
- " -a [iram-size] Check for internal RAM overflow",
- " -v [xram-size] Check for external RAM overflow",
- " -w [code-size] Check for code overflow",
- " -y Generate memory usage summary file[mem]",
- " -Y Pack internal ram",
- " -A [stack-size] Allocate space for stack",
- "End:",
- " -e or null line terminates input",
- 0
+ "Startup:",
+ " -c Command line input",
+ " -f file[LNK] File input",
+ " -p Prompt and echo of file[LNK] to stdout (default)",
+ " -n No echo of file[LNK] to stdout",
+/* "Usage: [-Options] file [file ...]", */
+ "Libraries:",
+ " -k Library path specification, one per -k",
+ " -l Library file specification, one per -l",
+ "Relocation:",
+ " -b area base address = expression",
+ " -g global symbol = expression",
+ "Map format:",
+ " -m Map output generated as file[MAP]",
+ " -x Hexadecimal (default), -d Decimal, -q Octal",
+ "Output:",
+ " -i Intel Hex as file[IHX]",
+ " -s Motorola S19 as file[S19]",
+ " -j Produce NoICE debug as file[NOI]",
+ " -z Produce SDCdb debug as file[cdb]",
+/* "List:", */
+ " -u Update listing file(s) with link data as file(s)[.RST]",
+ "Miscellaneous:\n"
+ " -a [iram-size] Check for internal RAM overflow",
+ " -v [xram-size] Check for external RAM overflow",
+ " -w [code-size] Check for code overflow",
+ " -y Generate memory usage summary file[mem]",
+ " -Y Pack internal ram",
+ " -A [stack-size] Allocate space for stack",
+ "End:",
+ " -e or null line terminates input",
+ 0
};
-/*)Function VOID usage()
+/*)Function VOID usage()
*
- * The function usage() outputs to the stderr device the
- * assembler name and version and a list of valid assembler options.
+ * The function usage() outputs to the stderr device the
+ * assembler name and version and a list of valid assembler options.
*
- * local variables:
- * char ** dp pointer to an array of
- * text string pointers.
+ * local variables:
+ * char ** dp pointer to an array of
+ * text string pointers.
*
- * global variables:
- * FILE * stderr c_library
+ * global variables:
+ * FILE * stderr c_library
*
- * functions called:
- * int fprintf() c_library
+ * functions called:
+ * int fprintf() c_library
*
- * side effects:
- * none
+ * side effects:
+ * none
*/
VOID
usage()
{
- register char **dp;
+ register char **dp;
- fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION);
- for (dp = usetxt; *dp; dp++)
- fprintf(stderr, "%s\n", *dp);
- lkexit(1);
+ fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION);
+ for (dp = usetxt; *dp; dp++)
+ fprintf(stderr, "%s\n", *dp);
+ lkexit(1);
}
-/*)Function VOID copyfile()
- *
- * FILE *dest destination file
- * FILE *src source file
+/*)Function VOID copyfile()
+ *
+ * FILE *dest destination file
+ * FILE *src source file
*
* function will copy source file to destination file
*
*
- * functions called:
- * int fgetc() c_library
- * int fputc() c_library
+ * functions called:
+ * int fgetc() c_library
+ * int fputc() c_library
*
- * side effects:
- * none
+ * side effects:
+ * none
*/
VOID copyfile (dest,src)
FILE *src,*dest ;
-{
+{
int ch;
while ((ch = fgetc(src)) != EOF) {
- fputc(ch,dest);
+ fputc(ch,dest);
}
}
#include "aslink.h"
#include "strcmpi.h"
-int summary(struct area * areap)
+int summary(struct area * areap)
{
- #define EQ(A,B) !as_strcmpi((A),(B))
- #define MIN_STACK 16
- #define REPORT_ERROR(A, H) \
- {\
- fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \
- fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \
- toreturn=1; \
- }
-
- #define REPORT_WARNING(A, H) \
- { \
- fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \
- fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \
- }
-
- char buff[128];
- int j, toreturn=0;
- unsigned int Total_Last=0, k;
-
- struct area * xp;
- FILE * of;
-
- /*Artifacts used for printing*/
- char start[15], end[15], size[15], max[15];
- char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
- char line[]="---------------------";
-
- typedef struct
- {
- unsigned long Start;
- unsigned long Size;
- unsigned long Max;
- char Name[NCPS];
- unsigned long flag;
- } _Mem;
-
- unsigned int dram[0x100];
- _Mem Ram[]={
- {0, 8, 8, "REG_BANK_0", 0x0001},
- {0x8, 8, 8, "REG_BANK_1", 0x0002},
- {0x10, 8, 8, "REG_BANK_2", 0x0004},
- {0x18, 8, 8, "REG_BANK_3", 0x0008},
- {0x20, 0, 16, "BSEG_BYTES", 0x0010},
- {0, 0, 128, "UNUSED", 0x0000},
- {0x7f, 0, 128, "DATA", 0x0020},
- {0, 0, 128, "TOTAL:", 0x0000}
- };
-
- _Mem IRam= {0xff, 0, 128, "INDIRECT RAM", 0x0080};
- _Mem Stack={0xff, 0, 1, "STACK", 0x0000};
- _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100};
- _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
-
- if(stacksize==0) stacksize=MIN_STACK;
-
- if(rflag) /*For the DS390*/
- {
- XRam.Max=0x1000000; /*24 bits*/
- XRam.Start=0xffffff;
- Rom.Max=0x1000000;
- Rom.Start=0xffffff;
- }
-
- if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/
- {
- Ram[5].Max=0x80;
- Ram[6].Max=0x80;
- Ram[7].Max=0x80;
- IRam.Max=0x80;
- iram_size=0x100;
- }
- else if(iram_size<0x80)
- {
- Ram[5].Max=iram_size;
- Ram[6].Max=iram_size;
- Ram[7].Max=iram_size;
- IRam.Max=0;
- }
- else
- {
- Ram[5].Max=0x80;
- Ram[6].Max=0x80;
- Ram[7].Max=0x80;
- IRam.Max=iram_size-0x80;
- }
-
- for(j=0; j<(int)iram_size; j++) dram[j]=0;
- for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/
-
- /* Open Memory Summary File*/
- of = afile(linkp->f_idp, "mem", 1);
- if (of == NULL)
- {
- lkexit(1);
- }
-
- xp=areap;
- while (xp)
- {
- /**/ if (EQ(xp->a_id, "REG_BANK_0"))
- {
- Ram[0].Size=xp->a_size;
- }
- else if (EQ(xp->a_id, "REG_BANK_1"))
- {
- Ram[1].Size=xp->a_size;
- }
- else if (EQ(xp->a_id, "REG_BANK_2"))
- {
- Ram[2].Size=xp->a_size;
- }
- else if (EQ(xp->a_id, "REG_BANK_3"))
- {
- Ram[3].Size=xp->a_size;
- }
- else if (EQ(xp->a_id, "BSEG_BYTES"))
- {
- Ram[4].Size=xp->a_size;
- }
+ #define EQ(A,B) !as_strcmpi((A),(B))
+ #define MIN_STACK 16
+ #define REPORT_ERROR(A, H) \
+ {\
+ fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \
+ fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \
+ toreturn=1; \
+ }
+
+ #define REPORT_WARNING(A, H) \
+ { \
+ fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \
+ fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \
+ }
+
+ char buff[128];
+ int j, toreturn=0;
+ unsigned int Total_Last=0, k;
+
+ struct area * xp;
+ FILE * of;
+
+ /*Artifacts used for printing*/
+ char start[15], end[15], size[15], max[15];
+ char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
+ char line[]="---------------------";
+
+ typedef struct
+ {
+ unsigned long Start;
+ unsigned long Size;
+ unsigned long Max;
+ char Name[NCPS];
+ unsigned long flag;
+ } _Mem;
+
+ unsigned int dram[0x100];
+ _Mem Ram[]={
+ {0, 8, 8, "REG_BANK_0", 0x0001},
+ {0x8, 8, 8, "REG_BANK_1", 0x0002},
+ {0x10, 8, 8, "REG_BANK_2", 0x0004},
+ {0x18, 8, 8, "REG_BANK_3", 0x0008},
+ {0x20, 0, 16, "BSEG_BYTES", 0x0010},
+ {0, 0, 128, "UNUSED", 0x0000},
+ {0x7f, 0, 128, "DATA", 0x0020},
+ {0, 0, 128, "TOTAL:", 0x0000}
+ };
+
+ _Mem IRam= {0xff, 0, 128, "INDIRECT RAM", 0x0080};
+ _Mem Stack={0xff, 0, 1, "STACK", 0x0000};
+ _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100};
+ _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
+
+ if(stacksize==0) stacksize=MIN_STACK;
+
+ if(rflag) /*For the DS390*/
+ {
+ XRam.Max=0x1000000; /*24 bits*/
+ XRam.Start=0xffffff;
+ Rom.Max=0x1000000;
+ Rom.Start=0xffffff;
+ }
+
+ if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/
+ {
+ Ram[5].Max=0x80;
+ Ram[6].Max=0x80;
+ Ram[7].Max=0x80;
+ IRam.Max=0x80;
+ iram_size=0x100;
+ }
+ else if(iram_size<0x80)
+ {
+ Ram[5].Max=iram_size;
+ Ram[6].Max=iram_size;
+ Ram[7].Max=iram_size;
+ IRam.Max=0;
+ }
+ else
+ {
+ Ram[5].Max=0x80;
+ Ram[6].Max=0x80;
+ Ram[7].Max=0x80;
+ IRam.Max=iram_size-0x80;
+ }
+
+ for(j=0; j<(int)iram_size; j++) dram[j]=0;
+ for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/
+
+ /* Open Memory Summary File*/
+ of = afile(linkp->f_idp, "mem", 1);
+ if (of == NULL)
+ {
+ lkexit(1);
+ }
+
+ xp=areap;
+ while (xp)
+ {
+ /**/ if (EQ(xp->a_id, "REG_BANK_0"))
+ {
+ Ram[0].Size=xp->a_size;
+ }
+ else if (EQ(xp->a_id, "REG_BANK_1"))
+ {
+ Ram[1].Size=xp->a_size;
+ }
+ else if (EQ(xp->a_id, "REG_BANK_2"))
+ {
+ Ram[2].Size=xp->a_size;
+ }
+ else if (EQ(xp->a_id, "REG_BANK_3"))
+ {
+ Ram[3].Size=xp->a_size;
+ }
+ else if (EQ(xp->a_id, "BSEG_BYTES"))
+ {
+ Ram[4].Size=xp->a_size;
+ }
else if(xp->a_flag & A_CODE)
- {
+ {
if(xp->a_size>0)
{
- Rom.Size+=xp->a_size;
- if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
+ Rom.Size+=xp->a_size;
+ if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
}
- }
-
- else if (EQ(xp->a_id, "SSEG"))
- {
- Stack.Size+=xp->a_size;
- if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
- }
+ }
+
+ else if (EQ(xp->a_id, "SSEG"))
+ {
+ Stack.Size+=xp->a_size;
+ if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
+ }
else if(xp->a_flag & A_XDATA)
- {
+ {
if(xp->a_size>0)
{
- XRam.Size+=xp->a_size;
- if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
+ XRam.Size+=xp->a_size;
+ if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
}
- }
+ }
- else if (EQ(xp->a_id, "ISEG"))
- {
- IRam.Size+=xp->a_size;
- if(xp->a_addr<IRam.Start) IRam.Start=xp->a_addr;
- }
+ else if (EQ(xp->a_id, "ISEG"))
+ {
+ IRam.Size+=xp->a_size;
+ if(xp->a_addr<IRam.Start) IRam.Start=xp->a_addr;
+ }
/*If is not a register bank, bit, stack, or idata, then it should be data*/
else if((xp->a_flag & (A_CODE|A_BIT|A_XDATA))==0)
- {
+ {
if(xp->a_size)
{
- Ram[6].Size+=xp->a_size;
- if(xp->a_addr<Ram[6].Start) Ram[6].Start=xp->a_addr;
+ Ram[6].Size+=xp->a_size;
+ if(xp->a_addr<Ram[6].Start) Ram[6].Start=xp->a_addr;
}
- }
+ }
xp=xp->a_ap;
- }
-
- for(j=0; j<7; j++)
- for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++)
- dram[k]|=Ram[j].flag; /*Mark as used*/
-
- for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++)
- dram[k]|=IRam.flag; /*Mark as used*/
-
- /*Compute the amount of unused memory in direct data Ram. This is the
- gap between the last register bank or bit segment and the data segment.*/
- for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--);
- Ram[5].Start=k+1;
- Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/
-
- /*Compute the data Ram totals*/
- for(j=0; j<7; j++)
- {
- if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start;
- Ram[7].Size+=Ram[j].Size;
- }
- Total_Last=Ram[6].Size+Ram[6].Start-1;
-
- /*Report the Ram totals*/
- fprintf(of, "Direct Internal RAM:\n");
- fprintf(of, format, "Name", "Start", "End", "Size", "Max");
-
- for(j=0; j<8; j++)
- {
- if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line);
- if((j!=5) || (Ram[j].Size>0))
- {
- sprintf(start, "0x%02lx", Ram[j].Start);
- if(Ram[j].Size==0)
- end[0]=0;/*Empty string*/
- else
- sprintf(end, "0x%02lx", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1);
- sprintf(size, "%5lu", Ram[j].Size);
- sprintf(max, "%5lu", Ram[j].Max);
- fprintf(of, format, Ram[j].Name, start, end, size, max);
- }
- }
-
- for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++)
- {
- if(dram[k]!=Ram[6].flag)
- {
- sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k);
- REPORT_ERROR(buff, 1);
- break;
- }
- }
-
- if(Ram[4].Size>Ram[4].Max)
- {
- k=Ram[4].Size-Ram[4].Max;
- sprintf(buff, "Insufficient bit addressable memory. "
- "%d byte%s short.\n", k, (k==1)?"":"s");
- REPORT_ERROR(buff, 1);
- }
-
- if(Ram[5].Size!=0)
- {
- sprintf(buff, "%ld bytes in data memory wasted. "
- "SDCC link could use: --data-loc 0x%02lx\n",
- Ram[5].Size, Ram[6].Start-Ram[5].Size);
- REPORT_WARNING(buff, 1);
- }
-
- if((Ram[6].Start+Ram[6].Size)>Ram[6].Max)
- {
- k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max;
- sprintf(buff, "Insufficient space in data memory. "
- "%d byte%s short.\n", k, (k==1)?"":"s");
- REPORT_ERROR(buff, 1);
- }
-
- /*Report the position of the begining of the stack*/
- fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx)",
- rflag ? "16 bit mode initial s" : "S", Stack.Start, Stack.Start-1);
-
- /*Check that the stack pointer is landing in a safe place:*/
- if( (dram[Stack.Start] & 0x8000) == 0x8000 )
- {
- fprintf(of, ".\n");
- sprintf(buff, "Stack set to unavailable memory.\n");
- REPORT_ERROR(buff, 1);
- }
- else if(dram[Stack.Start])
- {
- fprintf(of, ".\n");
- sprintf(buff, "Stack overlaps area ");
- REPORT_ERROR(buff, 1);
- for(j=0; j<7; j++)
- {
- if(dram[Stack.Start]&Ram[j].flag)
- {
- sprintf(buff, "'%s'\n", Ram[j].Name);
- break;
- }
- }
- if(dram[Stack.Start]&IRam.flag)
- {
- sprintf(buff, "'%s'\n", IRam.Name);
- }
- REPORT_ERROR(buff, 0);
- }
- else
- {
- for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++);
- fprintf(of, " with %d bytes available\n", k);
- if ((int)k<stacksize)
- {
- sprintf(buff, "Only %d byte%s available for stack.\n",
- k, (k==1)?"":"s");
- REPORT_WARNING(buff, 1);
- }
- }
-
- fprintf(of, "\nOther memory:\n");
- fprintf(of, format, "Name", "Start", "End", "Size", "Max");
- fprintf(of, format, line, line, line, line, line);
-
- /*Report IRam totals:*/
- if(IRam.Size==0)
- {
- start[0]=0;/*Empty string*/
- end[0]=0;/*Empty string*/
- }
- else
- {
- sprintf(start, "0x%02lx", IRam.Start);
- sprintf(end, "0x%02lx", IRam.Size+IRam.Start-1);
- }
- sprintf(size, "%5lu", IRam.Size);
- sprintf(max, "%5lu", IRam.Max);
- fprintf(of, format, IRam.Name, start, end, size, max);
-
- /*Report XRam totals:*/
- if(XRam.Size==0)
- {
- start[0]=0;/*Empty string*/
- end[0]=0;/*Empty string*/
- }
- else
- {
- sprintf(start, "0x%04lx", XRam.Start);
- sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1);
- }
- sprintf(size, "%5lu", XRam.Size);
- sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
- fprintf(of, format, XRam.Name, start, end, size, max);
-
- /*Report Rom/Flash totals:*/
- if(Rom.Size==0)
- {
- start[0]=0;/*Empty string*/
- end[0]=0;/*Empty string*/
- }
- else
- {
- sprintf(start, "0x%04lx", Rom.Start);
- sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1);
- }
- sprintf(size, "%5lu", Rom.Size);
- sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
- fprintf(of, format, Rom.Name, start, end, size, max);
-
- /*Report any excess:*/
- if((IRam.Start+IRam.Size)>(IRam.Max+0x80))
- {
- sprintf(buff, "Insufficient INDIRECT RAM memory.\n");
- REPORT_ERROR(buff, 1);
- }
- if( ((XRam.Start+XRam.Size)>XRam.Max) ||
- (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
- {
- sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
- REPORT_ERROR(buff, 1);
- }
- if( ((Rom.Start+Rom.Size)>Rom.Max) ||
- (((int)Rom.Size>code_size)&&(code_size>=0)) )
- {
- sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
- REPORT_ERROR(buff, 1);
- }
-
- fclose(of);
- return toreturn;
+ }
+
+ for(j=0; j<7; j++)
+ for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++)
+ dram[k]|=Ram[j].flag; /*Mark as used*/
+
+ for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++)
+ dram[k]|=IRam.flag; /*Mark as used*/
+
+ /*Compute the amount of unused memory in direct data Ram. This is the
+ gap between the last register bank or bit segment and the data segment.*/
+ for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--);
+ Ram[5].Start=k+1;
+ Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/
+
+ /*Compute the data Ram totals*/
+ for(j=0; j<7; j++)
+ {
+ if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start;
+ Ram[7].Size+=Ram[j].Size;
+ }
+ Total_Last=Ram[6].Size+Ram[6].Start-1;
+
+ /*Report the Ram totals*/
+ fprintf(of, "Direct Internal RAM:\n");
+ fprintf(of, format, "Name", "Start", "End", "Size", "Max");
+
+ for(j=0; j<8; j++)
+ {
+ if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line);
+ if((j!=5) || (Ram[j].Size>0))
+ {
+ sprintf(start, "0x%02lx", Ram[j].Start);
+ if(Ram[j].Size==0)
+ end[0]=0;/*Empty string*/
+ else
+ sprintf(end, "0x%02lx", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1);
+ sprintf(size, "%5lu", Ram[j].Size);
+ sprintf(max, "%5lu", Ram[j].Max);
+ fprintf(of, format, Ram[j].Name, start, end, size, max);
+ }
+ }
+
+ for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++)
+ {
+ if(dram[k]!=Ram[6].flag)
+ {
+ sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k);
+ REPORT_ERROR(buff, 1);
+ break;
+ }
+ }
+
+ if(Ram[4].Size>Ram[4].Max)
+ {
+ k=Ram[4].Size-Ram[4].Max;
+ sprintf(buff, "Insufficient bit addressable memory. "
+ "%d byte%s short.\n", k, (k==1)?"":"s");
+ REPORT_ERROR(buff, 1);
+ }
+
+ if(Ram[5].Size!=0)
+ {
+ sprintf(buff, "%ld bytes in data memory wasted. "
+ "SDCC link could use: --data-loc 0x%02lx\n",
+ Ram[5].Size, Ram[6].Start-Ram[5].Size);
+ REPORT_WARNING(buff, 1);
+ }
+
+ if((Ram[6].Start+Ram[6].Size)>Ram[6].Max)
+ {
+ k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max;
+ sprintf(buff, "Insufficient space in data memory. "
+ "%d byte%s short.\n", k, (k==1)?"":"s");
+ REPORT_ERROR(buff, 1);
+ }
+
+ /*Report the position of the beginning of the stack*/
+ fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx)",
+ rflag ? "16 bit mode initial s" : "S", Stack.Start, Stack.Start-1);
+
+ /*Check that the stack pointer is landing in a safe place:*/
+ if( (dram[Stack.Start] & 0x8000) == 0x8000 )
+ {
+ fprintf(of, ".\n");
+ sprintf(buff, "Stack set to unavailable memory.\n");
+ REPORT_ERROR(buff, 1);
+ }
+ else if(dram[Stack.Start])
+ {
+ fprintf(of, ".\n");
+ sprintf(buff, "Stack overlaps area ");
+ REPORT_ERROR(buff, 1);
+ for(j=0; j<7; j++)
+ {
+ if(dram[Stack.Start]&Ram[j].flag)
+ {
+ sprintf(buff, "'%s'\n", Ram[j].Name);
+ break;
+ }
+ }
+ if(dram[Stack.Start]&IRam.flag)
+ {
+ sprintf(buff, "'%s'\n", IRam.Name);
+ }
+ REPORT_ERROR(buff, 0);
+ }
+ else
+ {
+ for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++);
+ fprintf(of, " with %d bytes available\n", k);
+ if ((int)k<stacksize)
+ {
+ sprintf(buff, "Only %d byte%s available for stack.\n",
+ k, (k==1)?"":"s");
+ REPORT_WARNING(buff, 1);
+ }
+ }
+
+ fprintf(of, "\nOther memory:\n");
+ fprintf(of, format, "Name", "Start", "End", "Size", "Max");
+ fprintf(of, format, line, line, line, line, line);
+
+ /*Report IRam totals:*/
+ if(IRam.Size==0)
+ {
+ start[0]=0;/*Empty string*/
+ end[0]=0;/*Empty string*/
+ }
+ else
+ {
+ sprintf(start, "0x%02lx", IRam.Start);
+ sprintf(end, "0x%02lx", IRam.Size+IRam.Start-1);
+ }
+ sprintf(size, "%5lu", IRam.Size);
+ sprintf(max, "%5lu", IRam.Max);
+ fprintf(of, format, IRam.Name, start, end, size, max);
+
+ /*Report XRam totals:*/
+ if(XRam.Size==0)
+ {
+ start[0]=0;/*Empty string*/
+ end[0]=0;/*Empty string*/
+ }
+ else
+ {
+ sprintf(start, "0x%04lx", XRam.Start);
+ sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1);
+ }
+ sprintf(size, "%5lu", XRam.Size);
+ sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
+ fprintf(of, format, XRam.Name, start, end, size, max);
+
+ /*Report Rom/Flash totals:*/
+ if(Rom.Size==0)
+ {
+ start[0]=0;/*Empty string*/
+ end[0]=0;/*Empty string*/
+ }
+ else
+ {
+ sprintf(start, "0x%04lx", Rom.Start);
+ sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1);
+ }
+ sprintf(size, "%5lu", Rom.Size);
+ sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
+ fprintf(of, format, Rom.Name, start, end, size, max);
+
+ /*Report any excess:*/
+ if((IRam.Start+IRam.Size)>(IRam.Max+0x80))
+ {
+ sprintf(buff, "Insufficient INDIRECT RAM memory.\n");
+ REPORT_ERROR(buff, 1);
+ }
+ if( ((XRam.Start+XRam.Size)>XRam.Max) ||
+ (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
+ {
+ sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
+ REPORT_ERROR(buff, 1);
+ }
+ if( ((Rom.Start+Rom.Size)>Rom.Max) ||
+ (((int)Rom.Size>code_size)&&(code_size>=0)) )
+ {
+ sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
+ REPORT_ERROR(buff, 1);
+ }
+
+ fclose(of);
+ return toreturn;
}
extern char idatamap[]; //0:not used, 1:used
-int summary2(struct area * areap)
+int summary2(struct area * areap)
{
- #define EQ(A,B) !as_strcmpi((A),(B))
-
- char buff[128];
- int j, toreturn=0;
- long int Stack_Start=0, Stack_size;
-
- struct area * xp;
- FILE * of;
-
- /*Artifacts used for printing*/
- char start[15], end[15], size[15], max[15];
- char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
- char line[]="---------------------";
-
- typedef struct
- {
- unsigned long Start;
- unsigned long Size;
- unsigned long Max;
- char Name[NCPS];
- unsigned long flag;
- } _Mem;
-
- _Mem Stack={0xff, 0, 1, "STACK", 0x0000};
- _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100};
- _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
-
- if(rflag) /*For the DS390*/
- {
- XRam.Max=0x1000000; /*24 bits*/
- XRam.Start=0xffffff;
- Rom.Max=0x1000000;
- Rom.Start=0xffffff;
- }
-
- /* Open Memory Summary File*/
- of = afile(linkp->f_idp, "mem", 1);
- if (of == NULL)
- {
- lkexit(1);
- }
-
- xp=areap;
- while (xp)
- {
+ #define EQ(A,B) !as_strcmpi((A),(B))
+
+ char buff[128];
+ int toreturn = 0;
+ unsigned int j;
+ unsigned long int Stack_Start=0, Stack_Size;
+
+ struct area * xp;
+ struct area * xstack_xp = NULL;
+ FILE * of;
+
+ /*Artifacts used for printing*/
+ char start[15], end[15], size[15], max[15];
+ char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
+ char line[]="---------------------";
+
+ typedef struct
+ {
+ unsigned long Start;
+ unsigned long Size;
+ unsigned long Max;
+ char Name[NCPS];
+ unsigned long flag;
+ } _Mem;
+
+ _Mem Stack={0xff, 0, 1, "STACK", 0x0000};
+ _Mem Paged={0xff, 0, 256, "PAGED EXT. RAM", A_PAG};
+ _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100};
+ _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
+
+ if(rflag) /*For the DS390*/
+ {
+ XRam.Max=0x1000000; /*24 bits*/
+ XRam.Start=0xffffff;
+ Rom.Max=0x1000000;
+ Rom.Start=0xffffff;
+ }
+
+ /* Open Memory Summary File*/
+ of = afile(linkp->f_idp, "mem", 1);
+ if (of == NULL)
+ {
+ lkexit(1);
+ }
+
+ xp=areap;
+ while (xp)
+ {
if(xp->a_flag & A_CODE)
- {
+ {
if(xp->a_size)
{
- Rom.Size+=xp->a_size;
- if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
+ Rom.Size+=xp->a_size;
+ if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
}
- }
-
- else if (EQ(xp->a_id, "SSEG"))
- {
- Stack.Size+=xp->a_size;
- if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
- }
+ }
+
+ else if (EQ(xp->a_id, "SSEG"))
+ {
+ Stack.Size+=xp->a_size;
+ if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
+ }
+
+ else if (EQ(xp->a_id, "PSEG"))
+ {
+ Paged.Size+=xp->a_size;
+ if(xp->a_addr<Paged.Start) Paged.Start=xp->a_addr;
+ }
+
+ else if (EQ(xp->a_id, "XSTK"))
+ {
+ xstack_xp = xp;
+ Paged.Size+=xp->a_size;
+ if(xp->a_addr<Paged.Start) Paged.Start=xp->a_addr;
+ }
else if(xp->a_flag & A_XDATA)
- {
+ {
if(xp->a_size)
{
- XRam.Size+=xp->a_size;
- if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
+ XRam.Size+=xp->a_size;
+ if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
}
- }
+ }
- xp=xp->a_ap;
- }
+ xp=xp->a_ap;
+ }
- /*Report the Ram totals*/
- fprintf(of, "Internal RAM layout:\n");
- fprintf(of, " 0 1 2 3 4 5 6 7 8 9 A B C D E F");
+ /*Report the Ram totals*/
+ fprintf(of, "Internal RAM layout:\n");
+ fprintf(of, " 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for(j=0; j<256; j++)
- {
- 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");
+ {
+ 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");
for(j=0; j<256; j++)
{
}
}
- for(j=Stack_Start, Stack_size=0; j<256; j++)
+ for(j=Stack_Start, Stack_Size=0; j<((iram_size)?iram_size:256); j++)
{
- if((idatamap[j]=='S')||(idatamap[j]==' ')) Stack_size++;
+ if((idatamap[j]=='S')||(idatamap[j]==' ')) Stack_Size++;
else break;
}
-
- xp=areap;
- while (xp)
+
+ xp=areap;
+ while (xp)
{
if(xp->a_unaloc>0)
{
- fprintf(of, "\nERROR: Couldn't get %d byte%s allocated"
+ fprintf(of, "\nERROR: Couldn't get %d byte%s allocated"
" in internal RAM for area %s.",
xp->a_unaloc, xp->a_unaloc>1?"s":"", xp->a_id);
toreturn=1;
}
- xp=xp->a_ap;
+ xp=xp->a_ap;
}
- /*Report the position of the begining of the stack*/
+ /*Report the position of the begining of the stack*/
if(Stack_Start!=256)
- fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx) with %ld bytes available.",
- rflag ? "16 bit mode initial s" : "S", Stack_Start, Stack_Start-1, Stack_size);
+ fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx) with %ld bytes available.",
+ rflag ? "16 bit mode initial s" : "S", Stack_Start, Stack_Start-1, Stack_Size);
else
fprintf(of, "\nI don't have a clue where the stack ended up! Sorry...");
- fprintf(of, "\n\nOther memory:\n");
- fprintf(of, format, "Name", "Start", "End", "Size", "Max");
- fprintf(of, format, line, line, line, line, line);
+ /*Report about xstack*/
+ if (xstack_xp)
+ {
+ Stack_Start = xstack_xp->a_addr;
+ Stack_Size = xstack_xp->a_size;
+ fprintf(of, "\nXstack starts at: 0x%04lx with %ld bytes available.",
+ Stack_Start, Stack_Size);
+ }
+
+ fprintf(of, "\n\nOther memory:\n");
+ fprintf(of, format, "Name", "Start", "End", "Size", "Max");
+ fprintf(of, format, line, line, line, line, line);
- /*Report XRam totals:*/
- if(XRam.Size==0)
+ /*Report Paged XRam totals:*/
+ if(Paged.Size==0)
{
start[0]=0;/*Empty string*/
- end[0]=0;/*Empty string*/
+ end[0]=0;/*Empty string*/
+ }
+ else
+ {
+ sprintf(start, "0x%04lx", Paged.Start);
+ sprintf(end, "0x%04lx", Paged.Size+Paged.Start-1);
}
- else
+ sprintf(size, "%5lu", Paged.Size);
+ sprintf(max, "%5lu", xram_size<0 ? Paged.Max : xram_size<256 ? xram_size : 256);
+ fprintf(of, format, Paged.Name, start, end, size, max);
+
+ /*Report XRam totals:*/
+ if(XRam.Size==0)
+ {
+ start[0]=0;/*Empty string*/
+ end[0]=0;/*Empty string*/
+ }
+ else
{
- sprintf(start, "0x%04lx", XRam.Start);
- sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1);
+ sprintf(start, "0x%04lx", XRam.Start);
+ sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1);
}
- sprintf(size, "%5lu", XRam.Size);
- sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
- fprintf(of, format, XRam.Name, start, end, size, max);
+ sprintf(size, "%5lu", XRam.Size);
+ sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
+ fprintf(of, format, XRam.Name, start, end, size, max);
- /*Report Rom/Flash totals:*/
- if(Rom.Size==0)
+ /*Report Rom/Flash totals:*/
+ if(Rom.Size==0)
{
start[0]=0;/*Empty string*/
- end[0]=0;/*Empty string*/
- }
- else
- {
- sprintf(start, "0x%04lx", Rom.Start);
- sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1);
- }
- sprintf(size, "%5lu", Rom.Size);
- sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
- fprintf(of, format, Rom.Name, start, end, size, max);
-
- /*Report any excess:*/
- if( ((XRam.Start+XRam.Size)>XRam.Max) ||
- (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
- {
- sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
- REPORT_ERROR(buff, 1);
- }
- if( ((Rom.Start+Rom.Size)>Rom.Max) ||
- (((int)Rom.Size>code_size)&&(code_size>=0)) )
- {
- sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
- REPORT_ERROR(buff, 1);
- }
-
- fclose(of);
- return toreturn;
+ end[0]=0;/*Empty string*/
+ }
+ else
+ {
+ sprintf(start, "0x%04lx", Rom.Start);
+ sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1);
+ }
+ sprintf(size, "%5lu", Rom.Size);
+ sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
+ fprintf(of, format, Rom.Name, start, end, size, max);
+
+ /*Report any excess:*/
+ if( ((XRam.Start+XRam.Size)>XRam.Max) ||
+ (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
+ {
+ sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
+ REPORT_ERROR(buff, 1);
+ }
+ if( ((Rom.Start+Rom.Size)>Rom.Max) ||
+ (((int)Rom.Size>code_size)&&(code_size>=0)) )
+ {
+ sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
+ REPORT_ERROR(buff, 1);
+ }
+
+ fclose(of);
+ return toreturn;
}
done \
fi
-model-mcs51-reentrant:
+model-mcs51-stack-auto:
if [ "`grep mcs51 ../../ports.build`" = mcs51 ]; then \
for model in $(MODELS); do \
- $(MAKE) MODELFLAGS="--model-$$model --stack-auto --int-long-reent --float-reent" PORT=reent-$$model objects; \
+ $(MAKE) MODELFLAGS="--model-$$model --stack-auto" PORT=$$model-stack-auto objects; \
+ done \
+ fi
+
+model-mcs51-xstack-auto:
+ if [ "`grep mcs51 ../../ports.build`" = mcs51 ]; then \
+ for model in $(MODELS); do \
+ $(MAKE) MODELFLAGS="--model-$$model --stack-auto --xstack" PORT=$$model-xstack-auto objects; \
done \
fi
|3.0| G
|-------> only this side 32 x 32 -> 32
*/
+#if defined(SDCC_USE_XSTACK)
+// currently the original code without u fails with --xstack
+// it runs out of pointer registers
+long
+_mullong (long a, long b)
+{
+ union bil t, u;
+
+ t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A
+ t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A
+ u.bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3; // B
+ u.bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B
+ u.bi.b0 = 0; // B
+ t.l += u.l;
+
+ t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0; // G
+ t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1; // F
+ t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E
+ t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D
+
+ u.bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2; // C
+ u.bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C
+ u.bi.b0 = 0; // C
+ t.l += u.l;
+
+ return t.l;
+}
+#else
long
_mullong (long a, long b)
{
return t.l + b;
}
+#endif
#endif // _MULLONG_ASM
; /*-------------------------------------------------------------------------
-;
+;
; crtclear.asm :- C run-time: clear DATA/IDATA
-;
+;
; This library is free software; you can redistribute it and/or modify it
; under the terms of the GNU Library General Public License as published by the
; Free Software Foundation; either version 2, or (at your option) any
; later version.
-;
+;
; This library 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 Library General Public License for more details.
-;
+;
; You should have received a copy of the GNU Library 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!
; -------------------------------------------------------------------------*/
.area CSEG (CODE)
.area GSINIT5 (CODE)
.area GSINIT (CODE)
.area GSFINAL (CODE)
-
+
.area GSINIT4 (CODE)
__mcs51_genRAMCLEAR::
clr a
- mov r0,a
-00005$: mov @r0,a
+ mov r0,#(l_IRAM-1)
+00005$: mov @r0,a
djnz r0,00005$
; _mcs51_genRAMCLEAR() end
.area GSINIT4 (CODE)
__mcs51_genXRAMCLEAR::
+ mov r0,#l_PSEG
+ mov a,r0
+ orl a,#(l_PSEG >> 8)
+ jz 00005$
+ mov r1,#s_PSEG
+ mov __XPAGE,#(s_PSEG >> 8)
+ clr a
+00004$: movx @r1,a
+ inc r1
+ djnz r0,00004$
+00005$:
mov r0,#l_XSEG
mov a,r0
orl a,#(l_XSEG >> 8)
- jz 00005$
+ jz 00007$
mov r1,#((l_XSEG + 255) >> 8)
mov dptr,#s_XSEG
clr a
-00004$: movx @dptr,a
+00006$: movx @dptr,a
inc dptr
- djnz r0,00004$
- djnz r1,00004$
-00005$:
+ djnz r0,00006$
+ djnz r1,00006$
+00007$:
.area GSINIT5 (CODE)
-; Need to initialize in GSINIT5 because __mcs51_genXINIT modifies __PAGESFR
+; Need to initialize in GSINIT5 because __mcs51_genXINIT modifies __XPAGE
; and __mcs51_genRAMCLEAR modifies _spx.
mov __XPAGE,#(__start__xstack >> 8)
void printIval (symbol *, sym_link *, initList *, FILE *);
set *publics = NULL; /* public variables */
-set *externs = NULL; /* Varibles that are declared as extern */
+set *externs = NULL; /* Variables that are declared as extern */
-/* TODO: this should be configurable (DS803C90 uses more than 6) */
-unsigned maxInterrupts = 6;
+unsigned maxInterrupts = 0;
int allocInfo = 1;
symbol *mainf;
set *pipeSet = NULL; /* set of pipes */
emitRegularMap (data, TRUE, TRUE);
emitRegularMap (idata, TRUE, TRUE);
emitRegularMap (bit, TRUE, FALSE);
+ emitRegularMap (pdata, TRUE, TRUE);
emitRegularMap (xdata, TRUE, TRUE);
if (port->genXINIT) {
emitRegularMap (xidata, TRUE, TRUE);
void
createInterruptVect (FILE * vFile)
{
- unsigned i = 0;
mainf = newSymbol ("main", 0);
mainf->block = 0;
if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
{
- /* "generic" interrupt table header (if port doesn't specify one).
- * Look suspiciously like 8051 code to me...
- */
-
- fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
-
- /* now for the other interrupts */
- for (; i < maxInterrupts; i++)
- {
- if (interrupts[i])
- {
- fprintf (vFile, "\tljmp\t%s\n", interrupts[i]->rname);
- if ( i != maxInterrupts - 1 )
- fprintf (vFile, "\t.ds\t5\n");
- }
- else
- {
- fprintf (vFile, "\treti\n");
- if ( i != maxInterrupts - 1 )
- fprintf (vFile, "\t.ds\t7\n");
- }
- }
+ /* There's no such thing as a "generic" interrupt table header. */
+ wassert(0);
}
}
copyFile (asmFile, bit->oFile);
}
- /* if external stack then reserve space of it */
+ /* copy paged external ram data */
+ if (mcs51_like)
+ {
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; paged external ram data\n");
+ fprintf (asmFile, "%s", iComments2);
+ copyFile (asmFile, pdata->oFile);
+ }
+
+ /* if external stack then reserve space for it */
if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
{
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; external stack \n");
fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
- fprintf (asmFile, "\t.ds 256\n");
+ fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
+ "__start__xstack:\n\t.ds\t1\n\n");
}
-
- /* copy xtern ram data */
+ /* copy external ram data */
if (mcs51_like) {
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; external ram data\n");
copyFile (asmFile, xdata->oFile);
}
- /* copy xternal initialized ram data */
+ /* copy external initialized ram data */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; external initialized ram data\n");
fprintf (asmFile, "%s", iComments2);
/** Creates a temporary file with unique file name
Scans, in order:
- - TMP, TEMP, TMPDIR env. varibles
+ - TMP, TEMP, TMPDIR env. variables
- if Un*x system: /usr/tmp and /tmp
- - root directory using mkstemp() if avaliable
+ - root directory using mkstemp() if available
- default location using tempnam()
*/
static int
#define OPTION_DUMP_ALL "--dumpall"
#define OPTION_PEEP_FILE "--peep-file"
#define OPTION_LIB_PATH "--lib-path"
-#define OPTION_XSTACK_LOC "--xstack-loc"
#define OPTION_CALLEE_SAVES "--callee-saves"
#define OPTION_STACK_LOC "--stack-loc"
+#define OPTION_XSTACK_LOC "--xstack-loc"
+#define OPTION_DATA_LOC "--data-loc"
+#define OPTION_IDATA_LOC "--idata-loc"
#define OPTION_XRAM_LOC "--xram-loc"
+#define OPTION_CODE_LOC "--code-loc"
+#define OPTION_STACK_SIZE "--stack-size"
#define OPTION_IRAM_SIZE "--iram-size"
+#define OPTION_XRAM_SIZE "--xram-size"
+#define OPTION_CODE_SIZE "--code-size"
#define OPTION_VERSION "--version"
-#define OPTION_DATA_LOC "--data-loc"
-#define OPTION_CODE_LOC "--code-loc"
-#define OPTION_IDATA_LOC "--idata-loc"
#define OPTION_NO_LABEL_OPT "--nolabelopt"
#define OPTION_NO_LOOP_INV "--noinvariant"
#define OPTION_NO_LOOP_IND "--noinduction"
#define OPTION_SHORT_IS_8BITS "--short-is-8bits"
#define OPTION_TINI_LIBID "--tini-libid"
#define OPTION_NO_XINIT_OPT "--no-xinit-opt"
-#define OPTION_XRAM_SIZE "--xram-size"
-#define OPTION_CODE_SIZE "--code-size"
#define OPTION_NO_CCODE_IN_ASM "--no-c-code-in-asm"
#define OPTION_ICODE_IN_ASM "--i-code-in-asm"
#define OPTION_PRINT_SEARCH_DIRS "--print-search-dirs"
#define OPTION_MSVC_ERROR_STYLE "--vc"
#define OPTION_USE_STDOUT "--use-stdout"
-#define OPTION_STACK_SIZE "--stack-size"
#define OPTION_PACK_IRAM "--pack-iram"
#define OPTION_NO_PEEP_COMMENTS "--no-peep-comments"
#define OPTION_OPT_CODE_SPEED "--opt-code-speed"
{ 0, OPTION_SMALL_MODEL, NULL, "internal data space is used (default)" },
#if !OPT_DISABLE_DS390
{ 0, OPTION_FLAT24_MODEL, NULL, "use the flat24 model for the ds390 (default)" },
-#endif
- { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
-#if !OPT_DISABLE_DS390
{ 0, OPTION_STACK_8BIT, NULL, "use the 8bit stack for the ds390 (not supported yet)" },
{ 0, "--stack-10bit", &options.stack10bit, "use the 10bit stack for ds390 (default)" },
#endif
+ { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
{ 0, "--xstack", &options.useXstack, "Use external stack" },
{ 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
{ 0, "--float-reent", &options.float_rent, "Use reenterant calls on the float support functions" },
/* else no module given: help text is displayed */
}
+ /* set int, long and float reentrancy based on stack-auto */
+ if (options.stackAuto)
+ {
+ options.intlong_rent++;
+ options.float_rent++;
+ }
+
/* set up external stack location if not explicitly specified */
if (!options.xstack_loc)
options.xstack_loc = options.xdata_loc;
WRITE_SEG_LOC (DATA_NAME, options.data_loc);
}
- /* xdata start */
- WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
+ /* xdata segment start. If zero, the linker chooses
+ the best place for xdata */
+ if(options.xdata_loc)
+ {
+ WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
+ }
/* indirect data */
if (IDATA_NAME)
WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
}
- /* bit segment start */
- WRITE_SEG_LOC (BIT_NAME, 0);
+ /* bit segment start */
+ WRITE_SEG_LOC (BIT_NAME, 0);
- /* stack start */
- if ( (options.stack_loc) && (options.stack_loc<0x100) )
- {
- WRITE_SEG_LOC ("SSEG", options.stack_loc);
- }
+ /* stack start */
+ if ( (options.stack_loc) && (options.stack_loc<0x100) )
+ {
+ WRITE_SEG_LOC ("SSEG", options.stack_loc);
+ }
}
else /*For the z80, gbz80*/
{
{
switch (options.model)
{
- case MODEL_SMALL:
+ case MODEL_SMALL:
c = "small";
break;
case MODEL_LARGE:
memmap *istack = NULL; /* internal stack */
memmap *code = NULL; /* code segment */
memmap *data = NULL; /* internal data upto 128 */
+memmap *pdata = NULL; /* paged external data */
memmap *xdata = NULL; /* external data */
memmap *xidata = NULL; /* the initialized xdata */
memmap *xinit = NULL; /* the initializers for xidata */
overlay = NULL;
}
+ /* Xternal paged segment ;
+ SFRSPACE - NO
+ FAR-SPACE - YES
+ PAGED - YES
+ DIRECT-ACCESS - NO
+ BIT-ACCESS - NO
+ CODE-ACESS - NO
+ DEBUG-NAME - 'P'
+ POINTER-TYPE - PPOINTER
+ */
+ if (PDATA_NAME) {
+ pdata = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, PDATA_NAME, 'P', PPOINTER);
+ } else {
+ pdata = NULL;
+ }
+
/* Xternal Data segment -
SFRSPACE - NO
FAR-SPACE - YES
xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
- /* Inderectly addressed internal data segment
+ /* Indirectly addressed internal data segment
SFRSPACE - NO
FAR-SPACE - NO
PAGED - NO
idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,
IDATA_NAME, 'G', IPOINTER);
} else {
- idata=NULL;
+ idata = NULL;
}
/* Static segment (code for variables );
then put it in the interrupt service array */
if (FUNC_ISISR (sym->type) && !options.noiv
&& (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
- {
- if (interrupts[FUNC_INTNO (sym->type)])
- werror (E_INT_DEFINED,
- FUNC_INTNO (sym->type),
- interrupts[FUNC_INTNO (sym->type)]->name);
- else
- interrupts[FUNC_INTNO (sym->type)] = sym;
-
- /* automagically extend the maximum interrupts */
- if (FUNC_INTNO (sym->type) >= maxInterrupts)
- maxInterrupts = FUNC_INTNO (sym->type) + 1;
- }
+ {
+ if (interrupts[FUNC_INTNO (sym->type)])
+ werror (E_INT_DEFINED,
+ FUNC_INTNO (sym->type),
+ interrupts[FUNC_INTNO (sym->type)]->name);
+ else
+ interrupts[FUNC_INTNO (sym->type)] = sym;
+
+ /* automagically extend the maximum interrupts */
+ if (FUNC_INTNO (sym->type) >= maxInterrupts)
+ maxInterrupts = FUNC_INTNO (sym->type) + 1;
+ }
/* if it is not compiler defined */
if (!sym->cdef)
- allocIntoSeg (sym);
+ allocIntoSeg (sym);
return;
}
if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level))
/* register storage class ignored changed to FIXED */
- if (SPEC_SCLS (sym->etype) == S_REGISTER)
- SPEC_SCLS (sym->etype) = S_FIXED;
+ if (SPEC_SCLS (sym->etype) == S_REGISTER)
+ SPEC_SCLS (sym->etype) = S_FIXED;
/* if data specified then */
if (SPEC_SCLS (sym->etype) == S_DATA)
// should we move this to the initialized data segment?
if (port->genXINIT &&
sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
- SPEC_OCLS(sym->etype)=xidata;
+ SPEC_OCLS(sym->etype)=xidata;
} else {
- SPEC_OCLS (sym->etype) = xdata;
+ SPEC_OCLS (sym->etype) = xdata;
}
allocIntoSeg (sym);
return;
return;
}
+ if (SPEC_SCLS (sym->etype) == S_PDATA)
+ {
+ SPEC_OCLS (sym->etype) = pdata;
+ sym->iaccess = 1;
+ allocIntoSeg (sym);
+ return;
+ }
+
if (SPEC_SCLS (sym->etype) == S_EEPROM)
{
SPEC_OCLS (sym->etype) = eeprom;
it as a local variable by adding it
to the first block we see in the body */
if (IS_REGPARM (lval->etype))
- continue;
+ continue;
/* mark it as my parameter */
lval->sym->ismyparm = 1;
/* if automatic variables r 2b stacked */
if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
- {
+ {
- if (lval->sym)
- lval->sym->onStack = 1;
+ if (lval->sym)
+ lval->sym->onStack = 1;
/* choose which stack 2 use */
/* use xternal stack */
if (options.useXstack)
{
- /* PENDING: stack direction support */
- SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
- SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
- xstackPtr - getSize (lval->type);
- xstackPtr -= getSize (lval->type);
+ /* PENDING: stack direction support */
+ SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
+ SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
+ xstackPtr - getSize (lval->type);
+ xstackPtr -= getSize (lval->type);
}
else
{ /* use internal stack */
/* this is automatic */
- /* if it to be placed on the stack */
+ /* if it's to be placed on the stack */
if (options.stackAuto || reentrant) {
sym->onStack = 1;
if (options.useXstack) {
/* if this is a function or a pointer to function */
/* then args processing */
if (funcInChain (csym->type))
- {
- processFuncArgs (csym);
-
- /* if register bank specified then update maxRegBank */
- if (maxRegBank < FUNC_REGBANK (csym->type))
- maxRegBank = FUNC_REGBANK (csym->type);
- /*JCF: Mark the register bank as used*/
- RegBankUsed[FUNC_REGBANK(csym->type)]=1;
- }
+ {
+ processFuncArgs (csym);
+
+ /* if register bank specified then update maxRegBank */
+ if (maxRegBank < FUNC_REGBANK (csym->type))
+ maxRegBank = FUNC_REGBANK (csym->type);
+ /*JCF: Mark the register bank as used*/
+ RegBankUsed[FUNC_REGBANK(csym->type)]=1;
+ }
/* if this is a extern variable then change the */
/* level to zero temporarily */
#define CODE_NAME port->mem.code_name
#define DATA_NAME port->mem.data_name
#define IDATA_NAME port->mem.idata_name
+#define PDATA_NAME port->mem.pdata_name
#define XDATA_NAME port->mem.xdata_name
#define XIDATA_NAME port->mem.xidata_name
#define XINIT_NAME port->mem.xinit_name
#define OVERLAY_NAME port->mem.overlay_name
/* forward definition for variables */
-extern memmap *xstack; /* xternal stack data */
-extern memmap *istack; /* internal stack */
-extern memmap *code; /* code segment */
-extern memmap *data; /* internal data upto 128 */
-extern memmap *xdata; /* external data */
-extern memmap *xidata; /* the initialized xdata */
-extern memmap *xinit; /* the initializers for xidata */
-extern memmap *idata; /* internal data upto 256 */
-extern memmap *bit; /* bit addressable space */
-extern memmap *statsg; /* static code segment */
-extern memmap *sfr; /* register space */
-extern memmap *sfrbit; /* sfr bit space */
-extern memmap *reg; /* register space */
-extern memmap *generic; /* unknown */
-extern memmap *overlay; /* the overlay segment */
-extern memmap *eeprom; /* eepromp space */
-extern memmap *eeprom; /* eepromp space */
-extern memmap *home; /* Non-banked home space */
+extern memmap *xstack; /* xternal stack data */
+extern memmap *istack; /* internal stack */
+extern memmap *code; /* code segment */
+extern memmap *data; /* internal data upto 128 */
+extern memmap *pdata; /* paged external data upto 256 */
+extern memmap *xdata; /* external data */
+extern memmap *xidata; /* the initialized xdata */
+extern memmap *xinit; /* the initializers for xidata */
+extern memmap *idata; /* internal data upto 256 */
+extern memmap *bit; /* bit addressable space */
+extern memmap *statsg; /* static code segment */
+extern memmap *sfr; /* register space */
+extern memmap *sfrbit; /* sfr bit space */
+extern memmap *reg; /* register space */
+extern memmap *generic; /* unknown */
+extern memmap *overlay; /* the overlay segment */
+extern memmap *eeprom; /* eepromp space */
+extern memmap *eeprom; /* eepromp space */
+extern memmap *home; /* Non-banked home space */
extern int fatalError;
}
static void
-_avr_reset_regparm ()
+_avr_reset_regparm (void)
{
regParmFlg = 0;
}
"CSEG",
"DSEG",
"ISEG",
+ NULL, //PSEG
"XSEG",
"BSEG",
"RSEG",
}
static void
-_ds390_reset_regparm ()
+_ds390_reset_regparm (void)
{
regParmFlg = 0;
}
if (options.model != MODEL_FLAT24)
{
- /* Let the default code handle it. */
- return FALSE;
+ fprintf (of, "\tljmp\t__sdcc_gsinit_startup\n");
+
+ /* now for the other interrupts */
+ for (i = 0; i < maxInterrupts; i++)
+ {
+ if (interrupts[i])
+ {
+ fprintf (of, "\tljmp\t%s\n", interrupts[i]->rname);
+ if ( i != maxInterrupts - 1 )
+ fprintf (of, "\t.ds\t5\n");
+ }
+ else
+ {
+ fprintf (of, "\treti\n");
+ if ( i != maxInterrupts - 1 )
+ fprintf (of, "\t.ds\t7\n");
+ }
+ }
+ return TRUE;
}
fprintf (of, "\tajmp\t__reset_vect\n");
"CSEG (CODE)",
"DSEG (DATA)",
"ISEG (DATA)",
+ "PSEG (PAG,XDATA)",
"XSEG (XDATA)",
"BSEG (BIT)",
"RSEG (DATA)",
static int _tininative_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
{
- return 1;
+ return TRUE;
}
static void _tininative_genAssemblerPreamble (FILE * of)
{
"CSEG (CODE)",
"DSEG (DATA)",
"ISEG (DATA)",
+ "PSEG (PAG,XDATA)",
"XSEG (XDATA)",
"BSEG (BIT)",
"RSEG (DATA)",
"GSINIT (CODE)",
"OSEG (OVR,DATA)",
"GSFINAL (CODE)",
- "HOME (CODE)",
+ "HOME (CODE)",
NULL,
NULL,
NULL,
"CSEG (CODE)",
"DSEG (DATA)",
"ISEG (DATA)",
+ "PSEG (PAG,XDATA)",
"XSEG (XDATA)",
"BSEG (BIT)",
"RSEG (DATA)",
}
static void
-_hc08_reset_regparm ()
+_hc08_reset_regparm (void)
{
regParmFlg = 0;
}
"CSEG (CODE)",
"DSEG",
NULL, /* "ISEG" */
+ NULL, /* "PSEG" */
"XSEG",
"BSEG",
"RSEG",
{
short r0Pushed;
short r1Pushed;
- short r0InB;
- short r1InB;
+ union
+ {
+ struct
+ {
+ short r0InB : 2;//2 so we can see it overflow
+ short r1InB : 2;//2 so we can see it overflow
+ short OpInB : 2;//2 so we can see it overflow
+ } ;
+ short BInUse;
+ } ;
short accInUse;
short inLine;
short debugLine;
extern int mcs51_nRegs;
extern FILE *codeOutFile;
static void saveRBank (int, iCode *, bool);
+
#define RESULTONSTACK(x) \
(IC_RESULT(x) && IC_RESULT(x)->aop && \
IC_RESULT(x)->aop->type == AOP_STK )
-#define MOVA(x) mova(x) /* use function to avoid multiple eval */
-#define CLRC emitcode("clr","c")
-#define SETC emitcode("setb","c")
+#define MOVA(x) mova(x) /* use function to avoid multiple eval */
+#define CLRC emitcode("clr","c")
+#define SETC emitcode("setb","c")
static lineNode *lineHead = NULL;
static lineNode *lineCurr = NULL;
if (inst && *inst)
{
if (fmt && *fmt)
- SNPRINTF (lb, sizeof(lb), "%s\t", inst);
+ SNPRINTF (lb, sizeof(lb), "%s\t", inst);
else
- SNPRINTF (lb, sizeof(lb), "%s", inst);
+ SNPRINTF (lb, sizeof(lb), "%s", inst);
tvsprintf (lb + strlen(lb), sizeof(lb) - strlen(lb), fmt, ap);
}
else
- tvsprintf (lb, sizeof(lb), fmt, ap);
+ tvsprintf (lb, sizeof(lb), fmt, ap);
while (isspace (*lbp))
- lbp++;
+ lbp++;
if (lbp && *lbp)
- lineCurr = (lineCurr ?
- connectLine (lineCurr, newLineNode (lb)) :
- (lineHead = newLineNode (lb)));
+ lineCurr = (lineCurr ?
+ connectLine (lineCurr, newLineNode (lb)) :
+ (lineHead = newLineNode (lb)));
lineCurr->isInline = _G.inLine;
lineCurr->isDebug = _G.debugLine;
lineCurr->ic = _G.current_iCode;
mova (const char *x)
{
/* do some early peephole optimization */
- if (!strcmp(x, "a") || !strcmp(x, "acc"))
+ if (!strncmp(x, "a", 2) || !strncmp(x, "acc", 4))
return;
emitcode("mov","a,%s", x);
}
+/*-----------------------------------------------------------------*/
+/* pushB - saves register B if necessary */
+/*-----------------------------------------------------------------*/
+static bool
+pushB (void)
+{
+ bool pushedB = FALSE;
+
+ if (_G.BInUse)
+ {
+ emitcode ("push", "b");
+// printf("B was in use !\n");
+ pushedB = TRUE;
+ }
+ else
+ {
+ _G.OpInB++;
+ }
+ return pushedB;
+}
+
+/*-----------------------------------------------------------------*/
+/* popB - restores value of register B if necessary */
+/*-----------------------------------------------------------------*/
+static void
+popB (bool pushedB)
+{
+ if (pushedB)
+ {
+ emitcode ("pop", "b");
+ }
+ else
+ {
+ _G.OpInB--;
+ }
+}
+
/*-----------------------------------------------------------------*/
/* getFreePtr - returns r0 or r1 whichever is free or can be pushed */
/*-----------------------------------------------------------------*/
}
-
/*-----------------------------------------------------------------*/
/* leftRightUseAcc - returns size of accumulator use by operands */
/*-----------------------------------------------------------------*/
return accuse;
}
-
/*-----------------------------------------------------------------*/
/* aopForSym - for a true symbol */
/*-----------------------------------------------------------------*/
{
iCode *ic = sym->rematiCode;
asmop *aop = newAsmop (AOP_IMMD);
- int ptr_type=0;
+ int ptr_type = 0;
int val = 0;
for (;;)
if (strcmp (d, s) ||
bvolatile)
- emitcode ("mov", "%s,%s", d, s);
+ emitcode ("mov", "%s,%s", d, s);
break;
{
int size = AOP_SIZE (oper) - 1;
int offset = 1;
- MOVA (aopGet (AOP (oper), 0, FALSE, FALSE));
- while (size--)
- emitcode ("orl", "a,%s", aopGet (AOP (oper), offset++, FALSE, FALSE));
+ char *l = aopGet (AOP (oper), 0, FALSE, FALSE);
+ bool pushedB;
+
+ if (!strncmp (l, "a", 2) || !strncmp (l, "acc", 4))
+ {
+ if (size--)
+ {
+ pushedB = pushB ();
+ emitcode("mov", "b,a");
+ while (size--)
+ {
+ MOVA (aopGet (AOP (oper), offset++, FALSE, FALSE));
+ emitcode ("orl", "b,a");
+ }
+ MOVA (aopGet (AOP (oper), offset, FALSE, FALSE));
+ emitcode ("orl", "a,b");
+ popB (pushedB);
+ }
+ }
+ else
+ {
+ MOVA (l);
+ while (size--)
+ {
+ emitcode ("orl", "a,%s", aopGet (AOP (oper), offset++, FALSE, FALSE));
+ }
+ }
}
IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic)))))
return;
- /* safe the registers in use at this time but skip the
+ /* save the registers in use at this time but skip the
ones for the result */
rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
mcs51_rUmaskForOp (IC_RESULT(ic)));
if (options.useXstack)
{
if (bitVectBitValue (rsave, R0_IDX))
- emitcode ("mov", "b,r0");
+ {
+ emitcode ("mov", "a,r0");
+ emitcode ("push", "%s", mcs51_regWithIdx (R0_IDX)->dname);
+ }
emitcode ("mov", "r0,%s", spname);
for (i = 0; i < mcs51_nRegs; i++)
{
if (bitVectBitValue (rsave, i))
{
- if (i == R0_IDX)
- emitcode ("mov", "a,b");
- else
+ if (i != R0_IDX)
emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name);
emitcode ("movx", "@r0,a");
emitcode ("inc", "r0");
}
emitcode ("mov", "%s,r0", spname);
if (bitVectBitValue (rsave, R0_IDX))
- emitcode ("mov", "r0,b");
+ {
+ emitcode ("pop", "%s", mcs51_regWithIdx (R0_IDX)->dname);
+ }
}
else
for (i = 0; i < mcs51_nRegs; i++)
{
emitcode ("dec", "r0");
emitcode ("movx", "a,@r0");
- if (i == R0_IDX)
- emitcode ("mov", "b,a");
- else
+ if (i != R0_IDX)
emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name);
}
}
emitcode ("mov", "%s,r0", spname);
if (bitVectBitValue (rsave, R0_IDX))
- emitcode ("mov", "r0,b");
+ {
+ emitcode ("mov", "r0,a");
+ }
}
else
for (i = mcs51_nRegs; i >= 0; i--)
emitcode ("push", "acc");
}
else
- emitcode ("push", "%s", l);
+ emitcode ("push", "%s", l);
+ }
}
-}
/*-----------------------------------------------------------------*/
/* assignResultValue - */
emitcode ("push", "acc");
}
else
- emitcode ("push", "%s", l);
- }
+ emitcode ("push", "%s", l);
+ }
freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
}
emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff);
}
- if (aop)
+ if (aop)
{
- freeAsmop (NULL, aop, ic, TRUE);
+ freeAsmop (NULL, aop, ic, TRUE);
}
if (ic)
{
- ic->bankSaved = 1;
+ ic->bankSaved = 1;
}
}
{
if (aopGetUsesAcc (leftOp, offset) && aopGetUsesAcc (rightOp, offset))
{
- emitcode("mov", "b,a");
+ bool pushedB;
MOVA (aopGet (leftOp, offset, FALSE, TRUE));
+ pushedB = pushB ();
emitcode("xch", "a,b");
MOVA (aopGet (rightOp, offset, FALSE, TRUE));
emitcode (add, "a,b");
+ popB (pushedB);
}
else if (aopGetUsesAcc (leftOp, offset))
{
while (size--)
{
if (aopGetUsesAcc(rightOp, offset)) {
- wassertl(!aopGetUsesAcc(leftOp, offset), "accumulator clash");
- MOVA (aopGet(rightOp, offset, FALSE, TRUE));
- if (offset == 0) {
- emitcode( "setb", "c");
+ if (aopGetUsesAcc(leftOp, offset)) {
+ bool pushedB;
+
+ MOVA (aopGet (rightOp, offset, FALSE, FALSE));
+ pushedB = pushB ();
+ emitcode ("mov", "b,a");
+ if (offset == 0)
+ CLRC;
+ MOVA (aopGet (leftOp, offset, FALSE, FALSE));
+ emitcode ("subb", "a,b");
+ popB (pushedB);
+ } else {
+ wassertl(!aopGetUsesAcc(leftOp, offset), "accumulator clash");
+ MOVA (aopGet(rightOp, offset, FALSE, TRUE));
+ if (offset == 0) {
+ emitcode( "setb", "c");
+ }
+ emitcode("subb", "a,%s", aopGet(leftOp, offset, FALSE, TRUE));
+ emitcode("cpl", "a");
}
- emitcode("subb", "a,%s", aopGet(leftOp, offset, FALSE, TRUE));
- emitcode("cpl", "a");
} else {
MOVA (aopGet (leftOp, offset, FALSE, FALSE));
if (offset == 0)
symbol *lbl;
int size = AOP_SIZE (result);
bool runtimeSign, compiletimeSign;
- bool lUnsigned, rUnsigned;
+ bool lUnsigned, rUnsigned, pushedB;
D(emitcode ("; genMultOneByte",""));
lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
+ pushedB = pushB ();
+
if (size == 1 /* no, this is not a bug; with a 1 byte result there's
no need to take care about the signedness! */
|| (lUnsigned && rUnsigned))
aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
if (size == 2)
aopPut (AOP (result), "b", 1, isOperandVolatile (result, FALSE));
+
+ popB (pushedB);
return;
}
aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
if (size == 2)
aopPut (AOP (result), "b", 1, isOperandVolatile (result, FALSE));
+
+ popB (pushedB);
}
/*-----------------------------------------------------------------*/
operand * right,
operand * result)
{
-
char *l;
+ bool pushedB;
D(emitcode ("; genDivbits",""));
+ pushedB = pushB ();
+
/* the result must be bit */
emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
l = aopGet (AOP (left), 0, FALSE, FALSE);
emitcode ("div", "ab");
emitcode ("rrc", "a");
+
+ popB (pushedB);
+
aopPut (AOP (result), "c", 0, isOperandVolatile (result, FALSE));
}
operand * right,
operand * result)
{
- bool lUnsigned, rUnsigned;
+ bool lUnsigned, rUnsigned, pushedB;
bool runtimeSign, compiletimeSign;
symbol *lbl;
int size, offset;
lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
+ pushedB = pushB ();
+
/* signed or unsigned */
if (lUnsigned && rUnsigned)
{
aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
while (size--)
aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE));
+
+ popB (pushedB);
return;
}
while (size--)
aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE));
}
+
+ popB (pushedB);
}
/*-----------------------------------------------------------------*/
operand * right,
operand * result)
{
-
char *l;
+ bool pushedB;
D(emitcode ("; genModbits",""));
+ pushedB = pushB ();
+
/* the result must be bit */
emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
l = aopGet (AOP (left), 0, FALSE, FALSE);
emitcode ("div", "ab");
emitcode ("mov", "a,b");
emitcode ("rrc", "a");
+
+ popB (pushedB);
+
aopPut (AOP (result), "c", 0, isOperandVolatile (result, FALSE));
}
operand * right,
operand * result)
{
- bool lUnsigned, rUnsigned;
+ bool lUnsigned, rUnsigned, pushedB;
bool runtimeSign, compiletimeSign;
symbol *lbl;
int size, offset;
lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
+ pushedB = pushB ();
+
/* signed or unsigned */
if (lUnsigned && rUnsigned)
{
aopPut (AOP (result), "b", 0, isOperandVolatile (result, FALSE));
while (size--)
aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE));
+
+ popB (pushedB);
return;
}
while (size--)
aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE));
}
+
+ popB (pushedB);
}
/*-----------------------------------------------------------------*/
CLRC;
while (size--)
{
+ bool pushedB = FALSE;
rightInB = aopGetUsesAcc(AOP (right), offset);
if (rightInB)
- emitcode ("mov", "b,%s", aopGet (AOP (right), offset, FALSE, FALSE));
+ {
+ pushedB = pushB ();
+ emitcode ("mov", "b,%s", aopGet (AOP (right), offset, FALSE, FALSE));
+ }
MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
if (sign && size == 0)
{
else
{
if (!rightInB)
- emitcode ("mov", "b,%s", aopGet (AOP (right), offset, FALSE, FALSE));
+ {
+ pushedB = pushB ();
+ rightInB++;
+ emitcode ("mov", "b,%s", aopGet (AOP (right), offset, FALSE, FALSE));
+ }
emitcode ("xrl", "b,#0x80");
emitcode ("subb", "a,b");
}
else
emitcode ("subb", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
}
+ if (rightInB)
+ popB (pushedB);
offset++;
}
}
/* right is a pointer reg need both a & b */
while (size--)
{
- char *l = aopGet (AOP (left), offset, FALSE, FALSE);
+ char *l;
+ //if B in use: push B; mov B,left; mov A,right; clrc; subb A,B; pop B; jnz
+ wassertl(!_G.BInUse, "B was in use");
+ l = aopGet (AOP (left), offset, FALSE, FALSE);
if (strcmp (l, "b"))
emitcode ("mov", "b,%s", l);
MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
"acc.%d", posbit & 0x07);
genIfxJump (ifx, buffer, left, right, result);
}
- else
+ else
{// what is this case? just found it in ds390/gen.c
emitcode ("anl","a,#!constbyte",1 << (posbit & 0x07));
}
if (isOperandVolatile (left, FALSE))
MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
else
- continue;
+ continue;
}
else if (bytelit == 0)
{
aopGet (AOP (right), offset, FALSE, FALSE));
} else {
if (AOP_TYPE(left)==AOP_ACC) {
+ bool pushedB = pushB ();
emitcode("mov", "b,a");
MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
emitcode("anl", "a,b");
+ popB (pushedB);
}else {
MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
emitcode ("anl", "a,%s",
if (isOperandVolatile (left, FALSE))
MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
else
- continue;
+ continue;
}
else if (IS_AOP_PREG (left))
{
else if (operandsEqu (left, result))
{
char * reg = "a";
+ bool pushedB = FALSE, leftInB = FALSE;
+
MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
if (aopGetUsesAcc(AOP (left), 1) || aopGetUsesAcc(AOP (result), 0))
{
+ pushedB = pushB ();
emitcode ("mov", "b,a");
reg = "b";
+ leftInB = TRUE;
}
aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE),
0, isOperandVolatile (result, FALSE));
aopPut (AOP (result), reg, 1, isOperandVolatile (result, FALSE));
+
+ if (leftInB)
+ popB (pushedB);
}
else
{
int size, offset;
char *l;
symbol *tlbl, *tlbl1;
+ bool pushedB;
D(emitcode ("; genLeftShift",""));
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
+ pushedB = pushB ();
emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
emitcode ("inc", "b");
freeAsmop (right, NULL, ic, TRUE);
aopOp (left, ic, FALSE);
aopOp (result, ic, FALSE);
- /* now move the left to the result if they are not the
- same */
+ /* now move the left to the result if they are not the same */
if (!sameRegs (AOP (left), AOP (result)) &&
AOP_SIZE (result) > 1)
{
emitcode ("add", "a,acc");
emitcode ("", "%05d$:", tlbl1->key + 100);
emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+ popB (pushedB);
aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
goto release;
}
emitcode ("", "%05d$:", tlbl1->key + 100);
emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+ popB (pushedB);
release:
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
int size, offset;
char *l;
symbol *tlbl, *tlbl1;
+ bool pushedB;
D(emitcode ("; genSignedRightShift",""));
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
+ pushedB = pushB ();
emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
emitcode ("inc", "b");
freeAsmop (right, NULL, ic, TRUE);
emitcode ("rrc", "a");
emitcode ("", "%05d$:", tlbl1->key + 100);
emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+ popB (pushedB);
aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
goto release;
}
reAdjustPreg (AOP (result));
emitcode ("", "%05d$:", tlbl1->key + 100);
emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+ popB (pushedB);
release:
freeAsmop (left, NULL, ic, TRUE);
int size, offset;
char *l;
symbol *tlbl, *tlbl1;
+ bool pushedB;
D(emitcode ("; genRightShift",""));
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
+ pushedB = pushB ();
emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
emitcode ("inc", "b");
freeAsmop (right, NULL, ic, TRUE);
emitcode ("rrc", "a");
emitcode ("", "%05d$:", tlbl1->key + 100);
emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+ popB (pushedB);
aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
goto release;
}
emitcode ("", "%05d$:", tlbl1->key + 100);
emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+ popB (pushedB);
release:
freeAsmop (left, NULL, ic, TRUE);
SNPRINTF (buffer, sizeof(buffer),
"acc.%d", bstr);
genIfxJump (ifx, buffer, NULL, NULL, NULL);
- }
+ }
else
{
if (blen < 8)
emitcode ("anl", "a,#0x%02x",
- (((unsigned char) -1) >> (8 - blen)) << bstr);
+ (((unsigned char) -1) >> (8 - blen)) << bstr);
genIfxJump (ifx, "a", NULL, NULL, NULL);
- }
+ }
return;
}
wassert (!ifx);
-
+
/* If the bitfield length is less than a byte */
if (blen < 8)
{
operand * result,
iCode * ic,
iCode * pi,
- iCode * ifx)
+ iCode * ifx)
{
asmop *aop = NULL;
regs *preg = NULL;
emitcode ("mov", "a,@%s", rname);
if (!ifx)
- aopPut (AOP (result), "a", offset, isOperandVolatile (result, FALSE));
+ aopPut (AOP (result), "a", offset, isOperandVolatile (result, FALSE));
}
else
{
emitcode ("dec", "%s", rname);
}
}
-
+
if (ifx && !ifx->generated)
{
genIfxJump (ifx, "a", left, NULL, result);
operand * result,
iCode * ic,
iCode *pi,
- iCode *ifx)
+ iCode *ifx)
{
asmop *aop = NULL;
regs *preg = NULL;
emitcode ("movx", "a,@%s", rname);
if (!ifx)
- aopPut (AOP (result), "a", offset, isOperandVolatile (result, FALSE));
+ aopPut (AOP (result), "a", offset, isOperandVolatile (result, FALSE));
offset++;
{
if (AOP_TYPE (op) != AOP_STR)
{
- /* if this is remateriazable */
+ /* if this is rematerializable */
if (AOP_TYPE (op) == AOP_IMMD)
{
emitcode ("mov", "dptr,%s", aopGet (AOP (op), 0, TRUE, FALSE));
while (size--)
{
emitcode ("movx", "a,@dptr");
- if (!ifx)
+ if (!ifx)
aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
if (size || pi)
emitcode ("inc", "dptr");
}
-
}
-
+
if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR)
{
- aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE));
- aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE));
- pi->generated = 1;
- }
+ aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE));
+ aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE));
+ pi->generated = 1;
+ }
if (ifx && !ifx->generated)
{
emitcode ("clr", "a");
emitcode ("movc", "a,@a+dptr");
if (!ifx)
- aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
+ aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
emitcode ("inc", "dptr");
}
else
emitcode ("mov", "a,#0x%02x", offset);
emitcode ("movc", "a,@a+dptr");
if (!ifx)
- aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
+ aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
}
}
}
if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR)
{
- aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE));
- aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE));
- pi->generated = 1;
- }
+ aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE));
+ aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE));
+ pi->generated = 1;
+ }
if (ifx && !ifx->generated)
{
{
emitcode ("lcall", "__gptrget");
if (!ifx)
- aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
+ aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
if (size || pi)
emitcode ("inc", "dptr");
}
if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR)
{
- aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE));
- aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE));
- pi->generated = 1;
- }
+ aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE));
+ aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE));
+ pi->generated = 1;
+ }
if (ifx && !ifx->generated)
{
genIfxJump (ifx, "a", left, NULL, result);
}
-
+
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
left = IC_LEFT (ic);
result = IC_RESULT (ic);
-
+
if (getSize (operandType (result))>1)
ifx = NULL;
}
else
{
+ bool pushedB;
/* Case with a bitfield length < 8 and arbitrary source
*/
MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
AccLsh (bstr);
emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
+ pushedB = pushB ();
/* transfer A to B and get next byte */
emitPtrByteGet (rname, p_type, TRUE);
emitcode ("orl", "a,b");
if (p_type == GPOINTER)
emitcode ("pop", "b");
+
+ popB (pushedB);
}
}
}
else
{
+ bool pushedB;
/* Case with partial byte and arbitrary source
*/
MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
+ pushedB = pushB ();
/* transfer A to B and get next byte */
emitPtrByteGet (rname, p_type, TRUE);
emitcode ("orl", "a,b");
if (p_type == GPOINTER)
emitcode ("pop", "b");
+
+ popB (pushedB);
}
emitPtrByteSet (rname, p_type, "a");
}
if (popIc)
genIpop (popIc);
- /* if the condition is a bit variable */
+ /* if the condition is a bit variable */
if (isbit && IS_ITEMP (cond) &&
SPIL_LOC (cond))
genIfxJump (ic, SPIL_LOC (cond)->rname, NULL, NULL, NULL);
if( count <= 16 )
{
- /* this algorithm needs 9 cycles and 7 + 3*n bytes
- if the switch argument is in an register.
- (8 cycles and 6+2*n bytes if peepholes can change ljmp to sjmp) */
+ /* this algorithm needs 9 cycles and 7 + 3*n bytes
+ if the switch argument is in a register.
+ (8 cycles and 6+2*n bytes if peepholes can change ljmp to sjmp) */
+ /* (MB) What if peephole converts ljmp to sjmp or ret ???
+ How will multiply by three be updated ???*/
aopOp (IC_JTCOND (ic), ic, FALSE);
/* get the condition into accumulator */
l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE);
}
else
{
- /* this algorithm needs 14 cycles and 13 + 2*n bytes
- if the switch argument is in an register.
- For n>6 this algorithm may be more compact */
+ /* this algorithm needs 14 cycles and 13 + 2*n bytes
+ if the switch argument is in a register.
+ For n>6 this algorithm may be more compact */
jtablo = newiTempLabel (NULL);
jtabhi = newiTempLabel (NULL);
/* get the condition into accumulator.
- Using b as temporary storage, if register push/pop is needed */
+ Using b as temporary storage, if register push/pop is needed */
aopOp (IC_JTCOND (ic), ic, FALSE);
l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE);
if ((AOP_TYPE (IC_JTCOND (ic)) == AOP_R0 && _G.r0Pushed) ||
(AOP_TYPE (IC_JTCOND (ic)) == AOP_R1 && _G.r1Pushed))
{
+ // (MB) what if B is in use???
+ wassertl(!_G.BInUse, "B was in use");
emitcode ("mov", "b,%s", l);
l = "b";
}
- freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
- MOVA (l);
+ freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
+ MOVA (l);
if( count <= 112 )
{
emitcode ("add", "a,#(%05d$-3-.)", jtablo->key + 100);
emitcode ("movc", "a,@a+pc");
emitcode ("push", "acc");
}
- else
+ else
{
/* this scales up to n<=255, but needs two more bytes
and changes dptr */
for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
jtab = setNextItem (IC_JTLABELS (ic)))
emitcode (".db", "%05d$>>8", jtab->key + 100);
-
- }
-
+ }
}
/*-----------------------------------------------------------------*/
{
if (options.debug)
{
- debugFile->writeCLine(ic);
+ debugFile->writeCLine (ic);
}
if (!options.noCcodeInAsm) {
emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno,
case GET_VALUE_AT_ADDRESS:
genPointerGet (ic,
hasInc (IC_LEFT (ic), ic,
- getSize (operandType (IC_RESULT (ic)))),
+ getSize (operandType (IC_RESULT (ic)))),
ifxForOp (IC_RESULT (ic), ic) );
break;
}
static void
-_mcs51_reset_regparm ()
+_mcs51_reset_regparm (void)
{
regParmFlg = 0;
}
static int
_mcs51_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
{
- return FALSE;
+ int i;
+
+ fprintf (of, "\tljmp\t__sdcc_gsinit_startup\n");
+
+ /* now for the other interrupts */
+ for (i = 0; i < maxInterrupts; i++)
+ {
+ if (interrupts[i])
+ {
+ fprintf (of, "\tljmp\t%s\n", interrupts[i]->rname);
+ if ( i != maxInterrupts - 1 )
+ fprintf (of, "\t.ds\t5\n");
+ }
+ else
+ {
+ fprintf (of, "\treti\n");
+ if ( i != maxInterrupts - 1 )
+ fprintf (of, "\t.ds\t7\n");
+ }
+ }
+ return TRUE;
}
static void
{
tfprintf (of, "\t!global\n", "__sdcc_init_xstack");
tfprintf (of, "\t!global\n", "__start__xstack");
- fprintf (of, "__start__xstack = 0x%04x", options.xdata_loc);
}
// if the port can copy the XINIT segment to XISEG
1, 2, 2, 4, 1, 2, 3, 1, 4, 4
},
{
- "XSEG (XDATA)",
+ "XSTK (PAG,XDATA)",
"STACK (DATA)",
"CSEG (CODE)",
"DSEG (DATA)",
"ISEG (DATA)",
+ "PSEG (PAG,XDATA)",
"XSEG (XDATA)",
"BSEG (BIT)",
"RSEG (DATA)",
// applies to f.e. bug-408972.c
// not before peephole 177.c
-replace {
+replace restart {
mov %1,%2
mov %3,%4
mov %2,%1
"code",
"DSEG (DATA)",
"ISEG (DATA)",
+ NULL, /* pdata */
"XSEG (XDATA)",
"BSEG (BIT)",
"RSEG (DATA)",
{
static int abs_usection_no=0;
regs *r, *rprev;
- int init_addr, i;
+ unsigned int init_addr, i;
regs **rlist;
regs *r1;
fprintf(of, "%s\tres\t%d\n", r->name, r->size);
}
} else {
- int j=0;
+ unsigned int j=0;
int deb_addr=0;
rprev = NULL;
{
static int abs_isection_no=0;
symbol *s, *sprev;
- int init_addr, i;
+ unsigned int init_addr, i;
symbol **slist;
/* put all symbols in an array */
}
} else {
- int j=0;
+ unsigned int j=0;
symbol *s1;
sprev = NULL;
"CSEG (CODE)", // code
"DSEG (DATA)", // data
"ISEG (DATA)", // idata
+ NULL, // pdata
"XSEG (XDATA)", // xdata
"BSEG (BIT)", // bit
"RSEG (DATA)", // reg
const char *code_name;
const char *data_name;
const char *idata_name;
+ const char *pdata_name;
const char *xdata_name;
const char *bit_name;
const char *reg_name;
}
static void
-_xa51_reset_regparm ()
+_xa51_reset_regparm (void)
{
regParmFlg = 0;
}
"CSEG (CODE)",
"DSEG (DATA)",
NULL, //"ISEG (DATA)",
+ NULL, //"PSEG (PAG,XDATA)",
"XSEG (XDATA)",
"BSEG (BIT)",
NULL, //"RSEG (DATA)",
emitDebug("; genUminusFloat");
/* for this we just need to flip the
- first it then copy the rest in place */
+ first bit then copy the rest in place */
size = AOP_SIZE (op) - 1;
_moveA(aopGet (AOP (op), MSB32, FALSE));
chunks.
*/
static void
-_rleAppend(RLECTX *self, int c)
+_rleAppend(RLECTX *self, unsigned c)
{
int i;
}
static void
-_reset_regparm ()
+_reset_regparm (void)
{
_G.regParams = 0;
}
"CODE",
"DATA",
"ISEG",
+ NULL, /* pdata */
"XSEG",
"BSEG",
"RSEG",
"CODE",
"DATA",
"ISEG",
+ NULL, /* pdata */
"XSEG",
"BSEG",
"RSEG",
/** Zeropad tests.
- storage: idata, xdata, code,
+ storage: idata, pdata, xdata, code,
*/
#ifndef STORAGE
#define STORAGE {storage}
#if defined(PORT_HOST) || defined(SDCC_z80) || defined(SDCC_gbz80)
# define idata
+# define pdata
# define xdata
# define code
#endif
#if defined(SDCC_hc08)
# define idata data
+# define pdata data
#endif
const char *string1 = "\x00\x01";