]>
Commit | Line | Data |
---|---|---|
49bd1d27 | 1 | /* Machine description patterns for PowerPC running Darwin (Mac OS X). |
8d9254fc | 2 | Copyright (C) 2004-2020 Free Software Foundation, Inc. |
49bd1d27 SS |
3 | Contributed by Apple Computer Inc. |
4 | ||
713e31f4 | 5 | This file is part of GCC. |
49bd1d27 SS |
6 | |
7 | GNU CC is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
2f83c7d6 | 9 | the Free Software Foundation; either version 3, or (at your option) |
49bd1d27 SS |
10 | any later version. |
11 | ||
12 | GNU CC is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
2f83c7d6 NC |
18 | ;; along with GCC; see the file COPYING3. If not see |
19 | ;; <http://www.gnu.org/licenses/>. */ | |
49bd1d27 SS |
20 | |
21 | (define_insn "adddi3_high" | |
22 | [(set (match_operand:DI 0 "gpc_reg_operand" "=b") | |
23 | (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") | |
24 | (high:DI (match_operand 2 "" ""))))] | |
25 | "TARGET_MACHO && TARGET_64BIT" | |
b24a46be | 26 | "addis %0,%1,ha16(%2)") |
49bd1d27 | 27 | |
b8a55285 | 28 | (define_insn "movdf_low_si" |
c5dce79b | 29 | [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") |
b8a55285 AP |
30 | (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") |
31 | (match_operand 2 "" ""))))] | |
11d8d07e | 32 | "TARGET_MACHO && TARGET_HARD_FLOAT && !TARGET_64BIT" |
b8a55285 AP |
33 | { |
34 | switch (which_alternative) | |
35 | { | |
36 | case 0: | |
6c332313 | 37 | return "lfd %0,lo16(%2)(%1)"; |
b8a55285 AP |
38 | case 1: |
39 | { | |
b8a55285 AP |
40 | if (TARGET_POWERPC64 && TARGET_32BIT) |
41 | /* Note, old assemblers didn't support relocation here. */ | |
6c332313 | 42 | return "ld %0,lo16(%2)(%1)"; |
b8a55285 | 43 | else |
af8e8908 | 44 | { |
6c332313 SB |
45 | output_asm_insn ("la %0,lo16(%2)(%1)", operands); |
46 | output_asm_insn ("lwz %L0,4(%0)", operands); | |
47 | return ("lwz %0,0(%0)"); | |
af8e8908 | 48 | } |
b8a55285 AP |
49 | } |
50 | default: | |
992d08b1 | 51 | gcc_unreachable (); |
b8a55285 | 52 | } |
6c332313 | 53 | } |
b8a55285 AP |
54 | [(set_attr "type" "load") |
55 | (set_attr "length" "4,12")]) | |
56 | ||
57 | ||
49bd1d27 SS |
58 | (define_insn "movdf_low_di" |
59 | [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") | |
60 | (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") | |
61 | (match_operand 2 "" ""))))] | |
11d8d07e | 62 | "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT" |
07a38de7 SB |
63 | "@ |
64 | lfd %0,lo16(%2)(%1) | |
65 | ld %0,lo16(%2)(%1)" | |
b24a46be | 66 | [(set_attr "type" "load")]) |
49bd1d27 | 67 | |
b8a55285 AP |
68 | (define_insn "movdf_low_st_si" |
69 | [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") | |
70 | (match_operand 2 "" ""))) | |
71 | (match_operand:DF 0 "gpc_reg_operand" "f"))] | |
11d8d07e | 72 | "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" |
b8a55285 | 73 | "stfd %0,lo16(%2)(%1)" |
b24a46be | 74 | [(set_attr "type" "store")]) |
b8a55285 | 75 | |
49bd1d27 SS |
76 | (define_insn "movdf_low_st_di" |
77 | [(set (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") | |
78 | (match_operand 2 "" ""))) | |
79 | (match_operand:DF 0 "gpc_reg_operand" "f"))] | |
11d8d07e | 80 | "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT" |
49bd1d27 | 81 | "stfd %0,lo16(%2)(%1)" |
b24a46be | 82 | [(set_attr "type" "store")]) |
49bd1d27 | 83 | |
b8a55285 AP |
84 | (define_insn "movsf_low_si" |
85 | [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") | |
86 | (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") | |
87 | (match_operand 2 "" ""))))] | |
11d8d07e | 88 | "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" |
b8a55285 AP |
89 | "@ |
90 | lfs %0,lo16(%2)(%1) | |
6b39bc38 | 91 | lwz %0,lo16(%2)(%1)" |
b24a46be | 92 | [(set_attr "type" "load")]) |
b8a55285 | 93 | |
49bd1d27 SS |
94 | (define_insn "movsf_low_di" |
95 | [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") | |
96 | (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") | |
97 | (match_operand 2 "" ""))))] | |
11d8d07e | 98 | "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT" |
49bd1d27 SS |
99 | "@ |
100 | lfs %0,lo16(%2)(%1) | |
6b39bc38 | 101 | lwz %0,lo16(%2)(%1)" |
b24a46be | 102 | [(set_attr "type" "load")]) |
49bd1d27 | 103 | |
b8a55285 AP |
104 | (define_insn "movsf_low_st_si" |
105 | [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") | |
106 | (match_operand 2 "" ""))) | |
107 | (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] | |
11d8d07e | 108 | "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" |
b8a55285 AP |
109 | "@ |
110 | stfs %0,lo16(%2)(%1) | |
6b39bc38 | 111 | stw %0,lo16(%2)(%1)" |
b24a46be | 112 | [(set_attr "type" "store")]) |
b8a55285 | 113 | |
49bd1d27 SS |
114 | (define_insn "movsf_low_st_di" |
115 | [(set (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") | |
116 | (match_operand 2 "" ""))) | |
117 | (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] | |
11d8d07e | 118 | "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_64BIT" |
49bd1d27 SS |
119 | "@ |
120 | stfs %0,lo16(%2)(%1) | |
6b39bc38 | 121 | stw %0,lo16(%2)(%1)" |
b24a46be | 122 | [(set_attr "type" "store")]) |
49bd1d27 SS |
123 | |
124 | ;; 64-bit MachO load/store support | |
49bd1d27 | 125 | |
23cb6f8e | 126 | ;; Mach-O PIC. |
b8a55285 | 127 | |
23cb6f8e IS |
128 | (define_insn "@macho_high_<mode>" |
129 | [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") | |
130 | (high:P (match_operand 1 "" "")))] | |
131 | "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN)" | |
6b39bc38 | 132 | "lis %0,ha16(%1)") |
49bd1d27 | 133 | |
7a40dd5a IS |
134 | (define_insn "@macho_low_<mode>" |
135 | [(set (match_operand:P 0 "gpc_reg_operand" "=r") | |
136 | (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") | |
49bd1d27 | 137 | (match_operand 2 "" "")))] |
7a40dd5a | 138 | "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN)" |
76f93d99 | 139 | "la %0,lo16(%2)(%1)") |
49bd1d27 SS |
140 | |
141 | (define_split | |
ad18eed2 SB |
142 | [(set (mem:V4SI (plus:DI (match_operand:DI 0 "gpc_reg_operand") |
143 | (match_operand:DI 1 "short_cint_operand"))) | |
144 | (match_operand:V4SI 2 "register_operand")) | |
145 | (clobber (match_operand:DI 3 "gpc_reg_operand"))] | |
49bd1d27 SS |
146 | "TARGET_MACHO && TARGET_64BIT" |
147 | [(set (match_dup 3) (plus:DI (match_dup 0) (match_dup 1))) | |
148 | (set (mem:V4SI (match_dup 3)) | |
149 | (match_dup 2))] | |
150 | "") | |
151 | ||
576113ab IS |
152 | (define_insn "@macho_correct_pic_<mode>" |
153 | [(set (match_operand:P 0 "gpc_reg_operand" "=r") | |
154 | (plus:P (match_operand:P 1 "gpc_reg_operand" "r") | |
155 | (unspec:P [(match_operand:P 2 "immediate_operand" "s") | |
156 | (match_operand:P 3 "immediate_operand" "s")] | |
157 | UNSPEC_MPIC_CORRECT)))] | |
158 | "DEFAULT_ABI == ABI_DARWIN" | |
159 | "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" | |
160 | [(set_attr "length" "8")]) | |
161 | ||
4fc1d262 | 162 | (define_insn "@load_macho_picbase_<mode>" |
dd9ed099 IS |
163 | [(set (reg:P LR_REGNO) |
164 | (unspec:P [(match_operand:P 0 "immediate_operand" "s") | |
d5b5b8bf | 165 | (pc)] UNSPEC_LD_MPIC))] |
b8a55285 | 166 | "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" |
e1c5c877 | 167 | { |
bd9534e2 | 168 | #if TARGET_MACHO |
e1c5c877 | 169 | machopic_should_output_picbase_label (); /* Update for new func. */ |
bd9534e2 IS |
170 | #else |
171 | gcc_unreachable (); | |
172 | #endif | |
6c332313 | 173 | return "bcl 20,31,%0\n%0:"; |
e1c5c877 | 174 | } |
b8a55285 | 175 | [(set_attr "type" "branch") |
a79db151 | 176 | (set_attr "cannot_copy" "yes")]) |
b8a55285 | 177 | |
4fc1d262 | 178 | (define_insn "@reload_macho_picbase_<mode>" |
dd9ed099 IS |
179 | [(set (reg:P LR_REGNO) |
180 | (unspec:P [(match_operand:P 0 "immediate_operand" "s") | |
e1c5c877 IS |
181 | (pc)] UNSPEC_RELD_MPIC))] |
182 | "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" | |
183 | { | |
bd9534e2 | 184 | #if TARGET_MACHO |
e1c5c877 IS |
185 | if (machopic_should_output_picbase_label ()) |
186 | { | |
187 | static char tmp[64]; | |
188 | const char *cnam = machopic_get_function_picbase (); | |
6c332313 | 189 | snprintf (tmp, 64, "bcl 20,31,%s\n%s:\n%%0:", cnam, cnam); |
e1c5c877 IS |
190 | return tmp; |
191 | } | |
192 | else | |
bd9534e2 IS |
193 | #else |
194 | gcc_unreachable (); | |
195 | #endif | |
6c332313 | 196 | return "bcl 20,31,%0\n%0:"; |
e1c5c877 IS |
197 | } |
198 | [(set_attr "type" "branch") | |
a79db151 | 199 | (set_attr "cannot_copy" "yes")]) |
e1c5c877 IS |
200 | |
201 | ;; We need to restore the PIC register, at the site of nonlocal label. | |
202 | ||
203 | (define_insn_and_split "nonlocal_goto_receiver" | |
204 | [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)] | |
205 | "TARGET_MACHO && flag_pic" | |
206 | "#" | |
207 | "&& reload_completed" | |
208 | [(const_int 0)] | |
209 | { | |
bd9534e2 | 210 | #if TARGET_MACHO |
e1c5c877 IS |
211 | if (crtl->uses_pic_offset_table) |
212 | { | |
213 | static unsigned n = 0; | |
214 | rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); | |
215 | rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); | |
216 | rtx tmplrtx; | |
217 | char tmplab[20]; | |
218 | ||
219 | ASM_GENERATE_INTERNAL_LABEL(tmplab, "Lnlgr", ++n); | |
220 | tmplrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); | |
221 | ||
4fc1d262 | 222 | emit_insn (gen_reload_macho_picbase (Pmode, tmplrtx)); |
e1c5c877 | 223 | emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); |
576113ab IS |
224 | emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg, |
225 | picrtx, tmplrtx)); | |
e1c5c877 IS |
226 | } |
227 | else | |
228 | /* Not using PIC reg, no reload needed. */ | |
229 | emit_note (NOTE_INSN_DELETED); | |
bd9534e2 IS |
230 | #else |
231 | gcc_unreachable (); | |
232 | #endif | |
e1c5c877 IS |
233 | DONE; |
234 | }) |