* Improved the pop params code
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 6 Feb 2000 19:07:10 +0000 (19:07 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 6 Feb 2000 19:07:10 +0000 (19:07 +0000)
* dhry.c now compiles and links for the z80
* Added simple z80 lib files and a stub strings.c

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@69 4a8a32a2-be11-0410-ad9d-d568d2c75423

device/lib/z80/Makefile [new file with mode: 0644]
device/lib/z80/crt0.s [new file with mode: 0644]
device/lib/z80/div.s [new file with mode: 0644]
device/lib/z80/mul.s [new file with mode: 0644]
device/lib/z80/putchar.s [new file with mode: 0644]
src/z80/gen.c
src/z80/main.c
support/tests/dhrystone/Makefile
support/tests/dhrystone/dhry.c
support/tests/dhrystone/dhry.h

diff --git a/device/lib/z80/Makefile b/device/lib/z80/Makefile
new file mode 100644 (file)
index 0000000..4115137
--- /dev/null
@@ -0,0 +1,25 @@
+# libc/z80 Makefile
+
+TOPDIR = ../../..
+
+SCC = $(TOPDIR)/bin/sdcc -mz80
+SAS = as-z80
+
+OBJ = div.o mul.o putchar.o string.o
+LIB = z80.lib
+CC = $(SCC)
+AS = $(SAS)
+CFLAGS = -I../include -I.
+
+all: $(LIB) crt0.o
+
+$(LIB): $(OBJ) Makefile _dummy
+       rm -f $(LIB)
+       for i in $(OBJ); do echo $$i >> $(LIB); done
+
+_dummy:
+
+clean:
+       rm -f $(OBJ) *~ $(CLEANSPEC)
+
+
diff --git a/device/lib/z80/crt0.s b/device/lib/z80/crt0.s
new file mode 100644 (file)
index 0000000..dee48ca
--- /dev/null
@@ -0,0 +1,32 @@
+       ;; Generic crt0.s for a Z80
+       .globl  __main
+
+       .area _HEADER (ABS)
+       ;; Reset vector
+       .org    0
+       jp      init
+
+       .org    0x38
+       reti
+       
+       .org    0x150
+init:
+       ;; Stack at the top of memory.
+       ld      sp,#0xffff        
+
+       ;; Use _main instead of main to bypass sdcc's intelligence
+       call    __main
+       jp      _exit
+
+       ;; Ordering of segments for the linker.
+       .area   _CODE
+       .area   _DATA
+
+       .area   _CODE
+_exit::
+       ;; Exit - special code to the emulator
+       ld      a,#0
+       out     (1),a
+1$:
+       halt
+       jr      1$
diff --git a/device/lib/z80/div.s b/device/lib/z80/div.s
new file mode 100644 (file)
index 0000000..5917c24
--- /dev/null
@@ -0,0 +1,318 @@
+       ;; Originally from GBDK by Pascal Felber.
+       .area   _CODE
+
+__divschar::   
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      e,9(ix)
+       call    .div8
+
+       ld      l,c
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+       
+__modschar::
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      e,9(ix)
+       call    .div8
+
+       ld      l,e
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+
+__divsint::
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      b,9(ix)
+       ld      e,10(ix)
+       ld      d,11(ix)
+       call    .div16
+
+       ld      l,c
+       ld      h,b
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+       
+__modsint::
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      b,9(ix)
+       ld      e,10(ix)
+       ld      d,11(ix)
+       call    .div16
+
+       ld      l,e
+       ld      h,d
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+
+       ;; Unsigned
+__divuchar::   
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      e,9(ix)
+       call    .divu8
+
+       ld      l,c
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+       
+__moduchar::
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      e,9(ix)
+       call    .divu8
+
+       ld      l,e
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+
+__divuint::
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      b,9(ix)
+       ld      e,10(ix)
+       ld      d,11(ix)
+       call    .divu16
+
+       ld      l,c
+       ld      h,b
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+       
+__moduint::
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      b,9(ix)
+       ld      e,10(ix)
+       ld      d,11(ix)
+       call    .divu16
+
+       ld      l,e
+       ld      h,d
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+       
+.div8::
+.mod8::
+       LD      A,C             ; Sign extend
+       RLCA
+       SBC     A
+       LD      B,A
+       LD      A,E             ; Sign extend
+       RLCA
+       SBC     A
+       LD      D,A
+
+       ; Fall through to .div16
+       
+       ;; 16-bit division
+       ;; 
+       ;; Entry conditions
+       ;;   BC = dividend
+       ;;   DE = divisor
+       ;; 
+       ;; Exit conditions
+       ;;   BC = quotient
+       ;;   DE = remainder
+       ;;   If divisor is non-zero, carry=0
+       ;;   If divisor is 0, carry=1 and both quotient and remainder are 0
+       ;;
+       ;; Register used: AF,BC,DE,HL
+.div16::
+.mod16::
+       ;; Determine sign of quotient by xor-ing high bytes of dividend
+       ;;  and divisor. Quotient is positive if signs are the same, negative
+       ;;  if signs are different
+       ;; Remainder has same sign as dividend
+       LD      A,B             ; Get high byte of dividend
+       LD      (.srem),A       ; Save as sign of remainder
+       XOR     D               ; Xor with high byte of divisor
+       LD      (.squot),A      ; Save sign of quotient
+       ;; Take absolute value of divisor
+       BIT     7,D
+       JR      Z,.chkde        ; Jump if divisor is positive
+       SUB     A               ; Substract divisor from 0
+       SUB     E
+       LD      E,A
+       SBC     A               ; Propagate borrow (A=0xFF if borrow)
+       SUB     D
+       LD      D,A
+       ;; Take absolute value of dividend
+.chkde:
+       BIT     7,B
+       JR      Z,.dodiv        ; Jump if dividend is positive
+       SUB     A               ; Substract dividend from 0
+       SUB     C
+       LD      C,A
+       SBC     A               ; Propagate borrow (A=0xFF if borrow)
+       SUB     B
+       LD      B,A
+       ;; Divide absolute values
+.dodiv:
+       CALL    .divu16
+       RET     C               ; Exit if divide by zero
+       ;; Negate quotient if it is negative
+       LD      A,(.squot)
+       AND     #0x80
+       JR      Z,.dorem        ; Jump if quotient is positive
+       SUB     A               ; Substract quotient from 0
+       SUB     C
+       LD      C,A
+       SBC     A               ; Propagate borrow (A=0xFF if borrow)
+       SUB     B
+       LD      B,A
+.dorem:
+       ;; Negate remainder if it is negative
+       LD      A,(.srem)
+       AND     #0x80
+       RET     Z               ; Return if remainder is positive
+       SUB     A               ; Substract remainder from 0
+       SUB     E
+       LD      E,A
+       SBC     A               ; Propagate remainder (A=0xFF if borrow)
+       SUB     D
+       LD      D,A
+       RET
+
+.divu8::
+.modu8::
+       LD      B,#0x00
+       LD      D,B
+       ; Fall through to divu16
+
+.divu16::
+.modu16::
+       ;; Check for division by zero
+       LD      A,E
+       OR      D
+       JR      NZ,.divide      ; Branch if divisor is non-zero
+       LD      BC,#0x00        ; Divide by zero error
+       LD      D,B
+       LD      E,C
+       SCF                     ; Set carry, invalid result
+       RET
+.divide:
+       LD      L,C             ; L = low byte of dividend/quotient
+       LD      H,B             ; H = high byte of dividend/quotient
+       LD      BC,#0x00        ; BC = remainder
+       OR      A               ; Clear carry to start
+       LD      A,#16           ; 16 bits in dividend
+.dvloop:
+       ;; Shift next bit of quotient into bit 0 of dividend
+       ;; Shift next MSB of dividend into LSB of remainder
+       ;; BC holds both dividend and quotient. While we shift a bit from
+       ;;  MSB of dividend, we shift next bit of quotient in from carry
+       ;; HL holds remainder
+       ;; Do a 32-bit left shift, shifting carry to L, L to H,
+       ;;  H to C, C to B
+       LD      (.dcnt),A
+       RL      L               ; Carry (next bit of quotient) to bit 0
+       RL      H               ; Shift remaining bytes
+       RL      C
+       RL      B               ; Clears carry since BC was 0
+       ;; If remainder is >= divisor, next bit of quotient is 1. This
+       ;;  bit goes to carry
+       PUSH    BC              ; Save current remainder
+       LD      A,C             ; Substract divisor from remainder
+       SBC     E
+       LD      C,A
+       LD      A,B
+       SBC     D
+       LD      B,A
+       CCF                     ; Complement borrow so 1 indicates a
+                               ;  successful substraction (this is the
+                               ;  next bit of quotient)
+       JR      C,.drop         ; Jump if remainder is >= dividend
+       POP     BC              ; Otherwise, restore remainder
+       JR      .nodrop
+.drop:
+       INC     SP
+       INC     SP
+.nodrop:
+       LD      A,(.dcnt)
+       DEC     A               ; DEC does not affect carry flag
+       JR      NZ,.dvloop
+       ;; Shift last carry bit into quotient
+       LD      D,B             ; DE = remainder
+       LD      E,C
+       RL      L               ; Carry to L
+       LD      C,L             ; C = low byte of quotient
+       RL      H
+       LD      B,H             ; B = high byte of quotient
+       OR      A               ; Clear carry, valid result
+       RET
+
+       .area   _BSS
+
+.srem:
+       .ds 0x01                ; Sign of quotient
+.squot:
+       .ds 0x01                ; Sign of remainder
+.dcnt:
+       .ds 0x01                ; Counter for division
diff --git a/device/lib/z80/mul.s b/device/lib/z80/mul.s
new file mode 100644 (file)
index 0000000..57c06a9
--- /dev/null
@@ -0,0 +1,78 @@
+       ;; Originally from GBDK by Pascal Felber.
+       
+       .area   _CODE
+__mulschar::   
+__muluchar::
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      e,9(ix)
+       call    .mulu8
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+
+__mulsint::
+__muluint::
+       push    de
+       push    bc
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      c,8(ix)
+       ld      b,9(ix)
+       ld      e,10(ix)
+       ld      d,11(ix)
+       call    .mulu16
+       
+       pop     ix
+       pop     bc
+       pop     de
+       ret
+               
+.mul8:
+.mulu8:
+       LD      B,#0x00         ; Sign extend is not necessary with mul
+       LD      D,B
+       ; Fall through
+       
+       ;; 16-bit multiplication
+       ;; 
+       ;; Entry conditions
+       ;;   BC = multiplicand
+       ;;   DE = multiplier
+       ;; 
+       ;; Exit conditions
+       ;;   DE = less significant word of product
+       ;;
+       ;; Register used: AF,BC,DE,HL
+.mul16:
+.mulu16:
+       LD      HL,#0x00        ; Product = 0
+       LD      A,#15           ; Count = bit length - 1
+       ;; Shift-and-add algorithm
+       ;; If MSB of multiplier is 1, add multiplicand to partial product
+       ;; Shift partial product, multiplier left 1 bit
+.mlp:
+       SLA     E               ; Shift multiplier left 1 bit
+       RL      D
+       JR      NC,.mlp1        ; Jump if MSB of multiplier = 0
+       ADD     HL,BC           ; Add multiplicand to partial product
+.mlp1:
+       ADD     HL,HL           ; Shift partial product left
+       DEC     A
+       JR      NZ,.mlp         ; Continue until count = 0
+       ;; Add multiplicand one last time if MSB of multiplier is 1
+       BIT     7,D             ; Get MSB of multiplier
+       JR      Z,.mend         ; Exit if MSB of multiplier is 0
+       ADD     HL,BC           ; Add multiplicand to product
+.mend:
+       RET                     ; HL = result
+
diff --git a/device/lib/z80/putchar.s b/device/lib/z80/putchar.s
new file mode 100644 (file)
index 0000000..2b8fa68
--- /dev/null
@@ -0,0 +1,13 @@
+       .area _CODE
+_putchar::
+       push    ix
+       ld      ix,#0
+       add     ix,sp
+
+       ld      a,4(ix)
+       out     (0xff),a
+
+       pop     ix
+       ret
+       
+                       
index 625ea1036ee262e97cf580c16fc94afb1c1bbb97..fef1897971e31b66912125bcaff8219dc16cabba 100644 (file)
@@ -1097,13 +1097,19 @@ static void emitCall (iCode *ic, bool ispcall)
     /* adjust the stack for parameters if required */
     if (IC_LEFT(ic)->parmBytes) {
        int i = IC_LEFT(ic)->parmBytes;
-       /* PENDING: do better */
-       while (i>1) {
-           emitcode("pop", "hl");
-           i-=2;
+       if (i>6) {
+           emitcode("ld", "hl,#%d", i);
+           emitcode("add", "hl,sp");
+           emitcode("ld", "sp,hl");
+       }
+       else {
+           while (i>1) {
+               emitcode("pop", "hl");
+               i-=2;
+           }
+           if (i) 
+               emitcode("inc", "sp");
        }
-       if (i) 
-           emitcode("inc", "sp");
     }
 
 }
index cc416fa2eeb64f2c6a491860040aaae3147358b8..5378f7be295affd8cf5a7548f97677881a534c0d 100644 (file)
@@ -37,6 +37,7 @@ static const char *_z80_getRegName(struct regs *reg)
 {
     if (reg)
        return reg->name;
+    assert(0);
     return "err";
 }
 
index f97747e585c942703aab181cd2e373862cf5746d..d55569e667575f1dfa08fd94acc434847c0eb9b2 100644 (file)
@@ -1,10 +1,26 @@
 # Simple Makefile for dhrystone and sdcc
 
-CC = /home/michaelh/projects/sdcc/bin/sdcc -mz80 -v
-CFLAGS = -DREG= -DNOSTRUCTASSIGN -DNOENUM
+CC = /home/michaelh/projects/sdcc/bin/sdcc
+# -DNOENUM is here to make the results more predictable
+CFLAGS = -mz80 -v
+CFLAGS += -DREG= -DNOSTRUCTASSIGN -DNOENUM
+LIBDIR = /home/michaelh/projects/sdcc/device/lib/z80/
+LD = link-z80
+
+OBJ = dhry.o
 
 all: dhry
 
+dhry: $(OBJ)
+       $(LD) -n -- -i -j -k$(LIBDIR) -lz80.lib \
+       -b_CODE=0x200 dhry.ihx $(LIBDIR)crt0.o $(OBJ)
+       cat dhry.ihx | ../../makebin/makebin > dhry.rom
+
+.c.o:
+       $(CC) $(CFLAGS) $<
+
+dhry.c: $(CC)
+
 clean:
        rm -r *~ dhry
-       
+
index b6c78613cc48fa1c14ff56069523a9bfc6ffcc62..79de20ff13a3aa50d72adc8d8bcd9755e6bd1a29 100644 (file)
@@ -59,7 +59,7 @@ Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val);
 Boolean Func_2 (char *Str_1_Par_Ref, char *Str_2_Par_Ref);
 Boolean Func_3 (Enumeration Enum_Par_Val);
 
