Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C to 8051 compiler

0 views
Skip to first unread message

Guillem Borras

unread,
Dec 7, 1995, 3:00:00 AM12/7/95
to
Could someone help me in finding a C compiler for 8051 architectures
(I suppose it should exist somewhere on the net...).
Thank you in advance

Guillem


Doug Dyer

unread,
Dec 7, 1995, 3:00:00 AM12/7/95
to
Guillem Borras <bor...@creatis.insa-lyon.fr> writes:

>Guillem


You can get free demo disks of both BSO/Tasking (1-800-458-8276)
and the Keil/51 flavor which you can buy from Franklin
((408) 296-8051 (get it? 8051!)) and Keil (1-800-348-8051),
and Archimedes (1-800-338-1453).

So what's better, Keil or BSO? Well Keil seems to generate
faster/smaller code but BSO supports more architecture families
including support for their RTOS on many chips as well (and they
support UNIX hosts). Note though that I really don't know much
about BSO at all, I just have their demo disk :)


I say call up for the free demos (and of course, junk mail for life :)
--
Doug Dyer - dy...@alx.sticomet.com | ECL: embedded command language
STI: voice (703) 329-9707 | for the 8051 family
"Wisdom is the domain of the Wis." - Zappa (ugh..)

Olaf 'Olu' Pfeiffer

unread,
Dec 7, 1995, 3:00:00 AM12/7/95
to
Guillem Borras <bor...@creatis.insa-lyon.fr> wrote:
>Could someone help me in finding a C compiler for 8051 architectures
>(I suppose it should exist somewhere on the net...).

A free light version of the Keil C51 is here:

http://www.hitex.com/hitex/demo/51light.zip

unfortunately it's VERY light - linker is restricted to 256 Bytes of code :-(

Olaf

Henrik Linderholm

unread,
Dec 8, 1995, 3:00:00 AM12/8/95
to
Guillem Borras wrote:
>
> Could someone help me in finding a C compiler for 8051 architectures
> (I suppose it should exist somewhere on the net...).
> Thank you in advance
>
> Guillem

You can get an IAR C compiler for the 8051. I suggest that you contact
one of our local distributers in France to get more information about
our compiler. I list the names, phone numbers and fax numbers for you:

Antycip, tel:1 39 61 14 14, fax:1 30 76 29 73.

Emulations, tel:1 69 41 28 01, fax:1 60 19 29 50.

MB Electronique, tel:1 39 56 81 31, fax:1 39 56 53 44.

Otherwise you can contact me for more information.

With regards

Henrik Linderholm
henrik.l...@iar.se

Jan Brittenson

unread,
Dec 11, 1995, 3:00:00 AM12/11/95
to
In article <4a787t$r...@shellx.best.com> Olaf 'Olu' Pfeiffer <pfei...@hitex.com> writes:

> unfortunately it's VERY light - linker is restricted to 256 Bytes of code :-(

Unfortunately, it's not a very good compiler. Its CSE, logic folding,
and register allocation is almost non-existant. It generates function
calls that cost as much or more just to setup than to inline the
function. This is the code I used to evaluate it for a hobby project.
Obviously, if all you do is trivial 8- and 16-bit arithmetic with tiny
data and place few demands on the compiler, then it might do just
fine. The code:

/* test in-line coding of 'long' arithmetic */
#pragma large debug objectextend code
#define NULL ((void *) 0)

typedef long seq_t;
typedef unsigned short u16;
struct tcp_state {u16 rwnd; seq_t rnxt; };
struct tcphdr {char lotsastuff[24]; seq_t seq; seq_t ack;
char morestuff[8]; };

#define SEQ_LT(A, B) ((A) - (B) < 0)
#define SEQ_LE(A, B) ((A) - (B) <= 0)
#define SEQ_GT(A, B) (!SEQ_LE(A, B))
#define SEQ_GE(A, B) (!SEQ_LT(A, B))

/* Check if TCP segment is within advertised window.
Returns address of first octet within window.
Adjusts seglen to new size.
Reduces seglen to discard overshoot.
Returns NULL if segment is entirely outside window. */
/* Avoid register declarations. A good register allocator will do a
better job than a programmer, so register allocation is an important
compiler benchmark. */
char *
tcp_rwnd_adj (struct tcphdr *tcph, struct tcp_state *tcps, u16 *seglen,
char *payload)
{
char *rptr = payload;

/* Discard overshoot. Lots of CSE and logic folding here. */
if (SEQ_LT(tcps->rnxt + tcps->rwnd, tcph->seq + *seglen)) {
if (SEQ_GE(tcph->seq, tcps->rnxt + tcps->rwnd))
/* Complete overshoot: discard segment */
goto discard;
*seglen -= tcph->seq + *seglen - tcps->rnxt + tcps->rwnd;
}

/* Drop retransmitted portion at start */
if (SEQ_LE(tcph->seq, tcps->rnxt)) { /* 32bit arithmetic-logic */
if (*seglen < tcps->rnxt - tcph->seq) /* CSE/fold logic */
/* Complete retransmit: discard segment */
goto discard;
*seglen -= tcps->rnxt - tcph->seq; /* long->u16 convert */
rptr += tcps->rnxt - tcph->seq; /* CSE test */
}

/* Return new start */
return rptr;

discard:
*seglen = 0;
return NULL;
}


