1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
$NetBSD: patch-af,v 1.4 2002/03/28 10:11:52 jmc Exp $
--- ../gcc-2.95.3/gcc/config/arm/arm.c.orig 2001/04/23 11:59:30 1.1.1.2
+++ ../gcc-2.95.3/gcc/config/arm/arm.c 2001/12/19 23:14:50 1.4
@@ -281,7 +281,7 @@
if (ptr->string != NULL && ptr->string[0] != '\0')
{
- struct processors * sel;
+ const struct processors * sel;
for (sel = ptr->processors; sel->name != NULL; sel ++)
if (streq (ptr->string, sel->name))
@@ -566,7 +566,7 @@
if (!reload_completed
|| current_function_pretend_args_size
|| current_function_anonymous_args
- || ((get_frame_size () + current_function_outgoing_args_size != 0)
+ || ((arm_get_frame_size () + current_function_outgoing_args_size != 0)
&& !(TARGET_APCS && frame_pointer_needed)))
return 0;
@@ -5397,6 +5397,18 @@
return "";
}
+/* Generate a sequence of insns that will generate the correct return
+ address mask depending on the physical architecture that the program
+ is running on. */
+rtx
+arm_gen_return_addr_mask ()
+{
+ rtx reg = gen_reg_rtx (Pmode);
+
+ emit_insn (gen_return_addr_mask (reg));
+ return reg;
+}
+
/* Return nonzero if optimizing and the current function is volatile.
Such functions never return, and many memory cycles can be saved
by not storing register values that will never be needed again.
@@ -5828,11 +5840,71 @@
emit_insn (par);
}
+/* Calculate the size of the stack frame, taking into account any
+ padding that is required to ensure stack-alignment. */
+int arm_get_frame_size ()
+{
+ int regno;
+
+ int base_size = (get_frame_size () + 3) & ~3;
+ int entry_size = 0;
+ int live_regs_mask = 0;
+ int volatile_func = (optimize > 0
+ && TREE_THIS_VOLATILE (current_function_decl));
+
+ if (! TARGET_ATPCS_STACK_ALIGN)
+ return base_size;
+
+ /* We know that SP will be word aligned on entry, and we must
+ preserve that condition at any subroutine call. But those are
+ the only constraints. */
+
+ /* Space for variadic functions. */
+ if (current_function_pretend_args_size)
+ entry_size += current_function_pretend_args_size;
+
+ if (! volatile_func)
+ {
+ for (regno = 0; regno <= 10; regno++)
+ if (regs_ever_live[regno] && ! call_used_regs[regno])
+ live_regs_mask |= 1 << regno;
+
+ if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+ live_regs_mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
+
+ if (regs_ever_live[14])
+ live_regs_mask |= 0x4000;
+ }
+
+ if (frame_pointer_needed)
+ live_regs_mask |= 0xD800;
+
+ /* If we have to push any registers, we must also push lr as well. */
+ if (live_regs_mask)
+ live_regs_mask |= 0x4000;
+
+ for (regno = 0; regno < 16; regno++)
+ if (live_regs_mask & (1 << regno))
+ entry_size += 4;
+
+ if (! volatile_func)
+ {
+ for (regno = 23; regno > 15; regno--)
+ if (regs_ever_live[regno] && ! call_used_regs[regno])
+ entry_size += 12;
+ }
+
+ if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
+ base_size += 4;
+
+ return base_size;
+}
+
void
arm_expand_prologue ()
{
int reg;
- rtx amount = GEN_INT (-(get_frame_size ()
+ rtx amount = GEN_INT (-(arm_get_frame_size ()
+ current_function_outgoing_args_size));
int live_regs_mask = 0;
int store_arg_regs = 0;
|