-int main(void) 
+int _main(void) 
 {
     One_Fifty       Int_1_Loc;
     REG   One_Fifty       Int_2_Loc;
index 8a880aaef5c91ea549d669b48787aa089f80a95f..81477aa1d55ffebae739ce81c29870e38e7a70e0 100644 (file)
@@ -413,24 +413,24 @@ typedef int     Arr_1_Dim [50];
 typedef int     Arr_2_Dim [50] [50];
 
 typedef struct record 
-    {
+{
     struct record *Ptr_Comp;
     Enumeration    Discr;
     union {
-          struct {
-                  Enumeration Enum_Comp;
-                  int         Int_Comp;
-                  char        Str_Comp [31];
-                  } var_1;
-          struct {
-                  Enumeration E_Comp_2;
-                  char        Str_2_Comp [31];
-                  } var_2;
-          struct {
-                  char        Ch_1_Comp;
-                  char        Ch_2_Comp;
-                  } var_3;
-          } variant;
-      } Rec_Type, *Rec_Pointer;
+       struct {
+           Enumeration Enum_Comp;
+           int         Int_Comp;
+           char        Str_Comp [31];
+       } var_1;
+       struct {
+           Enumeration E_Comp_2;
+           char        Str_2_Comp [31];
+       } var_2;
+       struct {
+           char        Ch_1_Comp;
+           char        Ch_2_Comp;
+       } var_3;
+    } variant;
+} Rec_Type, *Rec_Pointer;