And the output. Can't say I'm too impressed.


C51 COMPILER X4.10, LONG 10/12/95 17:23:35 PAGE 1


DOS C51 COMPILER X4.10, COMPILATION OF MODULE LONG
OBJECT MODULE PLACED IN LONG.OBJ
COMPILER INVOKED BY: D:\5LIGHT\C51.EXE LONG.C

stmt level source

1 /* test in-line coding of 'long' arithmetic */
2 #pragma large debug objectextend code
3 #define NULL ((void *) 0)
4
5 typedef long seq_t;
6 typedef unsigned short u16;
7 struct tcp_state {u16 rwnd; seq_t rnxt; };
8 struct tcphdr {char lotsastuff[24]; seq_t seq; seq_t ack;
9 char morestuff[8]; };
10
11 #define SEQ_LT(A, B) ((A) - (B) < 0)
12 #define SEQ_LE(A, B) ((A) - (B) <= 0)
13 #define SEQ_GT(A, B) (!SEQ_LE(A, B))
14 #define SEQ_GE(A, B) (!SEQ_LT(A, B))
15
16 /* Check if TCP segment is within advertised window.
17 Returns address of first octet within window.
18 Adjusts seglen to new size.
19 Reduces seglen to discard overshoot.
20 Returns NULL if segment is entirely outside window. */
21 /* Avoid register declarations. A good register allocator will do a
22 better job than a programmer, so register allocation is an important
23 compiler benchmark. */
24 char *
25 tcp_rwnd_adj (struct tcphdr *tcph, struct tcp_state *tcps, u16 *seglen,
26 char *payload)
27 {
28 1 char *rptr = payload;
29 1
30 1 /* Discard overshoot. Lots of CSE and logic folding here. */
31 1 if (SEQ_LT(tcps->rnxt + tcps->rwnd, tcph->seq + *seglen)) {
32 2 if (SEQ_GE(tcph->seq, tcps->rnxt + tcps->rwnd))
33 2 /* Complete overshoot: discard segment */
34 2 goto discard;
35 2 *seglen -= tcph->seq + *seglen - tcps->rnxt + tcps->rwnd;
36 2 }
37 1
38 1 /* Drop retransmitted portion at start */
39 1 if (SEQ_LE(tcph->seq, tcps->rnxt)) { /* 32bit arithmetic-logic */
40 2 if (*seglen < tcps->rnxt - tcph->seq) /* CSE/fold logic */
41 2 /* Complete retransmit: discard segment */
42 2 goto discard;
43 2 *seglen -= tcps->rnxt - tcph->seq; /* long->u16 convert */
44 2 rptr += tcps->rnxt - tcph->seq; /* CSE test */
45 2 }
46 1
47 1 /* Return new start */
48 1 return rptr;
49 1
50 1 discard:
51 1 *seglen = 0;
52 1 return NULL;
53 1 }
54
C51 COMPILER X4.10, LONG 10/12/95 17:23:35 PAGE 2

ASSEMBLY LISTING OF GENERATED OBJECT CODE


; FUNCTION _tcp_rwnd_adj (BEGIN)
0000 900000 R MOV DPTR,#tcph
0003 EB MOV A,R3
0004 F0 MOVX @DPTR,A
0005 A3 INC DPTR
0006 EA MOV A,R2
0007 F0 MOVX @DPTR,A
0008 A3 INC DPTR
0009 E9 MOV A,R1
000A F0 MOVX @DPTR,A
; SOURCE LINE # 25
; SOURCE LINE # 27
; SOURCE LINE # 28
000B 900000 R MOV DPTR,#payload
000E E0 MOVX A,@DPTR
000F F9 MOV R1,A
0010 A3 INC DPTR
0011 E0 MOVX A,@DPTR
0012 FA MOV R2,A
0013 A3 INC DPTR
0014 E0 MOVX A,@DPTR
0015 A3 INC DPTR
0016 C9 XCH A,R1
0017 F0 MOVX @DPTR,A
0018 A3 INC DPTR
0019 EA MOV A,R2
001A F0 MOVX @DPTR,A
001B A3 INC DPTR
001C E9 MOV A,R1
001D F0 MOVX @DPTR,A
; SOURCE LINE # 31
001E 7F00 MOV R7,#00H
0020 7E00 MOV R6,#00H
0022 7D00 MOV R5,#00H
0024 7C00 MOV R4,#00H
0026 120000 E LCALL ?C_LPUSH
0029 900000 R MOV DPTR,#tcph
002C E0 MOVX A,@DPTR
002D FB MOV R3,A
002E A3 INC DPTR
002F E0 MOVX A,@DPTR
0030 FA MOV R2,A
0031 A3 INC DPTR
0032 E0 MOVX A,@DPTR
0033 F9 MOV R1,A
0034 900018 MOV DPTR,#018H
0037 120000 E LCALL ?C_LLDOPTR
003A 120000 E LCALL ?C_LPUSH
003D 900000 R MOV DPTR,#seglen
0040 E0 MOVX A,@DPTR
0041 FB MOV R3,A
0042 A3 INC DPTR
0043 E0 MOVX A,@DPTR
0044 FA MOV R2,A
0045 A3 INC DPTR
0046 E0 MOVX A,@DPTR
0047 F9 MOV R1,A
0048 120000 E LCALL ?C_ILDPTR
004B FF MOV R7,A
004C AEF0 MOV R6,B
004E E4 CLR A
004F FC MOV R4,A
0050 FD MOV R5,A
C51 COMPILER X4.10, LONG 10/12/95 17:23:35 PAGE 3

