gcc源代码分析 gen_rtx()函数

Gcc源代码分析,gcc-1.40

主要目的是找到rtl如何生成的?

rtl如何和i386.md连接起来的?

就把这两个问题解决了,即可。


emit_jump_insn()定义在emit-rtl.c文件中

被Expmed.c Expr.c Insn-emit.c Stmt.c中调用


/* Make an insn of code JUMP_INSN with pattern PATTERN
   and add it to the end of the doubly-linked list.  */

rtx
emit_jump_insn (pattern)
     rtx pattern;
{
  if (GET_CODE (pattern) == SEQUENCE)
    return emit_insn (pattern);
  else
    {
      register rtx insn = make_jump_insn_raw (pattern, NULL);
      add_insn (insn);
      return insn;
    }
}


#define GET_CODE(RTX)        ((enum rtx_code) ((RTX)->code))

在rtl.h中定义

rtx
gen_lowpart (mode, x)
     enum machine_mode mode;
     register rtx x;
{
  /* This case loses if X is a subreg.  To catch bugs early,
     complain if an invalid MODE is used even in other cases.  */
  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
      && GET_MODE_SIZE (mode) != GET_MODE_UNIT_SIZE (GET_MODE (x)))
    abort ();
  if (GET_MODE (x) == mode)
    return x;
  if (GET_CODE (x) == CONST_INT)
    return gen_rtx (CONST_INT, VOIDmode, INTVAL (x) & GET_MODE_MASK (mode));
  if (GET_CODE (x) == CONST_DOUBLE)





enum machine_mode {
#include "machmode.def"
MAX_MACHINE_MODE };


会调用 gen_rtx()函数  定义在emit-rtl.c文件中!!!



/* rtx gen_rtx (code, mode, [element1, ..., elementn])
**
**        This routine generates an RTX of the size specified by
**    <code>, which is an RTX code.   The RTX structure is initialized
**    from the arguments <element1> through <elementn>, which are
**    interpreted according to the specific RTX type's format.   The
**    special machine mode associated with the rtx (if any) is specified
**    in <mode>.
**
**        gen_rtx() can be invoked in a way which resembles the lisp-like
**    rtx it will generate.   For example, the following rtx structure:
**
**          (plus:QI (mem:QI (reg:SI 1))
**               (mem:QI (plusw:SI (reg:SI 2) (reg:SI 3))))
**
**        ...would be generated by the following C code:
**
**            gen_rtx (PLUS, QImode,
**            gen_rtx (MEM, QImode,
**            gen_rtx (REG, SImode, 1)),
**            gen_rtx (MEM, QImode,
**            gen_rtx (PLUS, SImode,
**                gen_rtx (REG, SImode, 2),
**                gen_rtx (REG, SImode, 3)))),
*/




/*VARARGS2*/
rtx
gen_rtx (va_alist)
     va_dcl
{
  va_list p;
  enum rtx_code code;
  enum machine_mode mode;
  register int i;        /* Array indices...            */
  register char *fmt;        /* Current rtx's format...        */
  register rtx rt_val;        /* RTX to return to caller...        */

  va_start (p);
  code = va_arg (p, enum rtx_code);
  mode = va_arg (p, enum machine_mode);

  if (code == CONST_INT)
    {
      int arg = va_arg (p, int);
      if (arg == 0)
    return const0_rtx;
      if (arg == 1)
    return const1_rtx;
      rt_val = rtx_alloc (code);
      INTVAL (rt_val) = arg;
    }
  else
    {
      rt_val = rtx_alloc (code);    /* Allocate the storage space.  */
      rt_val->mode = mode;        /* Store the machine mode...  */

      fmt = GET_RTX_FORMAT (code);    /* Find the right format...  */
      for (i = 0; i < GET_RTX_LENGTH (code); i++)
    {
      switch (*fmt++)
        {
        case '0':        /* Unused field.  */
          break;

        case 'i':        /* An integer?  */
          XINT (rt_val, i) = va_arg (p, int);            定义在gvarargs.h
          break;

        case 's':        /* A string?  */
          XSTR (rt_val, i) = va_arg (p, char *);
          break;

        case 'e':        /* An expression?  */
        case 'u':        /* An insn?  Same except when printing.  */
          XEXP (rt_val, i) = va_arg (p, rtx);
          break;

        case 'E':        /* An RTX vector?  */
          XVEC (rt_val, i) = va_arg (p, rtvec);
          break;

        default:
          abort();
        }
    }
    }
  va_end (p);
  return rt_val;        /* Return the new RTX...        */
}




#define GET_RTX_FORMAT(CODE)        (rtx_format[(int)(CODE)])    在rtl.h中


rtx_format 定义在rtl.c中






/* Indexed by rtx code, gives a sequence of operand-types for
   rtx's of that code.  The sequence is a C string in which
   each charcter describes one operand.  */

char *rtx_format[] = {
  /* "*" undefined.
         can cause a warning message
     "0" field is unused (or used in a phase-dependent manner)
         prints nothing
     "i" an integer
         prints the integer
     "s" a pointer to a string
         prints the string
     "S" like "s", but optional:
     the containing rtx may end before this operand
     "e" a pointer to an rtl expression
         prints the expression
     "E" a pointer to a vector that points to a number of rtl expressions
         prints a list of the rtl expressions
     "u" a pointer to another insn
         prints the uid of the insn.  */

#define DEF_RTL_EXPR(ENUM, NAME, FORMAT)   FORMAT ,
#include "rtl.def"        /* rtl expressions are defined here */
#undef DEF_RTL_EXPR
};





#define XINT(RTX, N)    ((RTX)->fld[N].rtint)    定义在rtl.h中




;; Call subroutine returning no value.
(define_insn "call"
  [(call (match_operand:QI 0 "indirect_operand" "m")
     (match_operand:SI 1 "general_operand" "g"))]
  ;; Operand 1 not really used on the m68000.
  ""
  "*
{
  if (GET_CODE (operands[0]) == MEM
      && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
    {
      operands[0] = XEXP (operands[0], 0);
      return \"call %*%0\";
    }
  else
    return \"call %0\";
}")




;; Function main

(note 2 0 3 "" NOTE_INSN_DELETED)

(note 3 2 4 "" NOTE_INSN_FUNCTION_BEG)

(note 4 3 6 "" NOTE_INSN_DELETED)

(insn 6 4 7 (set (mem:SI (pre_dec:SI (reg:SI 7)))
       (symbol_ref:SI ("*LC0"))) -1 (nil)
   (nil))

(call_insn 7 6 9 (set (reg:SI 0)
       (call (mem:QI (symbol_ref/v:SI ("printf")))
           (const_int 4))) -1 (nil)
   (nil))


(insn 9 7 10 (set (reg/i:SI 0)
       (const_int 0)) -1 (nil)
   (nil))

(insn 10 9 11 (use (reg/i:SI 0)) -1 (nil)
   (nil))

(jump_insn 11 10 12 (set (pc)
       (label_ref 15)) -1 (nil)
   (nil))

(barrier 12 11 13)

(note 13 12 15 "" NOTE_INSN_FUNCTION_END)

(code_label 15 13 0 1)





    .file    "hello.c"
gcc_compiled.:
.text
LC0:
    .ascii "Hello, world!\12\0"
    .align 2
.globl _main
_main:
    pushl %ebp
    movl %esp,%ebp
    pushl $LC0
    call _printf
    xorl %eax,%eax
    jmp L1
    .align 2
L1:
    leave
    ret
 

你可能感兴趣的:(gcc)