]>
Commit | Line | Data |
---|---|---|
7f71f849 JR |
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. */ |