0051 120000 E LCALL ?C_LADD
0054 120000 E LCALL ?C_LPUSH
0057 900000 R MOV DPTR,#tcps
005A E0 MOVX A,@DPTR
005B FB MOV R3,A
005C A3 INC DPTR
005D E0 MOVX A,@DPTR
005E FA MOV R2,A
005F A3 INC DPTR
0060 E0 MOVX A,@DPTR
0061 F9 MOV R1,A
0062 900002 MOV DPTR,#02H
0065 120000 E LCALL ?C_LLDOPTR
0068 120000 E LCALL ?C_LPUSH
006B 120000 E LCALL ?C_ILDPTR
006E FF MOV R7,A
006F AEF0 MOV R6,B
0071 E4 CLR A
0072 FC MOV R4,A
0073 FD MOV R5,A
0074 120000 E LCALL ?C_LADD
0077 120000 E LCALL ?C_LSUB
007A 120000 E LCALL ?C_SLCMP
007D 4003 JC $ + 5H
007F 020000 R LJMP ?C0001
; SOURCE LINE # 32
0082 7F00 MOV R7,#00H
0084 7E00 MOV R6,#00H
0086 7D00 MOV R5,#00H
0088 7C00 MOV R4,#00H
008A 120000 E LCALL ?C_LPUSH
008D 900000 R MOV DPTR,#tcps
0090 E0 MOVX A,@DPTR
0091 A3 INC DPTR
0092 E0 MOVX A,@DPTR
0093 A3 INC DPTR
0094 E0 MOVX A,@DPTR
0095 900002 MOV DPTR,#02H
0098 120000 E LCALL ?C_LLDOPTR
009B 120000 E LCALL ?C_LPUSH
009E 120000 E LCALL ?C_ILDPTR
00A1 FF MOV R7,A
00A2 AEF0 MOV R6,B
00A4 E4 CLR A
00A5 FC MOV R4,A
00A6 FD MOV R5,A
00A7 120000 E LCALL ?C_LADD
00AA 120000 E LCALL ?C_LPUSH
00AD 900000 R MOV DPTR,#tcph
00B0 E0 MOVX A,@DPTR
00B1 FB MOV R3,A
00B2 A3 INC DPTR
00B3 E0 MOVX A,@DPTR
00B4 FA MOV R2,A
00B5 A3 INC DPTR
00B6 E0 MOVX A,@DPTR
00B7 F9 MOV R1,A
00B8 900018 MOV DPTR,#018H
00BB 120000 E LCALL ?C_LLDOPTR
00BE 120000 E LCALL ?C_LSUB
00C1 120000 E LCALL ?C_SLCMP
00C4 4003 JC $ + 5H
00C6 020000 R LJMP discard
; SOURCE LINE # 34
00C9 ?C0002:
; SOURCE LINE # 35
C51 COMPILER X4.10, LONG 10/12/95 17:23:35 PAGE 4

00C9 900018 MOV DPTR,#018H
00CC 120000 E LCALL ?C_LLDOPTR
00CF 900000 R MOV DPTR,#seglen
00D2 E0 MOVX A,@DPTR
00D3 FB MOV R3,A
00D4 A3 INC DPTR
00D5 E0 MOVX A,@DPTR
00D6 FA MOV R2,A
00D7 A3 INC DPTR
00D8 E0 MOVX A,@DPTR
00D9 F9 MOV R1,A
00DA 120000 E LCALL ?C_ILDPTR
00DD 2F ADD A,R7
00DE FF MOV R7,A
00DF EE MOV A,R6
00E0 35F0 ADDC A,B
00E2 FE MOV R6,A
00E3 C006 PUSH AR6
00E5 C007 PUSH AR7
00E7 900000 R MOV DPTR,#tcps
00EA E0 MOVX A,@DPTR
00EB FB MOV R3,A
00EC A3 INC DPTR
00ED E0 MOVX A,@DPTR
00EE FA MOV R2,A
00EF A3 INC DPTR
00F0 E0 MOVX A,@DPTR
00F1 F9 MOV R1,A
00F2 900002 MOV DPTR,#02H
00F5 120000 E LCALL ?C_LLDOPTR
00F8 C3 CLR C
00F9 D0E0 POP ACC
00FB 9F SUBB A,R7
00FC FF MOV R7,A
00FD D0E0 POP ACC
00FF 9E SUBB A,R6
0100 FE MOV R6,A
0101 120000 E LCALL ?C_ILDPTR
0104 2F ADD A,R7
0105 FF MOV R7,A
0106 EE MOV A,R6
0107 35F0 ADDC A,B
0109 FE MOV R6,A
010A 900000 R MOV DPTR,#seglen
010D E0 MOVX A,@DPTR
010E FB MOV R3,A
010F A3 INC DPTR
0110 E0 MOVX A,@DPTR
0111 FA MOV R2,A
0112 A3 INC DPTR
0113 E0 MOVX A,@DPTR
0114 F9 MOV R1,A
0115 120000 E LCALL ?C_ILDPTR
0118 C3 CLR C
0119 9F SUBB A,R7
011A FF MOV R7,A
011B E5F0 MOV A,B
011D 9E SUBB A,R6
011E 8FF0 MOV B,R7
0120 120000 E LCALL ?C_ISTPTR
; SOURCE LINE # 36
0123 ?C0001:
; SOURCE LINE # 39
0123 7F00 MOV R7,#00H
0125 7E00 MOV R6,#00H
0127 7D00 MOV R5,#00H
C51 COMPILER X4.10, LONG 10/12/95 17:23:35 PAGE 5

0129 7C00 MOV R4,#00H
012B 120000 E LCALL ?C_LPUSH
012E 900000 R MOV DPTR,#tcps
0131 E0 MOVX A,@DPTR
0132 FB MOV R3,A
0133 A3 INC DPTR
0134 E0 MOVX A,@DPTR
0135 FA MOV R2,A
0136 A3 INC DPTR
0137 E0 MOVX A,@DPTR
0138 F9 MOV R1,A
0139 900002 MOV DPTR,#02H
013C 120000 E LCALL ?C_LLDOPTR
013F 120000 E LCALL ?C_LPUSH
0142 900000 R MOV DPTR,#tcph
0145 E0 MOVX A,@DPTR
0146 FB MOV R3,A
0147 A3 INC DPTR
0148 E0 MOVX A,@DPTR
0149 FA MOV R2,A
014A A3 INC DPTR
014B E0 MOVX A,@DPTR
014C F9 MOV R1,A
014D 900018 MOV DPTR,#018H
0150 120000 E LCALL ?C_LLDOPTR
0153 120000 E LCALL ?C_LSUB
0156 120000 E LCALL ?C_SLCMP
0159 6005 JZ $ + 7H
015B 4003 JC $ + 5H
015D 020000 R LJMP ?C0004
; SOURCE LINE # 40
0160 900018 MOV DPTR,#018H
0163 120000 E LCALL ?C_LLDOPTR
0166 120000 E LCALL ?C_LPUSH
0169 900000 R MOV DPTR,#tcps
016C E0 MOVX A,@DPTR
016D FB MOV R3,A
016E A3 INC DPTR
016F E0 MOVX A,@DPTR
0170 FA MOV R2,A
0171 A3 INC DPTR
0172 E0 MOVX A,@DPTR
0173 F9 MOV R1,A
0174 900002 MOV DPTR,#02H
0177 120000 E LCALL ?C_LLDOPTR
017A 120000 E LCALL ?C_LSUB
017D 120000 E LCALL ?C_LPUSH
0180 900000 R MOV DPTR,#seglen
0183 E0 MOVX A,@DPTR
0184 FB MOV R3,A
0185 A3 INC DPTR
0186 E0 MOVX A,@DPTR
0187 FA MOV R2,A
0188 A3 INC DPTR
0189 E0 MOVX A,@DPTR
018A F9 MOV R1,A
018B 120000 E LCALL ?C_ILDPTR
018E FF MOV R7,A
018F AEF0 MOV R6,B
0191 E4 CLR A
0192 FC MOV R4,A
0193 FD MOV R5,A
0194 120000 E LCALL ?C_SLCMP
0197 5003 JNC $ + 5H
0199 020000 R LJMP discard
; SOURCE LINE # 42
C51 COMPILER X4.10, LONG 10/12/95 17:23:35 PAGE 6

