Path: utzoo!utgpu!water!watmath!clyde!att!mtunx!mtune!codas!peora!ge-dab!ge-rtp!edison!toylnd!dca From: dca@toylnd.UUCP (David C. Albrecht) Newsgroups: comp.sys.amiga.tech Subject: Lattice 4.1 register yuck! Message-ID: <222@toylnd.UUCP> Date: 18 Jun 88 02:16:24 GMT Organization: Dave & Anne in Charlottesville, VA Lines: 148 Oooh, I'm annoyed. For those of you that use Lattice 4.1 I have found what I consider a big BUG. Not the 'code doesn't work variety' but rather the 'produces lousy code' type. I have developed over the last year or so the instincts of localizing register variables and auto variables with their area of usage to give maximum efficiency in register allocation and use of stack space. Come to find out this can produce worse code than not using register declarations at all. Gack! Ack! Phooey! Example: If I was to loop through an array assigning the elements to a value I might have: { register short i; for (i = 0; i < MAX_SIZE; i++) { some_array[i] = -1; } } One expects the register variable i to be dead after the last brace and thus available for re-use, right? Wrongo! Lattice doesn't think so. Or how bout this: { short i[100]; i[0] = 12; } You would expect the space for i on the stack to be freed after the last brace for re-use. Nope. Want proof? Take a look at the following code section: main(argc,argv) int argc; char **argv; { { register long r1, r2, r3, r4, r5; long a[1]; r1 = 0; a[r1] = 1; r2 = 2; r3 = 3; r4 = 4; r5 = r4 + r3; a[r1] = r1 + r2; } { register long r1, r2, r3, r4; long a[1]; r1 = 0; a[r1] = r1 + r1; r2 = 2; r3 = 3; r4 = a[r1]; } } Now lets look at the omd: Some notes: Lattice seems to reserve D0-D3 for its use and allocates starting with D0. It allocates D4-D7 to register variables and starts with D7. LATTICE OBJECT MODULE DISASSEMBLER V2.00 Amiga Object File Loader V1.00 68000 Instruction Set EXTERNAL DEFINITIONS _main 0000-00 SECTION 00 "testcase.o" 00000054 BYTES main(argc,argv) int argc; char **argv; { 0000 4E55FFE8 LINK A5,FFE8 0004 48E73F00 MOVEM.L D2-D7,-(A7) { register long r1, r2, r3, r4, r5; long a[1]; r1 = 0; 0008 7E00 MOVEQ #00,D7 First register alloc a[r1] = 1; 000A 2007 MOVE.L D7,D0 First lattice reg 000C 2200 MOVE.L D0,D1 Second lattice reg 000E E541 ASL.W #2,D1 0010 7401 MOVEQ #01,D2 Third lattice reg 0012 2B8210E8 MOVE.L D2,E8(A5,D1.W) Note a[] is at E8. r2 = 2; 0016 7C02 MOVEQ #02,D6 Second register alloc r3 = 3; 0018 7A03 MOVEQ #03,D5 Third register alloc r4 = 4; 001A 7804 MOVEQ #04,D4 Last register alloc r5 = r4 + r3; 001C 2404 MOVE.L D4,D2 Reuse lattice reg 001E 2404 MOVE.L D4,D2 ? 0020 D485 ADD.L D5,D2 a[r1] = r1 + r2; 0022 2607 MOVE.L D7,D3 Last lattice reg 0024 2600 MOVE.L D0,D3 0026 D686 ADD.L D6,D3 0028 2B8310E8 MOVE.L D3,E8(A5,D1.W) } { register long r1, r2, r3, r4; long a[1]; r1 = 0; Note that it put r1 in 002C 7200 MOVEQ #00,D1 a lattice reg not a user reg. a[r1] = r1 + r1; 002E 2601 MOVE.L D1,D3 0030 E543 ASL.W #2,D3 0032 2001 MOVE.L D1,D0 0034 D081 ADD.L D1,D0 0036 2B8030EC MOVE.L D0,EC(A5,D3.W) Note a[] is at EC. r2 = 2; Out of lattice regs 003A 7002 MOVEQ #02,D0 Saves r2 on the stack 003C 2B40FFF8 MOVE.L D0,FFF8(A5) gag! r3 = 3; Ditto! 0040 7003 MOVEQ #03,D0 0042 2B40FFF4 MOVE.L D0,FFF4(A5) r4 = a[r1]; Ditto again. 0046 2B7530ECFFF0 MOVE.L EC(A5,D3.W),FFF0(A5) } } 004C 4CDF00FC MOVEM.L (A7)+,D2-D7 0050 4E5D UNLK A5 0052 4E75 RTS SECTION 01 "__MERGED" 00000000 BYTES Moral of the story is check your register variables they may not be producing the code you expect. We are not amused. Time to go find the LBBS number. Growl, snarl, snap. David Albrecht