From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,94472ba0fa186a8d X-Google-Attributes: gid103376,public From: mfb@mbunix.mitre.org (Michael F Brenner) Subject: Re: Ada on the super (packed arrays) Date: 1998/04/21 Message-ID: <6hiv6k$s0k@top.mitre.org>#1/1 X-Deja-AN: 346413106 Distribution: inet References: <6h7v0c$r68$1@bambi.zdv.Uni-Mainz.DE> <6hfjmg$hvt@top.mitre.org> Organization: The MITRE Corporation, Bedford Mass. Newsgroups: comp.lang.ada Date: 1998-04-21T00:00:00+00:00 List-Id: Mike > Gnat has good optimization. Gnat has good code generation > except for packed arrays. Robert is right about bench > marking your application with ALL of your data before > deciding what is fast and what is slow. Robert > Actually, this is probably an over-generalization. > Packed array stuff is notorious...a good challenge is Matt Weber's > x := x(1 .. 31) & x(0); > to do a simple rotate. Andi > It is surprising that Gnat doesn't do this. > At least the C frontend of gcc does a very similar optimization: /* Expects sizeof(unsigned int) == 4 */ int rotate(unsigned int i) {return (i << 1) | (i >> 31);} Compiled with -O2 on i386 Linux. Generated this code: rotate: pushl %ebp movl %esp,%ebp movl 8(%ebp),%eax roll $1,%eax ret Robert (paraphrased) > [the Weber concatenation is more general than the integer rotate -- comparable Ada code would generate comparable assembler code] I am trying to confirm this with comparable Ada code as follows: procedure tmp is use interfaces; x, y: unsigned_32 := 42; function rotate (i: unsigned_32) return unsigned_32 is begin return shift_left (i, 1) or shift_right (i, 31); end rotate; begin Y := rotate (x); end tmp; Compiling it with the parameters: gcc -c -dak -O3 -gnatn -gnatp tmp.adb for maximal optimization, the following code is generated: File tmp.adb.sched2: (insn:QI 4 16 14 (set (mem:SI (plus:SI (reg:SI 14 %sp) (const_int 100))) (reg:SI 2 %g2)) 106 {*movsi_insn} (nil) (expr_list:REG_DEAD (reg:SI 2 %g2) (nil))) (insn 14 4 15 (set (reg:SI 2 %g2) (ashift:SI (reg/v/u:SI 24 %i0) (const_int 1))) 330 {ashlsi3} (insn_list:REG_DEP_ANTI 4 (nil)) (nil)) (insn 15 14 18 (set (reg:SI 24 %i0) (lshiftrt:SI (reg/v/u:SI 24 %i0) (const_int 31))) 336 {lshrsi3} (insn_list:REG_DEP_ANTI 14 (nil)) (expr_list:REG_DEAD (reg/v/u:SI 24 %i0) (nil))) (insn 18 15 19 (set (reg/i:SI 24 %i0) (ior:SI (reg:SI 2 %g2) (reg:SI 24 %i0))) 265 {iorsi3} (insn_list 15 (insn_list 14 (nil))) (expr_list:REG_DEAD (reg:SI 2 %g2) (expr_list:REG_DEAD (reg:SI 24 %i0) (nil)))) This is doing two shifts and the OR operation rather than the single rotate. Robert, could you please show me how to rewrite this code and how to compile it so that it generates the rotate command instead of the two shifts and the OR command, like gcc generates for the C command? Thanks