019C ?C0005:
; SOURCE LINE # 43
019C 900000 R MOV DPTR,#tcph
019F E0 MOVX A,@DPTR
01A0 FB MOV R3,A
01A1 A3 INC DPTR
01A2 E0 MOVX A,@DPTR
01A3 FA MOV R2,A
01A4 A3 INC DPTR
01A5 E0 MOVX A,@DPTR
01A6 F9 MOV R1,A
01A7 900018 MOV DPTR,#018H
01AA 120000 E LCALL ?C_LLDOPTR
01AD C006 PUSH AR6
01AF C007 PUSH AR7
01B1 900000 R MOV DPTR,#tcps
01B4 E0 MOVX A,@DPTR
01B5 FB MOV R3,A
01B6 A3 INC DPTR
01B7 E0 MOVX A,@DPTR
01B8 FA MOV R2,A
01B9 A3 INC DPTR
01BA E0 MOVX A,@DPTR
01BB F9 MOV R1,A
01BC 900002 MOV DPTR,#02H
01BF 120000 E LCALL ?C_LLDOPTR
01C2 AD07 MOV R5,AR7
01C4 AC06 MOV R4,AR6
01C6 D007 POP AR7
01C8 D006 POP AR6
01CA C3 CLR C
01CB ED MOV A,R5
01CC 9F SUBB A,R7
01CD FF MOV R7,A
01CE EC MOV A,R4
01CF 9E SUBB A,R6
01D0 FE MOV R6,A
01D1 900000 R MOV DPTR,#seglen
01D4 E0 MOVX A,@DPTR
01D5 FB MOV R3,A
01D6 A3 INC DPTR
01D7 E0 MOVX A,@DPTR
01D8 FA MOV R2,A
01D9 A3 INC DPTR
01DA E0 MOVX A,@DPTR
01DB F9 MOV R1,A
01DC 120000 E LCALL ?C_ILDPTR
01DF C3 CLR C
01E0 9F SUBB A,R7
01E1 FF MOV R7,A
01E2 E5F0 MOV A,B
01E4 9E SUBB A,R6
01E5 8FF0 MOV B,R7
01E7 120000 E LCALL ?C_ISTPTR
; SOURCE LINE # 44
01EA 900000 R MOV DPTR,#tcph
01ED E0 MOVX A,@DPTR
01EE FB MOV R3,A
01EF A3 INC DPTR
01F0 E0 MOVX A,@DPTR
01F1 FA MOV R2,A
01F2 A3 INC DPTR
01F3 E0 MOVX A,@DPTR
01F4 F9 MOV R1,A
01F5 900018 MOV DPTR,#018H
01F8 120000 E LCALL ?C_LLDOPTR
C51 COMPILER X4.10, LONG 10/12/95 17:23:35 PAGE 7

01FB C006 PUSH AR6
01FD C007 PUSH AR7
01FF 900000 R MOV DPTR,#tcps
0202 E0 MOVX A,@DPTR
0203 FB MOV R3,A
0204 A3 INC DPTR
0205 E0 MOVX A,@DPTR
0206 FA MOV R2,A
0207 A3 INC DPTR
0208 E0 MOVX A,@DPTR
0209 F9 MOV R1,A
020A 900002 MOV DPTR,#02H
020D 120000 E LCALL ?C_LLDOPTR
0210 AD07 MOV R5,AR7
0212 AC06 MOV R4,AR6
0214 D007 POP AR7
0216 D006 POP AR6
0218 C3 CLR C
0219 ED MOV A,R5
021A 9F SUBB A,R7
021B FF MOV R7,A
021C EC MOV A,R4
021D 9E SUBB A,R6
021E 900000 R MOV DPTR,#rptr+01H
0221 8FF0 MOV B,R7
0223 120000 E LCALL ?C_IILDX
; SOURCE LINE # 45
0226 ?C0004:
; SOURCE LINE # 48
0226 900000 R MOV DPTR,#rptr
0229 E0 MOVX A,@DPTR
022A FB MOV R3,A
022B A3 INC DPTR
022C E0 MOVX A,@DPTR
022D FA MOV R2,A
022E A3 INC DPTR
022F E0 MOVX A,@DPTR
0230 F9 MOV R1,A
0231 22 RET
; SOURCE LINE # 50
0232 discard:
; SOURCE LINE # 51
0232 900000 R MOV DPTR,#seglen
0235 E0 MOVX A,@DPTR
0236 FB MOV R3,A
0237 A3 INC DPTR
0238 E0 MOVX A,@DPTR
0239 FA MOV R2,A
023A A3 INC DPTR
023B E0 MOVX A,@DPTR
023C F9 MOV R1,A
023D E4 CLR A
023E F5F0 MOV B,A
0240 120000 E LCALL ?C_ISTPTR
; SOURCE LINE # 52
0243 7B00 MOV R3,#00H
0245 7A00 MOV R2,#00H
0247 7900 MOV R1,#00H
; SOURCE LINE # 53
0249 ?C0006:
0249 22 RET
; FUNCTION _tcp_rwnd_adj (END)

MODULE INFORMATION: STATIC OVERLAYABLE
C51 COMPILER X4.10, LONG 10/12/95 17:23:35 PAGE 8

CODE SIZE = 586 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- 15
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)

--
-- Jan Brittenson
bs...@eng.sun.com

Olaf 'Olu' Pfeiffer

unread,
Dec 12, 1995, 3:00:00 AM12/12/95
to bs...@bugmotel.eng.sun.com, upha...@aol.com
bs...@bugmotel.eng.sun.com (Jan Brittenson) wrote:

>Unfortunately, it's not a very good compiler. Its CSE, logic folding,
>and register allocation is almost non-existant. It generates function
>calls that cost as much or more just to setup than to inline the
>function. This is the code I used to evaluate it for a hobby project.
>Obviously, if all you do is trivial 8- and 16-bit arithmetic with tiny
>data and place few demands on the compiler, then it might do just
>fine.

..

Hi Jan,

the version you used for testing is "really" light. I hope that
someone from Keil (Jon - R U ?) will do a follow up on this...

Their C51 compiler is known to be one of the best. That's why
so many others sell it under their own brand name ;-)

The standard benchmarks like Dhrystone, Whetstone and
Sieve of Erosthostenes show that Keil and BSO are both far
ahead of their competition.

Olaf 'Olu' Pfeiffer
http://www.hitex.com [/olu]


Jan Brittenson

