Re: Jump to registers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Alessandro Pellegrini wrote:

> So, the final question is: when does gcc produces that 
> kind of jumps? Is it possible to tell gcc to avoid generation of such 
> code?

I'm sure it is.  Rather than answering your first question, I'm going
to show you how to find out for yourself.

1.  Use the option -dP -save-temps -v.  This produces assembler like:

main:
.LFB0:
	.cfi_startproc
#(insn/f 26 6 27 hello.c:5 (set (mem:DI (pre_dec:DI (reg/f:DI 7 sp)) [0 S8 A8])
#        (reg/f:DI 6 bp)) 82 {*pushdi2_rex64} (nil))
	pushq	%rbp	# 26	*pushdi2_rex64/1	[length = 1]

Note that every assembly instruction is accompanied by the RTL that
corresponds to that instruction.  Note also that the first number in
each line of RTL is the number of that insn.

The -v option tells you the options used to run cc1.
Now, run cc1 under gdb:

zebedee:~ $ gdb  /home/aph/gcc/trunk/install/libexec/gcc/x86_64-unknown-linux-gnu/4.4.0/cc1
GNU gdb Red Hat Linux (6.6-3.fc7rh)
Copyright (C) 2006 Free Software Foundation, Inc.

Put a breakpoint on make_insn_raw:

(gdb) b make_insn_raw
Breakpoint 1 at 0x52aaa0: file /home/aph/gcc/trunk/gcc/emit-rtl.c, line 3410.
(gdb) cd ~
Working directory /home/aph.

Make the breakpoint conditional on the insn you're interested in: this one
is number 26.

(gdb) cond 1 ( (&x_rtl)->emit.x_cur_insn_uid) == 26
(gdb) r -fpreprocessed hello.i -quiet -dumpbase hello.c -dP -mtune=generic -auxbase hello -version -o hello.s
(gdb)
Starting program: /home/aph/gcc/trunk/install/libexec/gcc/x86_64-unknown-linux-gnu/4.4.0/cc1 -fpreprocessed hello.i -quiet -dumpbase hello.c -dP -mtune=generic -auxbase hello -version -o hello.s
GNU C (GCC) version 4.4.0 20081104 (experimental) (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.1.2 20070626 (Red Hat 4.1.2-13), GMP version 4.2.2, MPFR version 2.3.0-p2.
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 80c040c98b6e848eeea2b26609c8bed8

Breakpoint 1, make_insn_raw (pattern=0x2aaaae3a8360)
    at /home/aph/gcc/trunk/gcc/emit-rtl.c:3410
3410    {
(gdb) p debug_rtx(pattern)
(set (mem:DI (pre_dec:DI (reg/f:DI 7 sp)) [0 S8 A8])
    (reg/f:DI 6 bp))
$1 = void
(gdb) up
#1  0x000000000052ab56 in emit_insn (x=0x2aaaae3a8360)
    at /home/aph/gcc/trunk/gcc/emit-rtl.c:4446
4446          last = make_insn_raw (x);
(gdb) up
#2  0x00000000008955f0 in ix86_expand_prologue ()
    at /home/aph/gcc/trunk/gcc/config/i386/i386.c:7924
7924          insn = emit_insn (gen_push (hard_frame_pointer_rtx));
(gdb) up
#3  0x00000000009c4d7b in gen_prologue ()
    at /home/aph/gcc/trunk/gcc/config/i386/i386.md:15248
15248     "ix86_expand_prologue (); DONE;")
(gdb) up
#4  0x00000000005bb10b in rest_of_handle_thread_prologue_and_epilogue ()
    at /home/aph/gcc/trunk/gcc/function.c:4854
4854          seq = gen_prologue ();

Here you see that insn 26 was generated by ix86_expand_prologue ().

There's also make_jump_insn_raw , which is like make_insn_raw but
for jumps.

Now you can easily discover the code in gcc that generates any machine
instruction.  Enjoy!

Andrew.

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux