From: michaelh Date: Thu, 30 Mar 2000 05:53:44 +0000 (+0000) Subject: Fixed a character pointer bug X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=fc8ce1a538d4f56e80f3129db270426c840baf1b;p=fw%2Fsdcc Fixed a character pointer bug Amalgimated some .db x,x into dw's Implemented rsh Implemented returns of longs on GB. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@214 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/src/Makefile.in b/src/Makefile.in index 4792bfaa..739ada3b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -20,7 +20,9 @@ OBJECTS = SDCCy.o SDCClex.o SDCCerr.o SDCChasht.o SDCCmain.o \ SDCCsymt.o SDCCopt.o SDCCast.o SDCCmem.o SDCCval.o \ SDCCicode.o SDCCbitv.o SDCCset.o SDCClabel.o \ SDCCBBlock.o SDCCloop.o SDCCcse.o SDCCcflow.o SDCCdflow.o \ - SDCClrange.o SDCCptropt.o SDCCpeeph.o SDCCglue.o spawn.o + SDCClrange.o SDCCptropt.o SDCCpeeph.o SDCCglue.o spawn.o \ + asm.o + SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) TARGET = $(PRJDIR)/bin/sdcc diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 9412e4ae..ab215efc 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -23,6 +23,7 @@ -------------------------------------------------------------------------*/ #include "common.h" +#include "asm.h" #include symbol *interrupts[256]; @@ -81,10 +82,7 @@ void copyFile (FILE * dest, FILE * src) fputc (ch, dest); } -/*-----------------------------------------------------------------*/ -/* aopLiteral - string from a literal value */ -/*-----------------------------------------------------------------*/ -char *aopLiteral (value *val, int offset) +char *aopLiteralLong(value *val, int offset, int size) { char *rs; union { @@ -98,11 +96,24 @@ char *aopLiteral (value *val, int offset) unsigned long v = floatFromVal(val); v >>= (offset * 8); - sprintf(buffer,"#0x%02x",((char) v) & 0xff); + switch (size) { + case 1: + sprintf(buffer,"#0x%02x", (unsigned int)v & 0xff); + break; + case 2: + sprintf(buffer,"#0x%04x", (unsigned int)v & 0xffff); + break; + default: + /* Hmm. Too big for now. */ + assert(0); + } ALLOC_ATOMIC(rs,strlen(buffer)+1); return strcpy (rs,buffer); } + /* PENDING: For now size must be 1 */ + assert(size == 1); + /* it is type float */ fl.f = (float) floatFromVal(val); #ifdef _BIG_ENDIAN @@ -114,6 +125,14 @@ char *aopLiteral (value *val, int offset) return strcpy (rs,buffer); } +/*-----------------------------------------------------------------*/ +/* aopLiteral - string from a literal value */ +/*-----------------------------------------------------------------*/ +char *aopLiteral (value *val, int offset) +{ + return aopLiteralLong(val, offset, 1); +} + /*-----------------------------------------------------------------*/ /* emitRegularMap - emit code for maps with no special cases */ /*-----------------------------------------------------------------*/ @@ -122,7 +141,7 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag) symbol *sym; if (addPublics) - fprintf (map->oFile, "\t.area\t%s\n", map->sname); + asm_printf(map->oFile, asm_port->area, map->sname); /* print the area name */ for (sym = setFirstItem (map->syms); sym; @@ -183,8 +202,8 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag) /* allocate space */ if ((options.debug || sym->level == 0) && !options.nodebug) fprintf(map->oFile,"==.\n"); - fprintf (map->oFile, "%s:\n", sym->rname); - fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff); + asm_printf(map->oFile, asm_port->label, sym->rname); + asm_printf(map->oFile, asm_port->ds, (unsigned int)getSize (sym->type) & 0xffff); } /* if it has a initial value then do it only if @@ -286,9 +305,41 @@ void printChar (FILE * ofile, char *s, int plen) int i; int len = strlen (s); int pplen = 0; - - while (len && pplen < plen) { + char buf[100]; + char *p = buf; + while (len && pplen < plen) { + while (i && *s && pplen < plen) { + if (*s < ' ' || *s == '\"') { + *p = '\0'; + if (p != buf) + asm_printf(ofile, asm_port->ascii, buf); + asm_printf(ofile, asm_port->db, *s); + p = buf; + } + else { + *p = *s; + p++; + } + s++; + pplen++; + i--; + } + if (p != buf) { + *p = '\0'; + asm_printf(ofile, asm_port->ascii, buf); + } + + if (len > 60) + len -= 60; + else + len = 0; + } + asm_printf(ofile, asm_port->db, 0); +#if 0 + if (pplen < plen) + fprintf(ofile,"\t.byte\t0\n"); + fprintf (ofile, "\t.ascii /"); i = 60; while (i && *s && pplen < plen) { @@ -309,6 +360,7 @@ void printChar (FILE * ofile, char *s, int plen) } if (pplen < plen) fprintf(ofile,"\t.byte\t0\n"); +#endif } /*-----------------------------------------------------------------*/ @@ -333,13 +385,8 @@ void printIvalType (link * type, initList * ilist, FILE * oFile) break; case 2: - if (!val) - fprintf (oFile, "\t.word 0\n"); - else - fprintf (oFile, "\t.byte %s,%s\n", - aopLiteral (val, 0), aopLiteral (val, 1)); - break; - + fprintf(oFile, "\t.word %s\n", aopLiteralLong(val, 0, 2)); +break; case 4: if (!val) fprintf (oFile, "\t.word 0,0\n"); @@ -502,21 +549,49 @@ int printIvalCharPtr (symbol * sym, link * type, value * val, FILE * oFile) { int size = 0; + /* PENDING: this is _very_ mcs51 specific, including a magic + number... + It's also endin specific. + */ size = getSize (type); - - if (size == 1) - fprintf(oFile, - "\t.byte %s", val->name) ; - else - fprintf (oFile, - "\t.byte %s,(%s >> 8)", - val->name, val->name); - - if (size > 2) - fprintf (oFile, ",#0x02\n"); - else - fprintf (oFile, "\n"); - + + if (val->name && strlen(val->name)) { + switch (size) { + case 1: + fprintf(oFile, + "\t.byte %s\n", val->name) ; + break; + case 2: + fprintf(oFile, "\t.word %s\n", val->name); + break; + /* PENDING: probably just 3 */ + default: + /* PENDING: 0x02 or 0x%02x, CDATA? */ + fprintf (oFile, + "\t.byte %s,(%s >> 8),#0x02\n", + val->name, val->name); + } + } + else { + switch (size) { + case 1: + fprintf(oFile, "\t.byte %s\n", aopLiteral(val, 0)); + break; + case 2: + fprintf(oFile, "\t.word %s\n", + aopLiteralLong(val, 0, 2)); + break; + case 3: + /* PENDING: 0x02 or 0x%02x, CDATA? */ + fprintf(oFile, "\t.byte %s,%s,0x02\n", + aopLiteral (val, 0), aopLiteral (val, 1)); + break; + default: + assert(0); + } + } + + if (val->sym && val->sym->isstrlit) addSet (&statsg->syms, val->sym); @@ -559,9 +634,7 @@ void printIvalPtr (symbol * sym, link * type, initList * ilist, FILE * oFile) fprintf (oFile, "\t.byte 0x%02x\n", ((char) floatFromVal (val)) & 0xff); break; case 2: - fprintf (oFile, "\t.byte %s,%s\n", - aopLiteral (val, 0), aopLiteral (val, 1)); - + fprintf (oFile, "\t.word %s\n", aopLiteralLong(val, 0, 2)); break; case 3: fprintf (oFile, "\t.byte %s,%s,0x%02x\n", @@ -690,8 +763,8 @@ void emitStaticSeg (memmap * map) printChar (code->oFile, SPEC_CVAL (sym->etype).v_char, strlen(SPEC_CVAL (sym->etype).v_char)+1); - else - fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type)& 0xffff); + else + asm_printf(code->oFile, asm_port->ds, (unsigned int)getSize (sym->type)& 0xffff); } } } @@ -797,7 +870,7 @@ void printPublics (FILE * afile) for (sym = setFirstItem (publics); sym; sym = setNextItem (publics)) - fprintf (afile, "\t.globl %s\n", sym->rname); + asm_printf(afile, asm_port->global, sym->rname); } /*-----------------------------------------------------------------*/ @@ -886,8 +959,8 @@ static void emitOverlay(FILE *afile) fprintf(afile,"==.\n"); /* allocate space */ - fprintf (afile, "%s:\n", sym->rname); - fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff); + asm_printf(afile, asm_port->label, sym->rname); + asm_printf(afile, asm_port->ds, (unsigned int)getSize (sym->type) & 0xffff); } } @@ -942,7 +1015,7 @@ void glue () initialComments (asmFile); /* print module name */ - fprintf (asmFile, "\t.module %s\n", moduleName); + asm_printf(asmFile, asm_port->module, moduleName); /* Let the port generate any global directives, etc. */ if (port->genAssemblerPreamble) diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 8f958818..ceeadef7 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -144,6 +144,16 @@ static PORT *_ports[] = { #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0])) +extern ASM_PORT asxxxx_port; +extern ASM_PORT rgbds_port; + +ASM_PORT *asm_port; + +static ASM_PORT *_asm_ports[] = { + &asxxxx_port, + &rgbds_port +}; + /** Sets the port to the one given by the command line option. @param The name minus the option (eg 'mcs51') @return 0 on success. @@ -1257,6 +1267,7 @@ static int preProcess (char **envp) static void _findPort(int argc, char **argv) { + asm_port = _asm_ports[0]; argc--; while (argc) { if (!strncmp(*argv, "-m", 2)) { diff --git a/src/common.h b/src/common.h index ea5ac522..ced0a15a 100644 --- a/src/common.h +++ b/src/common.h @@ -22,6 +22,7 @@ #include "SDCCptropt.h" #include "SDCCopt.h" +#include "asm.h" #include "port.h" #include "config.h" diff --git a/src/z80/gen.c b/src/z80/gen.c index f9a32ecf..5f31f3c4 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -741,22 +741,22 @@ static void fetchLitPair(PAIR_ID pairId, asmop *left, int offset) emitcode("ld", "%s,#%s", pair, l); } -static void fetchPair(PAIR_ID pairId, asmop *aop) +static void fetchPairLong(PAIR_ID pairId, asmop *aop, int offset) { /* if this is remateriazable */ if (isLitWord(aop)) { - fetchLitPair(pairId, aop, 0); + fetchLitPair(pairId, aop, offset); } else { /* we need to get it byte by byte */ if (pairId == PAIR_HL && IS_GB && requiresHL(aop)) { - aopGet(aop, 0, FALSE); + aopGet(aop, offset, FALSE); emitcode("ld", "a,(hl+)"); emitcode("ld", "h,(hl)"); emitcode("ld", "l,a"); } else { - emitcode("ld", "%s,%s", _pairs[pairId].l, aopGet(aop, 0, FALSE)); - emitcode("ld", "%s,%s", _pairs[pairId].h, aopGet(aop, 1, FALSE)); + emitcode("ld", "%s,%s", _pairs[pairId].l, aopGet(aop, offset, FALSE)); + emitcode("ld", "%s,%s", _pairs[pairId].h, aopGet(aop, offset+1, FALSE)); } /* PENDING: check? */ if (pairId == PAIR_HL) @@ -764,6 +764,11 @@ static void fetchPair(PAIR_ID pairId, asmop *aop) } } +static void fetchPair(PAIR_ID pairId, asmop *aop) +{ + fetchPairLong(pairId, aop, 0); +} + static void fetchHL(asmop *aop) { fetchPair(PAIR_HL, aop); @@ -1259,14 +1264,29 @@ release: /*-----------------------------------------------------------------*/ void assignResultValue(operand * oper) { - int offset = 0; int size = AOP_SIZE(oper); + bool topInA = 0; - wassert(size <= 2); + wassert(size <= 4); + topInA = requiresHL(AOP(oper)); - while (size--) { - aopPut(AOP(oper),_fReturn[offset],offset); - offset++; + if (!IS_GB) + wassert(size <= 2); + if (IS_GB && size == 4 && requiresHL(AOP(oper))) { + /* We do it the hard way here. */ + emitcode("push", "hl"); + _G.stack.pushed += 2; + aopPut(AOP(oper), _fReturn[0], 0); + aopPut(AOP(oper), _fReturn[1], 1); + emitcode("pop", "de"); + _G.stack.pushed -= 2; + aopPut(AOP(oper), _fReturn[0], 2); + aopPut(AOP(oper), _fReturn[1], 3); + } + else { + while (size--) { + aopPut(AOP(oper), _fReturn[size], size); + } } } @@ -1599,16 +1619,11 @@ static void genEndFunction (iCode *ic) } else { if (_G.stack.offset) { - emitcode("ld", "hl,#%d", _G.stack.offset); - emitcode("add", "hl,sp"); - emitcode("ld", "sp,hl"); + emitcode("lda", "sp,%d(sp)", _G.stack.offset); } } emitcode("pop", "bc"); emitcode("ret", ""); - emitcode("; Useful for profiling and debugging", ""); - emitcode(".dw", "%s", sym->rname); - emitcode("", "__%s_end:", sym->rname); } _G.stack.pushed = 0; _G.stack.offset = 0; @@ -1643,11 +1658,17 @@ static void genRet (iCode *ic) } } else { - while (size--) { - l = aopGet(AOP(IC_LEFT(ic)),offset, - FALSE); - if (strcmp(_fReturn[offset],l)) - emitcode("ld","%s,%s", _fReturn[offset++],l); + if (IS_GB && size == 4 && requiresHL(AOP(IC_LEFT(ic)))) { + fetchPair(PAIR_DE, AOP(IC_LEFT(ic))); + fetchPairLong(PAIR_HL, AOP(IC_LEFT(ic)), 2); + } + else { + while (size--) { + l = aopGet(AOP(IC_LEFT(ic)),offset, + FALSE); + if (strcmp(_fReturn[offset],l)) + emitcode("ld","%s,%s", _fReturn[offset++],l); + } } } freeAsmop (IC_LEFT(ic),NULL,ic); @@ -3396,6 +3417,7 @@ static void genLeftShift (iCode *ic) freeAsmop(result,NULL,ic); } +/*-----------------------------------------------------------------*/ /* genlshTwo - left shift two bytes by known amount != 0 */ /*-----------------------------------------------------------------*/ static void genrshOne (operand *result,operand *left, int shCount) @@ -3537,7 +3559,26 @@ static void genRightShiftLiteral (operand *left, /*-----------------------------------------------------------------*/ static void genRightShift (iCode *ic) { - operand *left,*right, *result; + operand *right, *left, *result; + link *retype ; + int size, offset, first = 1; + char *l; + bool is_signed; + + symbol *tlbl, *tlbl1 ; + + /* if signed then we do it the hard way preserve the + sign bit moving it inwards */ + retype = getSpec(operandType(IC_RESULT(ic))); + + is_signed = !SPEC_USIGN(retype); + + /* signed & unsigned types are treated the same : i.e. the + signed is NOT propagated inwards : quoting from the + ANSI - standard : "for E1 >> E2, is equivalent to division + by 2**E2 if unsigned or if it has a non-negative value, + otherwise the result is implementation defined ", MY definition + is that the sign does not get propagated */ right = IC_RIGHT(ic); left = IC_LEFT(ic); @@ -3548,12 +3589,56 @@ static void genRightShift (iCode *ic) /* if the shift count is known then do it as efficiently as possible */ if (AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic); - return ; + genRightShiftLiteral(left,right,result,ic); + return; } - else { - wassert(0); + + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); + + /* now move the left to the result if they are not the + same */ + if (!sameRegs(AOP(left),AOP(result)) && + AOP_SIZE(result) > 1) { + + size = AOP_SIZE(result); + offset=0; + while (size--) { + l = aopGet(AOP(left),offset,FALSE); + aopPut(AOP(result),l,offset); + offset++; + } } + + emitcode("ld", "a,%s",aopGet(AOP(right),0,FALSE)); + emitcode("inc","a"); + freeAsmop (right, NULL, ic); + + tlbl = newiTempLabel(NULL); + tlbl1= newiTempLabel(NULL); + size = AOP_SIZE(result); + offset = size - 1; + + emitcode(_shortJP, LABEL_STR, tlbl1->key+100); + emitcode("", LABEL_STR ":", tlbl->key+100); + while (size--) { + l = aopGet(AOP(result),offset--,FALSE); + if (first) { + if (is_signed) + emitcode("sra", "%s", l); + else + emitcode("srl", "%s", l); + first = 0; + } + else + emitcode("rr", "%s", l); + } + emitcode("", LABEL_STR ":", tlbl1->key+100); + emitcode("dec", "a"); + emitcode(_shortJP, "nz," LABEL_STR, tlbl->key+100); + + freeAsmop(left,NULL,ic); + freeAsmop(result,NULL,ic); } /*-----------------------------------------------------------------*/