unread,
Dec 14, 1995, 3:00:00 AM12/14/95
to
In article <4am5ef$k...@news-f.iadfw.net> jon...@airmail.net (Jon Ward) writes:

> [many good ideas, and good explanations omitted]

Thanks!


> OK, Here's a challenge that will impress you. I bet you can't write
> your sample program in 8051 assembly that is more than 25% smaller
> than the code generated by our compiler. If you can beat our compiler
> by 25%, I'll sell you our compiler for the upgrade price.

What I did instead of recoding it all in assembler was to break out
common expressions by hand (I've omitted the comments for brevity; the
function I started with is included at the end):

#define TARGET_8051

#pragma small code


#define NULL ((void *) 0)

#ifdef TARGET_8051
#define DATA data
#else
#define DATA
#endif

typedef long seq_t;
typedef unsigned short u16;
struct tcp_state {u16 rwnd; seq_t rnxt; };
struct tcphdr {char lotsastuff[24]; seq_t seq; seq_t ack;
char morestuff[8]; };

char DATA *
tcp_rwnd_adj (struct tcphdr DATA *tcph,
struct tcp_state DATA *tcps,
u16 DATA *seglen,
char DATA *payload)
{
seq_t tmp = tcph->seq;
seq_t tmp1 = tcps->rnxt + tcps->rwnd;
seq_t tmp3 = tcps->rnxt - tmp;

if (tmp1 < tmp + *seglen) {
if (tmp >= tmp1)
goto discard;
*seglen += tmp - tmp1;
}

if (tmp3 > 0) {
if (tmp3 > *seglen) {
discard:
*seglen= 0;
payload = NULL;
goto done;
} else {
*seglen -= tmp3;
payload += tmp3;
}
}
done:
return payload;
}

Obviously, a lot more could be done in terms of clever optimizations,
but the above is what I might expect a compiler to do given what's in
the original function (which I've only carefully rearranged to derive
the above). The original function resulted in 352 bytes. The above
compiles to 260 bytes -- 26% less.

But because 32-bit arithmetic and pointer access is so expensive, it's
IMHO even more important for an 8051 compiler to work hard at CSE.
Even at the cost of using the stack for temporary storage.


> 1. You must write in 8051 assembly and you must locate your variables
> in the same memory space the compiler uses.

Jon, I think it's reasonable to expect a compiler to spill registers
onto the stack or in static storage reserved for the purpose... If an
application is cramped for space or for some other reason doesn't want
it, it might to be useful to be able to turn it off with a compiler
option, or #pragma.

Here's the original I derived the above from (basically the same as I
posted the other day plus qualifying pointer types, sans a few
comments):

#define TARGET_8051

/* test in-line coding of 'long' arithmetic */

#pragma small code


#define NULL ((void *) 0)

#ifdef TARGET_8051
#define DATA data
#else
#define DATA
#endif

typedef long seq_t;
typedef unsigned short u16;
struct tcp_state {u16 rwnd; seq_t rnxt; };
struct tcphdr {char lotsastuff[24]; seq_t seq; seq_t ack;
char morestuff[8]; };

#define SEQ_LT(A, B) ((A) - (B) < 0)
#define SEQ_LE(A, B) ((A) - (B) <= 0)
#define SEQ_GT(A, B) (!SEQ_LE(A, B))
#define SEQ_GE(A, B) (!SEQ_LT(A, B))

/* Check if TCP segment is within advertised window.
Returns address of first octet within window.
Adjusts seglen to new size.
Reduces seglen to discard overshoot.
Returns NULL if segment is entirely outside window. */

char DATA *
tcp_rwnd_adj (struct tcphdr DATA *tcph,
struct tcp_state DATA *tcps,
u16 DATA *seglen,
char DATA *payload)
{
/* Discard overshoot. */


if (SEQ_LT(tcps->rnxt + tcps->rwnd, tcph->seq + *seglen)) {
if (SEQ_GE(tcph->seq, tcps->rnxt + tcps->rwnd))
/* Complete overshoot: discard segment */
goto discard;

*seglen -= tcph->seq + *seglen - (tcps->rnxt + tcps->rwnd);
}

/* Drop retransmitted portion at start */
if (SEQ_LE(tcph->seq, tcps->rnxt)) {

if (*seglen < tcps->rnxt - tcph->seq)

/* Complete retransmit: discard segment */
goto discard;
*seglen -= tcps->rnxt - tcph->seq;

payload += tcps->rnxt - tcph->seq;
}

/* Return new start */

return payload;

discard:
*seglen = 0;
return NULL;
}

--
-- Jan Brittenson
bs...@eng.sun.com

Olaf 'Olu' Pfeiffer

unread,
Dec 14, 1995, 3:00:00 AM12/14/95
to fie...@kagcpd01.ag01.kodak.com
fie...@kagcpd01.ag01.kodak.COM (Roman Fietze) wrote:
>Olaf 'Olu' Pfeiffer <pfei...@hitex.com> wrote:

> bs...@bugmotel.eng.sun.com (Jan Brittenson) wrote:
>
> >Unfortunately, it's not a very good compiler. Its CSE, logic folding,

..

> The standard benchmarks like Dhrystone, Whetstone and
> Sieve of Erosthostenes show that Keil and BSO are both far
> ahead of their competition.
>

