Fixed a character pointer bug
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 30 Mar 2000 05:53:44 +0000 (05:53 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 30 Mar 2000 05:53:44 +0000 (05:53 +0000)
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

src/Makefile.in
src/SDCCglue.c
src/SDCCmain.c
src/common.h
src/z80/gen.c

index 4792bfaa2e0cf872d0fb8bc71b9315652545b3a3..739ada3bbafd8aef5df7f6981c826beb608ccd74 100644 (file)
@@ -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
index 9412e4ae700713846b98aa6f52867d2a4575330c..ab215efc917517b23a2c83596e8f347c54742e72 100644 (file)
@@ -23,6 +23,7 @@
 -------------------------------------------------------------------------*/
 
 #include "common.h"
+#include "asm.h"
 #include <time.h>
 
 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)
index 8f958818ad1cd6700a46f17ce8a3f85cf7e221f3..ceeadef727d2aa53def68bec2ef60d5dfb9d8a03 100644 (file)
@@ -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)) {
index ea5ac522f587ddccecd84c3304555b195b701456..ced0a15a2ebb5caadb8bc707f568cb2a1b1e49ce 100644 (file)
@@ -22,6 +22,7 @@
 #include "SDCCptropt.h"
 #include "SDCCopt.h"
 
+#include "asm.h"
 #include "port.h"
 #include "config.h"
 
index f9a32ecfd57315b7c3c48d7d6c643e4b30b94d63..5f31f3c49377841ff96bce3c4a8bcea596cea63d 100644 (file)
@@ -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);
 }
 
 /*-----------------------------------------------------------------*/