]> git.pld-linux.org Git - packages/crossavr-gcc.git/blob - 509-gcc-AVRTC-544-call-used-registers-tiny10.patch
- synchronized patches with official AVR toolchain 3.4.1.830
[packages/crossavr-gcc.git] / 509-gcc-AVRTC-544-call-used-registers-tiny10.patch
1 diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
2 --- gcc/config/avr/avr.c        2012-06-22 15:29:05.000000000 +0530
3 +++ gcc/config/avr/avr.c        2012-06-28 12:50:23.000000000 +0530
4 @@ -111,6 +111,9 @@ static void avr_help (void);
5  /* Allocate registers from r25 to r8 for parameters for function calls.  */
6  #define FIRST_CUM_REG 26
7  
8 +/* Last call saved register */
9 +#define LAST_CALLEE_SAVED_REG (AVR_TINY ? 21 : 17)
10 +
11  /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
12  static GTY(()) rtx tmp_reg_rtx;
13  
14 @@ -611,7 +614,7 @@ sequent_regs_live (void)
15    int live_seq=0;
16    int cur_seq=0;
17  
18 -  for (reg = 0; reg < 18; ++reg)
19 +  for (reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
20      {
21        if (fixed_regs[reg])
22          {
23 @@ -838,11 +841,11 @@ expand_prologue (void)
24  
25        /* Note that live_seq always contains r28+r29, but the other
26          registers to be saved are all below 18.  */
27 -      first_reg = 18 - (live_seq - 2);
28 +      first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
29  
30        for (reg = 29, offset = -live_seq + 1;
31            reg >= first_reg;
32 -          reg = (reg == 28 ? 17 : reg - 1), ++offset)
33 +          reg = (reg == 28 ? (LAST_CALLEE_SAVED_REG) : reg - 1), ++offset)
34         {
35           rtx m, r;
36  
37 @@ -6375,6 +6378,17 @@ order_regs_for_local_alloc (void)
38      0,1,
39      32,33,34,35
40    };
41 +  static const int tiny_order_0[] = {
42 +    24,25,
43 +    22,23,
44 +    30,31,
45 +    26,27,
46 +    28,29,
47 +    21,20,19,18,
48 +    16,17,
49 +    32,33,34,35,
50 +    15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
51 +  };
52    static const int order_1[] = {
53      18,19,
54      20,21,
55 @@ -6387,6 +6401,17 @@ order_regs_for_local_alloc (void)
56      0,1,
57      32,33,34,35
58    };
59 +  static const int tiny_order_1[] = {
60 +    22,23,
61 +    24,25,
62 +    30,31,
63 +    26,27,
64 +    28,29,
65 +    21,20,19,18,
66 +    16,17,
67 +    32,33,34,35,
68 +    15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
69 +  };
70    static const int order_2[] = {
71      25,24,
72      23,22,
73 @@ -6400,10 +6425,15 @@ order_regs_for_local_alloc (void)
74      1,0,
75      32,33,34,35
76    };
77 -  
78 -  const int *order = (TARGET_ORDER_1 ? order_1 :
79 -                     TARGET_ORDER_2 ? order_2 :
80 -                     order_0);
81
82 +  /*
83 +  Select specific register allocation order. Tiny Core (attiny4/5/9/10/20/40)
84 +  devices has only 16 registers, so different allocation order should be used
85 +  */ 
86 +  const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1) :
87 +                     TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_1 : order_2) :
88 +                                       (AVR_TINY ? tiny_order_0 : order_0));
89 +
90    for (i=0; i < ARRAY_SIZE (order_0); ++i)
91        reg_alloc_order[i] = order[i];
92  }
93 @@ -7395,15 +7425,45 @@ avr_output_addr_vec_elt (FILE *stream, i
94  
95  static void
96  avr_conditional_register_usage(void) {
97 -   if (AVR_TINY) {                             
98 -     int i;                                    
99 -     for (i = 0;  i <= 17;  i++) {             
100 -       fixed_regs[i] = 1;                      
101 -       call_used_regs[i] = 1;                  
102 -     }                                         
103 -       CLEAR_HARD_REG_SET(reg_class_contents[(int)ADDW_REGS]);           
104 -       CLEAR_HARD_REG_SET(reg_class_contents[(int)NO_LD_REGS]);           
105 -   }
106 +  if (AVR_TINY) {
107 +    int i;
108 +
109 +    const int tiny_reg_alloc_order[] = {
110 +      24,25,
111 +      22,23,
112 +      30,31,
113 +      26,27,
114 +      28,29,
115 +      21,20,19,18,
116 +      16,17,
117 +      32,33,34,35,
118 +      15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
119 +    };
120 +
121 +    /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list
122 +    - R0-R15 are not available in Tiny Core devices
123 +    - R16 and R17 are fixed registers
124 +    */
125 +    for (i = 0;  i <= 17;  i++) {
126 +      fixed_regs[i] = 1;
127 +      call_used_regs[i] = 1;
128 +    }
129 +
130 +    /* Set R18 to R21 as call used register 
131 +    - R18, R19, R20 and R21 are the call used registers in Tiny Core devices
132 +    */
133 +    for (i = 18; i <= LAST_CALLEE_SAVED_REG; i++) {
134 +      call_used_regs[i] = 0;
135 +    }
136 +
137 +    /*update register allocation order for Tiny Core devices */
138 +    for (i=0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++) {
139 +      reg_alloc_order[i] = tiny_reg_alloc_order[i];
140 +    }
141 +
142 +    CLEAR_HARD_REG_SET(reg_class_contents[(int)ADDW_REGS]);
143 +    CLEAR_HARD_REG_SET(reg_class_contents[(int)NO_LD_REGS]);
144 +  }
145  }
146  
147  /* Returns true if SCRATCH are safe to be allocated as a scratch
148 @@ -7553,13 +7613,20 @@ avr_asm_out_dtor (rtx symbol, int priori
149  static bool
150  avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
151  {
152 -  if (TYPE_MODE (type) == BLKmode)
153 -    {
154 -      HOST_WIDE_INT size = int_size_in_bytes (type);
155 -      return (size == -1 || size > 8);
156 -    }
157 +  HOST_WIDE_INT size = int_size_in_bytes (type);
158 +  HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8;
159 +
160 +  /* In avr, there are 8 return registers. But, for Tiny Core 
161 +  (attiny4/5/9/10/20/40) devices, only 4 registers available.
162 +  Return true if size is unknown or greater than the limit */
163 +  if ((size == -1) || (size > ret_size_limit))
164 +  {
165 +    return true;
166 +  }
167    else
168 +  {
169      return false;
170 +  }
171  }
172  
173  /* Worker function for CASE_VALUES_THRESHOLD.  */
This page took 0.08112 seconds and 3 git commands to generate.