>Does anybody have these Benchmarks available or do you have an
>internet * to them?

Unfortunately I only have the results as published by the
German magazine BYTE. I hope they will be available from
the upcoming KEIL www server...

Olaf 'Olu'
Pfei...@Hitex.com

John Payson

unread,
Dec 14, 1995, 3:00:00 AM12/14/95
to
In article <4am5ef$k...@news-f.iadfw.net>, Jon Ward <jon...@airmail.net> wrote:
>There are 3 memory models we provide with the C51 compiler. They are:
>
>SMALL - This is the default. All variables are located in internal
>data memory.
>
>COMPACT - All variables are located in 1 page of XDATA (accessed with
>@R0 and @R1).
>
>LARGE - All variables are located in XDATA (using MOVX @DPTR).

I use Arch5 which, if I recall, Archimedes licenses from Keil? Anyway,
the three models are reasonably nice, but it would be even better if the
compiler could be set to place objects based on type/size, at least to
the extent of being able to place arrays automatically in IDATA [bytes
0-255 of internal memory] while placing single variables in DATA [bytes
0-127 of internal memory]. Since arrays are _usually_ accessed indirectly,
there is less penalty associated with storing them in IDATA than there is
with single variables.

Also, I'd like to see a memory area that's a cross between CODE and XDATA;
specifically, one that uses MOVC for reads and MOVX for writes. This would
make the wiring of Von Neuman machines easier [no need to "and" the /RD and
/PSEN signals] and also save a port pin [P3.6 could be used for other
putposes]. Any possibility of managing such a thing?

[btw, my preferred embodiment of the Von Neuman construct above would be an
8751 with a bootloader in EPROM, connected to a 62256 via just a 74?373.
Real cheap easy board, and lower cost than using an external EPROM or /OE
control gate.

>What do I have to gain by all of this? It's simple. I hope you can
>show us something we haven't thought of when it comes to our compiler.
>If you can, it's a cheap price to pay for innovation.

Well, one thing I'd noticed in Arch--don't know if the Keil compiler is
better--is that the overlay variable placement routine has to keep all the
variables for a routine consecutively. This can sometimes cause the comp-
iler to use more memory for variables than would otherwise be needed--since
DATA is very scarce on many 8x51's, this can pose a problem. Does Keil
also allocate the local variables for each function as contiguous segments?


I've been toying with the idea of writing a pseudo-C compiler for the PIC
microcontroller and figuring out how best to do certain things, and one
idea I was thinking would be nice, though implementing it in anything
resemblng normal object-file format tools would be very difficult, would
be for the compiler to have several different potential expansions for each
statement [e.g. either call a subroutine or invoke in-line] and keep a
count of how many cycles would be used in each approach [use a #pragma to
identify the time/codesize tradeoffs in different sections of code]. Then
after a pre-compile pass through everything, the system could produce the
following line of "reasoning":

The following routines are called seldom enough the fastest and smallest
code will be produced by expanding inline:
[list of such routines]

The following routines are called often enough that breaking them out and
calling them will produce smaller, slower, code:
NAME BYTES FOR CALLABLE COPY BYTES SAVED/INSTANCE TIME LOST/INSTANCE
xxx xxxx xxx xxx

Coding for minimum size or scratchpad utilization, the compiler will
generate 3900 bytes of code using 120 bytes of data memory, including
user-requested 8 bytes of stack for interrupt handling. Thus, up to
296 bytes of code may be added to improve speed.

This may be done most efficiently by converting routine XXX to inline
calls at a cost of 10 cycle-points per byte saved. This leaves us with
23 bytes of code which can be used to expand yyy.

The idea being, rather than having the user try to weasel things to they
'just barely' fit, let the compiler do it and use any extra space for code
speed improvements. This probably isn't quite as important on the 8x51 as
on the PIC, but I was thinking it might be an interesting idea to explore.
For efficient compiling/linking, I was planning on having the compiler
generate both versions of the code, with embedded directives to the linker
to elide one or the other. While this would require the linker to process
local fixups, I don't think that should be a major problem.
--
-------------------------------------------------------------------------------
supe...@mcs.com | "Je crois que je ne vais jamais voir... | J\_/L
John Payson | Un animal aussi beau qu'un chat." | ( o o )

Roman Fietze

unread,
Dec 14, 1995, 3:00:00 AM12/14/95
to
In article <4ak53i$k...@shellx.best.com> Olaf 'Olu' Pfeiffer <pfei...@hitex.com> writes:

bs...@bugmotel.eng.sun.com (Jan Brittenson) wrote:

>Unfortunately, it's not a very good compiler. Its CSE, logic folding,

>and register allocation is almost non-existant. It generates function
>calls that cost as much or more just to setup than to inline the
>function. This is the code I used to evaluate it for a hobby project.
>Obviously, if all you do is trivial 8- and 16-bit arithmetic with tiny
>data and place few demands on the compiler, then it might do just
>fine.

...

the version you used for testing is "really" light. I hope that
someone from Keil (Jon - R U ?) will do a follow up on this...

Their C51 compiler is known to be one of the best. That's why
so many others sell it under their own brand name ;-)

