diff options
Diffstat (limited to 'meta/recipes-devtools/elfutils/files/debian/0002-Add-support-for-mips64-abis-in-mips_retval.c.patch')
-rw-r--r-- | meta/recipes-devtools/elfutils/files/debian/0002-Add-support-for-mips64-abis-in-mips_retval.c.patch | 171 |
1 files changed, 0 insertions, 171 deletions
diff --git a/meta/recipes-devtools/elfutils/files/debian/0002-Add-support-for-mips64-abis-in-mips_retval.c.patch b/meta/recipes-devtools/elfutils/files/debian/0002-Add-support-for-mips64-abis-in-mips_retval.c.patch deleted file mode 100644 index aee00cba14..0000000000 --- a/meta/recipes-devtools/elfutils/files/debian/0002-Add-support-for-mips64-abis-in-mips_retval.c.patch +++ /dev/null | |||
@@ -1,171 +0,0 @@ | |||
1 | From fdaab18a65ed2529656baa64cb6169f34d7e507b Mon Sep 17 00:00:00 2001 | ||
2 | From: James Cowgill <james410@cowgill.org.uk> | ||
3 | Date: Mon, 5 Jan 2015 15:17:01 +0000 | ||
4 | Subject: [PATCH 2/3] Add support for mips64 abis in mips_retval.c | ||
5 | |||
6 | Signed-off-by: James Cowgill <james410@cowgill.org.uk> | ||
7 | |||
8 | Upstream-Status: Pending [from debian] | ||
9 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
10 | --- | ||
11 | backends/mips_retval.c | 104 ++++++++++++++++++++++++++++++++++++++++++++----- | ||
12 | 1 file changed, 94 insertions(+), 10 deletions(-) | ||
13 | |||
14 | diff --git a/backends/mips_retval.c b/backends/mips_retval.c | ||
15 | index 33f12a7..d5c6ef0 100644 | ||
16 | --- a/backends/mips_retval.c | ||
17 | +++ b/backends/mips_retval.c | ||
18 | @@ -91,6 +91,8 @@ enum mips_abi find_mips_abi(Elf *elf) | ||
19 | default: | ||
20 | if ((elf_flags & EF_MIPS_ABI2)) | ||
21 | return MIPS_ABI_N32; | ||
22 | + else if ((ehdr->e_ident[EI_CLASS] == ELFCLASS64)) | ||
23 | + return MIPS_ABI_N64; | ||
24 | } | ||
25 | |||
26 | /* GCC creates a pseudo-section whose name describes the ABI. */ | ||
27 | @@ -195,6 +197,57 @@ static const Dwarf_Op loc_aggregate[] = | ||
28 | }; | ||
29 | #define nloc_aggregate 1 | ||
30 | |||
31 | +/* Test if a struct member is a float */ | ||
32 | +static int is_float_child(Dwarf_Die *childdie) | ||
33 | +{ | ||
34 | + /* Test if this is actually a struct member */ | ||
35 | + if (dwarf_tag(childdie) != DW_TAG_member) | ||
36 | + return 0; | ||
37 | + | ||
38 | + /* Get type of member */ | ||
39 | + Dwarf_Attribute attr_mem; | ||
40 | + Dwarf_Die child_type_mem; | ||
41 | + Dwarf_Die *child_typedie = | ||
42 | + dwarf_formref_die(dwarf_attr_integrate(childdie, | ||
43 | + DW_AT_type, | ||
44 | + &attr_mem), &child_type_mem); | ||
45 | + | ||
46 | + if (dwarf_tag(child_typedie) != DW_TAG_base_type) | ||
47 | + return 0; | ||
48 | + | ||
49 | + /* Get base subtype */ | ||
50 | + Dwarf_Word encoding; | ||
51 | + if (dwarf_formudata (dwarf_attr_integrate (child_typedie, | ||
52 | + DW_AT_encoding, | ||
53 | + &attr_mem), &encoding) != 0) | ||
54 | + return 0; | ||
55 | + | ||
56 | + return encoding == DW_ATE_float; | ||
57 | +} | ||
58 | + | ||
59 | +/* Returns the number of fpregs which can be returned in the given struct */ | ||
60 | +static int get_struct_fpregs(Dwarf_Die *structtypedie) | ||
61 | +{ | ||
62 | + Dwarf_Die child_mem; | ||
63 | + int fpregs = 0; | ||
64 | + | ||
65 | + /* Get first structure member */ | ||
66 | + if (dwarf_child(structtypedie, &child_mem) != 0) | ||
67 | + return 0; | ||
68 | + | ||
69 | + do | ||
70 | + { | ||
71 | + /* Ensure this register is a float */ | ||
72 | + if (!is_float_child(&child_mem)) | ||
73 | + return 0; | ||
74 | + | ||
75 | + fpregs++; | ||
76 | + } | ||
77 | + while (dwarf_siblingof (&child_mem, &child_mem) == 0); | ||
78 | + | ||
79 | + return fpregs; | ||
80 | +} | ||
81 | + | ||
82 | int | ||
83 | mips_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) | ||
84 | { | ||
85 | @@ -240,6 +293,7 @@ mips_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) | ||
86 | tag = dwarf_tag (typedie); | ||
87 | } | ||
88 | |||
89 | + Dwarf_Word size; | ||
90 | switch (tag) | ||
91 | { | ||
92 | case -1: | ||
93 | @@ -258,8 +312,6 @@ mips_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) | ||
94 | case DW_TAG_enumeration_type: | ||
95 | case DW_TAG_pointer_type: | ||
96 | case DW_TAG_ptr_to_member_type: | ||
97 | - { | ||
98 | - Dwarf_Word size; | ||
99 | if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, | ||
100 | &attr_mem), &size) != 0) | ||
101 | { | ||
102 | @@ -289,7 +341,7 @@ mips_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) | ||
103 | if (size <= 4*regsize && abi == MIPS_ABI_O32) | ||
104 | return nloc_fpregquad; | ||
105 | |||
106 | - goto aggregate; | ||
107 | + goto large; | ||
108 | } | ||
109 | } | ||
110 | *locp = ABI_LOC(loc_intreg, regsize); | ||
111 | @@ -298,18 +350,50 @@ mips_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) | ||
112 | if (size <= 2*regsize) | ||
113 | return nloc_intregpair; | ||
114 | |||
115 | - /* Else fall through. Shouldn't happen though (at least with gcc) */ | ||
116 | - } | ||
117 | + /* Else pass in memory. Shouldn't happen though (at least with gcc) */ | ||
118 | + goto large; | ||
119 | |||
120 | case DW_TAG_structure_type: | ||
121 | case DW_TAG_class_type: | ||
122 | case DW_TAG_union_type: | ||
123 | - case DW_TAG_array_type: | ||
124 | - aggregate: | ||
125 | - /* XXX TODO: Can't handle structure return with other ABI's yet :-/ */ | ||
126 | - if ((abi != MIPS_ABI_O32) && (abi != MIPS_ABI_O64)) | ||
127 | - return -2; | ||
128 | + /* Handle special cases for structures <= 128 bytes in newer ABIs */ | ||
129 | + if (abi == MIPS_ABI_EABI32 || abi == MIPS_ABI_EABI64 || | ||
130 | + abi == MIPS_ABI_N32 || abi == MIPS_ABI_N64) | ||
131 | + { | ||
132 | + if (dwarf_aggregate_size (typedie, &size) == 0 && size <= 16) | ||
133 | + { | ||
134 | + /* | ||
135 | + * Special case in N64 / N32 - | ||
136 | + * structures containing only floats are returned in fp regs. | ||
137 | + * Everything else is returned in integer regs. | ||
138 | + */ | ||
139 | + if (tag != DW_TAG_union_type && | ||
140 | + (abi == MIPS_ABI_N32 || abi == MIPS_ABI_N64)) | ||
141 | + { | ||
142 | + int num_fpregs = get_struct_fpregs(typedie); | ||
143 | + if (num_fpregs == 1 || num_fpregs == 2) | ||
144 | + { | ||
145 | + *locp = loc_fpreg; | ||
146 | + if (num_fpregs == 1) | ||
147 | + return nloc_fpreg; | ||
148 | + else | ||
149 | + return nloc_fpregpair; | ||
150 | + } | ||
151 | + } | ||
152 | + | ||
153 | + *locp = loc_intreg; | ||
154 | + if (size <= 8) | ||
155 | + return nloc_intreg; | ||
156 | + else | ||
157 | + return nloc_intregpair; | ||
158 | + } | ||
159 | + } | ||
160 | + | ||
161 | + /* Fallthrough to handle large types */ | ||
162 | |||
163 | + case DW_TAG_array_type: | ||
164 | + large: | ||
165 | + /* Return large structures in memory */ | ||
166 | *locp = loc_aggregate; | ||
167 | return nloc_aggregate; | ||
168 | } | ||
169 | -- | ||
170 | 2.1.4 | ||
171 | |||