现在的位置: 首页 > 综合 > 正文

GCC’s bacl-end & assemble emission (5)

2013年05月08日 ⁄ 综合 ⁄ 共 5095字 ⁄ 字号 评论关闭


3.2.3.


Add RTL Template of Patterns into Decision
Sequence

For our define_insn example above, the type passed to add_to_sequence

at line 2467, is RECOG. And the parameter pattern

is the RTL template of the define_insn
pattern. For our example is:

[(set (reg 17)

      
(compare
(match_operand:DI 0 "nonimmediate_operand" "r,?mr")

            
 
(match_operand:DI 1 "const0_operand"
"n,n")))]

 

767 


static
struct
decision
*


768 


add_to_sequence
(rtx pattern, struct
decision_head
*last,                               
in genrecog.c

769 


             
const
char *position, enum
routine_type insn_type, int top)

770 


{

771 


 
RTX_CODE code;

772 


 

struct
decision
*this, *sub;

773 


 

struct
decision_test
*test;

774 


 

struct
decision_test
**place;

775 


 

char *subpos;

776 


 

size_t i;

777 


 

const
char *fmt;

778 


 
int depth = strlen (position);

779 


 
int len;

780 


 
enum
machine_mode mode;

781 

782 


 

if (depth > max_depth

)

783 


   

max_depth

= depth;

784 

785 


 
subpos = xmalloc (depth + 2);

786 


 
strcpy (subpos, position);

787 


 
subpos[depth + 1] = 0;

788 

789 


 

sub = this = new_decision
(position, last);

790 


 

place = &this->tests;

791 

792 


restart:

793 


 
mode = GET_MODE (pattern);

794 


 
code = GET_CODE (pattern);

795 

796 


 

switch
(code)

797 


 

{

798 


   

case
PARALLEL:

           

819 


     

break
;

820 

821 


   

case
MATCH_PARALLEL:

          

831 


   

case
MATCH_OPERAND:

832 


   

case
MATCH_SCRATCH:

833 


   

case
MATCH_OPERATOR:

834 


   

case
MATCH_INSN:

835 


   

{

           

915 


   

}

916 

917 


   

case
MATCH_OP_DUP:

           

932 


     

goto
fini;

933 

934 


   

case
MATCH_DUP:

935 


   

case
MATCH_PAR_DUP:

936 


     
code = UNKNOWN;

937 

938 


     

test = new_decision_test
(DT_dup,
&place);

939 


     

test->u.dup = XINT (pattern, 0);

940 


     

goto
fini;

941 

942 


   

case
ADDRESS:

943 


     

pattern = XEXP (pattern, 0);

944 


   

  
goto
restart;

945 

946 


   

default
:

947 


     

break
;

948 


 

}

 

When it first enters this function with the SET code, it will go to
the default statement at line 946. At this top level, the parameter position

is a null string (“”). And notice that at line 789, variable sub

and test

point to the same new allocated descision instance. See new_decision

below.

 

316 


static
struct
decision
*


317 


new_decision (const
char *position, struct
decision_head *last)                      
in
genrecog.c

318 


{

319 


 

struct
decision
*new = xcalloc (1, sizeof
(struct
decision));

320 

321 


 

new->success = *last;

322 


 

new->position = xstrdup (position);

323 


 

new->number = next_number

++;

324 

325 


 

last->first = last->last = new;

326 


 

return
new;

327 


}

 

At line 789, the second parameter passed to new_decision


is the variable
head

declared in make_insn_sequence

at line 2421. The new decision is linked at head, as following figure
indicates.

f1


figure
5


 : add RTL template into decistion sequence, figure 1

 

add_to_sequence (continued)

 

950 


 

fmt = GET_RTX_FORMAT (code);

951 


 

len = GET_RTX_LENGTH (code);

952 

953 


 
/* Do tests against the current node
first. 


*/

954 


 
for
(i = 0; i < (size_t) len; i++)

955 


 

{

956 


   

if (fmt[i] == 'i')

957 


   

{

958 


     

if (i == 0)

959 


     

{

960 


       

test = new_decision_test
(DT_elt_zero_int, &place);

961 


    

   
test->u.intval = XINT
(pattern, i);

962 


     

}

963 


     

else if (i == 1)

964 


     

{

965 


       

test = new_decision_test
(DT_elt_one_int, &place);

966 


       

test->u.intval = XINT
(pattern, i);

967 


     

}

968 


     

else

969 


       

abort ();

970 


   

}

971 


   

else if (fmt[i] == 'w')

972 


   

{

973 


     

/* If this value actually fits in an int, we
can use a switch

974 


       
statement here, so indicate that. 
*/

975 


     

enum
decision_type
type

976 


        

= ((int) XWINT
(pattern, i) == XWINT
(pattern, i))

977 


          
? DT_elt_zero_wide_safe :
DT_elt_zero_wide;

978 

979 


     

if (i != 0)

980 


       

abort ();

981 

982 


     

test = new_decision_test
(type,
&place);

983 


     

test->u.intval = XWINT
(pattern, i);

984 


   
}

985 


   
else if (fmt[i] == 'E')

986 


   

{

987 


     

if (i != 0)

988 


       

abort ();

989 

990 


     

test = new_decision_test
(DT_veclen,
&place);

991 


     

test->u.veclen = XVECLEN (pattern, i);

992 


   

}

993 


 

}

 

Here, we again begin handle the pattern according to its format set.
For every element in the format, an instance of decision_test is created via new_decision_test

,
which defines the test being taken.

 

331 


static
struct
decision_test
*                                                                         
in
genrecog.c


332 


new_decision_test
(enum
decision_type
type, struct
decision_test
***pplace)

333 


{

334 


 

struct
decision_test
**place = *pplace;

335 


 

struct
decision_test
*test;

336 

337 


 

test = xmalloc (sizeof
(*test));

338 


 

test->next = *place;

339 


 

test->type = type;

340 


 

*place = test;

341 

342 


 

place = &test->next;

343 


 

*pplace = place;

344 

345 


 

return
test;

346 


}

 

Above, here the second parameter passed to new_decision_test

– variable place

is
declared in add_to_sequence

at line 790, which points to the tests

field of variable this

– an instance of decision
created at line 789 in add_to_sequence

,
while this

is linked in the list beginning with variable head

in make_insn_sequence


at line 2421.

The function
looks giddily, let’s look it step by step.

f2

 

figure
6


 : new_decision_test, step 1

Till line 339,
we can get data indicated by above figure. See that the next

field of new created
decision_test points to the old decision_test. Then at line 440, pplace

, place

and this->tests

all point to the new node as inidcating by following figure.

f3

 

figure
7


 : new_decision_test, step 2

In rest of new_decision_test

, place

and pplace

will point to the address of
next

field of created node as shown by following figure.

f4

figure
8


 : new_decision_test, step 3

Then for next
node added in (in yellow
), till line
340, we can get following diagram.

f9

figure
9


 : new_decision_test, step 4

At last, pplace

, place

will point to the new adding node (in yellow
).

f10


figure
10


 : new_decision_test, step 5

From these figures

抱歉!评论已关闭.