That's why Microseft sells so many copies of their windowing toy :)

The standard benchmarks like Dhrystone, Whetstone and
Sieve of Erosthostenes show that Keil and BSO are both far
ahead of their competition.

Does anybody have these Benchmarks available or do you have an
internet * to them?

I know that the IAR C compiler is a the same speed or a little bit
faster than the BSO when you use the memory models where you put the
auto variables in internal RAM. But when it comes to reentrancy, the
BSO wins by factors of 2 or 3. Check if you need reentrancy and then
do some small tests on the Keil again.

Roman
--
Roman Fietze (Mail Code 5023) Kodak AG Stuttgart/Germany
fie...@kagcpd01.ag01.kodak.COM fie...@kodak.COM

KeilSoftW

unread,
Dec 14, 1995, 3:00:00 AM12/14/95
to
>>Does anybody have these Benchmarks available or do you have an
>>internet * to them?

I have benchmarks, however, I don't want to start a benchmark writing
contest by posting them on the net. I really do have a lot more fun stuff
to do, like Christmas shopping (no, I haven't had time to even start) than
constantly update benchmark results.

If anyone wants to see the results, call us at 800-348-8051 or FAX us at
214-735-8055 and we will fax the results to you.

Jon Ward
Keil Software
800-348-8051

Thad Smith

unread,
Dec 17, 1995, 3:00:00 AM12/17/95
to
In article <4am5ef$k...@news-f.iadfw.net>,
jon...@airmail.net (Jon Ward) wrote:

>OK, Here's a challenge that will impress you. I bet you can't write
>your sample program in 8051 assembly that is more than 25% smaller
>than the code generated by our compiler. If you can beat our compiler
>by 25%, I'll sell you our compiler for the upgrade price.

In article <BSON.95De...@bugmotel.eng.sun.com>,
bs...@bugmotel.eng.sun.com (Jan Brittenson) wrote:

> What I did instead of recoding it all in assembler was to break out
> common expressions by hand (I've omitted the comments for brevity; the
> function I started with is included at the end):

...


> Obviously, a lot more could be done in terms of clever optimizations,
> but the above is what I might expect a compiler to do given what's in
> the original function (which I've only carefully rearranged to derive
> the above). The original function resulted in 352 bytes. The above
> compiles to 260 bytes -- 26% less.

I'd say that Jan met the challenge, assuming that the rewrite was
correct.

I compiled Jan's recoded version and compiled with Archimedes C51
5.02, which I understand is the latest Keil compiler, using no command
line options and looked at the output. Here are the most significant
opportunity for optimizations that I found:

(tmp3 is type long)
33 1 if (tmp3 > 0) {
Generated code:
009B 7F00 MOV R7,#00H
009D 7E00 MOV R6,#00H
009F 7D00 MOV R5,#00H
00A1 7C00 MOV R4,#00H
00A3 AB00 R MOV R3,tmp3+03H
00A5 AA00 R MOV R2,tmp3+02H
00A7 A900 R MOV R1,tmp3+01H
00A9 A800 R MOV R0,tmp3
00AB D3 SETB C
00AC 120000 E LCALL ?C?SLCMP
00AF 4037 JC done

Apparently ?C?SLCMP is a comparison routine for signed longs.
Since the right operand is 0, this can be tested by looking at tmp3
sign bit, then testing for 0:

mov A,tmp3
jb 7,ACC,done
orl tmp3+1
orl tmp3+2
orl tmp3+3
jz done

This segment used unneeded register temps:

40 3 *seglen -= tmp3;
(seglen is unsigned int*)

Generated code:
00CD A800 R MOV R0,seglen
00CF C000 PUSH AR0
00D1 E6 MOV A,@R0
00D2 FE MOV R6,A
00D3 08 INC R0
00D4 E6 MOV A,@R0
00D5 C3 CLR C
00D6 9500 R SUBB A,tmp3+03H
00D8 FF MOV R7,A
00D9 EE MOV A,R6
00DA 9500 R SUBB A,tmp3+02H
00DC D000 POP AR0
00DE F6 MOV @R0,A
00DF 08 INC R0
00E0 A607 MOV @R0,AR7

This can be made more efficient by processing strictly
ls to ms byte order:

mov r0,seglen
inc r0
clr c
mov a,@r0
subb a,tmp3+3
mov @r0,a
dec r0
mov a,@r0
subb a,tmp3+2
mov @r0,a

The rest of the code looked pretty darn good, although there was
a sequence:
mov r7,a
clr a
mov a,r7
add a,tmp+3
mov r7,a

By inspection, the first three instructions can be eliminated
entirely. This sequence was apparently part of a longer
sequence that was pruned by an optimization that discovered r4
and r5 already had zeros, and thus suppressed

mov r4,a
mov r5,a

following the clr a, but left in the clr a and the moves to and from r7.

BTW, I submitted a list of C51 compiler requests, including some
bugs, through Archimedes a few weeks ago. The list was
originally for Archimedes C51 5.01, but was updated for 5.02 and
resubmitted. Please contact me if you have not received the
list. If you are interested in further optimization suggestions, send
me email and I'll send some based on my own code.

Thad

0 new messages