1//
2// Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
3// Copyright (c) 2012, 2016 SAP SE. All rights reserved.
4// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5//
6// This code is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License version 2 only, as
8// published by the Free Software Foundation.
9//
10// This code is distributed in the hope that it will be useful, but WITHOUT
11// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13// version 2 for more details (a copy is included in the LICENSE file that
14// accompanied this code).
15//
16// You should have received a copy of the GNU General Public License version
17// 2 along with this work; if not, write to the Free Software Foundation,
18// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19//
20// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21// or visit www.oracle.com if you need additional information or have any
22// questions.
23//
24//
25
26//
27// PPC64 Architecture Description File
28//
29
30//----------REGISTER DEFINITION BLOCK------------------------------------------
31// This information is used by the matcher and the register allocator to
32// describe individual registers and classes of registers within the target
33// architecture.
34register %{
35//----------Architecture Description Register Definitions----------------------
36// General Registers
37// "reg_def"  name (register save type, C convention save type,
38//                  ideal register type, encoding);
39//
40// Register Save Types:
41//
42//   NS  = No-Save:     The register allocator assumes that these registers
43//                      can be used without saving upon entry to the method, &
44//                      that they do not need to be saved at call sites.
45//
46//   SOC = Save-On-Call: The register allocator assumes that these registers
47//                      can be used without saving upon entry to the method,
48//                      but that they must be saved at call sites.
49//                      These are called "volatiles" on ppc.
50//
51//   SOE = Save-On-Entry: The register allocator assumes that these registers
52//                      must be saved before using them upon entry to the
53//                      method, but they do not need to be saved at call
54//                      sites.
55//                      These are called "nonvolatiles" on ppc.
56//
57//   AS  = Always-Save:   The register allocator assumes that these registers
58//                      must be saved before using them upon entry to the
59//                      method, & that they must be saved at call sites.
60//
61// Ideal Register Type is used to determine how to save & restore a
62// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
63// spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
64//
65// The encoding number is the actual bit-pattern placed into the opcodes.
66//
67// PPC64 register definitions, based on the 64-bit PowerPC ELF ABI
68// Supplement Version 1.7 as of 2003-10-29.
69//
70// For each 64-bit register we must define two registers: the register
71// itself, e.g. R3, and a corresponding virtual other (32-bit-)'half',
72// e.g. R3_H, which is needed by the allocator, but is not used
73// for stores, loads, etc.
74
75// ----------------------------
76// Integer/Long Registers
77// ----------------------------
78
79  // PPC64 has 32 64-bit integer registers.
80
81  // types: v = volatile, nv = non-volatile, s = system
82  reg_def R0   ( SOC, SOC, Op_RegI,  0, R0->as_VMReg()         );  // v   used in prologs
83  reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() );
84  reg_def R1   ( NS,  NS,  Op_RegI,  1, R1->as_VMReg()         );  // s   SP
85  reg_def R1_H ( NS,  NS,  Op_RegI, 99, R1->as_VMReg()->next() );
86  reg_def R2   ( SOC, SOC, Op_RegI,  2, R2->as_VMReg()         );  // v   TOC
87  reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() );
88  reg_def R3   ( SOC, SOC, Op_RegI,  3, R3->as_VMReg()         );  // v   iarg1 & iret
89  reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() );
90  reg_def R4   ( SOC, SOC, Op_RegI,  4, R4->as_VMReg()         );  //     iarg2
91  reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() );
92  reg_def R5   ( SOC, SOC, Op_RegI,  5, R5->as_VMReg()         );  // v   iarg3
93  reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() );
94  reg_def R6   ( SOC, SOC, Op_RegI,  6, R6->as_VMReg()         );  // v   iarg4
95  reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() );
96  reg_def R7   ( SOC, SOC, Op_RegI,  7, R7->as_VMReg()         );  // v   iarg5
97  reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() );
98  reg_def R8   ( SOC, SOC, Op_RegI,  8, R8->as_VMReg()         );  // v   iarg6
99  reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() );
100  reg_def R9   ( SOC, SOC, Op_RegI,  9, R9->as_VMReg()         );  // v   iarg7
101  reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() );
102  reg_def R10  ( SOC, SOC, Op_RegI, 10, R10->as_VMReg()        );  // v   iarg8
103  reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next());
104  reg_def R11  ( SOC, SOC, Op_RegI, 11, R11->as_VMReg()        );  // v   ENV / scratch
105  reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next());
106  reg_def R12  ( SOC, SOC, Op_RegI, 12, R12->as_VMReg()        );  // v   scratch
107  reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next());
108  reg_def R13  ( NS,  NS,  Op_RegI, 13, R13->as_VMReg()        );  // s   system thread id
109  reg_def R13_H( NS,  NS,  Op_RegI, 99, R13->as_VMReg()->next());
110  reg_def R14  ( SOC, SOE, Op_RegI, 14, R14->as_VMReg()        );  // nv
111  reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next());
112  reg_def R15  ( SOC, SOE, Op_RegI, 15, R15->as_VMReg()        );  // nv
113  reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next());
114  reg_def R16  ( SOC, SOE, Op_RegI, 16, R16->as_VMReg()        );  // nv
115  reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next());
116  reg_def R17  ( SOC, SOE, Op_RegI, 17, R17->as_VMReg()        );  // nv
117  reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next());
118  reg_def R18  ( SOC, SOE, Op_RegI, 18, R18->as_VMReg()        );  // nv
119  reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next());
120  reg_def R19  ( SOC, SOE, Op_RegI, 19, R19->as_VMReg()        );  // nv
121  reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next());
122  reg_def R20  ( SOC, SOE, Op_RegI, 20, R20->as_VMReg()        );  // nv
123  reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next());
124  reg_def R21  ( SOC, SOE, Op_RegI, 21, R21->as_VMReg()        );  // nv
125  reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next());
126  reg_def R22  ( SOC, SOE, Op_RegI, 22, R22->as_VMReg()        );  // nv
127  reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next());
128  reg_def R23  ( SOC, SOE, Op_RegI, 23, R23->as_VMReg()        );  // nv
129  reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next());
130  reg_def R24  ( SOC, SOE, Op_RegI, 24, R24->as_VMReg()        );  // nv
131  reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next());
132  reg_def R25  ( SOC, SOE, Op_RegI, 25, R25->as_VMReg()        );  // nv
133  reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next());
134  reg_def R26  ( SOC, SOE, Op_RegI, 26, R26->as_VMReg()        );  // nv
135  reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next());
136  reg_def R27  ( SOC, SOE, Op_RegI, 27, R27->as_VMReg()        );  // nv
137  reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next());
138  reg_def R28  ( SOC, SOE, Op_RegI, 28, R28->as_VMReg()        );  // nv
139  reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next());
140  reg_def R29  ( SOC, SOE, Op_RegI, 29, R29->as_VMReg()        );  // nv
141  reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next());
142  reg_def R30  ( SOC, SOE, Op_RegI, 30, R30->as_VMReg()        );  // nv
143  reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next());
144  reg_def R31  ( SOC, SOE, Op_RegI, 31, R31->as_VMReg()        );  // nv
145  reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next());
146
147
148// ----------------------------
149// Float/Double Registers
150// ----------------------------
151
152  // Double Registers
153  // The rules of ADL require that double registers be defined in pairs.
154  // Each pair must be two 32-bit values, but not necessarily a pair of
155  // single float registers. In each pair, ADLC-assigned register numbers
156  // must be adjacent, with the lower number even. Finally, when the
157  // CPU stores such a register pair to memory, the word associated with
158  // the lower ADLC-assigned number must be stored to the lower address.
159
160  // PPC64 has 32 64-bit floating-point registers. Each can store a single
161  // or double precision floating-point value.
162
163  // types: v = volatile, nv = non-volatile, s = system
164  reg_def F0   ( SOC, SOC, Op_RegF,  0, F0->as_VMReg()         );  // v   scratch
165  reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() );
166  reg_def F1   ( SOC, SOC, Op_RegF,  1, F1->as_VMReg()         );  // v   farg1 & fret
167  reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() );
168  reg_def F2   ( SOC, SOC, Op_RegF,  2, F2->as_VMReg()         );  // v   farg2
169  reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() );
170  reg_def F3   ( SOC, SOC, Op_RegF,  3, F3->as_VMReg()         );  // v   farg3
171  reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() );
172  reg_def F4   ( SOC, SOC, Op_RegF,  4, F4->as_VMReg()         );  // v   farg4
173  reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() );
174  reg_def F5   ( SOC, SOC, Op_RegF,  5, F5->as_VMReg()         );  // v   farg5
175  reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() );
176  reg_def F6   ( SOC, SOC, Op_RegF,  6, F6->as_VMReg()         );  // v   farg6
177  reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() );
178  reg_def F7   ( SOC, SOC, Op_RegF,  7, F7->as_VMReg()         );  // v   farg7
179  reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() );
180  reg_def F8   ( SOC, SOC, Op_RegF,  8, F8->as_VMReg()         );  // v   farg8
181  reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() );
182  reg_def F9   ( SOC, SOC, Op_RegF,  9, F9->as_VMReg()         );  // v   farg9
183  reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() );
184  reg_def F10  ( SOC, SOC, Op_RegF, 10, F10->as_VMReg()        );  // v   farg10
185  reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next());
186  reg_def F11  ( SOC, SOC, Op_RegF, 11, F11->as_VMReg()        );  // v   farg11
187  reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next());
188  reg_def F12  ( SOC, SOC, Op_RegF, 12, F12->as_VMReg()        );  // v   farg12
189  reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next());
190  reg_def F13  ( SOC, SOC, Op_RegF, 13, F13->as_VMReg()        );  // v   farg13
191  reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next());
192  reg_def F14  ( SOC, SOE, Op_RegF, 14, F14->as_VMReg()        );  // nv
193  reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next());
194  reg_def F15  ( SOC, SOE, Op_RegF, 15, F15->as_VMReg()        );  // nv
195  reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next());
196  reg_def F16  ( SOC, SOE, Op_RegF, 16, F16->as_VMReg()        );  // nv
197  reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next());
198  reg_def F17  ( SOC, SOE, Op_RegF, 17, F17->as_VMReg()        );  // nv
199  reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next());
200  reg_def F18  ( SOC, SOE, Op_RegF, 18, F18->as_VMReg()        );  // nv
201  reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next());
202  reg_def F19  ( SOC, SOE, Op_RegF, 19, F19->as_VMReg()        );  // nv
203  reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next());
204  reg_def F20  ( SOC, SOE, Op_RegF, 20, F20->as_VMReg()        );  // nv
205  reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next());
206  reg_def F21  ( SOC, SOE, Op_RegF, 21, F21->as_VMReg()        );  // nv
207  reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next());
208  reg_def F22  ( SOC, SOE, Op_RegF, 22, F22->as_VMReg()        );  // nv
209  reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next());
210  reg_def F23  ( SOC, SOE, Op_RegF, 23, F23->as_VMReg()        );  // nv
211  reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next());
212  reg_def F24  ( SOC, SOE, Op_RegF, 24, F24->as_VMReg()        );  // nv
213  reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next());
214  reg_def F25  ( SOC, SOE, Op_RegF, 25, F25->as_VMReg()        );  // nv
215  reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next());
216  reg_def F26  ( SOC, SOE, Op_RegF, 26, F26->as_VMReg()        );  // nv
217  reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next());
218  reg_def F27  ( SOC, SOE, Op_RegF, 27, F27->as_VMReg()        );  // nv
219  reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next());
220  reg_def F28  ( SOC, SOE, Op_RegF, 28, F28->as_VMReg()        );  // nv
221  reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next());
222  reg_def F29  ( SOC, SOE, Op_RegF, 29, F29->as_VMReg()        );  // nv
223  reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next());
224  reg_def F30  ( SOC, SOE, Op_RegF, 30, F30->as_VMReg()        );  // nv
225  reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next());
226  reg_def F31  ( SOC, SOE, Op_RegF, 31, F31->as_VMReg()        );  // nv
227  reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next());
228
229// ----------------------------
230// Special Registers
231// ----------------------------
232
233// Condition Codes Flag Registers
234
235  // PPC64 has 8 condition code "registers" which are all contained
236  // in the CR register.
237
238  // types: v = volatile, nv = non-volatile, s = system
239  reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg());  // v
240  reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg());  // v
241  reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg());  // nv
242  reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg());  // nv
243  reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg());  // nv
244  reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg());  // v
245  reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg());  // v
246  reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg());  // v
247
248  // Special registers of PPC64
249
250  reg_def SR_XER(    SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg());     // v
251  reg_def SR_LR(     SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg());      // v
252  reg_def SR_CTR(    SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg());     // v
253  reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg());  // v
254  reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v
255  reg_def SR_PPR(    SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg());     // v
256
257
258// ----------------------------
259// Specify priority of register selection within phases of register
260// allocation. Highest priority is first. A useful heuristic is to
261// give registers a low priority when they are required by machine
262// instructions, like EAX and EDX on I486, and choose no-save registers
263// before save-on-call, & save-on-call before save-on-entry. Registers
264// which participate in fixed calling sequences should come last.
265// Registers which are used as pairs must fall on an even boundary.
266
267// It's worth about 1% on SPEC geomean to get this right.
268
269// Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration
270// in adGlobals_ppc.hpp which defines the <register>_num values, e.g.
271// R3_num. Therefore, R3_num may not be (and in reality is not)
272// the same as R3->encoding()! Furthermore, we cannot make any
273// assumptions on ordering, e.g. R3_num may be less than R2_num.
274// Additionally, the function
275//   static enum RC rc_class(OptoReg::Name reg )
276// maps a given <register>_num value to its chunk type (except for flags)
277// and its current implementation relies on chunk0 and chunk1 having a
278// size of 64 each.
279
280// If you change this allocation class, please have a look at the
281// default values for the parameters RoundRobinIntegerRegIntervalStart
282// and RoundRobinFloatRegIntervalStart
283
284alloc_class chunk0 (
285  // Chunk0 contains *all* 64 integer registers halves.
286
287  // "non-volatile" registers
288  R14, R14_H,
289  R15, R15_H,
290  R17, R17_H,
291  R18, R18_H,
292  R19, R19_H,
293  R20, R20_H,
294  R21, R21_H,
295  R22, R22_H,
296  R23, R23_H,
297  R24, R24_H,
298  R25, R25_H,
299  R26, R26_H,
300  R27, R27_H,
301  R28, R28_H,
302  R29, R29_H,
303  R30, R30_H,
304  R31, R31_H,
305
306  // scratch/special registers
307  R11, R11_H,
308  R12, R12_H,
309
310  // argument registers
311  R10, R10_H,
312  R9,  R9_H,
313  R8,  R8_H,
314  R7,  R7_H,
315  R6,  R6_H,
316  R5,  R5_H,
317  R4,  R4_H,
318  R3,  R3_H,
319
320  // special registers, not available for allocation
321  R16, R16_H,     // R16_thread
322  R13, R13_H,     // system thread id
323  R2,  R2_H,      // may be used for TOC
324  R1,  R1_H,      // SP
325  R0,  R0_H       // R0 (scratch)
326);
327
328// If you change this allocation class, please have a look at the
329// default values for the parameters RoundRobinIntegerRegIntervalStart
330// and RoundRobinFloatRegIntervalStart
331
332alloc_class chunk1 (
333  // Chunk1 contains *all* 64 floating-point registers halves.
334
335  // scratch register
336  F0,  F0_H,
337
338  // argument registers
339  F13, F13_H,
340  F12, F12_H,
341  F11, F11_H,
342  F10, F10_H,
343  F9,  F9_H,
344  F8,  F8_H,
345  F7,  F7_H,
346  F6,  F6_H,
347  F5,  F5_H,
348  F4,  F4_H,
349  F3,  F3_H,
350  F2,  F2_H,
351  F1,  F1_H,
352
353  // non-volatile registers
354  F14, F14_H,
355  F15, F15_H,
356  F16, F16_H,
357  F17, F17_H,
358  F18, F18_H,
359  F19, F19_H,
360  F20, F20_H,
361  F21, F21_H,
362  F22, F22_H,
363  F23, F23_H,
364  F24, F24_H,
365  F25, F25_H,
366  F26, F26_H,
367  F27, F27_H,
368  F28, F28_H,
369  F29, F29_H,
370  F30, F30_H,
371  F31, F31_H
372);
373
374alloc_class chunk2 (
375  // Chunk2 contains *all* 8 condition code registers.
376
377  CCR0,
378  CCR1,
379  CCR2,
380  CCR3,
381  CCR4,
382  CCR5,
383  CCR6,
384  CCR7
385);
386
387alloc_class chunk3 (
388  // special registers
389  // These registers are not allocated, but used for nodes generated by postalloc expand.
390  SR_XER,
391  SR_LR,
392  SR_CTR,
393  SR_VRSAVE,
394  SR_SPEFSCR,
395  SR_PPR
396);
397
398//-------Architecture Description Register Classes-----------------------
399
400// Several register classes are automatically defined based upon
401// information in this architecture description.
402
403// 1) reg_class inline_cache_reg           ( as defined in frame section )
404// 2) reg_class compiler_method_oop_reg    ( as defined in frame section )
405// 2) reg_class interpreter_method_oop_reg ( as defined in frame section )
406// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
407//
408
409// ----------------------------
410// 32 Bit Register Classes
411// ----------------------------
412
413// We specify registers twice, once as read/write, and once read-only.
414// We use the read-only registers for source operands. With this, we
415// can include preset read only registers in this class, as a hard-coded
416// '0'-register. (We used to simulate this on ppc.)
417
418// 32 bit registers that can be read and written i.e. these registers
419// can be dest (or src) of normal instructions.
420reg_class bits32_reg_rw(
421/*R0*/              // R0
422/*R1*/              // SP
423  R2,               // TOC
424  R3,
425  R4,
426  R5,
427  R6,
428  R7,
429  R8,
430  R9,
431  R10,
432  R11,
433  R12,
434/*R13*/             // system thread id
435  R14,
436  R15,
437/*R16*/             // R16_thread
438  R17,
439  R18,
440  R19,
441  R20,
442  R21,
443  R22,
444  R23,
445  R24,
446  R25,
447  R26,
448  R27,
449  R28,
450/*R29,*/             // global TOC
451  R30,
452  R31
453);
454
455// 32 bit registers that can only be read i.e. these registers can
456// only be src of all instructions.
457reg_class bits32_reg_ro(
458/*R0*/              // R0
459/*R1*/              // SP
460  R2                // TOC
461  R3,
462  R4,
463  R5,
464  R6,
465  R7,
466  R8,
467  R9,
468  R10,
469  R11,
470  R12,
471/*R13*/             // system thread id
472  R14,
473  R15,
474/*R16*/             // R16_thread
475  R17,
476  R18,
477  R19,
478  R20,
479  R21,
480  R22,
481  R23,
482  R24,
483  R25,
484  R26,
485  R27,
486  R28,
487/*R29,*/
488  R30,
489  R31
490);
491
492reg_class rscratch1_bits32_reg(R11);
493reg_class rscratch2_bits32_reg(R12);
494reg_class rarg1_bits32_reg(R3);
495reg_class rarg2_bits32_reg(R4);
496reg_class rarg3_bits32_reg(R5);
497reg_class rarg4_bits32_reg(R6);
498
499// ----------------------------
500// 64 Bit Register Classes
501// ----------------------------
502// 64-bit build means 64-bit pointers means hi/lo pairs
503
504reg_class rscratch1_bits64_reg(R11_H, R11);
505reg_class rscratch2_bits64_reg(R12_H, R12);
506reg_class rarg1_bits64_reg(R3_H, R3);
507reg_class rarg2_bits64_reg(R4_H, R4);
508reg_class rarg3_bits64_reg(R5_H, R5);
509reg_class rarg4_bits64_reg(R6_H, R6);
510// Thread register, 'written' by tlsLoadP, see there.
511reg_class thread_bits64_reg(R16_H, R16);
512
513reg_class r19_bits64_reg(R19_H, R19);
514
515// 64 bit registers that can be read and written i.e. these registers
516// can be dest (or src) of normal instructions.
517reg_class bits64_reg_rw(
518/*R0_H,  R0*/     // R0
519/*R1_H,  R1*/     // SP
520  R2_H,  R2,      // TOC
521  R3_H,  R3,
522  R4_H,  R4,
523  R5_H,  R5,
524  R6_H,  R6,
525  R7_H,  R7,
526  R8_H,  R8,
527  R9_H,  R9,
528  R10_H, R10,
529  R11_H, R11,
530  R12_H, R12,
531/*R13_H, R13*/   // system thread id
532  R14_H, R14,
533  R15_H, R15,
534/*R16_H, R16*/   // R16_thread
535  R17_H, R17,
536  R18_H, R18,
537  R19_H, R19,
538  R20_H, R20,
539  R21_H, R21,
540  R22_H, R22,
541  R23_H, R23,
542  R24_H, R24,
543  R25_H, R25,
544  R26_H, R26,
545  R27_H, R27,
546  R28_H, R28,
547/*R29_H, R29,*/
548  R30_H, R30,
549  R31_H, R31
550);
551
552// 64 bit registers used excluding r2, r11 and r12
553// Used to hold the TOC to avoid collisions with expanded LeafCall which uses
554// r2, r11 and r12 internally.
555reg_class bits64_reg_leaf_call(
556/*R0_H,  R0*/     // R0
557/*R1_H,  R1*/     // SP
558/*R2_H,  R2*/     // TOC
559  R3_H,  R3,
560  R4_H,  R4,
561  R5_H,  R5,
562  R6_H,  R6,
563  R7_H,  R7,
564  R8_H,  R8,
565  R9_H,  R9,
566  R10_H, R10,
567/*R11_H, R11*/
568/*R12_H, R12*/
569/*R13_H, R13*/   // system thread id
570  R14_H, R14,
571  R15_H, R15,
572/*R16_H, R16*/   // R16_thread
573  R17_H, R17,
574  R18_H, R18,
575  R19_H, R19,
576  R20_H, R20,
577  R21_H, R21,
578  R22_H, R22,
579  R23_H, R23,
580  R24_H, R24,
581  R25_H, R25,
582  R26_H, R26,
583  R27_H, R27,
584  R28_H, R28,
585/*R29_H, R29,*/
586  R30_H, R30,
587  R31_H, R31
588);
589
590// Used to hold the TOC to avoid collisions with expanded DynamicCall
591// which uses r19 as inline cache internally and expanded LeafCall which uses
592// r2, r11 and r12 internally.
593reg_class bits64_constant_table_base(
594/*R0_H,  R0*/     // R0
595/*R1_H,  R1*/     // SP
596/*R2_H,  R2*/     // TOC
597  R3_H,  R3,
598  R4_H,  R4,
599  R5_H,  R5,
600  R6_H,  R6,
601  R7_H,  R7,
602  R8_H,  R8,
603  R9_H,  R9,
604  R10_H, R10,
605/*R11_H, R11*/
606/*R12_H, R12*/
607/*R13_H, R13*/   // system thread id
608  R14_H, R14,
609  R15_H, R15,
610/*R16_H, R16*/   // R16_thread
611  R17_H, R17,
612  R18_H, R18,
613/*R19_H, R19*/
614  R20_H, R20,
615  R21_H, R21,
616  R22_H, R22,
617  R23_H, R23,
618  R24_H, R24,
619  R25_H, R25,
620  R26_H, R26,
621  R27_H, R27,
622  R28_H, R28,
623/*R29_H, R29,*/
624  R30_H, R30,
625  R31_H, R31
626);
627
628// 64 bit registers that can only be read i.e. these registers can
629// only be src of all instructions.
630reg_class bits64_reg_ro(
631/*R0_H,  R0*/     // R0
632  R1_H,  R1,
633  R2_H,  R2,       // TOC
634  R3_H,  R3,
635  R4_H,  R4,
636  R5_H,  R5,
637  R6_H,  R6,
638  R7_H,  R7,
639  R8_H,  R8,
640  R9_H,  R9,
641  R10_H, R10,
642  R11_H, R11,
643  R12_H, R12,
644/*R13_H, R13*/   // system thread id
645  R14_H, R14,
646  R15_H, R15,
647  R16_H, R16,    // R16_thread
648  R17_H, R17,
649  R18_H, R18,
650  R19_H, R19,
651  R20_H, R20,
652  R21_H, R21,
653  R22_H, R22,
654  R23_H, R23,
655  R24_H, R24,
656  R25_H, R25,
657  R26_H, R26,
658  R27_H, R27,
659  R28_H, R28,
660/*R29_H, R29,*/ // TODO: let allocator handle TOC!!
661  R30_H, R30,
662  R31_H, R31
663);
664
665
666// ----------------------------
667// Special Class for Condition Code Flags Register
668
669reg_class int_flags(
670/*CCR0*/             // scratch
671/*CCR1*/             // scratch
672/*CCR2*/             // nv!
673/*CCR3*/             // nv!
674/*CCR4*/             // nv!
675  CCR5,
676  CCR6,
677  CCR7
678);
679
680reg_class int_flags_ro(
681  CCR0,
682  CCR1,
683  CCR2,
684  CCR3,
685  CCR4,
686  CCR5,
687  CCR6,
688  CCR7
689);
690
691reg_class int_flags_CR0(CCR0);
692reg_class int_flags_CR1(CCR1);
693reg_class int_flags_CR6(CCR6);
694reg_class ctr_reg(SR_CTR);
695
696// ----------------------------
697// Float Register Classes
698// ----------------------------
699
700reg_class flt_reg(
701  F0,
702  F1,
703  F2,
704  F3,
705  F4,
706  F5,
707  F6,
708  F7,
709  F8,
710  F9,
711  F10,
712  F11,
713  F12,
714  F13,
715  F14,              // nv!
716  F15,              // nv!
717  F16,              // nv!
718  F17,              // nv!
719  F18,              // nv!
720  F19,              // nv!
721  F20,              // nv!
722  F21,              // nv!
723  F22,              // nv!
724  F23,              // nv!
725  F24,              // nv!
726  F25,              // nv!
727  F26,              // nv!
728  F27,              // nv!
729  F28,              // nv!
730  F29,              // nv!
731  F30,              // nv!
732  F31               // nv!
733);
734
735// Double precision float registers have virtual `high halves' that
736// are needed by the allocator.
737reg_class dbl_reg(
738  F0,  F0_H,
739  F1,  F1_H,
740  F2,  F2_H,
741  F3,  F3_H,
742  F4,  F4_H,
743  F5,  F5_H,
744  F6,  F6_H,
745  F7,  F7_H,
746  F8,  F8_H,
747  F9,  F9_H,
748  F10, F10_H,
749  F11, F11_H,
750  F12, F12_H,
751  F13, F13_H,
752  F14, F14_H,    // nv!
753  F15, F15_H,    // nv!
754  F16, F16_H,    // nv!
755  F17, F17_H,    // nv!
756  F18, F18_H,    // nv!
757  F19, F19_H,    // nv!
758  F20, F20_H,    // nv!
759  F21, F21_H,    // nv!
760  F22, F22_H,    // nv!
761  F23, F23_H,    // nv!
762  F24, F24_H,    // nv!
763  F25, F25_H,    // nv!
764  F26, F26_H,    // nv!
765  F27, F27_H,    // nv!
766  F28, F28_H,    // nv!
767  F29, F29_H,    // nv!
768  F30, F30_H,    // nv!
769  F31, F31_H     // nv!
770);
771
772 %}
773
774//----------DEFINITION BLOCK---------------------------------------------------
775// Define name --> value mappings to inform the ADLC of an integer valued name
776// Current support includes integer values in the range [0, 0x7FFFFFFF]
777// Format:
778//        int_def  <name>         ( <int_value>, <expression>);
779// Generated Code in ad_<arch>.hpp
780//        #define  <name>   (<expression>)
781//        // value == <int_value>
782// Generated code in ad_<arch>.cpp adlc_verification()
783//        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
784//
785definitions %{
786  // The default cost (of an ALU instruction).
787  int_def DEFAULT_COST_LOW        (     30,      30);
788  int_def DEFAULT_COST            (    100,     100);
789  int_def HUGE_COST               (1000000, 1000000);
790
791  // Memory refs
792  int_def MEMORY_REF_COST_LOW     (    200, DEFAULT_COST * 2);
793  int_def MEMORY_REF_COST         (    300, DEFAULT_COST * 3);
794
795  // Branches are even more expensive.
796  int_def BRANCH_COST             (    900, DEFAULT_COST * 9);
797  int_def CALL_COST               (   1300, DEFAULT_COST * 13);
798%}
799
800
801//----------SOURCE BLOCK-------------------------------------------------------
802// This is a block of C++ code which provides values, functions, and
803// definitions necessary in the rest of the architecture description.
804source_hpp %{
805  // Header information of the source block.
806  // Method declarations/definitions which are used outside
807  // the ad-scope can conveniently be defined here.
808  //
809  // To keep related declarations/definitions/uses close together,
810  // we switch between source %{ }% and source_hpp %{ }% freely as needed.
811
812  // Returns true if Node n is followed by a MemBar node that
813  // will do an acquire. If so, this node must not do the acquire
814  // operation.
815  bool followed_by_acquire(const Node *n);
816%}
817
818source %{
819
820// Should the Matcher clone shifts on addressing modes, expecting them
821// to be subsumed into complex addressing expressions or compute them
822// into registers?
823bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
824  return clone_base_plus_offset_address(m, mstack, address_visited);
825}
826
827void Compile::reshape_address(AddPNode* addp) {
828}
829
830// Optimize load-acquire.
831//
832// Check if acquire is unnecessary due to following operation that does
833// acquire anyways.
834// Walk the pattern:
835//
836//      n: Load.acq
837//           |
838//      MemBarAcquire
839//       |         |
840//  Proj(ctrl)  Proj(mem)
841//       |         |
842//   MemBarRelease/Volatile
843//
844bool followed_by_acquire(const Node *load) {
845  assert(load->is_Load(), "So far implemented only for loads.");
846
847  // Find MemBarAcquire.
848  const Node *mba = NULL;
849  for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) {
850    const Node *out = load->fast_out(i);
851    if (out->Opcode() == Op_MemBarAcquire) {
852      if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge.
853      mba = out;
854      break;
855    }
856  }
857  if (!mba) return false;
858
859  // Find following MemBar node.
860  //
861  // The following node must be reachable by control AND memory
862  // edge to assure no other operations are in between the two nodes.
863  //
864  // So first get the Proj node, mem_proj, to use it to iterate forward.
865  Node *mem_proj = NULL;
866  for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) {
867    mem_proj = mba->fast_out(i);      // Throw out-of-bounds if proj not found
868    assert(mem_proj->is_Proj(), "only projections here");
869    ProjNode *proj = mem_proj->as_Proj();
870    if (proj->_con == TypeFunc::Memory &&
871        !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only
872      break;
873  }
874  assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken");
875
876  // Search MemBar behind Proj. If there are other memory operations
877  // behind the Proj we lost.
878  for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) {
879    Node *x = mem_proj->fast_out(j);
880    // Proj might have an edge to a store or load node which precedes the membar.
881    if (x->is_Mem()) return false;
882
883    // On PPC64 release and volatile are implemented by an instruction
884    // that also has acquire semantics. I.e. there is no need for an
885    // acquire before these.
886    int xop = x->Opcode();
887    if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) {
888      // Make sure we're not missing Call/Phi/MergeMem by checking
889      // control edges. The control edge must directly lead back
890      // to the MemBarAcquire
891      Node *ctrl_proj = x->in(0);
892      if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) {
893        return true;
894      }
895    }
896  }
897
898  return false;
899}
900
901#define __ _masm.
902
903// Tertiary op of a LoadP or StoreP encoding.
904#define REGP_OP true
905
906// ****************************************************************************
907
908// REQUIRED FUNCTIONALITY
909
910// !!!!! Special hack to get all type of calls to specify the byte offset
911//       from the start of the call to the point where the return address
912//       will point.
913
914// PPC port: Removed use of lazy constant construct.
915
916int MachCallStaticJavaNode::ret_addr_offset() {
917  // It's only a single branch-and-link instruction.
918  return 4;
919}
920
921int MachCallDynamicJavaNode::ret_addr_offset() {
922  // Offset is 4 with postalloc expanded calls (bl is one instruction). We use
923  // postalloc expanded calls if we use inline caches and do not update method data.
924  if (UseInlineCaches)
925    return 4;
926
927  int vtable_index = this->_vtable_index;
928  if (vtable_index < 0) {
929    // Must be invalid_vtable_index, not nonvirtual_vtable_index.
930    assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value");
931    return 12;
932  } else {
933    assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
934    return 24;
935  }
936}
937
938int MachCallRuntimeNode::ret_addr_offset() {
939#if defined(ABI_ELFv2)
940  return 28;
941#else
942  return 40;
943#endif
944}
945
946//=============================================================================
947
948// condition code conversions
949
950static int cc_to_boint(int cc) {
951  return Assembler::bcondCRbiIs0 | (cc & 8);
952}
953
954static int cc_to_inverse_boint(int cc) {
955  return Assembler::bcondCRbiIs0 | (8-(cc & 8));
956}
957
958static int cc_to_biint(int cc, int flags_reg) {
959  return (flags_reg << 2) | (cc & 3);
960}
961
962//=============================================================================
963
964// Compute padding required for nodes which need alignment. The padding
965// is the number of bytes (not instructions) which will be inserted before
966// the instruction. The padding must match the size of a NOP instruction.
967
968// Currently not used on this platform.
969
970//=============================================================================
971
972// Indicate if the safepoint node needs the polling page as an input.
973bool SafePointNode::needs_polling_address_input() {
974  // The address is loaded from thread by a seperate node.
975  return true;
976}
977
978//=============================================================================
979
980// Emit an interrupt that is caught by the debugger (for debugging compiler).
981void emit_break(CodeBuffer &cbuf) {
982  MacroAssembler _masm(&cbuf);
983  __ illtrap();
984}
985
986#ifndef PRODUCT
987void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
988  st->print("BREAKPOINT");
989}
990#endif
991
992void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
993  emit_break(cbuf);
994}
995
996uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
997  return MachNode::size(ra_);
998}
999
1000//=============================================================================
1001
1002void emit_nop(CodeBuffer &cbuf) {
1003  MacroAssembler _masm(&cbuf);
1004  __ nop();
1005}
1006
1007static inline void emit_long(CodeBuffer &cbuf, int value) {
1008  *((int*)(cbuf.insts_end())) = value;
1009  cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord);
1010}
1011
1012//=============================================================================
1013
1014%} // interrupt source
1015
1016source_hpp %{ // Header information of the source block.
1017
1018//--------------------------------------------------------------
1019//---<  Used for optimization in Compile::Shorten_branches  >---
1020//--------------------------------------------------------------
1021
1022class CallStubImpl {
1023
1024 public:
1025
1026  // Emit call stub, compiled java to interpreter.
1027  static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset);
1028
1029  // Size of call trampoline stub.
1030  // This doesn't need to be accurate to the byte, but it
1031  // must be larger than or equal to the real size of the stub.
1032  static uint size_call_trampoline() {
1033    return MacroAssembler::trampoline_stub_size;
1034  }
1035
1036  // number of relocations needed by a call trampoline stub
1037  static uint reloc_call_trampoline() {
1038    return 5;
1039  }
1040
1041};
1042
1043%} // end source_hpp
1044
1045source %{
1046
1047// Emit a trampoline stub for a call to a target which is too far away.
1048//
1049// code sequences:
1050//
1051// call-site:
1052//   branch-and-link to <destination> or <trampoline stub>
1053//
1054// Related trampoline stub for this call-site in the stub section:
1055//   load the call target from the constant pool
1056//   branch via CTR (LR/link still points to the call-site above)
1057
1058void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) {
1059  address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset);
1060  if (stub == NULL) {
1061    ciEnv::current()->record_out_of_memory_failure();
1062  }
1063}
1064
1065//=============================================================================
1066
1067// Emit an inline branch-and-link call and a related trampoline stub.
1068//
1069// code sequences:
1070//
1071// call-site:
1072//   branch-and-link to <destination> or <trampoline stub>
1073//
1074// Related trampoline stub for this call-site in the stub section:
1075//   load the call target from the constant pool
1076//   branch via CTR (LR/link still points to the call-site above)
1077//
1078
1079typedef struct {
1080  int insts_call_instruction_offset;
1081  int ret_addr_offset;
1082} EmitCallOffsets;
1083
1084// Emit a branch-and-link instruction that branches to a trampoline.
1085// - Remember the offset of the branch-and-link instruction.
1086// - Add a relocation at the branch-and-link instruction.
1087// - Emit a branch-and-link.
1088// - Remember the return pc offset.
1089EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) {
1090  EmitCallOffsets offsets = { -1, -1 };
1091  const int start_offset = __ offset();
1092  offsets.insts_call_instruction_offset = __ offset();
1093
1094  // No entry point given, use the current pc.
1095  if (entry_point == NULL) entry_point = __ pc();
1096
1097  // Put the entry point as a constant into the constant pool.
1098  const address entry_point_toc_addr   = __ address_constant(entry_point, RelocationHolder::none);
1099  if (entry_point_toc_addr == NULL) {
1100    ciEnv::current()->record_out_of_memory_failure();
1101    return offsets;
1102  }
1103  const int     entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
1104  
1105  // Emit the trampoline stub which will be related to the branch-and-link below.
1106  CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
1107  if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
1108  __ relocate(rtype);
1109  
1110  // Note: At this point we do not have the address of the trampoline
1111  // stub, and the entry point might be too far away for bl, so __ pc()
1112  // serves as dummy and the bl will be patched later.
1113  __ bl((address) __ pc());
1114
1115  offsets.ret_addr_offset = __ offset() - start_offset;
1116
1117  return offsets;
1118}
1119
1120//=============================================================================
1121
1122// Factory for creating loadConL* nodes for large/small constant pool.
1123
1124static inline jlong replicate_immF(float con) {
1125  // Replicate float con 2 times and pack into vector.
1126  int val = *((int*)&con);
1127  jlong lval = val;
1128  lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1129  return lval;
1130}
1131
1132//=============================================================================
1133
1134const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1135int Compile::ConstantTable::calculate_table_base_offset() const {
1136  return 0;  // absolute addressing, no offset
1137}
1138
1139bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1140void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1141  iRegPdstOper *op_dst = new iRegPdstOper();
1142  MachNode *m1 = new loadToc_hiNode();
1143  MachNode *m2 = new loadToc_loNode();
1144
1145  m1->add_req(NULL);
1146  m2->add_req(NULL, m1);
1147  m1->_opnds[0] = op_dst;
1148  m2->_opnds[0] = op_dst;
1149  m2->_opnds[1] = op_dst;
1150  ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1151  ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1152  nodes->push(m1);
1153  nodes->push(m2);
1154}
1155
1156void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1157  // Is postalloc expanded.
1158  ShouldNotReachHere();
1159}
1160
1161uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1162  return 0;
1163}
1164
1165#ifndef PRODUCT
1166void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1167  st->print("-- \t// MachConstantBaseNode (empty encoding)");
1168}
1169#endif
1170
1171//=============================================================================
1172
1173#ifndef PRODUCT
1174void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1175  Compile* C = ra_->C;
1176  const long framesize = C->frame_slots() << LogBytesPerInt;
1177
1178  st->print("PROLOG\n\t");
1179  if (C->need_stack_bang(framesize)) {
1180    st->print("stack_overflow_check\n\t");
1181  }
1182
1183  if (!false /* TODO: PPC port C->is_frameless_method()*/) {
1184    st->print("save return pc\n\t");
1185    st->print("push frame %ld\n\t", -framesize);
1186  }
1187}
1188#endif
1189
1190// Macro used instead of the common __ to emulate the pipes of PPC.
1191// Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the
1192// micro scheduler to cope with "hand written" assembler like in the prolog. Though
1193// still no scheduling of this code is possible, the micro scheduler is aware of the
1194// code and can update its internal data. The following mechanism is used to achieve this:
1195// The micro scheduler calls size() of each compound node during scheduling. size() does a
1196// dummy emit and only during this dummy emit C->hb_scheduling() is not NULL.
1197#if 0 // TODO: PPC port
1198#define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling())                    \
1199                  C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \
1200                _masm.
1201#define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling())                    \
1202                  C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none)
1203#define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling())                 \
1204                  C->hb_scheduling()->_pdScheduling->advance_offset
1205#else
1206#define ___(op) if (UsePower6SchedulerPPC64)                                          \
1207                  Unimplemented();                                                    \
1208                _masm.
1209#define ___stop if (UsePower6SchedulerPPC64)                                          \
1210                  Unimplemented()
1211#define ___advance if (UsePower6SchedulerPPC64)                                       \
1212                  Unimplemented()
1213#endif
1214
1215void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1216  Compile* C = ra_->C;
1217  MacroAssembler _masm(&cbuf);
1218
1219  const long framesize = C->frame_size_in_bytes();
1220  assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment");
1221
1222  const bool method_is_frameless      = false /* TODO: PPC port C->is_frameless_method()*/;
1223
1224  const Register return_pc            = R20; // Must match return_addr() in frame section.
1225  const Register callers_sp           = R21;
1226  const Register push_frame_temp      = R22;
1227  const Register toc_temp             = R23;
1228  assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
1229
1230  if (method_is_frameless) {
1231    // Add nop at beginning of all frameless methods to prevent any
1232    // oop instructions from getting overwritten by make_not_entrant
1233    // (patching attempt would fail).
1234    ___(nop) nop();
1235  } else {
1236    // Get return pc.
1237    ___(mflr) mflr(return_pc);
1238  }
1239
1240  // Calls to C2R adapters often do not accept exceptional returns.
1241  // We require that their callers must bang for them. But be
1242  // careful, because some VM calls (such as call site linkage) can
1243  // use several kilobytes of stack. But the stack safety zone should
1244  // account for that. See bugs 4446381, 4468289, 4497237.
1245
1246  int bangsize = C->bang_size_in_bytes();
1247  assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect");
1248  if (C->need_stack_bang(bangsize) && UseStackBanging) {
1249    // Unfortunately we cannot use the function provided in
1250    // assembler.cpp as we have to emulate the pipes. So I had to
1251    // insert the code of generate_stack_overflow_check(), see
1252    // assembler.cpp for some illuminative comments.
1253    const int page_size = os::vm_page_size();
1254    int bang_end = JavaThread::stack_shadow_zone_size();
1255
1256    // This is how far the previous frame's stack banging extended.
1257    const int bang_end_safe = bang_end;
1258
1259    if (bangsize > page_size) {
1260      bang_end += bangsize;
1261    }
1262
1263    int bang_offset = bang_end_safe;
1264
1265    while (bang_offset <= bang_end) {
1266      // Need at least one stack bang at end of shadow zone.
1267
1268      // Again I had to copy code, this time from assembler_ppc.cpp,
1269      // bang_stack_with_offset - see there for comments.
1270
1271      // Stack grows down, caller passes positive offset.
1272      assert(bang_offset > 0, "must bang with positive offset");
1273
1274      long stdoffset = -bang_offset;
1275
1276      if (Assembler::is_simm(stdoffset, 16)) {
1277        // Signed 16 bit offset, a simple std is ok.
1278        if (UseLoadInstructionsForStackBangingPPC64) {
1279          ___(ld) ld(R0,  (int)(signed short)stdoffset, R1_SP);
1280        } else {
1281          ___(std) std(R0, (int)(signed short)stdoffset, R1_SP);
1282        }
1283      } else if (Assembler::is_simm(stdoffset, 31)) {
1284        // Use largeoffset calculations for addis & ld/std.
1285        const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset);
1286        const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
1287
1288        Register tmp = R11;
1289        ___(addis) addis(tmp, R1_SP, hi);
1290        if (UseLoadInstructionsForStackBangingPPC64) {
1291          ___(ld) ld(R0, lo, tmp);
1292        } else {
1293          ___(std) std(R0, lo, tmp);
1294        }
1295      } else {
1296        ShouldNotReachHere();
1297      }
1298
1299      bang_offset += page_size;
1300    }
1301    // R11 trashed
1302  } // C->need_stack_bang(framesize) && UseStackBanging
1303
1304  unsigned int bytes = (unsigned int)framesize;
1305  long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
1306  ciMethod *currMethod = C->method();
1307
1308  // Optimized version for most common case.
1309  if (UsePower6SchedulerPPC64 &&
1310      !method_is_frameless && Assembler::is_simm((int)(-offset), 16) &&
1311      !(false /* ConstantsALot TODO: PPC port*/)) {
1312    ___(or) mr(callers_sp, R1_SP);
1313    ___(std) std(return_pc, _abi(lr), R1_SP);
1314    ___(stdu) stdu(R1_SP, -offset, R1_SP);
1315    return;
1316  }
1317
1318  if (!method_is_frameless) {
1319    // Get callers sp.
1320    ___(or) mr(callers_sp, R1_SP);
1321
1322    // Push method's frame, modifies SP.
1323    assert(Assembler::is_uimm(framesize, 32U), "wrong type");
1324    // The ABI is already accounted for in 'framesize' via the
1325    // 'out_preserve' area.
1326    Register tmp = push_frame_temp;
1327    // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp).
1328    if (Assembler::is_simm(-offset, 16)) {
1329      ___(stdu) stdu(R1_SP, -offset, R1_SP);
1330    } else {
1331      long x = -offset;
1332      // Had to insert load_const(tmp, -offset).
1333      ___(addis)  lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16)));
1334      ___(ori)    ori( tmp, tmp, ((x >> 32) & 0x0000ffff));
1335      ___(rldicr) sldi(tmp, tmp, 32);
1336      ___(oris)   oris(tmp, tmp, (x & 0xffff0000) >> 16);
1337      ___(ori)    ori( tmp, tmp, (x & 0x0000ffff));
1338
1339      ___(stdux) stdux(R1_SP, R1_SP, tmp);
1340    }
1341  }
1342#if 0 // TODO: PPC port
1343  // For testing large constant pools, emit a lot of constants to constant pool.
1344  // "Randomize" const_size.
1345  if (ConstantsALot) {
1346    const int num_consts = const_size();
1347    for (int i = 0; i < num_consts; i++) {
1348      __ long_constant(0xB0B5B00BBABE);
1349    }
1350  }
1351#endif
1352  if (!method_is_frameless) {
1353    // Save return pc.
1354    ___(std) std(return_pc, _abi(lr), callers_sp);
1355  }
1356  
1357  C->set_frame_complete(cbuf.insts_size());
1358}
1359#undef ___
1360#undef ___stop
1361#undef ___advance
1362
1363uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1364  // Variable size. determine dynamically.
1365  return MachNode::size(ra_);
1366}
1367
1368int MachPrologNode::reloc() const {
1369  // Return number of relocatable values contained in this instruction.
1370  return 1; // 1 reloc entry for load_const(toc).
1371}
1372
1373//=============================================================================
1374
1375#ifndef PRODUCT
1376void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1377  Compile* C = ra_->C;
1378
1379  st->print("EPILOG\n\t");
1380  st->print("restore return pc\n\t");
1381  st->print("pop frame\n\t");
1382
1383  if (do_polling() && C->is_method_compilation()) {
1384    st->print("touch polling page\n\t");
1385  }
1386}
1387#endif
1388
1389void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1390  Compile* C = ra_->C;
1391  MacroAssembler _masm(&cbuf);
1392
1393  const long framesize = ((long)C->frame_slots()) << LogBytesPerInt;
1394  assert(framesize >= 0, "negative frame-size?");
1395
1396  const bool method_needs_polling = do_polling() && C->is_method_compilation();
1397  const bool method_is_frameless  = false /* TODO: PPC port C->is_frameless_method()*/;
1398  const Register return_pc        = R31;  // Must survive C-call to enable_stack_reserved_zone().
1399  const Register polling_page     = R12;
1400
1401  if (!method_is_frameless) {
1402    // Restore return pc relative to callers' sp.
1403    __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP);
1404  }
1405
1406  if (method_needs_polling) {
1407    if (LoadPollAddressFromThread) {
1408      // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread);
1409      Unimplemented();
1410    } else {
1411      __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); // TODO: PPC port: get_standard_polling_page()
1412    }
1413  }
1414
1415  if (!method_is_frameless) {
1416    // Move return pc to LR.
1417    __ mtlr(return_pc);
1418    // Pop frame (fixed frame-size).
1419    __ addi(R1_SP, R1_SP, (int)framesize);
1420  }
1421
1422  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1423    __ reserved_stack_check(return_pc);
1424  }
1425
1426  if (method_needs_polling) {
1427    // We need to mark the code position where the load from the safepoint
1428    // polling page was emitted as relocInfo::poll_return_type here.
1429    __ relocate(relocInfo::poll_return_type);
1430    __ load_from_polling_page(polling_page);
1431  }
1432}
1433
1434uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1435  // Variable size. Determine dynamically.
1436  return MachNode::size(ra_);
1437}
1438
1439int MachEpilogNode::reloc() const {
1440  // Return number of relocatable values contained in this instruction.
1441  return 1; // 1 for load_from_polling_page.
1442}
1443
1444const Pipeline * MachEpilogNode::pipeline() const {
1445  return MachNode::pipeline_class();
1446}
1447
1448// This method seems to be obsolete. It is declared in machnode.hpp
1449// and defined in all *.ad files, but it is never called. Should we
1450// get rid of it?
1451int MachEpilogNode::safepoint_offset() const {
1452  assert(do_polling(), "no return for this epilog node");
1453  return 0;
1454}
1455
1456#if 0 // TODO: PPC port
1457void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1458  MacroAssembler _masm(&cbuf);
1459  if (LoadPollAddressFromThread) {
1460    _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread);
1461  } else {
1462    _masm.nop();
1463  }
1464}
1465
1466uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const {
1467  if (LoadPollAddressFromThread) {
1468    return 4;
1469  } else {
1470    return 4;
1471  }
1472}
1473
1474#ifndef PRODUCT
1475void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1476  st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread");
1477}
1478#endif
1479
1480const RegMask &MachLoadPollAddrLateNode::out_RegMask() const {
1481  return RSCRATCH1_BITS64_REG_mask();
1482}
1483#endif // PPC port
1484
1485// =============================================================================
1486
1487// Figure out which register class each belongs in: rc_int, rc_float or
1488// rc_stack.
1489enum RC { rc_bad, rc_int, rc_float, rc_stack };
1490
1491static enum RC rc_class(OptoReg::Name reg) {
1492  // Return the register class for the given register. The given register
1493  // reg is a <register>_num value, which is an index into the MachRegisterNumbers
1494  // enumeration in adGlobals_ppc.hpp.
1495
1496  if (reg == OptoReg::Bad) return rc_bad;
1497
1498  // We have 64 integer register halves, starting at index 0.
1499  if (reg < 64) return rc_int;
1500
1501  // We have 64 floating-point register halves, starting at index 64.
1502  if (reg < 64+64) return rc_float;
1503
1504  // Between float regs & stack are the flags regs.
1505  assert(OptoReg::is_stack(reg), "blow up if spilling flags");
1506
1507  return rc_stack;
1508}
1509
1510static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset,
1511                        bool do_print, Compile* C, outputStream *st) {
1512
1513  assert(opcode == Assembler::LD_OPCODE   ||
1514         opcode == Assembler::STD_OPCODE  ||
1515         opcode == Assembler::LWZ_OPCODE  ||
1516         opcode == Assembler::STW_OPCODE  ||
1517         opcode == Assembler::LFD_OPCODE  ||
1518         opcode == Assembler::STFD_OPCODE ||
1519         opcode == Assembler::LFS_OPCODE  ||
1520         opcode == Assembler::STFS_OPCODE,
1521         "opcode not supported");
1522
1523  if (cbuf) {
1524    int d =
1525      (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ?
1526        Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/)
1527      : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build.
1528    emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP));
1529  }
1530#ifndef PRODUCT
1531  else if (do_print) {
1532    st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy",
1533              op_str,
1534              Matcher::regName[reg],
1535              offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/);
1536  }
1537#endif
1538  return 4; // size
1539}
1540
1541uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1542  Compile* C = ra_->C;
1543
1544  // Get registers to move.
1545  OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1546  OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1547  OptoReg::Name dst_hi = ra_->get_reg_second(this);
1548  OptoReg::Name dst_lo = ra_->get_reg_first(this);
1549
1550  enum RC src_hi_rc = rc_class(src_hi);
1551  enum RC src_lo_rc = rc_class(src_lo);
1552  enum RC dst_hi_rc = rc_class(dst_hi);
1553  enum RC dst_lo_rc = rc_class(dst_lo);
1554
1555  assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1556  if (src_hi != OptoReg::Bad)
1557    assert((src_lo&1)==0 && src_lo+1==src_hi &&
1558           (dst_lo&1)==0 && dst_lo+1==dst_hi,
1559           "expected aligned-adjacent pairs");
1560  // Generate spill code!
1561  int size = 0;
1562
1563  if (src_lo == dst_lo && src_hi == dst_hi)
1564    return size;            // Self copy, no move.
1565
1566  // --------------------------------------
1567  // Memory->Memory Spill. Use R0 to hold the value.
1568  if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1569    int src_offset = ra_->reg2offset(src_lo);
1570    int dst_offset = ra_->reg2offset(dst_lo);
1571    if (src_hi != OptoReg::Bad) {
1572      assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack,
1573             "expected same type of move for high parts");
1574      size += ld_st_helper(cbuf, "LD  ", Assembler::LD_OPCODE,  R0_num, src_offset, !do_size, C, st);
1575      if (!cbuf && !do_size) st->print("\n\t");
1576      size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st);
1577    } else {
1578      size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st);
1579      if (!cbuf && !do_size) st->print("\n\t");
1580      size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st);
1581    }
1582    return size;
1583  }
1584
1585  // --------------------------------------
1586  // Check for float->int copy; requires a trip through memory.
1587  if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1588    Unimplemented();
1589  }
1590
1591  // --------------------------------------
1592  // Check for integer reg-reg copy.
1593  if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1594      Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1595      Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1596      size = (Rsrc != Rdst) ? 4 : 0;
1597
1598      if (cbuf) {
1599        MacroAssembler _masm(cbuf);
1600        if (size) {
1601          __ mr(Rdst, Rsrc);
1602        }
1603      }
1604#ifndef PRODUCT
1605      else if (!do_size) {
1606        if (size) {
1607          st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1608        } else {
1609          st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1610        }
1611      }
1612#endif
1613      return size;
1614  }
1615
1616  // Check for integer store.
1617  if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1618    int dst_offset = ra_->reg2offset(dst_lo);
1619    if (src_hi != OptoReg::Bad) {
1620      assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack,
1621             "expected same type of move for high parts");
1622      size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1623    } else {
1624      size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st);
1625    }
1626    return size;
1627  }
1628
1629  // Check for integer load.
1630  if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1631    int src_offset = ra_->reg2offset(src_lo);
1632    if (src_hi != OptoReg::Bad) {
1633      assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack,
1634             "expected same type of move for high parts");
1635      size += ld_st_helper(cbuf, "LD  ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1636    } else {
1637      size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st);
1638    }
1639    return size;
1640  }
1641
1642  // Check for float reg-reg copy.
1643  if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1644    if (cbuf) {
1645      MacroAssembler _masm(cbuf);
1646      FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]);
1647      FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]);
1648      __ fmr(Rdst, Rsrc);
1649    }
1650#ifndef PRODUCT
1651    else if (!do_size) {
1652      st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
1653    }
1654#endif
1655    return 4;
1656  }
1657
1658  // Check for float store.
1659  if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1660    int dst_offset = ra_->reg2offset(dst_lo);
1661    if (src_hi != OptoReg::Bad) {
1662      assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack,
1663             "expected same type of move for high parts");
1664      size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st);
1665    } else {
1666      size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st);
1667    }
1668    return size;
1669  }
1670
1671  // Check for float load.
1672  if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1673    int src_offset = ra_->reg2offset(src_lo);
1674    if (src_hi != OptoReg::Bad) {
1675      assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack,
1676             "expected same type of move for high parts");
1677      size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st);
1678    } else {
1679      size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st);
1680    }
1681    return size;
1682  }
1683
1684  // --------------------------------------------------------------------
1685  // Check for hi bits still needing moving. Only happens for misaligned
1686  // arguments to native calls.
1687  if (src_hi == dst_hi)
1688    return size;               // Self copy; no move.
1689
1690  assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad");
1691  ShouldNotReachHere(); // Unimplemented
1692  return 0;
1693}
1694
1695#ifndef PRODUCT
1696void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1697  if (!ra_)
1698    st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
1699  else
1700    implementation(NULL, ra_, false, st);
1701}
1702#endif
1703
1704void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1705  implementation(&cbuf, ra_, false, NULL);
1706}
1707
1708uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1709  return implementation(NULL, ra_, true, NULL);
1710}
1711
1712#if 0 // TODO: PPC port
1713ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) {
1714#ifndef PRODUCT
1715  if (ra_->node_regs_max_index() == 0) return archOpcode_undefined;
1716#endif
1717  assert(ra_->node_regs_max_index() != 0, "");
1718
1719  // Get registers to move.
1720  OptoReg::Name src_hi = ra_->get_reg_second(n->in(1));
1721  OptoReg::Name src_lo = ra_->get_reg_first(n->in(1));
1722  OptoReg::Name dst_hi = ra_->get_reg_second(n);
1723  OptoReg::Name dst_lo = ra_->get_reg_first(n);
1724
1725  enum RC src_lo_rc = rc_class(src_lo);
1726  enum RC dst_lo_rc = rc_class(dst_lo);
1727
1728  if (src_lo == dst_lo && src_hi == dst_hi)
1729    return ppc64Opcode_none;            // Self copy, no move.
1730
1731  // --------------------------------------
1732  // Memory->Memory Spill. Use R0 to hold the value.
1733  if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1734    return ppc64Opcode_compound;
1735  }
1736
1737  // --------------------------------------
1738  // Check for float->int copy; requires a trip through memory.
1739  if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
1740    Unimplemented();
1741  }
1742
1743  // --------------------------------------
1744  // Check for integer reg-reg copy.
1745  if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
1746    Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
1747    Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
1748    if (Rsrc == Rdst) {
1749      return ppc64Opcode_none;
1750    } else {
1751      return ppc64Opcode_or;
1752    }
1753  }
1754
1755  // Check for integer store.
1756  if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
1757    if (src_hi != OptoReg::Bad) {
1758      return ppc64Opcode_std;
1759    } else {
1760      return ppc64Opcode_stw;
1761    }
1762  }
1763
1764  // Check for integer load.
1765  if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
1766    if (src_hi != OptoReg::Bad) {
1767      return ppc64Opcode_ld;
1768    } else {
1769      return ppc64Opcode_lwz;
1770    }
1771  }
1772
1773  // Check for float reg-reg copy.
1774  if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1775    return ppc64Opcode_fmr;
1776  }
1777
1778  // Check for float store.
1779  if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1780    if (src_hi != OptoReg::Bad) {
1781      return ppc64Opcode_stfd;
1782    } else {
1783      return ppc64Opcode_stfs;
1784    }
1785  }
1786
1787  // Check for float load.
1788  if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
1789    if (src_hi != OptoReg::Bad) {
1790      return ppc64Opcode_lfd;
1791    } else {
1792      return ppc64Opcode_lfs;
1793    }
1794  }
1795
1796  // --------------------------------------------------------------------
1797  // Check for hi bits still needing moving. Only happens for misaligned
1798  // arguments to native calls.
1799  if (src_hi == dst_hi) {
1800    return ppc64Opcode_none;               // Self copy; no move.
1801  }
1802
1803  ShouldNotReachHere();
1804  return ppc64Opcode_undefined;
1805}
1806#endif // PPC port
1807
1808#ifndef PRODUCT
1809void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1810  st->print("NOP \t// %d nops to pad for loops.", _count);
1811}
1812#endif
1813
1814void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const {
1815  MacroAssembler _masm(&cbuf);
1816  // _count contains the number of nops needed for padding.
1817  for (int i = 0; i < _count; i++) {
1818    __ nop();
1819  }
1820}
1821
1822uint MachNopNode::size(PhaseRegAlloc *ra_) const {
1823  return _count * 4;
1824}
1825
1826#ifndef PRODUCT
1827void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1828  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1829  char reg_str[128];
1830  ra_->dump_register(this, reg_str);
1831  st->print("ADDI    %s, SP, %d \t// box node", reg_str, offset);
1832}
1833#endif
1834
1835void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1836  MacroAssembler _masm(&cbuf);
1837
1838  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1839  int reg    = ra_->get_encode(this);
1840
1841  if (Assembler::is_simm(offset, 16)) {
1842    __ addi(as_Register(reg), R1, offset);
1843  } else {
1844    ShouldNotReachHere();
1845  }
1846}
1847
1848uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1849  // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
1850  return 4;
1851}
1852
1853#ifndef PRODUCT
1854void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1855  st->print_cr("---- MachUEPNode ----");
1856  st->print_cr("...");
1857}
1858#endif
1859
1860void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1861  // This is the unverified entry point.
1862  MacroAssembler _masm(&cbuf);
1863
1864  // Inline_cache contains a klass.
1865  Register ic_klass       = as_Register(Matcher::inline_cache_reg_encode());
1866  Register receiver_klass = R12_scratch2;  // tmp
1867
1868  assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1);
1869  assert(R11_scratch1 == R11, "need prologue scratch register");
1870
1871  // Check for NULL argument if we don't have implicit null checks.
1872  if (!ImplicitNullChecks || !os::zero_page_read_protected()) {
1873    if (TrapBasedNullChecks) {
1874      __ trap_null_check(R3_ARG1);
1875    } else {
1876      Label valid;
1877      __ cmpdi(CCR0, R3_ARG1, 0);
1878      __ bne_predict_taken(CCR0, valid);
1879      // We have a null argument, branch to ic_miss_stub.
1880      __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(),
1881                           relocInfo::runtime_call_type);
1882      __ bind(valid);
1883    }
1884  }
1885  // Assume argument is not NULL, load klass from receiver.
1886  __ load_klass(receiver_klass, R3_ARG1);
1887
1888  if (TrapBasedICMissChecks) {
1889    __ trap_ic_miss_check(receiver_klass, ic_klass);
1890  } else {
1891    Label valid;
1892    __ cmpd(CCR0, receiver_klass, ic_klass);
1893    __ beq_predict_taken(CCR0, valid);
1894    // We have an unexpected klass, branch to ic_miss_stub.
1895    __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(),
1896                         relocInfo::runtime_call_type);
1897    __ bind(valid);
1898  }
1899
1900  // Argument is valid and klass is as expected, continue.
1901}
1902
1903#if 0 // TODO: PPC port
1904// Optimize UEP code on z (save a load_const() call in main path).
1905int MachUEPNode::ep_offset() {
1906  return 0;
1907}
1908#endif
1909
1910uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1911  // Variable size. Determine dynamically.
1912  return MachNode::size(ra_);
1913}
1914
1915//=============================================================================
1916
1917%} // interrupt source
1918
1919source_hpp %{ // Header information of the source block.
1920
1921class HandlerImpl {
1922
1923 public:
1924
1925  static int emit_exception_handler(CodeBuffer &cbuf);
1926  static int emit_deopt_handler(CodeBuffer& cbuf);
1927
1928  static uint size_exception_handler() {
1929    // The exception_handler is a b64_patchable.
1930    return MacroAssembler::b64_patchable_size;
1931  }
1932
1933  static uint size_deopt_handler() {
1934    // The deopt_handler is a bl64_patchable.
1935    return MacroAssembler::bl64_patchable_size;
1936  }
1937
1938};
1939
1940%} // end source_hpp
1941
1942source %{
1943
1944int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) {
1945  MacroAssembler _masm(&cbuf);
1946
1947  address base = __ start_a_stub(size_exception_handler());
1948  if (base == NULL) return 0; // CodeBuffer::expand failed
1949
1950  int offset = __ offset();
1951  __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(),
1952                       relocInfo::runtime_call_type);
1953  assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size");
1954  __ end_a_stub();
1955
1956  return offset;
1957}
1958
1959// The deopt_handler is like the exception handler, but it calls to
1960// the deoptimization blob instead of jumping to the exception blob.
1961int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
1962  MacroAssembler _masm(&cbuf);
1963
1964  address base = __ start_a_stub(size_deopt_handler());
1965  if (base == NULL) return 0; // CodeBuffer::expand failed
1966
1967  int offset = __ offset();
1968  __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(),
1969                        relocInfo::runtime_call_type);
1970  assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size");
1971  __ end_a_stub();
1972
1973  return offset;
1974}
1975
1976//=============================================================================
1977
1978// Use a frame slots bias for frameless methods if accessing the stack.
1979static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) {
1980  if (as_Register(reg_enc) == R1_SP) {
1981    return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes();
1982  }
1983  return 0;
1984}
1985
1986const bool Matcher::match_rule_supported(int opcode) {
1987  if (!has_match_rule(opcode))
1988    return false;
1989
1990  switch (opcode) {
1991  case Op_SqrtD:
1992    return VM_Version::has_fsqrt();
1993  case Op_CountLeadingZerosI:
1994  case Op_CountLeadingZerosL:
1995  case Op_CountTrailingZerosI:
1996  case Op_CountTrailingZerosL:
1997    if (!UseCountLeadingZerosInstructionsPPC64)
1998      return false;
1999    break;
2000
2001  case Op_PopCountI:
2002  case Op_PopCountL:
2003    return (UsePopCountInstruction && VM_Version::has_popcntw());
2004
2005  case Op_StrComp:
2006    return SpecialStringCompareTo;
2007  case Op_StrEquals:
2008    return SpecialStringEquals;
2009  case Op_StrIndexOf:
2010    return SpecialStringIndexOf;
2011  case Op_StrIndexOfChar:
2012    return SpecialStringIndexOf;
2013  }
2014
2015  return true;  // Per default match rules are supported.
2016}
2017
2018const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
2019
2020  // TODO
2021  // identify extra cases that we might want to provide match rules for
2022  // e.g. Op_ vector nodes and other intrinsics while guarding with vlen
2023  bool ret_value = match_rule_supported(opcode);
2024  // Add rules here.
2025
2026  return ret_value;  // Per default match rules are supported.
2027}
2028
2029const bool Matcher::has_predicated_vectors(void) {
2030  return false;
2031}
2032
2033const int Matcher::float_pressure(int default_pressure_threshold) {
2034  return default_pressure_threshold;
2035}
2036
2037int Matcher::regnum_to_fpu_offset(int regnum) {
2038  // No user for this method?
2039  Unimplemented();
2040  return 999;
2041}
2042
2043const bool Matcher::convL2FSupported(void) {
2044  // fcfids can do the conversion (>= Power7).
2045  // fcfid + frsp showed rounding problem when result should be 0x3f800001.
2046  return VM_Version::has_fcfids(); // False means that conversion is done by runtime call.
2047}
2048
2049// Vector width in bytes.
2050const int Matcher::vector_width_in_bytes(BasicType bt) {
2051  assert(MaxVectorSize == 8, "");
2052  return 8;
2053}
2054
2055// Vector ideal reg.
2056const int Matcher::vector_ideal_reg(int size) {
2057  assert(MaxVectorSize == 8 && size == 8, "");
2058  return Op_RegL;
2059}
2060
2061const int Matcher::vector_shift_count_ideal_reg(int size) {
2062  fatal("vector shift is not supported");
2063  return Node::NotAMachineReg;
2064}
2065
2066// Limits on vector size (number of elements) loaded into vector.
2067const int Matcher::max_vector_size(const BasicType bt) {
2068  assert(is_java_primitive(bt), "only primitive type vectors");
2069  return vector_width_in_bytes(bt)/type2aelembytes(bt);
2070}
2071
2072const int Matcher::min_vector_size(const BasicType bt) {
2073  return max_vector_size(bt); // Same as max.
2074}
2075
2076// PPC doesn't support misaligned vectors store/load.
2077const bool Matcher::misaligned_vectors_ok() {
2078  return false;
2079}
2080
2081// PPC AES support not yet implemented
2082const bool Matcher::pass_original_key_for_aes() {
2083  return false;
2084}
2085
2086// RETURNS: whether this branch offset is short enough that a short
2087// branch can be used.
2088//
2089// If the platform does not provide any short branch variants, then
2090// this method should return `false' for offset 0.
2091//
2092// `Compile::Fill_buffer' will decide on basis of this information
2093// whether to do the pass `Compile::Shorten_branches' at all.
2094//
2095// And `Compile::Shorten_branches' will decide on basis of this
2096// information whether to replace particular branch sites by short
2097// ones.
2098bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2099  // Is the offset within the range of a ppc64 pc relative branch?
2100  bool b;
2101
2102  const int safety_zone = 3 * BytesPerInstWord;
2103  b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2104                         29 - 16 + 1 + 2);
2105  return b;
2106}
2107
2108const bool Matcher::isSimpleConstant64(jlong value) {
2109  // Probably always true, even if a temp register is required.
2110  return true;
2111}
2112/* TODO: PPC port
2113// Make a new machine dependent decode node (with its operands).
2114MachTypeNode *Matcher::make_decode_node() {
2115  assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0,
2116         "This method is only implemented for unscaled cOops mode so far");
2117  MachTypeNode *decode = new decodeN_unscaledNode();
2118  decode->set_opnd_array(0, new iRegPdstOper());
2119  decode->set_opnd_array(1, new iRegNsrcOper());
2120  return decode;
2121}
2122*/
2123
2124// false => size gets scaled to BytesPerLong, ok.
2125const bool Matcher::init_array_count_is_in_bytes = false;
2126
2127// Use conditional move (CMOVL) on Power7.
2128const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves
2129
2130// Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet.
2131// fsel doesn't accept a condition register as input, so this would be slightly different.
2132const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
2133
2134// Power6 requires postalloc expand (see block.cpp for description of postalloc expand).
2135const bool Matcher::require_postalloc_expand = true;
2136
2137// Do we need to mask the count passed to shift instructions or does
2138// the cpu only look at the lower 5/6 bits anyway?
2139// PowerPC requires masked shift counts.
2140const bool Matcher::need_masked_shift_count = true;
2141
2142// This affects two different things:
2143//  - how Decode nodes are matched
2144//  - how ImplicitNullCheck opportunities are recognized
2145// If true, the matcher will try to remove all Decodes and match them
2146// (as operands) into nodes. NullChecks are not prepared to deal with
2147// Decodes by final_graph_reshaping().
2148// If false, final_graph_reshaping() forces the decode behind the Cmp
2149// for a NullCheck. The matcher matches the Decode node into a register.
2150// Implicit_null_check optimization moves the Decode along with the
2151// memory operation back up before the NullCheck.
2152bool Matcher::narrow_oop_use_complex_address() {
2153  // TODO: PPC port if (MatchDecodeNodes) return true;
2154  return false;
2155}
2156
2157bool Matcher::narrow_klass_use_complex_address() {
2158  NOT_LP64(ShouldNotCallThis());
2159  assert(UseCompressedClassPointers, "only for compressed klass code");
2160  // TODO: PPC port if (MatchDecodeNodes) return true;
2161  return false;
2162}
2163
2164bool Matcher::const_oop_prefer_decode() {
2165  // Prefer ConN+DecodeN over ConP in simple compressed oops mode.
2166  return Universe::narrow_oop_base() == NULL;
2167}
2168
2169bool Matcher::const_klass_prefer_decode() {
2170  // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
2171  return Universe::narrow_klass_base() == NULL;
2172}
2173
2174// Is it better to copy float constants, or load them directly from memory?
2175// Intel can load a float constant from a direct address, requiring no
2176// extra registers. Most RISCs will have to materialize an address into a
2177// register first, so they would do better to copy the constant from stack.
2178const bool Matcher::rematerialize_float_constants = false;
2179
2180// If CPU can load and store mis-aligned doubles directly then no fixup is
2181// needed. Else we split the double into 2 integer pieces and move it
2182// piece-by-piece. Only happens when passing doubles into C code as the
2183// Java calling convention forces doubles to be aligned.
2184const bool Matcher::misaligned_doubles_ok = true;
2185
2186void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
2187 Unimplemented();
2188}
2189
2190// Advertise here if the CPU requires explicit rounding operations
2191// to implement the UseStrictFP mode.
2192const bool Matcher::strict_fp_requires_explicit_rounding = false;
2193
2194// Do floats take an entire double register or just half?
2195//
2196// A float occupies a ppc64 double register. For the allocator, a
2197// ppc64 double register appears as a pair of float registers.
2198bool Matcher::float_in_double() { return true; }
2199
2200// Do ints take an entire long register or just half?
2201// The relevant question is how the int is callee-saved:
2202// the whole long is written but de-opt'ing will have to extract
2203// the relevant 32 bits.
2204const bool Matcher::int_in_long = true;
2205
2206// Constants for c2c and c calling conventions.
2207
2208const MachRegisterNumbers iarg_reg[8] = {
2209  R3_num, R4_num, R5_num, R6_num,
2210  R7_num, R8_num, R9_num, R10_num
2211};
2212
2213const MachRegisterNumbers farg_reg[13] = {
2214  F1_num, F2_num, F3_num, F4_num,
2215  F5_num, F6_num, F7_num, F8_num,
2216  F9_num, F10_num, F11_num, F12_num,
2217  F13_num
2218};
2219
2220const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]);
2221
2222const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]);
2223
2224// Return whether or not this register is ever used as an argument. This
2225// function is used on startup to build the trampoline stubs in generateOptoStub.
2226// Registers not mentioned will be killed by the VM call in the trampoline, and
2227// arguments in those registers not be available to the callee.
2228bool Matcher::can_be_java_arg(int reg) {
2229  // We return true for all registers contained in iarg_reg[] and
2230  // farg_reg[] and their virtual halves.
2231  // We must include the virtual halves in order to get STDs and LDs
2232  // instead of STWs and LWs in the trampoline stubs.
2233
2234  if (   reg == R3_num  || reg == R3_H_num
2235      || reg == R4_num  || reg == R4_H_num
2236      || reg == R5_num  || reg == R5_H_num
2237      || reg == R6_num  || reg == R6_H_num
2238      || reg == R7_num  || reg == R7_H_num
2239      || reg == R8_num  || reg == R8_H_num
2240      || reg == R9_num  || reg == R9_H_num
2241      || reg == R10_num || reg == R10_H_num)
2242    return true;
2243
2244  if (   reg == F1_num  || reg == F1_H_num
2245      || reg == F2_num  || reg == F2_H_num
2246      || reg == F3_num  || reg == F3_H_num
2247      || reg == F4_num  || reg == F4_H_num
2248      || reg == F5_num  || reg == F5_H_num
2249      || reg == F6_num  || reg == F6_H_num
2250      || reg == F7_num  || reg == F7_H_num
2251      || reg == F8_num  || reg == F8_H_num
2252      || reg == F9_num  || reg == F9_H_num
2253      || reg == F10_num || reg == F10_H_num
2254      || reg == F11_num || reg == F11_H_num
2255      || reg == F12_num || reg == F12_H_num
2256      || reg == F13_num || reg == F13_H_num)
2257    return true;
2258
2259  return false;
2260}
2261
2262bool Matcher::is_spillable_arg(int reg) {
2263  return can_be_java_arg(reg);
2264}
2265
2266bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
2267  return false;
2268}
2269
2270// Register for DIVI projection of divmodI.
2271RegMask Matcher::divI_proj_mask() {
2272  ShouldNotReachHere();
2273  return RegMask();
2274}
2275
2276// Register for MODI projection of divmodI.
2277RegMask Matcher::modI_proj_mask() {
2278  ShouldNotReachHere();
2279  return RegMask();
2280}
2281
2282// Register for DIVL projection of divmodL.
2283RegMask Matcher::divL_proj_mask() {
2284  ShouldNotReachHere();
2285  return RegMask();
2286}
2287
2288// Register for MODL projection of divmodL.
2289RegMask Matcher::modL_proj_mask() {
2290  ShouldNotReachHere();
2291  return RegMask();
2292}
2293
2294const RegMask Matcher::method_handle_invoke_SP_save_mask() {
2295  return RegMask();
2296}
2297
2298const bool Matcher::convi2l_type_required = true;
2299
2300%}
2301
2302//----------ENCODING BLOCK-----------------------------------------------------
2303// This block specifies the encoding classes used by the compiler to output
2304// byte streams. Encoding classes are parameterized macros used by
2305// Machine Instruction Nodes in order to generate the bit encoding of the
2306// instruction. Operands specify their base encoding interface with the
2307// interface keyword. There are currently supported four interfaces,
2308// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
2309// operand to generate a function which returns its register number when
2310// queried. CONST_INTER causes an operand to generate a function which
2311// returns the value of the constant when queried. MEMORY_INTER causes an
2312// operand to generate four functions which return the Base Register, the
2313// Index Register, the Scale Value, and the Offset Value of the operand when
2314// queried. COND_INTER causes an operand to generate six functions which
2315// return the encoding code (ie - encoding bits for the instruction)
2316// associated with each basic boolean condition for a conditional instruction.
2317//
2318// Instructions specify two basic values for encoding. Again, a function
2319// is available to check if the constant displacement is an oop. They use the
2320// ins_encode keyword to specify their encoding classes (which must be
2321// a sequence of enc_class names, and their parameters, specified in
2322// the encoding block), and they use the
2323// opcode keyword to specify, in order, their primary, secondary, and
2324// tertiary opcode. Only the opcode sections which a particular instruction
2325// needs for encoding need to be specified.
2326encode %{
2327  enc_class enc_unimplemented %{
2328    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
2329    MacroAssembler _masm(&cbuf);
2330    __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
2331  %}
2332
2333  enc_class enc_untested %{
2334#ifdef ASSERT
2335    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
2336    MacroAssembler _masm(&cbuf);
2337    __ untested("Untested mach node encoding in AD file.");
2338#else
2339    // TODO: PPC port $archOpcode(ppc64Opcode_none);
2340#endif
2341  %}
2342
2343  enc_class enc_lbz(iRegIdst dst, memory mem) %{
2344    // TODO: PPC port $archOpcode(ppc64Opcode_lbz);
2345    MacroAssembler _masm(&cbuf);
2346    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2347    __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2348  %}
2349
2350  // Load acquire.
2351  enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
2352    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
2353    MacroAssembler _masm(&cbuf);
2354    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2355    __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
2356    __ twi_0($dst$$Register);
2357    __ isync();
2358  %}
2359
2360  enc_class enc_lhz(iRegIdst dst, memory mem) %{
2361    // TODO: PPC port $archOpcode(ppc64Opcode_lhz);
2362
2363    MacroAssembler _masm(&cbuf);
2364    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2365    __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2366  %}
2367
2368  // Load acquire.
2369  enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
2370    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
2371
2372    MacroAssembler _masm(&cbuf);
2373    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2374    __ lhz($dst$$Register, Idisp, $mem$$base$$Register);
2375    __ twi_0($dst$$Register);
2376    __ isync();
2377  %}
2378
2379  enc_class enc_lwz(iRegIdst dst, memory mem) %{
2380    // TODO: PPC port $archOpcode(ppc64Opcode_lwz);
2381
2382    MacroAssembler _masm(&cbuf);
2383    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2384    __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2385  %}
2386
2387  // Load acquire.
2388  enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
2389    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
2390
2391    MacroAssembler _masm(&cbuf);
2392    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2393    __ lwz($dst$$Register, Idisp, $mem$$base$$Register);
2394    __ twi_0($dst$$Register);
2395    __ isync();
2396  %}
2397
2398  enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
2399    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2400    MacroAssembler _masm(&cbuf);
2401    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2402    // Operand 'ds' requires 4-alignment.
2403    assert((Idisp & 0x3) == 0, "unaligned offset");
2404    __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2405  %}
2406
2407  // Load acquire.
2408  enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
2409    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
2410    MacroAssembler _masm(&cbuf);
2411    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2412    // Operand 'ds' requires 4-alignment.
2413    assert((Idisp & 0x3) == 0, "unaligned offset");
2414    __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2415    __ twi_0($dst$$Register);
2416    __ isync();
2417  %}
2418
2419  enc_class enc_lfd(RegF dst, memory mem) %{
2420    // TODO: PPC port $archOpcode(ppc64Opcode_lfd);
2421    MacroAssembler _masm(&cbuf);
2422    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2423    __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2424  %}
2425
2426  enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2427    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2428
2429    MacroAssembler _masm(&cbuf);
2430    int toc_offset = 0;
2431
2432    address const_toc_addr;
2433    // Create a non-oop constant, no relocation needed.
2434    // If it is an IC, it has a virtual_call_Relocation.
2435    const_toc_addr = __ long_constant((jlong)$src$$constant);
2436    if (const_toc_addr == NULL) {
2437      ciEnv::current()->record_out_of_memory_failure();
2438      return;
2439    }
2440    
2441    // Get the constant's TOC offset.
2442    toc_offset = __ offset_to_method_toc(const_toc_addr);
2443    
2444    // Keep the current instruction offset in mind.
2445    ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2446  
2447    __ ld($dst$$Register, toc_offset, $toc$$Register);
2448  %}
2449
2450  enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2451    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
2452
2453    MacroAssembler _masm(&cbuf);
2454
2455    if (!ra_->C->in_scratch_emit_size()) {
2456      address const_toc_addr;
2457      // Create a non-oop constant, no relocation needed.
2458      // If it is an IC, it has a virtual_call_Relocation.
2459      const_toc_addr = __ long_constant((jlong)$src$$constant);
2460      if (const_toc_addr == NULL) {
2461        ciEnv::current()->record_out_of_memory_failure();
2462        return;
2463      }
2464
2465      // Get the constant's TOC offset.
2466      const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2467      // Store the toc offset of the constant.
2468      ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2469
2470      // Also keep the current instruction offset in mind.
2471      ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2472    }
2473
2474    __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2475  %}
2476
2477%} // encode
2478
2479source %{
2480
2481typedef struct {
2482  loadConL_hiNode *_large_hi;
2483  loadConL_loNode *_large_lo;
2484  loadConLNode    *_small;
2485  MachNode        *_last;
2486} loadConLNodesTuple;
2487
2488loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2489                                             OptoReg::Name reg_second, OptoReg::Name reg_first) {
2490  loadConLNodesTuple nodes;
2491
2492  const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2493  if (large_constant_pool) {
2494    // Create new nodes.
2495    loadConL_hiNode *m1 = new loadConL_hiNode();
2496    loadConL_loNode *m2 = new loadConL_loNode();
2497
2498    // inputs for new nodes
2499    m1->add_req(NULL, toc);
2500    m2->add_req(NULL, m1);
2501
2502    // operands for new nodes
2503    m1->_opnds[0] = new iRegLdstOper(); // dst
2504    m1->_opnds[1] = immSrc;             // src
2505    m1->_opnds[2] = new iRegPdstOper(); // toc
2506    m2->_opnds[0] = new iRegLdstOper(); // dst
2507    m2->_opnds[1] = immSrc;             // src
2508    m2->_opnds[2] = new iRegLdstOper(); // base
2509
2510    // Initialize ins_attrib TOC fields.
2511    m1->_const_toc_offset = -1;
2512    m2->_const_toc_offset_hi_node = m1;
2513
2514    // Initialize ins_attrib instruction offset.
2515    m1->_cbuf_insts_offset = -1;
2516
2517    // register allocation for new nodes
2518    ra_->set_pair(m1->_idx, reg_second, reg_first);
2519    ra_->set_pair(m2->_idx, reg_second, reg_first);
2520
2521    // Create result.
2522    nodes._large_hi = m1;
2523    nodes._large_lo = m2;
2524    nodes._small = NULL;
2525    nodes._last = nodes._large_lo;
2526    assert(m2->bottom_type()->isa_long(), "must be long");
2527  } else {
2528    loadConLNode *m2 = new loadConLNode();
2529
2530    // inputs for new nodes
2531    m2->add_req(NULL, toc);
2532
2533    // operands for new nodes
2534    m2->_opnds[0] = new iRegLdstOper(); // dst
2535    m2->_opnds[1] = immSrc;             // src
2536    m2->_opnds[2] = new iRegPdstOper(); // toc
2537
2538    // Initialize ins_attrib instruction offset.
2539    m2->_cbuf_insts_offset = -1;
2540
2541    // register allocation for new nodes
2542    ra_->set_pair(m2->_idx, reg_second, reg_first);
2543
2544    // Create result.
2545    nodes._large_hi = NULL;
2546    nodes._large_lo = NULL;
2547    nodes._small = m2;
2548    nodes._last = nodes._small;
2549    assert(m2->bottom_type()->isa_long(), "must be long");
2550  }
2551
2552  return nodes;
2553}
2554
2555%} // source
2556
2557encode %{
2558  // Postalloc expand emitter for loading a long constant from the method's TOC.
2559  // Enc_class needed as consttanttablebase is not supported by postalloc
2560  // expand.
2561  enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2562    // Create new nodes.
2563    loadConLNodesTuple loadConLNodes =
2564      loadConLNodesTuple_create(ra_, n_toc, op_src,
2565                                ra_->get_reg_second(this), ra_->get_reg_first(this));
2566
2567    // Push new nodes.
2568    if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2569    if (loadConLNodes._last)     nodes->push(loadConLNodes._last);
2570
2571    // some asserts
2572    assert(nodes->length() >= 1, "must have created at least 1 node");
2573    assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2574  %}
2575
2576  enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2577    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2578
2579    MacroAssembler _masm(&cbuf);
2580    int toc_offset = 0;
2581
2582    intptr_t val = $src$$constant;
2583    relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
2584    address const_toc_addr;
2585    if (constant_reloc == relocInfo::oop_type) {
2586      // Create an oop constant and a corresponding relocation.
2587      AddressLiteral a = __ allocate_oop_address((jobject)val);
2588      const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2589      __ relocate(a.rspec());
2590    } else if (constant_reloc == relocInfo::metadata_type) {
2591      AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2592      const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2593      __ relocate(a.rspec());
2594    } else {
2595      // Create a non-oop constant, no relocation needed.
2596      const_toc_addr = __ long_constant((jlong)$src$$constant);
2597    }
2598
2599    if (const_toc_addr == NULL) {
2600      ciEnv::current()->record_out_of_memory_failure();
2601      return;
2602    }
2603    // Get the constant's TOC offset.
2604    toc_offset = __ offset_to_method_toc(const_toc_addr);
2605
2606    __ ld($dst$$Register, toc_offset, $toc$$Register);
2607  %}
2608
2609  enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2610    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
2611
2612    MacroAssembler _masm(&cbuf);
2613    if (!ra_->C->in_scratch_emit_size()) {
2614      intptr_t val = $src$$constant;
2615      relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
2616      address const_toc_addr;
2617      if (constant_reloc == relocInfo::oop_type) {
2618        // Create an oop constant and a corresponding relocation.
2619        AddressLiteral a = __ allocate_oop_address((jobject)val);
2620        const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2621        __ relocate(a.rspec());
2622      } else if (constant_reloc == relocInfo::metadata_type) {
2623        AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2624        const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2625        __ relocate(a.rspec());
2626      } else {  // non-oop pointers, e.g. card mark base, heap top
2627        // Create a non-oop constant, no relocation needed.
2628        const_toc_addr = __ long_constant((jlong)$src$$constant);
2629      }
2630
2631      if (const_toc_addr == NULL) {
2632        ciEnv::current()->record_out_of_memory_failure();
2633        return;
2634      }
2635      // Get the constant's TOC offset.
2636      const int toc_offset = __ offset_to_method_toc(const_toc_addr);
2637      // Store the toc offset of the constant.
2638      ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset;
2639    }
2640
2641    __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2642  %}
2643
2644  // Postalloc expand emitter for loading a ptr constant from the method's TOC.
2645  // Enc_class needed as consttanttablebase is not supported by postalloc
2646  // expand.
2647  enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{
2648    const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2649    if (large_constant_pool) {
2650      // Create new nodes.
2651      loadConP_hiNode *m1 = new loadConP_hiNode();
2652      loadConP_loNode *m2 = new loadConP_loNode();
2653
2654      // inputs for new nodes
2655      m1->add_req(NULL, n_toc);
2656      m2->add_req(NULL, m1);
2657
2658      // operands for new nodes
2659      m1->_opnds[0] = new iRegPdstOper(); // dst
2660      m1->_opnds[1] = op_src;             // src
2661      m1->_opnds[2] = new iRegPdstOper(); // toc
2662      m2->_opnds[0] = new iRegPdstOper(); // dst
2663      m2->_opnds[1] = op_src;             // src
2664      m2->_opnds[2] = new iRegLdstOper(); // base
2665
2666      // Initialize ins_attrib TOC fields.
2667      m1->_const_toc_offset = -1;
2668      m2->_const_toc_offset_hi_node = m1;
2669
2670      // Register allocation for new nodes.
2671      ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2672      ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2673
2674      nodes->push(m1);
2675      nodes->push(m2);
2676      assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2677    } else {
2678      loadConPNode *m2 = new loadConPNode();
2679
2680      // inputs for new nodes
2681      m2->add_req(NULL, n_toc);
2682
2683      // operands for new nodes
2684      m2->_opnds[0] = new iRegPdstOper(); // dst
2685      m2->_opnds[1] = op_src;             // src
2686      m2->_opnds[2] = new iRegPdstOper(); // toc
2687
2688      // Register allocation for new nodes.
2689      ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2690
2691      nodes->push(m2);
2692      assert(m2->bottom_type()->isa_ptr(), "must be ptr");
2693    }
2694  %}
2695
2696  // Enc_class needed as consttanttablebase is not supported by postalloc
2697  // expand.
2698  enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{
2699    bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2700
2701    MachNode *m2;
2702    if (large_constant_pool) {
2703      m2 = new loadConFCompNode();
2704    } else {
2705      m2 = new loadConFNode();
2706    }
2707    // inputs for new nodes
2708    m2->add_req(NULL, n_toc);
2709
2710    // operands for new nodes
2711    m2->_opnds[0] = op_dst;
2712    m2->_opnds[1] = op_src;
2713    m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2714
2715    // register allocation for new nodes
2716    ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2717    nodes->push(m2);
2718  %}
2719
2720  // Enc_class needed as consttanttablebase is not supported by postalloc
2721  // expand.
2722  enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{
2723    bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2724
2725    MachNode *m2;
2726    if (large_constant_pool) {
2727      m2 = new loadConDCompNode();
2728    } else {
2729      m2 = new loadConDNode();
2730    }
2731    // inputs for new nodes
2732    m2->add_req(NULL, n_toc);
2733
2734    // operands for new nodes
2735    m2->_opnds[0] = op_dst;
2736    m2->_opnds[1] = op_src;
2737    m2->_opnds[2] = new iRegPdstOper(); // constanttablebase
2738
2739    // register allocation for new nodes
2740    ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2741    nodes->push(m2);
2742  %}
2743
2744  enc_class enc_stw(iRegIsrc src, memory mem) %{
2745    // TODO: PPC port $archOpcode(ppc64Opcode_stw);
2746    MacroAssembler _masm(&cbuf);
2747    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2748    __ stw($src$$Register, Idisp, $mem$$base$$Register);
2749  %}
2750
2751  enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
2752    // TODO: PPC port $archOpcode(ppc64Opcode_std);
2753    MacroAssembler _masm(&cbuf);
2754    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2755    // Operand 'ds' requires 4-alignment.
2756    assert((Idisp & 0x3) == 0, "unaligned offset");
2757    __ std($src$$Register, Idisp, $mem$$base$$Register);
2758  %}
2759
2760  enc_class enc_stfs(RegF src, memory mem) %{
2761    // TODO: PPC port $archOpcode(ppc64Opcode_stfs);
2762    MacroAssembler _masm(&cbuf);
2763    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2764    __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
2765  %}
2766
2767  enc_class enc_stfd(RegF src, memory mem) %{
2768    // TODO: PPC port $archOpcode(ppc64Opcode_stfd);
2769    MacroAssembler _masm(&cbuf);
2770    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2771    __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
2772  %}
2773
2774  // Use release_store for card-marking to ensure that previous
2775  // oop-stores are visible before the card-mark change.
2776  enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{
2777    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
2778    // FIXME: Implement this as a cmove and use a fixed condition code
2779    // register which is written on every transition to compiled code,
2780    // e.g. in call-stub and when returning from runtime stubs.
2781    //
2782    // Proposed code sequence for the cmove implementation:
2783    //
2784    // Label skip_release;
2785    // __ beq(CCRfixed, skip_release);
2786    // __ release();
2787    // __ bind(skip_release);
2788    // __ stb(card mark);
2789
2790    MacroAssembler _masm(&cbuf);
2791    Label skip_storestore;
2792
2793#if 0 // TODO: PPC port
2794    // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the
2795    // StoreStore barrier conditionally.
2796    __ lwz(R0, 0, $releaseFieldAddr$$Register);
2797    __ cmpwi($crx$$CondRegister, R0, 0);
2798    __ beq_predict_taken($crx$$CondRegister, skip_storestore);
2799#endif
2800    __ li(R0, 0);
2801    __ membar(Assembler::StoreStore);
2802#if 0 // TODO: PPC port
2803    __ bind(skip_storestore);
2804#endif
2805
2806    // Do the store.
2807    if ($mem$$index == 0) {
2808      __ stb(R0, $mem$$disp, $mem$$base$$Register);
2809    } else {
2810      assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc");
2811      __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register);
2812    }
2813  %}
2814
2815  enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{
2816
2817    if (VM_Version::has_isel()) {
2818      // use isel instruction with Power 7
2819      cmpP_reg_imm16Node *n_compare  = new cmpP_reg_imm16Node();
2820      encodeP_subNode    *n_sub_base = new encodeP_subNode();
2821      encodeP_shiftNode  *n_shift    = new encodeP_shiftNode();
2822      cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode();
2823
2824      n_compare->add_req(n_region, n_src);
2825      n_compare->_opnds[0] = op_crx;
2826      n_compare->_opnds[1] = op_src;
2827      n_compare->_opnds[2] = new immL16Oper(0);
2828
2829      n_sub_base->add_req(n_region, n_src);
2830      n_sub_base->_opnds[0] = op_dst;
2831      n_sub_base->_opnds[1] = op_src;
2832      n_sub_base->_bottom_type = _bottom_type;
2833
2834      n_shift->add_req(n_region, n_sub_base);
2835      n_shift->_opnds[0] = op_dst;
2836      n_shift->_opnds[1] = op_dst;
2837      n_shift->_bottom_type = _bottom_type;
2838
2839      n_cond_set->add_req(n_region, n_compare, n_shift);
2840      n_cond_set->_opnds[0] = op_dst;
2841      n_cond_set->_opnds[1] = op_crx;
2842      n_cond_set->_opnds[2] = op_dst;
2843      n_cond_set->_bottom_type = _bottom_type;
2844
2845      ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2846      ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2847      ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2848      ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2849
2850      nodes->push(n_compare);
2851      nodes->push(n_sub_base);
2852      nodes->push(n_shift);
2853      nodes->push(n_cond_set);
2854
2855    } else {
2856      // before Power 7
2857      moveRegNode        *n_move     = new moveRegNode();
2858      cmpP_reg_imm16Node *n_compare  = new cmpP_reg_imm16Node();
2859      encodeP_shiftNode  *n_shift    = new encodeP_shiftNode();
2860      cond_sub_baseNode  *n_sub_base = new cond_sub_baseNode();
2861
2862      n_move->add_req(n_region, n_src);
2863      n_move->_opnds[0] = op_dst;
2864      n_move->_opnds[1] = op_src;
2865      ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop.
2866
2867      n_compare->add_req(n_region, n_src);
2868      n_compare->add_prec(n_move);
2869
2870      n_compare->_opnds[0] = op_crx;
2871      n_compare->_opnds[1] = op_src;
2872      n_compare->_opnds[2] = new immL16Oper(0);
2873
2874      n_sub_base->add_req(n_region, n_compare, n_src);
2875      n_sub_base->_opnds[0] = op_dst;
2876      n_sub_base->_opnds[1] = op_crx;
2877      n_sub_base->_opnds[2] = op_src;
2878      n_sub_base->_bottom_type = _bottom_type;
2879
2880      n_shift->add_req(n_region, n_sub_base);
2881      n_shift->_opnds[0] = op_dst;
2882      n_shift->_opnds[1] = op_dst;
2883      n_shift->_bottom_type = _bottom_type;
2884
2885      ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2886      ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2887      ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2888      ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2889
2890      nodes->push(n_move);
2891      nodes->push(n_compare);
2892      nodes->push(n_sub_base);
2893      nodes->push(n_shift);
2894    }
2895
2896    assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2897  %}
2898
2899  enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{
2900
2901    encodeP_subNode *n1 = new encodeP_subNode();
2902    n1->add_req(n_region, n_src);
2903    n1->_opnds[0] = op_dst;
2904    n1->_opnds[1] = op_src;
2905    n1->_bottom_type = _bottom_type;
2906
2907    encodeP_shiftNode *n2 = new encodeP_shiftNode();
2908    n2->add_req(n_region, n1);
2909    n2->_opnds[0] = op_dst;
2910    n2->_opnds[1] = op_dst;
2911    n2->_bottom_type = _bottom_type;
2912    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2913    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2914
2915    nodes->push(n1);
2916    nodes->push(n2);
2917    assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed.
2918  %}
2919
2920  enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
2921    decodeN_shiftNode *n_shift    = new decodeN_shiftNode();
2922    cmpN_reg_imm0Node *n_compare  = new cmpN_reg_imm0Node();
2923
2924    n_compare->add_req(n_region, n_src);
2925    n_compare->_opnds[0] = op_crx;
2926    n_compare->_opnds[1] = op_src;
2927    n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
2928
2929    n_shift->add_req(n_region, n_src);
2930    n_shift->_opnds[0] = op_dst;
2931    n_shift->_opnds[1] = op_src;
2932    n_shift->_bottom_type = _bottom_type;
2933
2934    if (VM_Version::has_isel()) {
2935      // use isel instruction with Power 7
2936
2937      decodeN_addNode *n_add_base = new decodeN_addNode();
2938      n_add_base->add_req(n_region, n_shift);
2939      n_add_base->_opnds[0] = op_dst;
2940      n_add_base->_opnds[1] = op_dst;
2941      n_add_base->_bottom_type = _bottom_type;
2942
2943      cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
2944      n_cond_set->add_req(n_region, n_compare, n_add_base);
2945      n_cond_set->_opnds[0] = op_dst;
2946      n_cond_set->_opnds[1] = op_crx;
2947      n_cond_set->_opnds[2] = op_dst;
2948      n_cond_set->_bottom_type = _bottom_type;
2949
2950      assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
2951      ra_->set_oop(n_cond_set, true);
2952
2953      ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2954      ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2955      ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2956      ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2957
2958      nodes->push(n_compare);
2959      nodes->push(n_shift);
2960      nodes->push(n_add_base);
2961      nodes->push(n_cond_set);
2962
2963    } else {
2964      // before Power 7
2965      cond_add_baseNode *n_add_base = new cond_add_baseNode();
2966
2967      n_add_base->add_req(n_region, n_compare, n_shift);
2968      n_add_base->_opnds[0] = op_dst;
2969      n_add_base->_opnds[1] = op_crx;
2970      n_add_base->_opnds[2] = op_dst;
2971      n_add_base->_bottom_type = _bottom_type;
2972
2973      assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
2974      ra_->set_oop(n_add_base, true);
2975
2976      ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2977      ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
2978      ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2979
2980      nodes->push(n_compare);
2981      nodes->push(n_shift);
2982      nodes->push(n_add_base);
2983    }
2984  %}
2985
2986  enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{
2987    decodeN_shiftNode *n1 = new decodeN_shiftNode();
2988    n1->add_req(n_region, n_src);
2989    n1->_opnds[0] = op_dst;
2990    n1->_opnds[1] = op_src;
2991    n1->_bottom_type = _bottom_type;
2992
2993    decodeN_addNode *n2 = new decodeN_addNode();
2994    n2->add_req(n_region, n1);
2995    n2->_opnds[0] = op_dst;
2996    n2->_opnds[1] = op_dst;
2997    n2->_bottom_type = _bottom_type;
2998    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
2999    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
3000
3001    assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
3002    ra_->set_oop(n2, true);
3003
3004    nodes->push(n1);
3005    nodes->push(n2);
3006  %}
3007
3008  enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{
3009    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3010
3011    MacroAssembler _masm(&cbuf);
3012    int cc        = $cmp$$cmpcode;
3013    int flags_reg = $crx$$reg;
3014    Label done;
3015    assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3016    // Branch if not (cmp crx).
3017    __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done);
3018    __ mr($dst$$Register, $src$$Register);
3019    // TODO PPC port __ endgroup_if_needed(_size == 12);
3020    __ bind(done);
3021  %}
3022
3023  enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{
3024    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3025
3026    MacroAssembler _masm(&cbuf);
3027    Label done;
3028    assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3029    // Branch if not (cmp crx).
3030    __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
3031    __ li($dst$$Register, $src$$constant);
3032    // TODO PPC port __ endgroup_if_needed(_size == 12);
3033    __ bind(done);
3034  %}
3035
3036  // This enc_class is needed so that scheduler gets proper
3037  // input mapping for latency computation.
3038  enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
3039    // TODO: PPC port $archOpcode(ppc64Opcode_andc);
3040    MacroAssembler _masm(&cbuf);
3041    __ andc($dst$$Register, $src1$$Register, $src2$$Register);
3042  %}
3043
3044  enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3045    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
3046
3047    MacroAssembler _masm(&cbuf);
3048
3049    Label done;
3050    __ cmpwi($crx$$CondRegister, $src$$Register, 0);
3051    __ li($dst$$Register, $zero$$constant);
3052    __ beq($crx$$CondRegister, done);
3053    __ li($dst$$Register, $notzero$$constant);
3054    __ bind(done);
3055  %}
3056
3057  enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
3058    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
3059
3060    MacroAssembler _masm(&cbuf);
3061
3062    Label done;
3063    __ cmpdi($crx$$CondRegister, $src$$Register, 0);
3064    __ li($dst$$Register, $zero$$constant);
3065    __ beq($crx$$CondRegister, done);
3066    __ li($dst$$Register, $notzero$$constant);
3067    __ bind(done);
3068  %}
3069
3070  enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
3071    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
3072
3073    MacroAssembler _masm(&cbuf);
3074    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
3075    Label done;
3076    __ bso($crx$$CondRegister, done);
3077    __ ld($dst$$Register, Idisp, $mem$$base$$Register);
3078    // TODO PPC port __ endgroup_if_needed(_size == 12);
3079    __ bind(done);
3080  %}
3081
3082  enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3083    // TODO: PPC port $archOpcode(ppc64Opcode_bc);
3084
3085    MacroAssembler _masm(&cbuf);
3086    Label d;   // dummy
3087    __ bind(d);
3088    Label* p = ($lbl$$label);
3089    // `p' is `NULL' when this encoding class is used only to
3090    // determine the size of the encoded instruction.
3091    Label& l = (NULL == p)? d : *(p);
3092    int cc = $cmp$$cmpcode;
3093    int flags_reg = $crx$$reg;
3094    assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
3095    int bhint = Assembler::bhintNoHint;
3096
3097    if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3098      if (_prob <= PROB_NEVER) {
3099        bhint = Assembler::bhintIsNotTaken;
3100      } else if (_prob >= PROB_ALWAYS) {
3101        bhint = Assembler::bhintIsTaken;
3102      }
3103    }
3104
3105    __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3106          cc_to_biint(cc, flags_reg),
3107          l);
3108  %}
3109
3110  enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3111    // The scheduler doesn't know about branch shortening, so we set the opcode
3112    // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3113    // TODO: PPC port $archOpcode(ppc64Opcode_bc);
3114
3115    MacroAssembler _masm(&cbuf);
3116    Label d;    // dummy
3117    __ bind(d);
3118    Label* p = ($lbl$$label);
3119    // `p' is `NULL' when this encoding class is used only to
3120    // determine the size of the encoded instruction.
3121    Label& l = (NULL == p)? d : *(p);
3122    int cc = $cmp$$cmpcode;
3123    int flags_reg = $crx$$reg;
3124    int bhint = Assembler::bhintNoHint;
3125
3126    if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3127      if (_prob <= PROB_NEVER) {
3128        bhint = Assembler::bhintIsNotTaken;
3129      } else if (_prob >= PROB_ALWAYS) {
3130        bhint = Assembler::bhintIsTaken;
3131      }
3132    }
3133
3134    // Tell the conditional far branch to optimize itself when being relocated.
3135    __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3136                  cc_to_biint(cc, flags_reg),
3137                  l,
3138                  MacroAssembler::bc_far_optimize_on_relocate);
3139  %}
3140
3141  // Branch used with Power6 scheduling (can be shortened without changing the node).
3142  enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
3143    // The scheduler doesn't know about branch shortening, so we set the opcode
3144    // to ppc64Opcode_bc in order to hide this detail from the scheduler.
3145    // TODO: PPC port $archOpcode(ppc64Opcode_bc);
3146
3147    MacroAssembler _masm(&cbuf);
3148    Label d;   // dummy
3149    __ bind(d);
3150    Label* p = ($lbl$$label);
3151    // `p' is `NULL' when this encoding class is used only to
3152    // determine the size of the encoded instruction.
3153    Label& l = (NULL == p)? d : *(p);
3154    int cc = $cmp$$cmpcode;
3155    int flags_reg = $crx$$reg;
3156    int bhint = Assembler::bhintNoHint;
3157
3158    if (UseStaticBranchPredictionForUncommonPathsPPC64) {
3159      if (_prob <= PROB_NEVER) {
3160        bhint = Assembler::bhintIsNotTaken;
3161      } else if (_prob >= PROB_ALWAYS) {
3162        bhint = Assembler::bhintIsTaken;
3163      }
3164    }
3165
3166#if 0 // TODO: PPC port
3167    if (_size == 8) {
3168      // Tell the conditional far branch to optimize itself when being relocated.
3169      __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3170                    cc_to_biint(cc, flags_reg),
3171                    l,
3172                    MacroAssembler::bc_far_optimize_on_relocate);
3173    } else {
3174      __ bc    (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3175                    cc_to_biint(cc, flags_reg),
3176                    l);
3177    }
3178#endif
3179    Unimplemented();
3180  %}
3181
3182  // Postalloc expand emitter for loading a replicatef float constant from
3183  // the method's TOC.
3184  // Enc_class needed as consttanttablebase is not supported by postalloc
3185  // expand.
3186  enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3187    // Create new nodes.
3188
3189    // Make an operand with the bit pattern to load as float.
3190    immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3191
3192    loadConLNodesTuple loadConLNodes =
3193      loadConLNodesTuple_create(ra_, n_toc, op_repl,
3194                                ra_->get_reg_second(this), ra_->get_reg_first(this));
3195
3196    // Push new nodes.
3197    if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3198    if (loadConLNodes._last)     nodes->push(loadConLNodes._last);
3199
3200    assert(nodes->length() >= 1, "must have created at least 1 node");
3201    assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3202  %}
3203
3204  // This enc_class is needed so that scheduler gets proper
3205  // input mapping for latency computation.
3206  enc_class enc_poll(immI dst, iRegLdst poll) %{
3207    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
3208    // Fake operand dst needed for PPC scheduler.
3209    assert($dst$$constant == 0x0, "dst must be 0x0");
3210
3211    MacroAssembler _masm(&cbuf);
3212    // Mark the code position where the load from the safepoint
3213    // polling page was emitted as relocInfo::poll_type.
3214    __ relocate(relocInfo::poll_type);
3215    __ load_from_polling_page($poll$$Register);
3216  %}
3217
3218  // A Java static call or a runtime call.
3219  //
3220  // Branch-and-link relative to a trampoline.
3221  // The trampoline loads the target address and does a long branch to there.
3222  // In case we call java, the trampoline branches to a interpreter_stub
3223  // which loads the inline cache and the real call target from the constant pool.
3224  //
3225  // This basically looks like this:
3226  //
3227  // >>>> consts      -+  -+
3228  //                   |   |- offset1
3229  // [call target1]    | <-+
3230  // [IC cache]        |- offset2
3231  // [call target2] <--+
3232  //
3233  // <<<< consts
3234  // >>>> insts
3235  //
3236  // bl offset16               -+  -+             ??? // How many bits available?
3237  //                            |   |
3238  // <<<< insts                 |   |
3239  // >>>> stubs                 |   |
3240  //                            |   |- trampoline_stub_Reloc
3241  // trampoline stub:           | <-+
3242  //   r2 = toc                 |
3243  //   r2 = [r2 + offset1]      |       // Load call target1 from const section
3244  //   mtctr r2                 |
3245  //   bctr                     |- static_stub_Reloc
3246  // comp_to_interp_stub:   <---+
3247  //   r1 = toc
3248  //   ICreg = [r1 + IC_offset]         // Load IC from const section
3249  //   r1    = [r1 + offset2]           // Load call target2 from const section
3250  //   mtctr r1
3251  //   bctr
3252  //
3253  // <<<< stubs
3254  //
3255  // The call instruction in the code either
3256  // - Branches directly to a compiled method if the offset is encodable in instruction.
3257  // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3258  // - Branches to the compiled_to_interp stub if the target is interpreted.
3259  //
3260  // Further there are three relocations from the loads to the constants in
3261  // the constant section.
3262  //
3263  // Usage of r1 and r2 in the stubs allows to distinguish them.
3264  enc_class enc_java_static_call(method meth) %{
3265    // TODO: PPC port $archOpcode(ppc64Opcode_bl);
3266
3267    MacroAssembler _masm(&cbuf);
3268    address entry_point = (address)$meth$$method;
3269
3270    if (!_method) {
3271      // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3272      emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type);
3273    } else {
3274      // Remember the offset not the address.
3275      const int start_offset = __ offset();
3276
3277      // The trampoline stub.
3278      // No entry point given, use the current pc.
3279      // Make sure branch fits into
3280      if (entry_point == 0) entry_point = __ pc();
3281
3282      // Put the entry point as a constant into the constant pool.
3283      const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
3284      if (entry_point_toc_addr == NULL) {
3285        ciEnv::current()->record_out_of_memory_failure();
3286        return;
3287      }
3288      const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
3289
3290      // Emit the trampoline stub which will be related to the branch-and-link below.
3291      CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
3292      if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3293      int method_index = resolved_method_index(cbuf);
3294      __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3295                  : static_call_Relocation::spec(method_index));
3296
3297      // The real call.
3298      // Note: At this point we do not have the address of the trampoline
3299      // stub, and the entry point might be too far away for bl, so __ pc()
3300      // serves as dummy and the bl will be patched later.
3301      cbuf.set_insts_mark();
3302      __ bl(__ pc());  // Emits a relocation.
3303
3304      // The stub for call to interpreter.
3305      address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
3306      if (stub == NULL) {
3307        ciEnv::current()->record_failure("CodeCache is full");
3308        return;
3309      }
3310    }
3311  %}
3312
3313  // Second node of expanded dynamic call - the call.
3314  enc_class enc_java_dynamic_call_sched(method meth) %{
3315    // TODO: PPC port $archOpcode(ppc64Opcode_bl);
3316
3317    MacroAssembler _masm(&cbuf);
3318
3319    if (!ra_->C->in_scratch_emit_size()) {
3320      // Create a call trampoline stub for the given method.
3321      const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method;
3322      const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none);
3323      if (entry_point_const == NULL) {
3324        ciEnv::current()->record_out_of_memory_failure();
3325        return;
3326      }
3327      const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const);
3328      CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset());
3329      if (ra_->C->env()->failing()) { return; } // Code cache may be full.
3330
3331      // Build relocation at call site with ic position as data.
3332      assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) ||
3333             (_load_ic_hi_node == NULL && _load_ic_node != NULL),
3334             "must have one, but can't have both");
3335      assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) ||
3336             (_load_ic_node != NULL    && _load_ic_node->_cbuf_insts_offset != -1),
3337             "must contain instruction offset");
3338      const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL
3339        ? _load_ic_hi_node->_cbuf_insts_offset
3340        : _load_ic_node->_cbuf_insts_offset;
3341      const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset);
3342      assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr),
3343             "should be load from TOC");
3344      int method_index = resolved_method_index(cbuf);
3345      __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
3346    }
3347
3348    // At this point I do not have the address of the trampoline stub,
3349    // and the entry point might be too far away for bl. Pc() serves
3350    // as dummy and bl will be patched later.
3351    __ bl((address) __ pc());
3352  %}
3353
3354  // postalloc expand emitter for virtual calls.
3355  enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{
3356
3357    // Create the nodes for loading the IC from the TOC.
3358    loadConLNodesTuple loadConLNodes_IC =
3359      loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()),
3360                                OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
3361
3362    // Create the call node.
3363    CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode();
3364    call->_method_handle_invoke = _method_handle_invoke;
3365    call->_vtable_index      = _vtable_index;
3366    call->_method            = _method;
3367    call->_bci               = _bci;
3368    call->_optimized_virtual = _optimized_virtual;
3369    call->_tf                = _tf;
3370    call->_entry_point       = _entry_point;
3371    call->_cnt               = _cnt;
3372    call->_argsize           = _argsize;
3373    call->_oop_map           = _oop_map;
3374    call->_jvms              = _jvms;
3375    call->_jvmadj            = _jvmadj;
3376    call->_in_rms            = _in_rms;
3377    call->_nesting           = _nesting;
3378    call->_override_symbolic_info = _override_symbolic_info;
3379
3380    // New call needs all inputs of old call.
3381    // Req...
3382    for (uint i = 0; i < req(); ++i) {
3383      // The expanded node does not need toc any more.
3384      // Add the inline cache constant here instead. This expresses the
3385      // register of the inline cache must be live at the call.
3386      // Else we would have to adapt JVMState by -1.
3387      if (i == mach_constant_base_node_input()) {
3388        call->add_req(loadConLNodes_IC._last);
3389      } else {
3390        call->add_req(in(i));
3391      }
3392    }
3393    // ...as well as prec
3394    for (uint i = req(); i < len(); ++i) {
3395      call->add_prec(in(i));
3396    }
3397
3398    // Remember nodes loading the inline cache into r19.
3399    call->_load_ic_hi_node = loadConLNodes_IC._large_hi;
3400    call->_load_ic_node    = loadConLNodes_IC._small;
3401
3402    // Operands for new nodes.
3403    call->_opnds[0] = _opnds[0];
3404    call->_opnds[1] = _opnds[1];
3405
3406    // Only the inline cache is associated with a register.
3407    assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19");
3408
3409    // Push new nodes.
3410    if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi);
3411    if (loadConLNodes_IC._last)     nodes->push(loadConLNodes_IC._last);
3412    nodes->push(call);
3413  %}
3414
3415  // Compound version of call dynamic
3416  // Toc is only passed so that it can be used in ins_encode statement.
3417  // In the code we have to use $constanttablebase.
3418  enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
3419    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
3420    MacroAssembler _masm(&cbuf);
3421    int start_offset = __ offset();
3422
3423    Register Rtoc = (ra_) ? $constanttablebase : R2_TOC;
3424#if 0
3425    int vtable_index = this->_vtable_index;
3426    if (_vtable_index < 0) {
3427      // Must be invalid_vtable_index, not nonvirtual_vtable_index.
3428      assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value");
3429      Register ic_reg = as_Register(Matcher::inline_cache_reg_encode());
3430
3431      // Virtual call relocation will point to ic load.
3432      address virtual_call_meta_addr = __ pc();
3433      // Load a clear inline cache.
3434      AddressLiteral empty_ic((address) Universe::non_oop_word());
3435      bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true);
3436      if (!success) {
3437        ciEnv::current()->record_out_of_memory_failure();
3438        return;
3439      }
3440      // CALL to fixup routine.  Fixup routine uses ScopeDesc info
3441      // to determine who we intended to call.
3442      __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr));
3443      emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none);
3444      assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3445             "Fix constant in ret_addr_offset()");
3446    } else {
3447      assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
3448      // Go thru the vtable. Get receiver klass. Receiver already
3449      // checked for non-null. If we'll go thru a C2I adapter, the
3450      // interpreter expects method in R19_method.
3451
3452      __ load_klass(R11_scratch1, R3);
3453
3454      int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes();
3455      int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
3456      __ li(R19_method, v_off);
3457      __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/);
3458      // NOTE: for vtable dispatches, the vtable entry will never be
3459      // null. However it may very well end up in handle_wrong_method
3460      // if the method is abstract for the particular class.
3461      __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method);
3462      // Call target. Either compiled code or C2I adapter.
3463      __ mtctr(R11_scratch1);
3464      __ bctrl();
3465      if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) {
3466        tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset);
3467      }
3468      assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset,
3469             "Fix constant in ret_addr_offset()");
3470    }
3471#endif
3472    Unimplemented();  // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!).
3473  %}
3474
3475  // a runtime call
3476  enc_class enc_java_to_runtime_call (method meth) %{
3477    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
3478
3479    MacroAssembler _masm(&cbuf);
3480    const address start_pc = __ pc();
3481
3482#if defined(ABI_ELFv2)
3483    address entry= !($meth$$method) ? NULL : (address)$meth$$method;
3484    __ call_c(entry, relocInfo::runtime_call_type);
3485#else
3486    // The function we're going to call.
3487    FunctionDescriptor fdtemp;
3488    const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
3489
3490    Register Rtoc = R12_scratch2;
3491    // Calculate the method's TOC.
3492    __ calculate_address_from_global_toc(Rtoc, __ method_toc());
3493    // Put entry, env, toc into the constant pool, this needs up to 3 constant
3494    // pool entries; call_c_using_toc will optimize the call.
3495    bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
3496    if (!success) {
3497      ciEnv::current()->record_out_of_memory_failure();
3498      return;
3499    }
3500#endif
3501
3502    // Check the ret_addr_offset.
3503    assert(((MachCallRuntimeNode*)this)->ret_addr_offset() ==  __ last_calls_return_pc() - start_pc,
3504           "Fix constant in ret_addr_offset()");
3505  %}
3506
3507  // Move to ctr for leaf call.
3508  // This enc_class is needed so that scheduler gets proper
3509  // input mapping for latency computation.
3510  enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3511    // TODO: PPC port $archOpcode(ppc64Opcode_mtctr);
3512    MacroAssembler _masm(&cbuf);
3513    __ mtctr($src$$Register);
3514  %}
3515
3516  // Postalloc expand emitter for runtime leaf calls.
3517  enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3518    loadConLNodesTuple loadConLNodes_Entry;
3519#if defined(ABI_ELFv2)
3520    jlong entry_address = (jlong) this->entry_point();
3521    assert(entry_address, "need address here");
3522    loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3523                                                    OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3524#else
3525    // Get the struct that describes the function we are about to call.
3526    FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3527    assert(fd, "need fd here");
3528    jlong entry_address = (jlong) fd->entry();
3529    // new nodes
3530    loadConLNodesTuple loadConLNodes_Env;
3531    loadConLNodesTuple loadConLNodes_Toc;
3532
3533    // Create nodes and operands for loading the entry point.
3534    loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3535                                                    OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3536
3537
3538    // Create nodes and operands for loading the env pointer.
3539    if (fd->env() != NULL) {
3540      loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3541                                                    OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3542    } else {
3543      loadConLNodes_Env._large_hi = NULL;
3544      loadConLNodes_Env._large_lo = NULL;
3545      loadConLNodes_Env._small    = NULL;
3546      loadConLNodes_Env._last = new loadConL16Node();
3547      loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3548      loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3549      ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3550    }
3551
3552    // Create nodes and operands for loading the Toc point.
3553    loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3554                                                  OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3555#endif // ABI_ELFv2
3556    // mtctr node
3557    MachNode *mtctr = new CallLeafDirect_mtctrNode();
3558
3559    assert(loadConLNodes_Entry._last != NULL, "entry must exist");
3560    mtctr->add_req(0, loadConLNodes_Entry._last);
3561
3562    mtctr->_opnds[0] = new iRegLdstOper();
3563    mtctr->_opnds[1] = new iRegLdstOper();
3564
3565    // call node
3566    MachCallLeafNode *call = new CallLeafDirectNode();
3567
3568    call->_opnds[0] = _opnds[0];
3569    call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3570
3571    // Make the new call node look like the old one.
3572    call->_name        = _name;
3573    call->_tf          = _tf;
3574    call->_entry_point = _entry_point;
3575    call->_cnt         = _cnt;
3576    call->_argsize     = _argsize;
3577    call->_oop_map     = _oop_map;
3578    guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
3579    call->_jvms        = NULL;
3580    call->_jvmadj      = _jvmadj;
3581    call->_in_rms      = _in_rms;
3582    call->_nesting     = _nesting;
3583
3584
3585    // New call needs all inputs of old call.
3586    // Req...
3587    for (uint i = 0; i < req(); ++i) {
3588      if (i != mach_constant_base_node_input()) {
3589        call->add_req(in(i));
3590      }
3591    }
3592
3593    // These must be reqired edges, as the registers are live up to
3594    // the call. Else the constants are handled as kills.
3595    call->add_req(mtctr);
3596#if !defined(ABI_ELFv2)
3597    call->add_req(loadConLNodes_Env._last);
3598    call->add_req(loadConLNodes_Toc._last);
3599#endif
3600
3601    // ...as well as prec
3602    for (uint i = req(); i < len(); ++i) {
3603      call->add_prec(in(i));
3604    }
3605
3606    // registers
3607    ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num));
3608
3609    // Insert the new nodes.
3610    if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
3611    if (loadConLNodes_Entry._last)     nodes->push(loadConLNodes_Entry._last);
3612#if !defined(ABI_ELFv2)
3613    if (loadConLNodes_Env._large_hi)   nodes->push(loadConLNodes_Env._large_hi);
3614    if (loadConLNodes_Env._last)       nodes->push(loadConLNodes_Env._last);
3615    if (loadConLNodes_Toc._large_hi)   nodes->push(loadConLNodes_Toc._large_hi);
3616    if (loadConLNodes_Toc._last)       nodes->push(loadConLNodes_Toc._last);
3617#endif
3618    nodes->push(mtctr);
3619    nodes->push(call);
3620  %}
3621%}
3622
3623//----------FRAME--------------------------------------------------------------
3624// Definition of frame structure and management information.
3625
3626frame %{
3627  // What direction does stack grow in (assumed to be same for native & Java).
3628  stack_direction(TOWARDS_LOW);
3629
3630  // These two registers define part of the calling convention between
3631  // compiled code and the interpreter.
3632
3633  // Inline Cache Register or method for I2C.
3634  inline_cache_reg(R19); // R19_method
3635
3636  // Method Oop Register when calling interpreter.
3637  interpreter_method_oop_reg(R19); // R19_method
3638
3639  // Optional: name the operand used by cisc-spilling to access
3640  // [stack_pointer + offset].
3641  cisc_spilling_operand_name(indOffset);
3642
3643  // Number of stack slots consumed by a Monitor enter.
3644  sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size));
3645
3646  // Compiled code's Frame Pointer.
3647  frame_pointer(R1); // R1_SP
3648
3649  // Interpreter stores its frame pointer in a register which is
3650  // stored to the stack by I2CAdaptors. I2CAdaptors convert from
3651  // interpreted java to compiled java.
3652  //
3653  // R14_state holds pointer to caller's cInterpreter.
3654  interpreter_frame_pointer(R14); // R14_state
3655
3656  stack_alignment(frame::alignment_in_bytes);
3657
3658  in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size));
3659
3660  // Number of outgoing stack slots killed above the
3661  // out_preserve_stack_slots for calls to C. Supports the var-args
3662  // backing area for register parms.
3663  //
3664  varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
3665
3666  // The after-PROLOG location of the return address. Location of
3667  // return address specifies a type (REG or STACK) and a number
3668  // representing the register number (i.e. - use a register name) or
3669  // stack slot.
3670  //
3671  // A: Link register is stored in stack slot ...
3672  // M:  ... but it's in the caller's frame according to PPC-64 ABI.
3673  // J: Therefore, we make sure that the link register is also in R11_scratch1
3674  //    at the end of the prolog.
3675  // B: We use R20, now.
3676  //return_addr(REG R20);
3677
3678  // G: After reading the comments made by all the luminaries on their
3679  //    failure to tell the compiler where the return address really is,
3680  //    I hardly dare to try myself.  However, I'm convinced it's in slot
3681  //    4 what apparently works and saves us some spills.
3682  return_addr(STACK 4);
3683
3684  // This is the body of the function
3685  //
3686  // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs
3687  //                                  uint length,      // length of array
3688  //                                  bool is_outgoing)
3689  //
3690  // The `sig' array is to be updated. sig[j] represents the location
3691  // of the j-th argument, either a register or a stack slot.
3692
3693  // Comment taken from i486.ad:
3694  // Body of function which returns an integer array locating
3695  // arguments either in registers or in stack slots. Passed an array
3696  // of ideal registers called "sig" and a "length" count. Stack-slot
3697  // offsets are based on outgoing arguments, i.e. a CALLER setting up
3698  // arguments for a CALLEE. Incoming stack arguments are
3699  // automatically biased by the preserve_stack_slots field above.
3700  calling_convention %{
3701    // No difference between ingoing/outgoing. Just pass false.
3702    SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3703  %}
3704
3705  // Comment taken from i486.ad:
3706  // Body of function which returns an integer array locating
3707  // arguments either in registers or in stack slots. Passed an array
3708  // of ideal registers called "sig" and a "length" count. Stack-slot
3709  // offsets are based on outgoing arguments, i.e. a CALLER setting up
3710  // arguments for a CALLEE. Incoming stack arguments are
3711  // automatically biased by the preserve_stack_slots field above.
3712  c_calling_convention %{
3713    // This is obviously always outgoing.
3714    // C argument in register AND stack slot.
3715    (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
3716  %}
3717
3718  // Location of native (C/C++) and interpreter return values. This
3719  // is specified to be the same as Java. In the 32-bit VM, long
3720  // values are actually returned from native calls in O0:O1 and
3721  // returned to the interpreter in I0:I1. The copying to and from
3722  // the register pairs is done by the appropriate call and epilog
3723  // opcodes. This simplifies the register allocator.
3724  c_return_value %{
3725    assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3726            (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0),
3727            "only return normal values");
3728    // enum names from opcodes.hpp:    Op_Node Op_Set Op_RegN       Op_RegI       Op_RegP       Op_RegF       Op_RegD       Op_RegL
3729    static int typeToRegLo[Op_RegL+1] = { 0,   0,     R3_num,   R3_num,   R3_num,   F1_num,   F1_num,   R3_num };
3730    static int typeToRegHi[Op_RegL+1] = { 0,   0,     OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3731    return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3732  %}
3733
3734  // Location of compiled Java return values.  Same as C
3735  return_value %{
3736    assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) ||
3737            (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0),
3738            "only return normal values");
3739    // enum names from opcodes.hpp:    Op_Node Op_Set Op_RegN       Op_RegI       Op_RegP       Op_RegF       Op_RegD       Op_RegL
3740    static int typeToRegLo[Op_RegL+1] = { 0,   0,     R3_num,   R3_num,   R3_num,   F1_num,   F1_num,   R3_num };
3741    static int typeToRegHi[Op_RegL+1] = { 0,   0,     OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num };
3742    return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]);
3743  %}
3744%}
3745
3746
3747//----------ATTRIBUTES---------------------------------------------------------
3748
3749//----------Operand Attributes-------------------------------------------------
3750op_attrib op_cost(1);          // Required cost attribute.
3751
3752//----------Instruction Attributes---------------------------------------------
3753
3754// Cost attribute. required.
3755ins_attrib ins_cost(DEFAULT_COST);
3756
3757// Is this instruction a non-matching short branch variant of some
3758// long branch? Not required.
3759ins_attrib ins_short_branch(0);
3760
3761ins_attrib ins_is_TrapBasedCheckNode(true);
3762
3763// Number of constants.
3764// This instruction uses the given number of constants
3765// (optional attribute).
3766// This is needed to determine in time whether the constant pool will
3767// exceed 4000 entries. Before postalloc_expand the overall number of constants
3768// is determined. It's also used to compute the constant pool size
3769// in Output().
3770ins_attrib ins_num_consts(0);
3771
3772// Required alignment attribute (must be a power of 2) specifies the
3773// alignment that some part of the instruction (not necessarily the
3774// start) requires. If > 1, a compute_padding() function must be
3775// provided for the instruction.
3776ins_attrib ins_alignment(1);
3777
3778// Enforce/prohibit rematerializations.
3779// - If an instruction is attributed with 'ins_cannot_rematerialize(true)'
3780//   then rematerialization of that instruction is prohibited and the
3781//   instruction's value will be spilled if necessary.
3782//   Causes that MachNode::rematerialize() returns false.
3783// - If an instruction is attributed with 'ins_should_rematerialize(true)'
3784//   then rematerialization should be enforced and a copy of the instruction
3785//   should be inserted if possible; rematerialization is not guaranteed.
3786//   Note: this may result in rematerializations in front of every use.
3787//   Causes that MachNode::rematerialize() can return true.
3788// (optional attribute)
3789ins_attrib ins_cannot_rematerialize(false);
3790ins_attrib ins_should_rematerialize(false);
3791
3792// Instruction has variable size depending on alignment.
3793ins_attrib ins_variable_size_depending_on_alignment(false);
3794
3795// Instruction is a nop.
3796ins_attrib ins_is_nop(false);
3797
3798// Instruction is mapped to a MachIfFastLock node (instead of MachFastLock).
3799ins_attrib ins_use_mach_if_fast_lock_node(false);
3800
3801// Field for the toc offset of a constant.
3802//
3803// This is needed if the toc offset is not encodable as an immediate in
3804// the PPC load instruction. If so, the upper (hi) bits of the offset are
3805// added to the toc, and from this a load with immediate is performed.
3806// With postalloc expand, we get two nodes that require the same offset
3807// but which don't know about each other. The offset is only known
3808// when the constant is added to the constant pool during emitting.
3809// It is generated in the 'hi'-node adding the upper bits, and saved
3810// in this node.  The 'lo'-node has a link to the 'hi'-node and reads
3811// the offset from there when it gets encoded.
3812ins_attrib ins_field_const_toc_offset(0);
3813ins_attrib ins_field_const_toc_offset_hi_node(0);
3814
3815// A field that can hold the instructions offset in the code buffer.
3816// Set in the nodes emitter.
3817ins_attrib ins_field_cbuf_insts_offset(-1);
3818
3819// Fields for referencing a call's load-IC-node.
3820// If the toc offset can not be encoded as an immediate in a load, we
3821// use two nodes.
3822ins_attrib ins_field_load_ic_hi_node(0);
3823ins_attrib ins_field_load_ic_node(0);
3824
3825//----------OPERANDS-----------------------------------------------------------
3826// Operand definitions must precede instruction definitions for correct
3827// parsing in the ADLC because operands constitute user defined types
3828// which are used in instruction definitions.
3829//
3830// Formats are generated automatically for constants and base registers.
3831
3832//----------Simple Operands----------------------------------------------------
3833// Immediate Operands
3834
3835// Integer Immediate: 32-bit
3836operand immI() %{
3837  match(ConI);
3838  op_cost(40);
3839  format %{ %}
3840  interface(CONST_INTER);
3841%}
3842
3843operand immI8() %{
3844  predicate(Assembler::is_simm(n->get_int(), 8));
3845  op_cost(0);
3846  match(ConI);
3847  format %{ %}
3848  interface(CONST_INTER);
3849%}
3850
3851// Integer Immediate: 16-bit
3852operand immI16() %{
3853  predicate(Assembler::is_simm(n->get_int(), 16));
3854  op_cost(0);
3855  match(ConI);
3856  format %{ %}
3857  interface(CONST_INTER);
3858%}
3859
3860// Integer Immediate: 32-bit, where lowest 16 bits are 0x0000.
3861operand immIhi16() %{
3862  predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0));
3863  match(ConI);
3864  op_cost(0);
3865  format %{ %}
3866  interface(CONST_INTER);
3867%}
3868
3869operand immInegpow2() %{
3870  predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int()))));
3871  match(ConI);
3872  op_cost(0);
3873  format %{ %}
3874  interface(CONST_INTER);
3875%}
3876
3877operand immIpow2minus1() %{
3878  predicate(is_power_of_2_long((((jlong) (n->get_int()))+1)));
3879  match(ConI);
3880  op_cost(0);
3881  format %{ %}
3882  interface(CONST_INTER);
3883%}
3884
3885operand immIpowerOf2() %{
3886  predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int())))));
3887  match(ConI);
3888  op_cost(0);
3889  format %{ %}
3890  interface(CONST_INTER);
3891%}
3892
3893// Unsigned Integer Immediate: the values 0-31
3894operand uimmI5() %{
3895  predicate(Assembler::is_uimm(n->get_int(), 5));
3896  match(ConI);
3897  op_cost(0);
3898  format %{ %}
3899  interface(CONST_INTER);
3900%}
3901
3902// Unsigned Integer Immediate: 6-bit
3903operand uimmI6() %{
3904  predicate(Assembler::is_uimm(n->get_int(), 6));
3905  match(ConI);
3906  op_cost(0);
3907  format %{ %}
3908  interface(CONST_INTER);
3909%}
3910
3911// Unsigned Integer Immediate:  6-bit int, greater than 32
3912operand uimmI6_ge32() %{
3913  predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32);
3914  match(ConI);
3915  op_cost(0);
3916  format %{ %}
3917  interface(CONST_INTER);
3918%}
3919
3920// Unsigned Integer Immediate: 15-bit
3921operand uimmI15() %{
3922  predicate(Assembler::is_uimm(n->get_int(), 15));
3923  match(ConI);
3924  op_cost(0);
3925  format %{ %}
3926  interface(CONST_INTER);
3927%}
3928
3929// Unsigned Integer Immediate: 16-bit
3930operand uimmI16() %{
3931  predicate(Assembler::is_uimm(n->get_int(), 16));
3932  match(ConI);
3933  op_cost(0);
3934  format %{ %}
3935  interface(CONST_INTER);
3936%}
3937
3938// constant 'int 0'.
3939operand immI_0() %{
3940  predicate(n->get_int() == 0);
3941  match(ConI);
3942  op_cost(0);
3943  format %{ %}
3944  interface(CONST_INTER);
3945%}
3946
3947// constant 'int 1'.
3948operand immI_1() %{
3949  predicate(n->get_int() == 1);
3950  match(ConI);
3951  op_cost(0);
3952  format %{ %}
3953  interface(CONST_INTER);
3954%}
3955
3956// constant 'int -1'.
3957operand immI_minus1() %{
3958  predicate(n->get_int() == -1);
3959  match(ConI);
3960  op_cost(0);
3961  format %{ %}
3962  interface(CONST_INTER);
3963%}
3964
3965// int value 16.
3966operand immI_16() %{
3967  predicate(n->get_int() == 16);
3968  match(ConI);
3969  op_cost(0);
3970  format %{ %}
3971  interface(CONST_INTER);
3972%}
3973
3974// int value 24.
3975operand immI_24() %{
3976  predicate(n->get_int() == 24);
3977  match(ConI);
3978  op_cost(0);
3979  format %{ %}
3980  interface(CONST_INTER);
3981%}
3982
3983// Compressed oops constants
3984// Pointer Immediate
3985operand immN() %{
3986  match(ConN);
3987
3988  op_cost(10);
3989  format %{ %}
3990  interface(CONST_INTER);
3991%}
3992
3993// NULL Pointer Immediate
3994operand immN_0() %{
3995  predicate(n->get_narrowcon() == 0);
3996  match(ConN);
3997
3998  op_cost(0);
3999  format %{ %}
4000  interface(CONST_INTER);
4001%}
4002
4003// Compressed klass constants
4004operand immNKlass() %{
4005  match(ConNKlass);
4006
4007  op_cost(0);
4008  format %{ %}
4009  interface(CONST_INTER);
4010%}
4011
4012// This operand can be used to avoid matching of an instruct
4013// with chain rule.
4014operand immNKlass_NM() %{
4015  match(ConNKlass);
4016  predicate(false);
4017  op_cost(0);
4018  format %{ %}
4019  interface(CONST_INTER);
4020%}
4021
4022// Pointer Immediate: 64-bit
4023operand immP() %{
4024  match(ConP);
4025  op_cost(0);
4026  format %{ %}
4027  interface(CONST_INTER);
4028%}
4029
4030// Operand to avoid match of loadConP.
4031// This operand can be used to avoid matching of an instruct
4032// with chain rule.
4033operand immP_NM() %{
4034  match(ConP);
4035  predicate(false);
4036  op_cost(0);
4037  format %{ %}
4038  interface(CONST_INTER);
4039%}
4040
4041// costant 'pointer 0'.
4042operand immP_0() %{
4043  predicate(n->get_ptr() == 0);
4044  match(ConP);
4045  op_cost(0);
4046  format %{ %}
4047  interface(CONST_INTER);
4048%}
4049
4050// pointer 0x0 or 0x1
4051operand immP_0or1() %{
4052  predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
4053  match(ConP);
4054  op_cost(0);
4055  format %{ %}
4056  interface(CONST_INTER);
4057%}
4058
4059operand immL() %{
4060  match(ConL);
4061  op_cost(40);
4062  format %{ %}
4063  interface(CONST_INTER);
4064%}
4065
4066operand immLmax30() %{
4067  predicate((n->get_long() <= 30));
4068  match(ConL);
4069  op_cost(0);
4070  format %{ %}
4071  interface(CONST_INTER);
4072%}
4073
4074// Long Immediate: 16-bit
4075operand immL16() %{
4076  predicate(Assembler::is_simm(n->get_long(), 16));
4077  match(ConL);
4078  op_cost(0);
4079  format %{ %}
4080  interface(CONST_INTER);
4081%}
4082
4083// Long Immediate: 16-bit, 4-aligned
4084operand immL16Alg4() %{
4085  predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
4086  match(ConL);
4087  op_cost(0);
4088  format %{ %}
4089  interface(CONST_INTER);
4090%}
4091
4092// Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
4093operand immL32hi16() %{
4094  predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L));
4095  match(ConL);
4096  op_cost(0);
4097  format %{ %}
4098  interface(CONST_INTER);
4099%}
4100
4101// Long Immediate: 32-bit
4102operand immL32() %{
4103  predicate(Assembler::is_simm(n->get_long(), 32));
4104  match(ConL);
4105  op_cost(0);
4106  format %{ %}
4107  interface(CONST_INTER);
4108%}
4109
4110// Long Immediate: 64-bit, where highest 16 bits are not 0x0000.
4111operand immLhighest16() %{
4112  predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L);
4113  match(ConL);
4114  op_cost(0);
4115  format %{ %}
4116  interface(CONST_INTER);
4117%}
4118
4119operand immLnegpow2() %{
4120  predicate(is_power_of_2_long((jlong)-(n->get_long())));
4121  match(ConL);
4122  op_cost(0);
4123  format %{ %}
4124  interface(CONST_INTER);
4125%}
4126
4127operand immLpow2minus1() %{
4128  predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) &&
4129            (n->get_long() != (jlong)0xffffffffffffffffL));
4130  match(ConL);
4131  op_cost(0);
4132  format %{ %}
4133  interface(CONST_INTER);
4134%}
4135
4136// constant 'long 0'.
4137operand immL_0() %{
4138  predicate(n->get_long() == 0L);
4139  match(ConL);
4140  op_cost(0);
4141  format %{ %}
4142  interface(CONST_INTER);
4143%}
4144
4145// constat ' long -1'.
4146operand immL_minus1() %{
4147  predicate(n->get_long() == -1L);
4148  match(ConL);
4149  op_cost(0);
4150  format %{ %}
4151  interface(CONST_INTER);
4152%}
4153
4154// Long Immediate: low 32-bit mask
4155operand immL_32bits() %{
4156  predicate(n->get_long() == 0xFFFFFFFFL);
4157  match(ConL);
4158  op_cost(0);
4159  format %{ %}
4160  interface(CONST_INTER);
4161%}
4162
4163// Unsigned Long Immediate: 16-bit
4164operand uimmL16() %{
4165  predicate(Assembler::is_uimm(n->get_long(), 16));
4166  match(ConL);
4167  op_cost(0);
4168  format %{ %}
4169  interface(CONST_INTER);
4170%}
4171
4172// Float Immediate
4173operand immF() %{
4174  match(ConF);
4175  op_cost(40);
4176  format %{ %}
4177  interface(CONST_INTER);
4178%}
4179
4180// Float Immediate: +0.0f.
4181operand immF_0() %{
4182  predicate(jint_cast(n->getf()) == 0);
4183  match(ConF);
4184
4185  op_cost(0);
4186  format %{ %}
4187  interface(CONST_INTER);
4188%}
4189
4190// Double Immediate
4191operand immD() %{
4192  match(ConD);
4193  op_cost(40);
4194  format %{ %}
4195  interface(CONST_INTER);
4196%}
4197
4198// Integer Register Operands
4199// Integer Destination Register
4200// See definition of reg_class bits32_reg_rw.
4201operand iRegIdst() %{
4202  constraint(ALLOC_IN_RC(bits32_reg_rw));
4203  match(RegI);
4204  match(rscratch1RegI);
4205  match(rscratch2RegI);
4206  match(rarg1RegI);
4207  match(rarg2RegI);
4208  match(rarg3RegI);
4209  match(rarg4RegI);
4210  format %{ %}
4211  interface(REG_INTER);
4212%}
4213
4214// Integer Source Register
4215// See definition of reg_class bits32_reg_ro.
4216operand iRegIsrc() %{
4217  constraint(ALLOC_IN_RC(bits32_reg_ro));
4218  match(RegI);
4219  match(rscratch1RegI);
4220  match(rscratch2RegI);
4221  match(rarg1RegI);
4222  match(rarg2RegI);
4223  match(rarg3RegI);
4224  match(rarg4RegI);
4225  format %{ %}
4226  interface(REG_INTER);
4227%}
4228
4229operand rscratch1RegI() %{
4230  constraint(ALLOC_IN_RC(rscratch1_bits32_reg));
4231  match(iRegIdst);
4232  format %{ %}
4233  interface(REG_INTER);
4234%}
4235
4236operand rscratch2RegI() %{
4237  constraint(ALLOC_IN_RC(rscratch2_bits32_reg));
4238  match(iRegIdst);
4239  format %{ %}
4240  interface(REG_INTER);
4241%}
4242
4243operand rarg1RegI() %{
4244  constraint(ALLOC_IN_RC(rarg1_bits32_reg));
4245  match(iRegIdst);
4246  format %{ %}
4247  interface(REG_INTER);
4248%}
4249
4250operand rarg2RegI() %{
4251  constraint(ALLOC_IN_RC(rarg2_bits32_reg));
4252  match(iRegIdst);
4253  format %{ %}
4254  interface(REG_INTER);
4255%}
4256
4257operand rarg3RegI() %{
4258  constraint(ALLOC_IN_RC(rarg3_bits32_reg));
4259  match(iRegIdst);
4260  format %{ %}
4261  interface(REG_INTER);
4262%}
4263
4264operand rarg4RegI() %{
4265  constraint(ALLOC_IN_RC(rarg4_bits32_reg));
4266  match(iRegIdst);
4267  format %{ %}
4268  interface(REG_INTER);
4269%}
4270
4271operand rarg1RegL() %{
4272  constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4273  match(iRegLdst);
4274  format %{ %}
4275  interface(REG_INTER);
4276%}
4277
4278operand rarg2RegL() %{
4279  constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4280  match(iRegLdst);
4281  format %{ %}
4282  interface(REG_INTER);
4283%}
4284
4285operand rarg3RegL() %{
4286  constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4287  match(iRegLdst);
4288  format %{ %}
4289  interface(REG_INTER);
4290%}
4291
4292operand rarg4RegL() %{
4293  constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4294  match(iRegLdst);
4295  format %{ %}
4296  interface(REG_INTER);
4297%}
4298
4299// Pointer Destination Register
4300// See definition of reg_class bits64_reg_rw.
4301operand iRegPdst() %{
4302  constraint(ALLOC_IN_RC(bits64_reg_rw));
4303  match(RegP);
4304  match(rscratch1RegP);
4305  match(rscratch2RegP);
4306  match(rarg1RegP);
4307  match(rarg2RegP);
4308  match(rarg3RegP);
4309  match(rarg4RegP);
4310  format %{ %}
4311  interface(REG_INTER);
4312%}
4313
4314// Pointer Destination Register
4315// Operand not using r11 and r12 (killed in epilog).
4316operand iRegPdstNoScratch() %{
4317  constraint(ALLOC_IN_RC(bits64_reg_leaf_call));
4318  match(RegP);
4319  match(rarg1RegP);
4320  match(rarg2RegP);
4321  match(rarg3RegP);
4322  match(rarg4RegP);
4323  format %{ %}
4324  interface(REG_INTER);
4325%}
4326
4327// Pointer Source Register
4328// See definition of reg_class bits64_reg_ro.
4329operand iRegPsrc() %{
4330  constraint(ALLOC_IN_RC(bits64_reg_ro));
4331  match(RegP);
4332  match(iRegPdst);
4333  match(rscratch1RegP);
4334  match(rscratch2RegP);
4335  match(rarg1RegP);
4336  match(rarg2RegP);
4337  match(rarg3RegP);
4338  match(rarg4RegP);
4339  match(threadRegP);
4340  format %{ %}
4341  interface(REG_INTER);
4342%}
4343
4344// Thread operand.
4345operand threadRegP() %{
4346  constraint(ALLOC_IN_RC(thread_bits64_reg));
4347  match(iRegPdst);
4348  format %{ "R16" %}
4349  interface(REG_INTER);
4350%}
4351
4352operand rscratch1RegP() %{
4353  constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4354  match(iRegPdst);
4355  format %{ "R11" %}
4356  interface(REG_INTER);
4357%}
4358
4359operand rscratch2RegP() %{
4360  constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4361  match(iRegPdst);
4362  format %{ %}
4363  interface(REG_INTER);
4364%}
4365
4366operand rarg1RegP() %{
4367  constraint(ALLOC_IN_RC(rarg1_bits64_reg));
4368  match(iRegPdst);
4369  format %{ %}
4370  interface(REG_INTER);
4371%}
4372
4373operand rarg2RegP() %{
4374  constraint(ALLOC_IN_RC(rarg2_bits64_reg));
4375  match(iRegPdst);
4376  format %{ %}
4377  interface(REG_INTER);
4378%}
4379
4380operand rarg3RegP() %{
4381  constraint(ALLOC_IN_RC(rarg3_bits64_reg));
4382  match(iRegPdst);
4383  format %{ %}
4384  interface(REG_INTER);
4385%}
4386
4387operand rarg4RegP() %{
4388  constraint(ALLOC_IN_RC(rarg4_bits64_reg));
4389  match(iRegPdst);
4390  format %{ %}
4391  interface(REG_INTER);
4392%}
4393
4394operand iRegNsrc() %{
4395  constraint(ALLOC_IN_RC(bits32_reg_ro));
4396  match(RegN);
4397  match(iRegNdst);
4398
4399  format %{ %}
4400  interface(REG_INTER);
4401%}
4402
4403operand iRegNdst() %{
4404  constraint(ALLOC_IN_RC(bits32_reg_rw));
4405  match(RegN);
4406
4407  format %{ %}
4408  interface(REG_INTER);
4409%}
4410
4411// Long Destination Register
4412// See definition of reg_class bits64_reg_rw.
4413operand iRegLdst() %{
4414  constraint(ALLOC_IN_RC(bits64_reg_rw));
4415  match(RegL);
4416  match(rscratch1RegL);
4417  match(rscratch2RegL);
4418  format %{ %}
4419  interface(REG_INTER);
4420%}
4421
4422// Long Source Register
4423// See definition of reg_class bits64_reg_ro.
4424operand iRegLsrc() %{
4425  constraint(ALLOC_IN_RC(bits64_reg_ro));
4426  match(RegL);
4427  match(iRegLdst);
4428  match(rscratch1RegL);
4429  match(rscratch2RegL);
4430  format %{ %}
4431  interface(REG_INTER);
4432%}
4433
4434// Special operand for ConvL2I.
4435operand iRegL2Isrc(iRegLsrc reg) %{
4436  constraint(ALLOC_IN_RC(bits64_reg_ro));
4437  match(ConvL2I reg);
4438  format %{ "ConvL2I($reg)" %}
4439  interface(REG_INTER)
4440%}
4441
4442operand rscratch1RegL() %{
4443  constraint(ALLOC_IN_RC(rscratch1_bits64_reg));
4444  match(RegL);
4445  format %{ %}
4446  interface(REG_INTER);
4447%}
4448
4449operand rscratch2RegL() %{
4450  constraint(ALLOC_IN_RC(rscratch2_bits64_reg));
4451  match(RegL);
4452  format %{ %}
4453  interface(REG_INTER);
4454%}
4455
4456// Condition Code Flag Registers
4457operand flagsReg() %{
4458  constraint(ALLOC_IN_RC(int_flags));
4459  match(RegFlags);
4460  format %{ %}
4461  interface(REG_INTER);
4462%}
4463
4464operand flagsRegSrc() %{
4465  constraint(ALLOC_IN_RC(int_flags_ro));
4466  match(RegFlags);
4467  match(flagsReg);
4468  match(flagsRegCR0);
4469  format %{ %}
4470  interface(REG_INTER);
4471%}
4472
4473// Condition Code Flag Register CR0
4474operand flagsRegCR0() %{
4475  constraint(ALLOC_IN_RC(int_flags_CR0));
4476  match(RegFlags);
4477  format %{ "CR0" %}
4478  interface(REG_INTER);
4479%}
4480
4481operand flagsRegCR1() %{
4482  constraint(ALLOC_IN_RC(int_flags_CR1));
4483  match(RegFlags);
4484  format %{ "CR1" %}
4485  interface(REG_INTER);
4486%}
4487
4488operand flagsRegCR6() %{
4489  constraint(ALLOC_IN_RC(int_flags_CR6));
4490  match(RegFlags);
4491  format %{ "CR6" %}
4492  interface(REG_INTER);
4493%}
4494
4495operand regCTR() %{
4496  constraint(ALLOC_IN_RC(ctr_reg));
4497  // RegFlags should work. Introducing a RegSpecial type would cause a
4498  // lot of changes.
4499  match(RegFlags);
4500  format %{"SR_CTR" %}
4501  interface(REG_INTER);
4502%}
4503
4504operand regD() %{
4505  constraint(ALLOC_IN_RC(dbl_reg));
4506  match(RegD);
4507  format %{ %}
4508  interface(REG_INTER);
4509%}
4510
4511operand regF() %{
4512  constraint(ALLOC_IN_RC(flt_reg));
4513  match(RegF);
4514  format %{ %}
4515  interface(REG_INTER);
4516%}
4517
4518// Special Registers
4519
4520// Method Register
4521operand inline_cache_regP(iRegPdst reg) %{
4522  constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg
4523  match(reg);
4524  format %{ %}
4525  interface(REG_INTER);
4526%}
4527
4528operand compiler_method_oop_regP(iRegPdst reg) %{
4529  constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg
4530  match(reg);
4531  format %{ %}
4532  interface(REG_INTER);
4533%}
4534
4535operand interpreter_method_oop_regP(iRegPdst reg) %{
4536  constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg
4537  match(reg);
4538  format %{ %}
4539  interface(REG_INTER);
4540%}
4541
4542// Operands to remove register moves in unscaled mode.
4543// Match read/write registers with an EncodeP node if neither shift nor add are required.
4544operand iRegP2N(iRegPsrc reg) %{
4545  predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0);
4546  constraint(ALLOC_IN_RC(bits64_reg_ro));
4547  match(EncodeP reg);
4548  format %{ "$reg" %}
4549  interface(REG_INTER)
4550%}
4551
4552operand iRegN2P(iRegNsrc reg) %{
4553  predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4554  constraint(ALLOC_IN_RC(bits32_reg_ro));
4555  match(DecodeN reg);
4556  format %{ "$reg" %}
4557  interface(REG_INTER)
4558%}
4559
4560operand iRegN2P_klass(iRegNsrc reg) %{
4561  predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4562  constraint(ALLOC_IN_RC(bits32_reg_ro));
4563  match(DecodeNKlass reg);
4564  format %{ "$reg" %}
4565  interface(REG_INTER)
4566%}
4567
4568//----------Complex Operands---------------------------------------------------
4569// Indirect Memory Reference
4570operand indirect(iRegPsrc reg) %{
4571  constraint(ALLOC_IN_RC(bits64_reg_ro));
4572  match(reg);
4573  op_cost(100);
4574  format %{ "[$reg]" %}
4575  interface(MEMORY_INTER) %{
4576    base($reg);
4577    index(0x0);
4578    scale(0x0);
4579    disp(0x0);
4580  %}
4581%}
4582
4583// Indirect with Offset
4584operand indOffset16(iRegPsrc reg, immL16 offset) %{
4585  constraint(ALLOC_IN_RC(bits64_reg_ro));
4586  match(AddP reg offset);
4587  op_cost(100);
4588  format %{ "[$reg + $offset]" %}
4589  interface(MEMORY_INTER) %{
4590    base($reg);
4591    index(0x0);
4592    scale(0x0);
4593    disp($offset);
4594  %}
4595%}
4596
4597// Indirect with 4-aligned Offset
4598operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{
4599  constraint(ALLOC_IN_RC(bits64_reg_ro));
4600  match(AddP reg offset);
4601  op_cost(100);
4602  format %{ "[$reg + $offset]" %}
4603  interface(MEMORY_INTER) %{
4604    base($reg);
4605    index(0x0);
4606    scale(0x0);
4607    disp($offset);
4608  %}
4609%}
4610
4611//----------Complex Operands for Compressed OOPs-------------------------------
4612// Compressed OOPs with narrow_oop_shift == 0.
4613
4614// Indirect Memory Reference, compressed OOP
4615operand indirectNarrow(iRegNsrc reg) %{
4616  predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4617  constraint(ALLOC_IN_RC(bits64_reg_ro));
4618  match(DecodeN reg);
4619  op_cost(100);
4620  format %{ "[$reg]" %}
4621  interface(MEMORY_INTER) %{
4622    base($reg);
4623    index(0x0);
4624    scale(0x0);
4625    disp(0x0);
4626  %}
4627%}
4628
4629operand indirectNarrow_klass(iRegNsrc reg) %{
4630  predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4631  constraint(ALLOC_IN_RC(bits64_reg_ro));
4632  match(DecodeNKlass reg);
4633  op_cost(100);
4634  format %{ "[$reg]" %}
4635  interface(MEMORY_INTER) %{
4636    base($reg);
4637    index(0x0);
4638    scale(0x0);
4639    disp(0x0);
4640  %}
4641%}
4642
4643// Indirect with Offset, compressed OOP
4644operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{
4645  predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4646  constraint(ALLOC_IN_RC(bits64_reg_ro));
4647  match(AddP (DecodeN reg) offset);
4648  op_cost(100);
4649  format %{ "[$reg + $offset]" %}
4650  interface(MEMORY_INTER) %{
4651    base($reg);
4652    index(0x0);
4653    scale(0x0);
4654    disp($offset);
4655  %}
4656%}
4657
4658operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{
4659  predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4660  constraint(ALLOC_IN_RC(bits64_reg_ro));
4661  match(AddP (DecodeNKlass reg) offset);
4662  op_cost(100);
4663  format %{ "[$reg + $offset]" %}
4664  interface(MEMORY_INTER) %{
4665    base($reg);
4666    index(0x0);
4667    scale(0x0);
4668    disp($offset);
4669  %}
4670%}
4671
4672// Indirect with 4-aligned Offset, compressed OOP
4673operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{
4674  predicate(false /* TODO: PPC port MatchDecodeNodes*/);
4675  constraint(ALLOC_IN_RC(bits64_reg_ro));
4676  match(AddP (DecodeN reg) offset);
4677  op_cost(100);
4678  format %{ "[$reg + $offset]" %}
4679  interface(MEMORY_INTER) %{
4680    base($reg);
4681    index(0x0);
4682    scale(0x0);
4683    disp($offset);
4684  %}
4685%}
4686
4687operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{
4688  predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4689  constraint(ALLOC_IN_RC(bits64_reg_ro));
4690  match(AddP (DecodeNKlass reg) offset);
4691  op_cost(100);
4692  format %{ "[$reg + $offset]" %}
4693  interface(MEMORY_INTER) %{
4694    base($reg);
4695    index(0x0);
4696    scale(0x0);
4697    disp($offset);
4698  %}
4699%}
4700
4701//----------Special Memory Operands--------------------------------------------
4702// Stack Slot Operand
4703//
4704// This operand is used for loading and storing temporary values on
4705// the stack where a match requires a value to flow through memory.
4706operand stackSlotI(sRegI reg) %{
4707  constraint(ALLOC_IN_RC(stack_slots));
4708  op_cost(100);
4709  //match(RegI);
4710  format %{ "[sp+$reg]" %}
4711  interface(MEMORY_INTER) %{
4712    base(0x1);   // R1_SP
4713    index(0x0);
4714    scale(0x0);
4715    disp($reg);  // Stack Offset
4716  %}
4717%}
4718
4719operand stackSlotL(sRegL reg) %{
4720  constraint(ALLOC_IN_RC(stack_slots));
4721  op_cost(100);
4722  //match(RegL);
4723  format %{ "[sp+$reg]" %}
4724  interface(MEMORY_INTER) %{
4725    base(0x1);   // R1_SP
4726    index(0x0);
4727    scale(0x0);
4728    disp($reg);  // Stack Offset
4729  %}
4730%}
4731
4732operand stackSlotP(sRegP reg) %{
4733  constraint(ALLOC_IN_RC(stack_slots));
4734  op_cost(100);
4735  //match(RegP);
4736  format %{ "[sp+$reg]" %}
4737  interface(MEMORY_INTER) %{
4738    base(0x1);   // R1_SP
4739    index(0x0);
4740    scale(0x0);
4741    disp($reg);  // Stack Offset
4742  %}
4743%}
4744
4745operand stackSlotF(sRegF reg) %{
4746  constraint(ALLOC_IN_RC(stack_slots));
4747  op_cost(100);
4748  //match(RegF);
4749  format %{ "[sp+$reg]" %}
4750  interface(MEMORY_INTER) %{
4751    base(0x1);   // R1_SP
4752    index(0x0);
4753    scale(0x0);
4754    disp($reg);  // Stack Offset
4755  %}
4756%}
4757
4758operand stackSlotD(sRegD reg) %{
4759  constraint(ALLOC_IN_RC(stack_slots));
4760  op_cost(100);
4761  //match(RegD);
4762  format %{ "[sp+$reg]" %}
4763  interface(MEMORY_INTER) %{
4764    base(0x1);   // R1_SP
4765    index(0x0);
4766    scale(0x0);
4767    disp($reg);  // Stack Offset
4768  %}
4769%}
4770
4771// Operands for expressing Control Flow
4772// NOTE: Label is a predefined operand which should not be redefined in
4773//       the AD file. It is generically handled within the ADLC.
4774
4775//----------Conditional Branch Operands----------------------------------------
4776// Comparison Op
4777//
4778// This is the operation of the comparison, and is limited to the
4779// following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE
4780// (!=).
4781//
4782// Other attributes of the comparison, such as unsignedness, are specified
4783// by the comparison instruction that sets a condition code flags register.
4784// That result is represented by a flags operand whose subtype is appropriate
4785// to the unsignedness (etc.) of the comparison.
4786//
4787// Later, the instruction which matches both the Comparison Op (a Bool) and
4788// the flags (produced by the Cmp) specifies the coding of the comparison op
4789// by matching a specific subtype of Bool operand below.
4790
4791// When used for floating point comparisons: unordered same as less.
4792operand cmpOp() %{
4793  match(Bool);
4794  format %{ "" %}
4795  interface(COND_INTER) %{
4796                           // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'.
4797                           //           BO          &  BI
4798    equal(0xA);            // 10 10:   bcondCRbiIs1 & Condition::equal
4799    not_equal(0x2);        // 00 10:   bcondCRbiIs0 & Condition::equal
4800    less(0x8);             // 10 00:   bcondCRbiIs1 & Condition::less
4801    greater_equal(0x0);    // 00 00:   bcondCRbiIs0 & Condition::less
4802    less_equal(0x1);       // 00 01:   bcondCRbiIs0 & Condition::greater
4803    greater(0x9);          // 10 01:   bcondCRbiIs1 & Condition::greater
4804    overflow(0xB);         // 10 11:   bcondCRbiIs1 & Condition::summary_overflow
4805    no_overflow(0x3);      // 00 11:   bcondCRbiIs0 & Condition::summary_overflow
4806  %}
4807%}
4808
4809//----------OPERAND CLASSES----------------------------------------------------
4810// Operand Classes are groups of operands that are used to simplify
4811// instruction definitions by not requiring the AD writer to specify
4812// seperate instructions for every form of operand when the
4813// instruction accepts multiple operand types with the same basic
4814// encoding and format. The classic case of this is memory operands.
4815// Indirect is not included since its use is limited to Compare & Swap.
4816
4817opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass);
4818// Memory operand where offsets are 4-aligned. Required for ld, std.
4819opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass);
4820opclass indirectMemory(indirect, indirectNarrow);
4821
4822// Special opclass for I and ConvL2I.
4823opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc);
4824
4825// Operand classes to match encode and decode. iRegN_P2N is only used
4826// for storeN. I have never seen an encode node elsewhere.
4827opclass iRegN_P2N(iRegNsrc, iRegP2N);
4828opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass);
4829
4830//----------PIPELINE-----------------------------------------------------------
4831
4832pipeline %{
4833
4834// See J.M.Tendler et al. "Power4 system microarchitecture", IBM
4835// J. Res. & Dev., No. 1, Jan. 2002.
4836
4837//----------ATTRIBUTES---------------------------------------------------------
4838attributes %{
4839
4840  // Power4 instructions are of fixed length.
4841  fixed_size_instructions;
4842
4843  // TODO: if `bundle' means number of instructions fetched
4844  // per cycle, this is 8. If `bundle' means Power4 `group', that is
4845  // max instructions issued per cycle, this is 5.
4846  max_instructions_per_bundle = 8;
4847
4848  // A Power4 instruction is 4 bytes long.
4849  instruction_unit_size = 4;
4850
4851  // The Power4 processor fetches 64 bytes...
4852  instruction_fetch_unit_size = 64;
4853
4854  // ...in one line
4855  instruction_fetch_units = 1
4856
4857  // Unused, list one so that array generated by adlc is not empty.
4858  // Aix compiler chokes if _nop_count = 0.
4859  nops(fxNop);
4860%}
4861
4862//----------RESOURCES----------------------------------------------------------
4863// Resources are the functional units available to the machine
4864resources(
4865   PPC_BR,         // branch unit
4866   PPC_CR,         // condition unit
4867   PPC_FX1,        // integer arithmetic unit 1
4868   PPC_FX2,        // integer arithmetic unit 2
4869   PPC_LDST1,      // load/store unit 1
4870   PPC_LDST2,      // load/store unit 2
4871   PPC_FP1,        // float arithmetic unit 1
4872   PPC_FP2,        // float arithmetic unit 2
4873   PPC_LDST = PPC_LDST1 | PPC_LDST2,
4874   PPC_FX = PPC_FX1 | PPC_FX2,
4875   PPC_FP = PPC_FP1 | PPC_FP2
4876 );
4877
4878//----------PIPELINE DESCRIPTION-----------------------------------------------
4879// Pipeline Description specifies the stages in the machine's pipeline
4880pipe_desc(
4881   // Power4 longest pipeline path
4882   PPC_IF,   // instruction fetch
4883   PPC_IC,
4884   //PPC_BP, // branch prediction
4885   PPC_D0,   // decode
4886   PPC_D1,   // decode
4887   PPC_D2,   // decode
4888   PPC_D3,   // decode
4889   PPC_Xfer1,
4890   PPC_GD,   // group definition
4891   PPC_MP,   // map
4892   PPC_ISS,  // issue
4893   PPC_RF,   // resource fetch
4894   PPC_EX1,  // execute (all units)
4895   PPC_EX2,  // execute (FP, LDST)
4896   PPC_EX3,  // execute (FP, LDST)
4897   PPC_EX4,  // execute (FP)
4898   PPC_EX5,  // execute (FP)
4899   PPC_EX6,  // execute (FP)
4900   PPC_WB,   // write back
4901   PPC_Xfer2,
4902   PPC_CP
4903 );
4904
4905//----------PIPELINE CLASSES---------------------------------------------------
4906// Pipeline Classes describe the stages in which input and output are
4907// referenced by the hardware pipeline.
4908
4909// Simple pipeline classes.
4910
4911// Default pipeline class.
4912pipe_class pipe_class_default() %{
4913  single_instruction;
4914  fixed_latency(2);
4915%}
4916
4917// Pipeline class for empty instructions.
4918pipe_class pipe_class_empty() %{
4919  single_instruction;
4920  fixed_latency(0);
4921%}
4922
4923// Pipeline class for compares.
4924pipe_class pipe_class_compare() %{
4925  single_instruction;
4926  fixed_latency(16);
4927%}
4928
4929// Pipeline class for traps.
4930pipe_class pipe_class_trap() %{
4931  single_instruction;
4932  fixed_latency(100);
4933%}
4934
4935// Pipeline class for memory operations.
4936pipe_class pipe_class_memory() %{
4937  single_instruction;
4938  fixed_latency(16);
4939%}
4940
4941// Pipeline class for call.
4942pipe_class pipe_class_call() %{
4943  single_instruction;
4944  fixed_latency(100);
4945%}
4946
4947// Define the class for the Nop node.
4948define %{
4949   MachNop = pipe_class_default;
4950%}
4951
4952%}
4953
4954//----------INSTRUCTIONS-------------------------------------------------------
4955
4956// Naming of instructions:
4957//   opA_operB / opA_operB_operC:
4958//     Operation 'op' with one or two source operands 'oper'. Result
4959//     type is A, source operand types are B and C.
4960//     Iff A == B == C, B and C are left out.
4961//
4962// The instructions are ordered according to the following scheme:
4963//  - loads
4964//  - load constants
4965//  - prefetch
4966//  - store
4967//  - encode/decode
4968//  - membar
4969//  - conditional moves
4970//  - compare & swap
4971//  - arithmetic and logic operations
4972//    * int: Add, Sub, Mul, Div, Mod
4973//    * int: lShift, arShift, urShift, rot
4974//    * float: Add, Sub, Mul, Div
4975//    * and, or, xor ...
4976//  - register moves: float <-> int, reg <-> stack, repl
4977//  - cast (high level type cast, XtoP, castPP, castII, not_null etc.
4978//  - conv (low level type cast requiring bit changes (sign extend etc)
4979//  - compares, range & zero checks.
4980//  - branches
4981//  - complex operations, intrinsics, min, max, replicate
4982//  - lock
4983//  - Calls
4984//
4985// If there are similar instructions with different types they are sorted:
4986// int before float
4987// small before big
4988// signed before unsigned
4989// e.g., loadS before loadUS before loadI before loadF.
4990
4991
4992//----------Load/Store Instructions--------------------------------------------
4993
4994//----------Load Instructions--------------------------------------------------
4995
4996// Converts byte to int.
4997// As convB2I_reg, but without match rule.  The match rule of convB2I_reg
4998// reuses the 'amount' operand, but adlc expects that operand specification
4999// and operands in match rule are equivalent.
5000instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
5001  effect(DEF dst, USE src);
5002  format %{ "EXTSB   $dst, $src \t// byte->int" %}
5003  size(4);
5004  ins_encode %{
5005    // TODO: PPC port $archOpcode(ppc64Opcode_extsb);
5006    __ extsb($dst$$Register, $src$$Register);
5007  %}
5008  ins_pipe(pipe_class_default);
5009%}
5010
5011instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{
5012  // match-rule, false predicate
5013  match(Set dst (LoadB mem));
5014  predicate(false);
5015
5016  format %{ "LBZ     $dst, $mem" %}
5017  size(4);
5018  ins_encode( enc_lbz(dst, mem) );
5019  ins_pipe(pipe_class_memory);
5020%}
5021
5022instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{
5023  // match-rule, false predicate
5024  match(Set dst (LoadB mem));
5025  predicate(false);
5026
5027  format %{ "LBZ     $dst, $mem\n\t"
5028            "TWI     $dst\n\t"
5029            "ISYNC" %}
5030  size(12);
5031  ins_encode( enc_lbz_ac(dst, mem) );
5032  ins_pipe(pipe_class_memory);
5033%}
5034
5035// Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5036instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{
5037  match(Set dst (LoadB mem));
5038  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5039  ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5040  expand %{
5041    iRegIdst tmp;
5042    loadUB_indirect(tmp, mem);
5043    convB2I_reg_2(dst, tmp);
5044  %}
5045%}
5046
5047instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{
5048  match(Set dst (LoadB mem));
5049  ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5050  expand %{
5051    iRegIdst tmp;
5052    loadUB_indirect_ac(tmp, mem);
5053    convB2I_reg_2(dst, tmp);
5054  %}
5055%}
5056
5057instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{
5058  // match-rule, false predicate
5059  match(Set dst (LoadB mem));
5060  predicate(false);
5061
5062  format %{ "LBZ     $dst, $mem" %}
5063  size(4);
5064  ins_encode( enc_lbz(dst, mem) );
5065  ins_pipe(pipe_class_memory);
5066%}
5067
5068instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{
5069  // match-rule, false predicate
5070  match(Set dst (LoadB mem));
5071  predicate(false);
5072
5073  format %{ "LBZ     $dst, $mem\n\t"
5074            "TWI     $dst\n\t"
5075            "ISYNC" %}
5076  size(12);
5077  ins_encode( enc_lbz_ac(dst, mem) );
5078  ins_pipe(pipe_class_memory);
5079%}
5080
5081// Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B.
5082instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{
5083  match(Set dst (LoadB mem));
5084  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5085  ins_cost(MEMORY_REF_COST + DEFAULT_COST);
5086
5087  expand %{
5088    iRegIdst tmp;
5089    loadUB_indOffset16(tmp, mem);
5090    convB2I_reg_2(dst, tmp);
5091  %}
5092%}
5093
5094instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{
5095  match(Set dst (LoadB mem));
5096  ins_cost(3*MEMORY_REF_COST + DEFAULT_COST);
5097
5098  expand %{
5099    iRegIdst tmp;
5100    loadUB_indOffset16_ac(tmp, mem);
5101    convB2I_reg_2(dst, tmp);
5102  %}
5103%}
5104
5105// Load Unsigned Byte (8bit UNsigned) into an int reg.
5106instruct loadUB(iRegIdst dst, memory mem) %{
5107  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5108  match(Set dst (LoadUB mem));
5109  ins_cost(MEMORY_REF_COST);
5110
5111  format %{ "LBZ     $dst, $mem \t// byte, zero-extend to int" %}
5112  size(4);
5113  ins_encode( enc_lbz(dst, mem) );
5114  ins_pipe(pipe_class_memory);
5115%}
5116
5117// Load  Unsigned Byte (8bit UNsigned) acquire.
5118instruct loadUB_ac(iRegIdst dst, memory mem) %{
5119  match(Set dst (LoadUB mem));
5120  ins_cost(3*MEMORY_REF_COST);
5121
5122  format %{ "LBZ     $dst, $mem \t// byte, zero-extend to int, acquire\n\t"
5123            "TWI     $dst\n\t"
5124            "ISYNC" %}
5125  size(12);
5126  ins_encode( enc_lbz_ac(dst, mem) );
5127  ins_pipe(pipe_class_memory);
5128%}
5129
5130// Load Unsigned Byte (8bit UNsigned) into a Long Register.
5131instruct loadUB2L(iRegLdst dst, memory mem) %{
5132  match(Set dst (ConvI2L (LoadUB mem)));
5133  predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5134  ins_cost(MEMORY_REF_COST);
5135
5136  format %{ "LBZ     $dst, $mem \t// byte, zero-extend to long" %}
5137  size(4);
5138  ins_encode( enc_lbz(dst, mem) );
5139  ins_pipe(pipe_class_memory);
5140%}
5141
5142instruct loadUB2L_ac(iRegLdst dst, memory mem) %{
5143  match(Set dst (ConvI2L (LoadUB mem)));
5144  ins_cost(3*MEMORY_REF_COST);
5145
5146  format %{ "LBZ     $dst, $mem \t// byte, zero-extend to long, acquire\n\t"
5147            "TWI     $dst\n\t"
5148            "ISYNC" %}
5149  size(12);
5150  ins_encode( enc_lbz_ac(dst, mem) );
5151  ins_pipe(pipe_class_memory);
5152%}
5153
5154// Load Short (16bit signed)
5155instruct loadS(iRegIdst dst, memory mem) %{
5156  match(Set dst (LoadS mem));
5157  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5158  ins_cost(MEMORY_REF_COST);
5159
5160  format %{ "LHA     $dst, $mem" %}
5161  size(4);
5162  ins_encode %{
5163    // TODO: PPC port $archOpcode(ppc64Opcode_lha);
5164    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5165    __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5166  %}
5167  ins_pipe(pipe_class_memory);
5168%}
5169
5170// Load Short (16bit signed) acquire.
5171instruct loadS_ac(iRegIdst dst, memory mem) %{
5172  match(Set dst (LoadS mem));
5173  ins_cost(3*MEMORY_REF_COST);
5174
5175  format %{ "LHA     $dst, $mem\t acquire\n\t"
5176            "TWI     $dst\n\t"
5177            "ISYNC" %}
5178  size(12);
5179  ins_encode %{
5180    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
5181    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5182    __ lha($dst$$Register, Idisp, $mem$$base$$Register);
5183    __ twi_0($dst$$Register);
5184    __ isync();
5185  %}
5186  ins_pipe(pipe_class_memory);
5187%}
5188
5189// Load Char (16bit unsigned)
5190instruct loadUS(iRegIdst dst, memory mem) %{
5191  match(Set dst (LoadUS mem));
5192  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5193  ins_cost(MEMORY_REF_COST);
5194
5195  format %{ "LHZ     $dst, $mem" %}
5196  size(4);
5197  ins_encode( enc_lhz(dst, mem) );
5198  ins_pipe(pipe_class_memory);
5199%}
5200
5201// Load Char (16bit unsigned) acquire.
5202instruct loadUS_ac(iRegIdst dst, memory mem) %{
5203  match(Set dst (LoadUS mem));
5204  ins_cost(3*MEMORY_REF_COST);
5205
5206  format %{ "LHZ     $dst, $mem \t// acquire\n\t"
5207            "TWI     $dst\n\t"
5208            "ISYNC" %}
5209  size(12);
5210  ins_encode( enc_lhz_ac(dst, mem) );
5211  ins_pipe(pipe_class_memory);
5212%}
5213
5214// Load Unsigned Short/Char (16bit UNsigned) into a Long Register.
5215instruct loadUS2L(iRegLdst dst, memory mem) %{
5216  match(Set dst (ConvI2L (LoadUS mem)));
5217  predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf));
5218  ins_cost(MEMORY_REF_COST);
5219
5220  format %{ "LHZ     $dst, $mem \t// short, zero-extend to long" %}
5221  size(4);
5222  ins_encode( enc_lhz(dst, mem) );
5223  ins_pipe(pipe_class_memory);
5224%}
5225
5226// Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire.
5227instruct loadUS2L_ac(iRegLdst dst, memory mem) %{
5228  match(Set dst (ConvI2L (LoadUS mem)));
5229  ins_cost(3*MEMORY_REF_COST);
5230
5231  format %{ "LHZ     $dst, $mem \t// short, zero-extend to long, acquire\n\t"
5232            "TWI     $dst\n\t"
5233            "ISYNC" %}
5234  size(12);
5235  ins_encode( enc_lhz_ac(dst, mem) );
5236  ins_pipe(pipe_class_memory);
5237%}
5238
5239// Load Integer.
5240instruct loadI(iRegIdst dst, memory mem) %{
5241  match(Set dst (LoadI mem));
5242  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5243  ins_cost(MEMORY_REF_COST);
5244
5245  format %{ "LWZ     $dst, $mem" %}
5246  size(4);
5247  ins_encode( enc_lwz(dst, mem) );
5248  ins_pipe(pipe_class_memory);
5249%}
5250
5251// Load Integer acquire.
5252instruct loadI_ac(iRegIdst dst, memory mem) %{
5253  match(Set dst (LoadI mem));
5254  ins_cost(3*MEMORY_REF_COST);
5255
5256  format %{ "LWZ     $dst, $mem \t// load acquire\n\t"
5257            "TWI     $dst\n\t"
5258            "ISYNC" %}
5259  size(12);
5260  ins_encode( enc_lwz_ac(dst, mem) );
5261  ins_pipe(pipe_class_memory);
5262%}
5263
5264// Match loading integer and casting it to unsigned int in
5265// long register.
5266// LoadI + ConvI2L + AndL 0xffffffff.
5267instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
5268  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5269  predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered());
5270  ins_cost(MEMORY_REF_COST);
5271
5272  format %{ "LWZ     $dst, $mem \t// zero-extend to long" %}
5273  size(4);
5274  ins_encode( enc_lwz(dst, mem) );
5275  ins_pipe(pipe_class_memory);
5276%}
5277
5278// Match loading integer and casting it to long.
5279instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
5280  match(Set dst (ConvI2L (LoadI mem)));
5281  predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5282  ins_cost(MEMORY_REF_COST);
5283
5284  format %{ "LWA     $dst, $mem \t// loadI2L" %}
5285  size(4);
5286  ins_encode %{
5287    // TODO: PPC port $archOpcode(ppc64Opcode_lwa);
5288    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5289    __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5290  %}
5291  ins_pipe(pipe_class_memory);
5292%}
5293
5294// Match loading integer and casting it to long - acquire.
5295instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
5296  match(Set dst (ConvI2L (LoadI mem)));
5297  ins_cost(3*MEMORY_REF_COST);
5298
5299  format %{ "LWA     $dst, $mem \t// loadI2L acquire"
5300            "TWI     $dst\n\t"
5301            "ISYNC" %}
5302  size(12);
5303  ins_encode %{
5304    // TODO: PPC port $archOpcode(ppc64Opcode_lwa);
5305    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5306    __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
5307    __ twi_0($dst$$Register);
5308    __ isync();
5309  %}
5310  ins_pipe(pipe_class_memory);
5311%}
5312
5313// Load Long - aligned
5314instruct loadL(iRegLdst dst, memoryAlg4 mem) %{
5315  match(Set dst (LoadL mem));
5316  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5317  ins_cost(MEMORY_REF_COST);
5318
5319  format %{ "LD      $dst, $mem \t// long" %}
5320  size(4);
5321  ins_encode( enc_ld(dst, mem) );
5322  ins_pipe(pipe_class_memory);
5323%}
5324
5325// Load Long - aligned acquire.
5326instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{
5327  match(Set dst (LoadL mem));
5328  ins_cost(3*MEMORY_REF_COST);
5329
5330  format %{ "LD      $dst, $mem \t// long acquire\n\t"
5331            "TWI     $dst\n\t"
5332            "ISYNC" %}
5333  size(12);
5334  ins_encode( enc_ld_ac(dst, mem) );
5335  ins_pipe(pipe_class_memory);
5336%}
5337
5338// Load Long - UNaligned
5339instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{
5340  match(Set dst (LoadL_unaligned mem));
5341  // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5342  ins_cost(MEMORY_REF_COST);
5343
5344  format %{ "LD      $dst, $mem \t// unaligned long" %}
5345  size(4);
5346  ins_encode( enc_ld(dst, mem) );
5347  ins_pipe(pipe_class_memory);
5348%}
5349
5350// Load nodes for superwords
5351
5352// Load Aligned Packed Byte
5353instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{
5354  predicate(n->as_LoadVector()->memory_size() == 8);
5355  match(Set dst (LoadVector mem));
5356  ins_cost(MEMORY_REF_COST);
5357
5358  format %{ "LD      $dst, $mem \t// load 8-byte Vector" %}
5359  size(4);
5360  ins_encode( enc_ld(dst, mem) );
5361  ins_pipe(pipe_class_memory);
5362%}
5363
5364// Load Range, range = array length (=jint)
5365instruct loadRange(iRegIdst dst, memory mem) %{
5366  match(Set dst (LoadRange mem));
5367  ins_cost(MEMORY_REF_COST);
5368
5369  format %{ "LWZ     $dst, $mem \t// range" %}
5370  size(4);
5371  ins_encode( enc_lwz(dst, mem) );
5372  ins_pipe(pipe_class_memory);
5373%}
5374
5375// Load Compressed Pointer
5376instruct loadN(iRegNdst dst, memory mem) %{
5377  match(Set dst (LoadN mem));
5378  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5379  ins_cost(MEMORY_REF_COST);
5380
5381  format %{ "LWZ     $dst, $mem \t// load compressed ptr" %}
5382  size(4);
5383  ins_encode( enc_lwz(dst, mem) );
5384  ins_pipe(pipe_class_memory);
5385%}
5386
5387// Load Compressed Pointer acquire.
5388instruct loadN_ac(iRegNdst dst, memory mem) %{
5389  match(Set dst (LoadN mem));
5390  ins_cost(3*MEMORY_REF_COST);
5391
5392  format %{ "LWZ     $dst, $mem \t// load acquire compressed ptr\n\t"
5393            "TWI     $dst\n\t"
5394            "ISYNC" %}
5395  size(12);
5396  ins_encode( enc_lwz_ac(dst, mem) );
5397  ins_pipe(pipe_class_memory);
5398%}
5399
5400// Load Compressed Pointer and decode it if narrow_oop_shift == 0.
5401instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{
5402  match(Set dst (DecodeN (LoadN mem)));
5403  predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0);
5404  ins_cost(MEMORY_REF_COST);
5405
5406  format %{ "LWZ     $dst, $mem \t// DecodeN (unscaled)" %}
5407  size(4);
5408  ins_encode( enc_lwz(dst, mem) );
5409  ins_pipe(pipe_class_memory);
5410%}
5411
5412instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
5413  match(Set dst (DecodeNKlass (LoadNKlass mem)));
5414  predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 &&
5415            _kids[0]->_leaf->as_Load()->is_unordered());
5416  ins_cost(MEMORY_REF_COST);
5417
5418  format %{ "LWZ     $dst, $mem \t// DecodeN (unscaled)" %}
5419  size(4);
5420  ins_encode( enc_lwz(dst, mem) );
5421  ins_pipe(pipe_class_memory);
5422%}
5423
5424// Load Pointer
5425instruct loadP(iRegPdst dst, memoryAlg4 mem) %{
5426  match(Set dst (LoadP mem));
5427  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5428  ins_cost(MEMORY_REF_COST);
5429
5430  format %{ "LD      $dst, $mem \t// ptr" %}
5431  size(4);
5432  ins_encode( enc_ld(dst, mem) );
5433  ins_pipe(pipe_class_memory);
5434%}
5435
5436// Load Pointer acquire.
5437instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{
5438  match(Set dst (LoadP mem));
5439  ins_cost(3*MEMORY_REF_COST);
5440
5441  format %{ "LD      $dst, $mem \t// ptr acquire\n\t"
5442            "TWI     $dst\n\t"
5443            "ISYNC" %}
5444  size(12);
5445  ins_encode( enc_ld_ac(dst, mem) );
5446  ins_pipe(pipe_class_memory);
5447%}
5448
5449// LoadP + CastP2L
5450instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
5451  match(Set dst (CastP2X (LoadP mem)));
5452  predicate(_kids[0]->_leaf->as_Load()->is_unordered());
5453  ins_cost(MEMORY_REF_COST);
5454
5455  format %{ "LD      $dst, $mem \t// ptr + p2x" %}
5456  size(4);
5457  ins_encode( enc_ld(dst, mem) );
5458  ins_pipe(pipe_class_memory);
5459%}
5460
5461// Load compressed klass pointer.
5462instruct loadNKlass(iRegNdst dst, memory mem) %{
5463  match(Set dst (LoadNKlass mem));
5464  ins_cost(MEMORY_REF_COST);
5465
5466  format %{ "LWZ     $dst, $mem \t// compressed klass ptr" %}
5467  size(4);
5468  ins_encode( enc_lwz(dst, mem) );
5469  ins_pipe(pipe_class_memory);
5470%}
5471
5472// Load Klass Pointer
5473instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
5474  match(Set dst (LoadKlass mem));
5475  ins_cost(MEMORY_REF_COST);
5476
5477  format %{ "LD      $dst, $mem \t// klass ptr" %}
5478  size(4);
5479  ins_encode( enc_ld(dst, mem) );
5480  ins_pipe(pipe_class_memory);
5481%}
5482
5483// Load Float
5484instruct loadF(regF dst, memory mem) %{
5485  match(Set dst (LoadF mem));
5486  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5487  ins_cost(MEMORY_REF_COST);
5488
5489  format %{ "LFS     $dst, $mem" %}
5490  size(4);
5491  ins_encode %{
5492    // TODO: PPC port $archOpcode(ppc64Opcode_lfs);
5493    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5494    __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5495  %}
5496  ins_pipe(pipe_class_memory);
5497%}
5498
5499// Load Float acquire.
5500instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
5501  match(Set dst (LoadF mem));
5502  effect(TEMP cr0);
5503  ins_cost(3*MEMORY_REF_COST);
5504
5505  format %{ "LFS     $dst, $mem \t// acquire\n\t"
5506            "FCMPU   cr0, $dst, $dst\n\t"
5507            "BNE     cr0, next\n"
5508            "next:\n\t"
5509            "ISYNC" %}
5510  size(16);
5511  ins_encode %{
5512    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
5513    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5514    Label next;
5515    __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5516    __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5517    __ bne(CCR0, next);
5518    __ bind(next);
5519    __ isync();
5520  %}
5521  ins_pipe(pipe_class_memory);
5522%}
5523
5524// Load Double - aligned
5525instruct loadD(regD dst, memory mem) %{
5526  match(Set dst (LoadD mem));
5527  predicate(n->as_Load()->is_unordered() || followed_by_acquire(n));
5528  ins_cost(MEMORY_REF_COST);
5529
5530  format %{ "LFD     $dst, $mem" %}
5531  size(4);
5532  ins_encode( enc_lfd(dst, mem) );
5533  ins_pipe(pipe_class_memory);
5534%}
5535
5536// Load Double - aligned acquire.
5537instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
5538  match(Set dst (LoadD mem));
5539  effect(TEMP cr0);
5540  ins_cost(3*MEMORY_REF_COST);
5541
5542  format %{ "LFD     $dst, $mem \t// acquire\n\t"
5543            "FCMPU   cr0, $dst, $dst\n\t"
5544            "BNE     cr0, next\n"
5545            "next:\n\t"
5546            "ISYNC" %}
5547  size(16);
5548  ins_encode %{
5549    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
5550    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
5551    Label next;
5552    __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
5553    __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister);
5554    __ bne(CCR0, next);
5555    __ bind(next);
5556    __ isync();
5557  %}
5558  ins_pipe(pipe_class_memory);
5559%}
5560
5561// Load Double - UNaligned
5562instruct loadD_unaligned(regD dst, memory mem) %{
5563  match(Set dst (LoadD_unaligned mem));
5564  // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense).
5565  ins_cost(MEMORY_REF_COST);
5566
5567  format %{ "LFD     $dst, $mem" %}
5568  size(4);
5569  ins_encode( enc_lfd(dst, mem) );
5570  ins_pipe(pipe_class_memory);
5571%}
5572
5573//----------Constants--------------------------------------------------------
5574
5575// Load MachConstantTableBase: add hi offset to global toc.
5576// TODO: Handle hidden register r29 in bundler!
5577instruct loadToc_hi(iRegLdst dst) %{
5578  effect(DEF dst);
5579  ins_cost(DEFAULT_COST);
5580
5581  format %{ "ADDIS   $dst, R29, DISP.hi \t// load TOC hi" %}
5582  size(4);
5583  ins_encode %{
5584    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
5585    __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
5586  %}
5587  ins_pipe(pipe_class_default);
5588%}
5589
5590// Load MachConstantTableBase: add lo offset to global toc.
5591instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
5592  effect(DEF dst, USE src);
5593  ins_cost(DEFAULT_COST);
5594
5595  format %{ "ADDI    $dst, $src, DISP.lo \t// load TOC lo" %}
5596  size(4);
5597  ins_encode %{
5598    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
5599    __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
5600  %}
5601  ins_pipe(pipe_class_default);
5602%}
5603
5604// Load 16-bit integer constant 0xssss????
5605instruct loadConI16(iRegIdst dst, immI16 src) %{
5606  match(Set dst src);
5607
5608  format %{ "LI      $dst, $src" %}
5609  size(4);
5610  ins_encode %{
5611    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
5612    __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
5613  %}
5614  ins_pipe(pipe_class_default);
5615%}
5616
5617// Load integer constant 0x????0000
5618instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
5619  match(Set dst src);
5620  ins_cost(DEFAULT_COST);
5621
5622  format %{ "LIS     $dst, $src.hi" %}
5623  size(4);
5624  ins_encode %{
5625    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
5626    // Lis sign extends 16-bit src then shifts it 16 bit to the left.
5627    __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5628  %}
5629  ins_pipe(pipe_class_default);
5630%}
5631
5632// Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted
5633// and sign extended), this adds the low 16 bits.
5634instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
5635  // no match-rule, false predicate
5636  effect(DEF dst, USE src1, USE src2);
5637  predicate(false);
5638
5639  format %{ "ORI     $dst, $src1.hi, $src2.lo" %}
5640  size(4);
5641  ins_encode %{
5642    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
5643    __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5644  %}
5645  ins_pipe(pipe_class_default);
5646%}
5647
5648instruct loadConI_Ex(iRegIdst dst, immI src) %{
5649  match(Set dst src);
5650  ins_cost(DEFAULT_COST*2);
5651
5652  expand %{
5653    // Would like to use $src$$constant.
5654    immI16 srcLo %{ _opnds[1]->constant() %}
5655    // srcHi can be 0000 if srcLo sign-extends to a negative number.
5656    immIhi16 srcHi %{ _opnds[1]->constant() %}
5657    iRegIdst tmpI;
5658    loadConIhi16(tmpI, srcHi);
5659    loadConI32_lo16(dst, tmpI, srcLo);
5660  %}
5661%}
5662
5663// No constant pool entries required.
5664instruct loadConL16(iRegLdst dst, immL16 src) %{
5665  match(Set dst src);
5666
5667  format %{ "LI      $dst, $src \t// long" %}
5668  size(4);
5669  ins_encode %{
5670    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
5671    __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
5672  %}
5673  ins_pipe(pipe_class_default);
5674%}
5675
5676// Load long constant 0xssssssss????0000
5677instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
5678  match(Set dst src);
5679  ins_cost(DEFAULT_COST);
5680
5681  format %{ "LIS     $dst, $src.hi \t// long" %}
5682  size(4);
5683  ins_encode %{
5684    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
5685    __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
5686  %}
5687  ins_pipe(pipe_class_default);
5688%}
5689
5690// To load a 32 bit constant: merge lower 16 bits into already loaded
5691// high 16 bits.
5692instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
5693  // no match-rule, false predicate
5694  effect(DEF dst, USE src1, USE src2);
5695  predicate(false);
5696
5697  format %{ "ORI     $dst, $src1, $src2.lo" %}
5698  size(4);
5699  ins_encode %{
5700    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
5701    __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
5702  %}
5703  ins_pipe(pipe_class_default);
5704%}
5705
5706// Load 32-bit long constant
5707instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{
5708  match(Set dst src);
5709  ins_cost(DEFAULT_COST*2);
5710
5711  expand %{
5712    // Would like to use $src$$constant.
5713    immL16     srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%}
5714    // srcHi can be 0000 if srcLo sign-extends to a negative number.
5715    immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%}
5716    iRegLdst tmpL;
5717    loadConL32hi16(tmpL, srcHi);
5718    loadConL32_lo16(dst, tmpL, srcLo);
5719  %}
5720%}
5721
5722// Load long constant 0x????000000000000.
5723instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{
5724  match(Set dst src);
5725  ins_cost(DEFAULT_COST);
5726
5727  expand %{
5728    immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%}
5729    immI shift32 %{ 32 %}
5730    iRegLdst tmpL;
5731    loadConL32hi16(tmpL, srcHi);
5732    lshiftL_regL_immI(dst, tmpL, shift32);
5733  %}
5734%}
5735
5736// Expand node for constant pool load: small offset.
5737instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{
5738  effect(DEF dst, USE src, USE toc);
5739  ins_cost(MEMORY_REF_COST);
5740
5741  ins_num_consts(1);
5742  // Needed so that CallDynamicJavaDirect can compute the address of this
5743  // instruction for relocation.
5744  ins_field_cbuf_insts_offset(int);
5745
5746  format %{ "LD      $dst, offset, $toc \t// load long $src from TOC" %}
5747  size(4);
5748  ins_encode( enc_load_long_constL(dst, src, toc) );
5749  ins_pipe(pipe_class_memory);
5750%}
5751
5752// Expand node for constant pool load: large offset.
5753instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{
5754  effect(DEF dst, USE src, USE toc);
5755  predicate(false);
5756
5757  ins_num_consts(1);
5758  ins_field_const_toc_offset(int);
5759  // Needed so that CallDynamicJavaDirect can compute the address of this
5760  // instruction for relocation.
5761  ins_field_cbuf_insts_offset(int);
5762
5763  format %{ "ADDIS   $dst, $toc, offset \t// load long $src from TOC (hi)" %}
5764  size(4);
5765  ins_encode( enc_load_long_constL_hi(dst, toc, src) );
5766  ins_pipe(pipe_class_default);
5767%}
5768
5769// Expand node for constant pool load: large offset.
5770// No constant pool entries required.
5771instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
5772  effect(DEF dst, USE src, USE base);
5773  predicate(false);
5774
5775  ins_field_const_toc_offset_hi_node(loadConL_hiNode*);
5776
5777  format %{ "LD      $dst, offset, $base \t// load long $src from TOC (lo)" %}
5778  size(4);
5779  ins_encode %{
5780    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
5781    int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
5782    __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
5783  %}
5784  ins_pipe(pipe_class_memory);
5785%}
5786
5787// Load long constant from constant table. Expand in case of
5788// offset > 16 bit is needed.
5789// Adlc adds toc node MachConstantTableBase.
5790instruct loadConL_Ex(iRegLdst dst, immL src) %{
5791  match(Set dst src);
5792  ins_cost(MEMORY_REF_COST);
5793
5794  format %{ "LD      $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %}
5795  // We can not inline the enc_class for the expand as that does not support constanttablebase.
5796  postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) );
5797%}
5798
5799// Load NULL as compressed oop.
5800instruct loadConN0(iRegNdst dst, immN_0 src) %{
5801  match(Set dst src);
5802  ins_cost(DEFAULT_COST);
5803
5804  format %{ "LI      $dst, $src \t// compressed ptr" %}
5805  size(4);
5806  ins_encode %{
5807    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
5808    __ li($dst$$Register, 0);
5809  %}
5810  ins_pipe(pipe_class_default);
5811%}
5812
5813// Load hi part of compressed oop constant.
5814instruct loadConN_hi(iRegNdst dst, immN src) %{
5815  effect(DEF dst, USE src);
5816  ins_cost(DEFAULT_COST);
5817
5818  format %{ "LIS     $dst, $src \t// narrow oop hi" %}
5819  size(4);
5820  ins_encode %{
5821    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
5822    __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff));
5823  %}
5824  ins_pipe(pipe_class_default);
5825%}
5826
5827// Add lo part of compressed oop constant to already loaded hi part.
5828instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
5829  effect(DEF dst, USE src1, USE src2);
5830  ins_cost(DEFAULT_COST);
5831
5832  format %{ "ORI     $dst, $src1, $src2 \t// narrow oop lo" %}
5833  size(4);
5834  ins_encode %{
5835    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
5836    assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
5837    int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant);
5838    RelocationHolder rspec = oop_Relocation::spec(oop_index);
5839    __ relocate(rspec, 1);
5840    __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff);
5841  %}
5842  ins_pipe(pipe_class_default);
5843%}
5844
5845// Needed to postalloc expand loadConN: ConN is loaded as ConI
5846// leaving the upper 32 bits with sign-extension bits.
5847// This clears these bits: dst = src & 0xFFFFFFFF.
5848// TODO: Eventually call this maskN_regN_FFFFFFFF.
5849instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
5850  effect(DEF dst, USE src);
5851  predicate(false);
5852
5853  format %{ "MASK    $dst, $src, 0xFFFFFFFF" %} // mask
5854  size(4);
5855  ins_encode %{
5856    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
5857    __ clrldi($dst$$Register, $src$$Register, 0x20);
5858  %}
5859  ins_pipe(pipe_class_default);
5860%}
5861
5862// Optimize DecodeN for disjoint base.
5863// Load base of compressed oops into a register
5864instruct loadBase(iRegLdst dst) %{
5865  effect(DEF dst);
5866
5867  format %{ "LoadConst $dst, heapbase" %}
5868  ins_encode %{
5869    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
5870    __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0);
5871  %}
5872  ins_pipe(pipe_class_default);
5873%}
5874
5875// Loading ConN must be postalloc expanded so that edges between
5876// the nodes are safe. They may not interfere with a safepoint.
5877// GL TODO: This needs three instructions: better put this into the constant pool.
5878instruct loadConN_Ex(iRegNdst dst, immN src) %{
5879  match(Set dst src);
5880  ins_cost(DEFAULT_COST*2);
5881
5882  format %{ "LoadN   $dst, $src \t// postalloc expanded" %} // mask
5883  postalloc_expand %{
5884    MachNode *m1 = new loadConN_hiNode();
5885    MachNode *m2 = new loadConN_loNode();
5886    MachNode *m3 = new clearMs32bNode();
5887    m1->add_req(NULL);
5888    m2->add_req(NULL, m1);
5889    m3->add_req(NULL, m2);
5890    m1->_opnds[0] = op_dst;
5891    m1->_opnds[1] = op_src;
5892    m2->_opnds[0] = op_dst;
5893    m2->_opnds[1] = op_dst;
5894    m2->_opnds[2] = op_src;
5895    m3->_opnds[0] = op_dst;
5896    m3->_opnds[1] = op_dst;
5897    ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5898    ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5899    ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5900    nodes->push(m1);
5901    nodes->push(m2);
5902    nodes->push(m3);
5903  %}
5904%}
5905
5906// We have seen a safepoint between the hi and lo parts, and this node was handled
5907// as an oop. Therefore this needs a match rule so that build_oop_map knows this is
5908// not a narrow oop.
5909instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
5910  match(Set dst src);
5911  effect(DEF dst, USE src);
5912  ins_cost(DEFAULT_COST);
5913
5914  format %{ "LIS     $dst, $src \t// narrow klass hi" %}
5915  size(4);
5916  ins_encode %{
5917    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
5918    intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant);
5919    __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
5920  %}
5921  ins_pipe(pipe_class_default);
5922%}
5923
5924// As loadConNKlass_hi this must be recognized as narrow klass, not oop!
5925instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5926  match(Set dst src1);
5927  effect(TEMP src2);
5928  ins_cost(DEFAULT_COST);
5929
5930  format %{ "MASK    $dst, $src2, 0xFFFFFFFF" %} // mask
5931  size(4);
5932  ins_encode %{
5933    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
5934    __ clrldi($dst$$Register, $src2$$Register, 0x20);
5935  %}
5936  ins_pipe(pipe_class_default);
5937%}
5938
5939// This needs a match rule so that build_oop_map knows this is
5940// not a narrow oop.
5941instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
5942  match(Set dst src1);
5943  effect(TEMP src2);
5944  ins_cost(DEFAULT_COST);
5945
5946  format %{ "ORI     $dst, $src1, $src2 \t// narrow klass lo" %}
5947  size(4);
5948  ins_encode %{
5949    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
5950    intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant);
5951    assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
5952    int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant);
5953    RelocationHolder rspec = metadata_Relocation::spec(klass_index);
5954
5955    __ relocate(rspec, 1);
5956    __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff);
5957  %}
5958  ins_pipe(pipe_class_default);
5959%}
5960
5961// Loading ConNKlass must be postalloc expanded so that edges between
5962// the nodes are safe. They may not interfere with a safepoint.
5963instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{
5964  match(Set dst src);
5965  ins_cost(DEFAULT_COST*2);
5966
5967  format %{ "LoadN   $dst, $src \t// postalloc expanded" %} // mask
5968  postalloc_expand %{
5969    // Load high bits into register. Sign extended.
5970    MachNode *m1 = new loadConNKlass_hiNode();
5971    m1->add_req(NULL);
5972    m1->_opnds[0] = op_dst;
5973    m1->_opnds[1] = op_src;
5974    ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5975    nodes->push(m1);
5976
5977    MachNode *m2 = m1;
5978    if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) {
5979      // Value might be 1-extended. Mask out these bits.
5980      m2 = new loadConNKlass_maskNode();
5981      m2->add_req(NULL, m1);
5982      m2->_opnds[0] = op_dst;
5983      m2->_opnds[1] = op_src;
5984      m2->_opnds[2] = op_dst;
5985      ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5986      nodes->push(m2);
5987    }
5988
5989    MachNode *m3 = new loadConNKlass_loNode();
5990    m3->add_req(NULL, m2);
5991    m3->_opnds[0] = op_dst;
5992    m3->_opnds[1] = op_src;
5993    m3->_opnds[2] = op_dst;
5994    ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
5995    nodes->push(m3);
5996  %}
5997%}
5998
5999// 0x1 is used in object initialization (initial object header).
6000// No constant pool entries required.
6001instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
6002  match(Set dst src);
6003
6004  format %{ "LI      $dst, $src \t// ptr" %}
6005  size(4);
6006  ins_encode %{
6007    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
6008    __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
6009  %}
6010  ins_pipe(pipe_class_default);
6011%}
6012
6013// Expand node for constant pool load: small offset.
6014// The match rule is needed to generate the correct bottom_type(),
6015// however this node should never match. The use of predicate is not
6016// possible since ADLC forbids predicates for chain rules. The higher
6017// costs do not prevent matching in this case. For that reason the
6018// operand immP_NM with predicate(false) is used.
6019instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6020  match(Set dst src);
6021  effect(TEMP toc);
6022
6023  ins_num_consts(1);
6024
6025  format %{ "LD      $dst, offset, $toc \t// load ptr $src from TOC" %}
6026  size(4);
6027  ins_encode( enc_load_long_constP(dst, src, toc) );
6028  ins_pipe(pipe_class_memory);
6029%}
6030
6031// Expand node for constant pool load: large offset.
6032instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{
6033  effect(DEF dst, USE src, USE toc);
6034  predicate(false);
6035
6036  ins_num_consts(1);
6037  ins_field_const_toc_offset(int);
6038
6039  format %{ "ADDIS   $dst, $toc, offset \t// load ptr $src from TOC (hi)" %}
6040  size(4);
6041  ins_encode( enc_load_long_constP_hi(dst, src, toc) );
6042  ins_pipe(pipe_class_default);
6043%}
6044
6045// Expand node for constant pool load: large offset.
6046instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
6047  match(Set dst src);
6048  effect(TEMP base);
6049
6050  ins_field_const_toc_offset_hi_node(loadConP_hiNode*);
6051
6052  format %{ "LD      $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
6053  size(4);
6054  ins_encode %{
6055    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
6056    int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
6057    __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
6058  %}
6059  ins_pipe(pipe_class_memory);
6060%}
6061
6062// Load pointer constant from constant table. Expand in case an
6063// offset > 16 bit is needed.
6064// Adlc adds toc node MachConstantTableBase.
6065instruct loadConP_Ex(iRegPdst dst, immP src) %{
6066  match(Set dst src);
6067  ins_cost(MEMORY_REF_COST);
6068
6069  // This rule does not use "expand" because then
6070  // the result type is not known to be an Oop.  An ADLC
6071  // enhancement will be needed to make that work - not worth it!
6072
6073  // If this instruction rematerializes, it prolongs the live range
6074  // of the toc node, causing illegal graphs.
6075  // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule().
6076  ins_cannot_rematerialize(true);
6077
6078  format %{ "LD    $dst, offset, $constanttablebase \t//  load ptr $src from table, postalloc expanded" %}
6079  postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) );
6080%}
6081
6082// Expand node for constant pool load: small offset.
6083instruct loadConF(regF dst, immF src, iRegLdst toc) %{
6084  effect(DEF dst, USE src, USE toc);
6085  ins_cost(MEMORY_REF_COST);
6086
6087  ins_num_consts(1);
6088
6089  format %{ "LFS     $dst, offset, $toc \t// load float $src from TOC" %}
6090  size(4);
6091  ins_encode %{
6092    // TODO: PPC port $archOpcode(ppc64Opcode_lfs);
6093    address float_address = __ float_constant($src$$constant);
6094    if (float_address == NULL) {
6095      ciEnv::current()->record_out_of_memory_failure();
6096      return;
6097    }
6098    __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register);
6099  %}
6100  ins_pipe(pipe_class_memory);
6101%}
6102
6103// Expand node for constant pool load: large offset.
6104instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
6105  effect(DEF dst, USE src, USE toc);
6106  ins_cost(MEMORY_REF_COST);
6107
6108  ins_num_consts(1);
6109
6110  format %{ "ADDIS   $toc, $toc, offset_hi\n\t"
6111            "LFS     $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t"
6112            "ADDIS   $toc, $toc, -offset_hi"%}
6113  size(12);
6114  ins_encode %{
6115    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6116    FloatRegister Rdst    = $dst$$FloatRegister;
6117    Register Rtoc         = $toc$$Register;
6118    address float_address = __ float_constant($src$$constant);
6119    if (float_address == NULL) {
6120      ciEnv::current()->record_out_of_memory_failure();
6121      return;
6122    }
6123    int offset            = __ offset_to_method_toc(float_address);
6124    int hi = (offset + (1<<15))>>16;
6125    int lo = offset - hi * (1<<16);
6126
6127    __ addis(Rtoc, Rtoc, hi);
6128    __ lfs(Rdst, lo, Rtoc);
6129    __ addis(Rtoc, Rtoc, -hi);
6130  %}
6131  ins_pipe(pipe_class_memory);
6132%}
6133
6134// Adlc adds toc node MachConstantTableBase.
6135instruct loadConF_Ex(regF dst, immF src) %{
6136  match(Set dst src);
6137  ins_cost(MEMORY_REF_COST);
6138
6139  // See loadConP.
6140  ins_cannot_rematerialize(true);
6141
6142  format %{ "LFS     $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6143  postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) );
6144%}
6145
6146// Expand node for constant pool load: small offset.
6147instruct loadConD(regD dst, immD src, iRegLdst toc) %{
6148  effect(DEF dst, USE src, USE toc);
6149  ins_cost(MEMORY_REF_COST);
6150
6151  ins_num_consts(1);
6152
6153  format %{ "LFD     $dst, offset, $toc \t// load double $src from TOC" %}
6154  size(4);
6155  ins_encode %{
6156    // TODO: PPC port $archOpcode(ppc64Opcode_lfd);
6157    address float_address = __ double_constant($src$$constant);
6158    if (float_address == NULL) {
6159      ciEnv::current()->record_out_of_memory_failure();
6160      return;
6161    }
6162    int offset =  __ offset_to_method_toc(float_address);
6163    __ lfd($dst$$FloatRegister, offset, $toc$$Register);
6164  %}
6165  ins_pipe(pipe_class_memory);
6166%}
6167
6168// Expand node for constant pool load: large offset.
6169instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
6170  effect(DEF dst, USE src, USE toc);
6171  ins_cost(MEMORY_REF_COST);
6172
6173  ins_num_consts(1);
6174
6175  format %{ "ADDIS   $toc, $toc, offset_hi\n\t"
6176            "LFD     $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t"
6177            "ADDIS   $toc, $toc, -offset_hi" %}
6178  size(12);
6179  ins_encode %{
6180    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6181    FloatRegister Rdst    = $dst$$FloatRegister;
6182    Register      Rtoc    = $toc$$Register;
6183    address float_address = __ double_constant($src$$constant);
6184    if (float_address == NULL) {
6185      ciEnv::current()->record_out_of_memory_failure();
6186      return;
6187    }
6188    int offset = __ offset_to_method_toc(float_address);
6189    int hi = (offset + (1<<15))>>16;
6190    int lo = offset - hi * (1<<16);
6191
6192    __ addis(Rtoc, Rtoc, hi);
6193    __ lfd(Rdst, lo, Rtoc);
6194    __ addis(Rtoc, Rtoc, -hi);
6195  %}
6196  ins_pipe(pipe_class_memory);
6197%}
6198
6199// Adlc adds toc node MachConstantTableBase.
6200instruct loadConD_Ex(regD dst, immD src) %{
6201  match(Set dst src);
6202  ins_cost(MEMORY_REF_COST);
6203
6204  // See loadConP.
6205  ins_cannot_rematerialize(true);
6206
6207  format %{ "ConD    $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %}
6208  postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) );
6209%}
6210
6211// Prefetch instructions.
6212// Must be safe to execute with invalid address (cannot fault).
6213
6214// Special prefetch versions which use the dcbz instruction.
6215instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{
6216  match(PrefetchAllocation (AddP mem src));
6217  predicate(AllocatePrefetchStyle == 3);
6218  ins_cost(MEMORY_REF_COST);
6219
6220  format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %}
6221  size(4);
6222  ins_encode %{
6223    // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst);
6224    __ dcbz($src$$Register, $mem$$base$$Register);
6225  %}
6226  ins_pipe(pipe_class_memory);
6227%}
6228
6229instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{
6230  match(PrefetchAllocation mem);
6231  predicate(AllocatePrefetchStyle == 3);
6232  ins_cost(MEMORY_REF_COST);
6233
6234  format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %}
6235  size(4);
6236  ins_encode %{
6237    // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst);
6238    __ dcbz($mem$$base$$Register);
6239  %}
6240  ins_pipe(pipe_class_memory);
6241%}
6242
6243instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
6244  match(PrefetchAllocation (AddP mem src));
6245  predicate(AllocatePrefetchStyle != 3);
6246  ins_cost(MEMORY_REF_COST);
6247
6248  format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
6249  size(4);
6250  ins_encode %{
6251    // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst);
6252    __ dcbtst($src$$Register, $mem$$base$$Register);
6253  %}
6254  ins_pipe(pipe_class_memory);
6255%}
6256
6257instruct prefetch_alloc_no_offset(indirectMemory mem) %{
6258  match(PrefetchAllocation mem);
6259  predicate(AllocatePrefetchStyle != 3);
6260  ins_cost(MEMORY_REF_COST);
6261
6262  format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
6263  size(4);
6264  ins_encode %{
6265    // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst);
6266    __ dcbtst($mem$$base$$Register);
6267  %}
6268  ins_pipe(pipe_class_memory);
6269%}
6270
6271//----------Store Instructions-------------------------------------------------
6272
6273// Store Byte
6274instruct storeB(memory mem, iRegIsrc src) %{
6275  match(Set mem (StoreB mem src));
6276  ins_cost(MEMORY_REF_COST);
6277
6278  format %{ "STB     $src, $mem \t// byte" %}
6279  size(4);
6280  ins_encode %{
6281    // TODO: PPC port $archOpcode(ppc64Opcode_stb);
6282    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6283    __ stb($src$$Register, Idisp, $mem$$base$$Register);
6284  %}
6285  ins_pipe(pipe_class_memory);
6286%}
6287
6288// Store Char/Short
6289instruct storeC(memory mem, iRegIsrc src) %{
6290  match(Set mem (StoreC mem src));
6291  ins_cost(MEMORY_REF_COST);
6292
6293  format %{ "STH     $src, $mem \t// short" %}
6294  size(4);
6295  ins_encode %{
6296    // TODO: PPC port $archOpcode(ppc64Opcode_sth);
6297    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
6298    __ sth($src$$Register, Idisp, $mem$$base$$Register);
6299  %}
6300  ins_pipe(pipe_class_memory);
6301%}
6302
6303// Store Integer
6304instruct storeI(memory mem, iRegIsrc src) %{
6305  match(Set mem (StoreI mem src));
6306  ins_cost(MEMORY_REF_COST);
6307
6308  format %{ "STW     $src, $mem" %}
6309  size(4);
6310  ins_encode( enc_stw(src, mem) );
6311  ins_pipe(pipe_class_memory);
6312%}
6313
6314// ConvL2I + StoreI.
6315instruct storeI_convL2I(memory mem, iRegLsrc src) %{
6316  match(Set mem (StoreI mem (ConvL2I src)));
6317  ins_cost(MEMORY_REF_COST);
6318
6319  format %{ "STW     l2i($src), $mem" %}
6320  size(4);
6321  ins_encode( enc_stw(src, mem) );
6322  ins_pipe(pipe_class_memory);
6323%}
6324
6325// Store Long
6326instruct storeL(memoryAlg4 mem, iRegLsrc src) %{
6327  match(Set mem (StoreL mem src));
6328  ins_cost(MEMORY_REF_COST);
6329
6330  format %{ "STD     $src, $mem \t// long" %}
6331  size(4);
6332  ins_encode( enc_std(src, mem) );
6333  ins_pipe(pipe_class_memory);
6334%}
6335
6336// Store super word nodes.
6337
6338// Store Aligned Packed Byte long register to memory
6339instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{
6340  predicate(n->as_StoreVector()->memory_size() == 8);
6341  match(Set mem (StoreVector mem src));
6342  ins_cost(MEMORY_REF_COST);
6343
6344  format %{ "STD     $mem, $src \t// packed8B" %}
6345  size(4);
6346  ins_encode( enc_std(src, mem) );
6347  ins_pipe(pipe_class_memory);
6348%}
6349
6350// Store Compressed Oop
6351instruct storeN(memory dst, iRegN_P2N src) %{
6352  match(Set dst (StoreN dst src));
6353  ins_cost(MEMORY_REF_COST);
6354
6355  format %{ "STW     $src, $dst \t// compressed oop" %}
6356  size(4);
6357  ins_encode( enc_stw(src, dst) );
6358  ins_pipe(pipe_class_memory);
6359%}
6360
6361// Store Compressed KLass
6362instruct storeNKlass(memory dst, iRegN_P2N src) %{
6363  match(Set dst (StoreNKlass dst src));
6364  ins_cost(MEMORY_REF_COST);
6365
6366  format %{ "STW     $src, $dst \t// compressed klass" %}
6367  size(4);
6368  ins_encode( enc_stw(src, dst) );
6369  ins_pipe(pipe_class_memory);
6370%}
6371
6372// Store Pointer
6373instruct storeP(memoryAlg4 dst, iRegPsrc src) %{
6374  match(Set dst (StoreP dst src));
6375  ins_cost(MEMORY_REF_COST);
6376
6377  format %{ "STD     $src, $dst \t// ptr" %}
6378  size(4);
6379  ins_encode( enc_std(src, dst) );
6380  ins_pipe(pipe_class_memory);
6381%}
6382
6383// Store Float
6384instruct storeF(memory mem, regF src) %{
6385  match(Set mem (StoreF mem src));
6386  ins_cost(MEMORY_REF_COST);
6387
6388  format %{ "STFS    $src, $mem" %}
6389  size(4);
6390  ins_encode( enc_stfs(src, mem) );
6391  ins_pipe(pipe_class_memory);
6392%}
6393
6394// Store Double
6395instruct storeD(memory mem, regD src) %{
6396  match(Set mem (StoreD mem src));
6397  ins_cost(MEMORY_REF_COST);
6398
6399  format %{ "STFD    $src, $mem" %}
6400  size(4);
6401  ins_encode( enc_stfd(src, mem) );
6402  ins_pipe(pipe_class_memory);
6403%}
6404
6405//----------Store Instructions With Zeros--------------------------------------
6406
6407// Card-mark for CMS garbage collection.
6408// This cardmark does an optimization so that it must not always
6409// do a releasing store. For this, it gets the address of
6410// CMSCollectorCardTableModRefBSExt::_requires_release as input.
6411// (Using releaseFieldAddr in the match rule is a hack.)
6412instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{
6413  match(Set mem (StoreCM mem releaseFieldAddr));
6414  effect(TEMP crx);
6415  predicate(false);
6416  ins_cost(MEMORY_REF_COST);
6417
6418  // See loadConP.
6419  ins_cannot_rematerialize(true);
6420
6421  format %{ "STB     #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %}
6422  ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) );
6423  ins_pipe(pipe_class_memory);
6424%}
6425
6426// Card-mark for CMS garbage collection.
6427// This cardmark does an optimization so that it must not always
6428// do a releasing store. For this, it needs the constant address of
6429// CMSCollectorCardTableModRefBSExt::_requires_release.
6430// This constant address is split off here by expand so we can use
6431// adlc / matcher functionality to load it from the constant section.
6432instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{
6433  match(Set mem (StoreCM mem zero));
6434  predicate(UseConcMarkSweepGC);
6435
6436  expand %{
6437    immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %}
6438    iRegLdst releaseFieldAddress;
6439    flagsReg crx;
6440    loadConL_Ex(releaseFieldAddress, baseImm);
6441    storeCM_CMS(mem, releaseFieldAddress, crx);
6442  %}
6443%}
6444
6445instruct storeCM_G1(memory mem, immI_0 zero) %{
6446  match(Set mem (StoreCM mem zero));
6447  predicate(UseG1GC);
6448  ins_cost(MEMORY_REF_COST);
6449
6450  ins_cannot_rematerialize(true);
6451
6452  format %{ "STB     #0, $mem \t// CMS card-mark byte store (G1)" %}
6453  size(8);
6454  ins_encode %{
6455    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6456    __ li(R0, 0);
6457    //__ release(); // G1: oops are allowed to get visible after dirty marking
6458    guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias");
6459    __ stb(R0, $mem$$disp, $mem$$base$$Register);
6460  %}
6461  ins_pipe(pipe_class_memory);
6462%}
6463
6464// Convert oop pointer into compressed form.
6465
6466// Nodes for postalloc expand.
6467
6468// Shift node for expand.
6469instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
6470  // The match rule is needed to make it a 'MachTypeNode'!
6471  match(Set dst (EncodeP src));
6472  predicate(false);
6473
6474  format %{ "SRDI    $dst, $src, 3 \t// encode" %}
6475  size(4);
6476  ins_encode %{
6477    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6478    __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f);
6479  %}
6480  ins_pipe(pipe_class_default);
6481%}
6482
6483// Add node for expand.
6484instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
6485  // The match rule is needed to make it a 'MachTypeNode'!
6486  match(Set dst (EncodeP src));
6487  predicate(false);
6488
6489  format %{ "SUB     $dst, $src, oop_base \t// encode" %}
6490  ins_encode %{
6491    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6492    __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0);
6493  %}
6494  ins_pipe(pipe_class_default);
6495%}
6496
6497// Conditional sub base.
6498instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6499  // The match rule is needed to make it a 'MachTypeNode'!
6500  match(Set dst (EncodeP (Binary crx src1)));
6501  predicate(false);
6502
6503  format %{ "BEQ     $crx, done\n\t"
6504            "SUB     $dst, $src1, heapbase \t// encode: subtract base if != NULL\n"
6505            "done:" %}
6506  ins_encode %{
6507    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6508    Label done;
6509    __ beq($crx$$CondRegister, done);
6510    __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0);
6511    __ bind(done);
6512  %}
6513  ins_pipe(pipe_class_default);
6514%}
6515
6516// Power 7 can use isel instruction
6517instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6518  // The match rule is needed to make it a 'MachTypeNode'!
6519  match(Set dst (EncodeP (Binary crx src1)));
6520  predicate(false);
6521
6522  format %{ "CMOVE   $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %}
6523  size(4);
6524  ins_encode %{
6525    // This is a Power7 instruction for which no machine description exists.
6526    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6527    __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6528  %}
6529  ins_pipe(pipe_class_default);
6530%}
6531
6532// Disjoint narrow oop base.
6533instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
6534  match(Set dst (EncodeP src));
6535  predicate(Universe::narrow_oop_base_disjoint());
6536
6537  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
6538  size(4);
6539  ins_encode %{
6540    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6541    __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32);
6542  %}
6543  ins_pipe(pipe_class_default);
6544%}
6545
6546// shift != 0, base != 0
6547instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{
6548  match(Set dst (EncodeP src));
6549  effect(TEMP crx);
6550  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull &&
6551            Universe::narrow_oop_shift() != 0 &&
6552            Universe::narrow_oop_base_overlaps());
6553
6554  format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %}
6555  postalloc_expand( postalloc_expand_encode_oop(dst, src, crx));
6556%}
6557
6558// shift != 0, base != 0
6559instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{
6560  match(Set dst (EncodeP src));
6561  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull &&
6562            Universe::narrow_oop_shift() != 0 &&
6563            Universe::narrow_oop_base_overlaps());
6564
6565  format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %}
6566  postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) );
6567%}
6568
6569// shift != 0, base == 0
6570// TODO: This is the same as encodeP_shift. Merge!
6571instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
6572  match(Set dst (EncodeP src));
6573  predicate(Universe::narrow_oop_shift() != 0 &&
6574            Universe::narrow_oop_base() ==0);
6575
6576  format %{ "SRDI    $dst, $src, #3 \t// encodeP, $src != NULL" %}
6577  size(4);
6578  ins_encode %{
6579    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6580    __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f);
6581  %}
6582  ins_pipe(pipe_class_default);
6583%}
6584
6585// Compressed OOPs with narrow_oop_shift == 0.
6586// shift == 0, base == 0
6587instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
6588  match(Set dst (EncodeP src));
6589  predicate(Universe::narrow_oop_shift() == 0);
6590
6591  format %{ "MR      $dst, $src \t// Ptr->Narrow" %}
6592  // variable size, 0 or 4.
6593  ins_encode %{
6594    // TODO: PPC port $archOpcode(ppc64Opcode_or);
6595    __ mr_if_needed($dst$$Register, $src$$Register);
6596  %}
6597  ins_pipe(pipe_class_default);
6598%}
6599
6600// Decode nodes.
6601
6602// Shift node for expand.
6603instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
6604  // The match rule is needed to make it a 'MachTypeNode'!
6605  match(Set dst (DecodeN src));
6606  predicate(false);
6607
6608  format %{ "SLDI    $dst, $src, #3 \t// DecodeN" %}
6609  size(4);
6610  ins_encode %{
6611    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
6612    __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift());
6613  %}
6614  ins_pipe(pipe_class_default);
6615%}
6616
6617// Add node for expand.
6618instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
6619  // The match rule is needed to make it a 'MachTypeNode'!
6620  match(Set dst (DecodeN src));
6621  predicate(false);
6622
6623  format %{ "ADD     $dst, $src, heapbase \t// DecodeN, add oop base" %}
6624  ins_encode %{
6625    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6626    __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0);
6627  %}
6628  ins_pipe(pipe_class_default);
6629%}
6630
6631// conditianal add base for expand
6632instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
6633  // The match rule is needed to make it a 'MachTypeNode'!
6634  // NOTICE that the rule is nonsense - we just have to make sure that:
6635  //  - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6636  //  - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6637  match(Set dst (DecodeN (Binary crx src)));
6638  predicate(false);
6639
6640  format %{ "BEQ     $crx, done\n\t"
6641            "ADD     $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n"
6642            "done:" %}
6643  ins_encode %{
6644    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6645    Label done;
6646    __ beq($crx$$CondRegister, done);
6647    __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0);
6648    __ bind(done);
6649  %}
6650  ins_pipe(pipe_class_default);
6651%}
6652
6653instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
6654  // The match rule is needed to make it a 'MachTypeNode'!
6655  // NOTICE that the rule is nonsense - we just have to make sure that:
6656  //  - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp)
6657  //  - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC.
6658  match(Set dst (DecodeN (Binary crx src1)));
6659  predicate(false);
6660
6661  format %{ "CMOVE   $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %}
6662  size(4);
6663  ins_encode %{
6664    // This is a Power7 instruction for which no machine description exists.
6665    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
6666    __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
6667  %}
6668  ins_pipe(pipe_class_default);
6669%}
6670
6671//  shift != 0, base != 0
6672instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6673  match(Set dst (DecodeN src));
6674  predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6675             n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6676            Universe::narrow_oop_shift() != 0 &&
6677            Universe::narrow_oop_base() != 0);
6678  ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex.
6679  effect(TEMP crx);
6680
6681  format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %}
6682  postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) );
6683%}
6684
6685// shift != 0, base == 0
6686instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
6687  match(Set dst (DecodeN src));
6688  predicate(Universe::narrow_oop_shift() != 0 &&
6689            Universe::narrow_oop_base() == 0);
6690
6691  format %{ "SLDI    $dst, $src, #3 \t// DecodeN (zerobased)" %}
6692  size(4);
6693  ins_encode %{
6694    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
6695    __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift());
6696  %}
6697  ins_pipe(pipe_class_default);
6698%}
6699
6700// Optimize DecodeN for disjoint base.
6701// Shift narrow oop and or it into register that already contains the heap base.
6702// Base == dst must hold, and is assured by construction in postaloc_expand.
6703instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
6704  match(Set dst (DecodeN src));
6705  effect(TEMP base);
6706  predicate(false);
6707
6708  format %{ "RLDIMI  $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
6709  size(4);
6710  ins_encode %{
6711    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
6712    __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
6713  %}
6714  ins_pipe(pipe_class_default);
6715%}
6716
6717// Optimize DecodeN for disjoint base.
6718// This node requires only one cycle on the critical path.
6719// We must postalloc_expand as we can not express use_def effects where
6720// the used register is L and the def'ed register P.
6721instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{
6722  match(Set dst (DecodeN src));
6723  effect(TEMP_DEF dst);
6724  predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6725             n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6726            Universe::narrow_oop_base_disjoint());
6727  ins_cost(DEFAULT_COST);
6728
6729  format %{ "MOV     $dst, heapbase \t\n"
6730            "RLDIMI  $dst, $src, shift, 32-shift \t// decode with disjoint base" %}
6731  postalloc_expand %{
6732    loadBaseNode *n1 = new loadBaseNode();
6733    n1->add_req(NULL);
6734    n1->_opnds[0] = op_dst;
6735
6736    decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6737    n2->add_req(n_region, n_src, n1);
6738    n2->_opnds[0] = op_dst;
6739    n2->_opnds[1] = op_src;
6740    n2->_opnds[2] = op_dst;
6741    n2->_bottom_type = _bottom_type;
6742
6743    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6744    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6745
6746    nodes->push(n1);
6747    nodes->push(n2);
6748  %}
6749%}
6750
6751instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{
6752  match(Set dst (DecodeN src));
6753  effect(TEMP_DEF dst, TEMP crx);
6754  predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6755             n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) &&
6756            Universe::narrow_oop_base_disjoint() && VM_Version::has_isel());
6757  ins_cost(3 * DEFAULT_COST);
6758
6759  format %{ "DecodeN  $dst, $src \t// decode with disjoint base using isel" %}
6760  postalloc_expand %{
6761    loadBaseNode *n1 = new loadBaseNode();
6762    n1->add_req(NULL);
6763    n1->_opnds[0] = op_dst;
6764
6765    cmpN_reg_imm0Node *n_compare  = new cmpN_reg_imm0Node();
6766    n_compare->add_req(n_region, n_src);
6767    n_compare->_opnds[0] = op_crx;
6768    n_compare->_opnds[1] = op_src;
6769    n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR);
6770
6771    decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode();
6772    n2->add_req(n_region, n_src, n1);
6773    n2->_opnds[0] = op_dst;
6774    n2->_opnds[1] = op_src;
6775    n2->_opnds[2] = op_dst;
6776    n2->_bottom_type = _bottom_type;
6777
6778    cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode();
6779    n_cond_set->add_req(n_region, n_compare, n2);
6780    n_cond_set->_opnds[0] = op_dst;
6781    n_cond_set->_opnds[1] = op_crx;
6782    n_cond_set->_opnds[2] = op_dst;
6783    n_cond_set->_bottom_type = _bottom_type;
6784
6785    assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
6786    ra_->set_oop(n_cond_set, true);
6787
6788    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6789    ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
6790    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6791    ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6792
6793    nodes->push(n1);
6794    nodes->push(n_compare);
6795    nodes->push(n2);
6796    nodes->push(n_cond_set);
6797  %}
6798%}
6799
6800// src != 0, shift != 0, base != 0
6801instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{
6802  match(Set dst (DecodeN src));
6803  predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6804             n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) &&
6805            Universe::narrow_oop_shift() != 0 &&
6806            Universe::narrow_oop_base() != 0);
6807  ins_cost(2 * DEFAULT_COST);
6808
6809  format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %}
6810  postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src));
6811%}
6812
6813// Compressed OOPs with narrow_oop_shift == 0.
6814instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
6815  match(Set dst (DecodeN src));
6816  predicate(Universe::narrow_oop_shift() == 0);
6817  ins_cost(DEFAULT_COST);
6818
6819  format %{ "MR      $dst, $src \t// DecodeN (unscaled)" %}
6820  // variable size, 0 or 4.
6821  ins_encode %{
6822    // TODO: PPC port $archOpcode(ppc64Opcode_or);
6823    __ mr_if_needed($dst$$Register, $src$$Register);
6824  %}
6825  ins_pipe(pipe_class_default);
6826%}
6827
6828// Convert compressed oop into int for vectors alignment masking.
6829instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
6830  match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6831  predicate(Universe::narrow_oop_shift() == 0);
6832  ins_cost(DEFAULT_COST);
6833
6834  format %{ "MR      $dst, $src \t// (int)DecodeN (unscaled)" %}
6835  // variable size, 0 or 4.
6836  ins_encode %{
6837    // TODO: PPC port $archOpcode(ppc64Opcode_or);
6838    __ mr_if_needed($dst$$Register, $src$$Register);
6839  %}
6840  ins_pipe(pipe_class_default);
6841%}
6842
6843// Convert klass pointer into compressed form.
6844
6845// Nodes for postalloc expand.
6846
6847// Shift node for expand.
6848instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
6849  // The match rule is needed to make it a 'MachTypeNode'!
6850  match(Set dst (EncodePKlass src));
6851  predicate(false);
6852
6853  format %{ "SRDI    $dst, $src, 3 \t// encode" %}
6854  size(4);
6855  ins_encode %{
6856    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6857    __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift());
6858  %}
6859  ins_pipe(pipe_class_default);
6860%}
6861
6862// Add node for expand.
6863instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6864  // The match rule is needed to make it a 'MachTypeNode'!
6865  match(Set dst (EncodePKlass (Binary base src)));
6866  predicate(false);
6867
6868  format %{ "SUB     $dst, $base, $src \t// encode" %}
6869  size(4);
6870  ins_encode %{
6871    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
6872    __ subf($dst$$Register, $base$$Register, $src$$Register);
6873  %}
6874  ins_pipe(pipe_class_default);
6875%}
6876
6877// Disjoint narrow oop base.
6878instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
6879  match(Set dst (EncodePKlass src));
6880  predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/);
6881
6882  format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
6883  size(4);
6884  ins_encode %{
6885    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
6886    __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32);
6887  %}
6888  ins_pipe(pipe_class_default);
6889%}
6890
6891// shift != 0, base != 0
6892instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{
6893  match(Set dst (EncodePKlass (Binary base src)));
6894  predicate(false);
6895
6896  format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6897  postalloc_expand %{
6898    encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode();
6899    n1->add_req(n_region, n_base, n_src);
6900    n1->_opnds[0] = op_dst;
6901    n1->_opnds[1] = op_base;
6902    n1->_opnds[2] = op_src;
6903    n1->_bottom_type = _bottom_type;
6904
6905    encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode();
6906    n2->add_req(n_region, n1);
6907    n2->_opnds[0] = op_dst;
6908    n2->_opnds[1] = op_dst;
6909    n2->_bottom_type = _bottom_type;
6910    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6911    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6912
6913    nodes->push(n1);
6914    nodes->push(n2);
6915  %}
6916%}
6917
6918// shift != 0, base != 0
6919instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{
6920  match(Set dst (EncodePKlass src));
6921  //predicate(Universe::narrow_klass_shift() != 0 &&
6922  //          true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/);
6923
6924  //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %}
6925  ins_cost(DEFAULT_COST*2);  // Don't count constant.
6926  expand %{
6927    immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %}
6928    iRegLdst base;
6929    loadConL_Ex(base, baseImm);
6930    encodePKlass_not_null_Ex(dst, base, src);
6931  %}
6932%}
6933
6934// Decode nodes.
6935
6936// Shift node for expand.
6937instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
6938  // The match rule is needed to make it a 'MachTypeNode'!
6939  match(Set dst (DecodeNKlass src));
6940  predicate(false);
6941
6942  format %{ "SLDI    $dst, $src, #3 \t// DecodeNKlass" %}
6943  size(4);
6944  ins_encode %{
6945    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
6946    __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift());
6947  %}
6948  ins_pipe(pipe_class_default);
6949%}
6950
6951// Add node for expand.
6952
6953instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
6954  // The match rule is needed to make it a 'MachTypeNode'!
6955  match(Set dst (DecodeNKlass (Binary base src)));
6956  predicate(false);
6957
6958  format %{ "ADD     $dst, $base, $src \t// DecodeNKlass, add klass base" %}
6959  size(4);
6960  ins_encode %{
6961    // TODO: PPC port $archOpcode(ppc64Opcode_add);
6962    __ add($dst$$Register, $base$$Register, $src$$Register);
6963  %}
6964  ins_pipe(pipe_class_default);
6965%}
6966
6967// src != 0, shift != 0, base != 0
6968instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{
6969  match(Set dst (DecodeNKlass (Binary base src)));
6970  //effect(kill src); // We need a register for the immediate result after shifting.
6971  predicate(false);
6972
6973  format %{ "DecodeNKlass $dst =  $base + ($src << 3) \t// $src != NULL, postalloc expanded" %}
6974  postalloc_expand %{
6975    decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode();
6976    n1->add_req(n_region, n_base, n_src);
6977    n1->_opnds[0] = op_dst;
6978    n1->_opnds[1] = op_base;
6979    n1->_opnds[2] = op_src;
6980    n1->_bottom_type = _bottom_type;
6981
6982    decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode();
6983    n2->add_req(n_region, n1);
6984    n2->_opnds[0] = op_dst;
6985    n2->_opnds[1] = op_dst;
6986    n2->_bottom_type = _bottom_type;
6987
6988    ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6989    ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
6990
6991    nodes->push(n1);
6992    nodes->push(n2);
6993  %}
6994%}
6995
6996// src != 0, shift != 0, base != 0
6997instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{
6998  match(Set dst (DecodeNKlass src));
6999  // predicate(Universe::narrow_klass_shift() != 0 &&
7000  //           Universe::narrow_klass_base() != 0);
7001
7002  //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %}
7003
7004  ins_cost(DEFAULT_COST*2);  // Don't count constant.
7005  expand %{
7006    // We add first, then we shift. Like this, we can get along with one register less.
7007    // But we have to load the base pre-shifted.
7008    immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %}
7009    iRegLdst base;
7010    loadConL_Ex(base, baseImm);
7011    decodeNKlass_notNull_addBase_Ex(dst, base, src);
7012  %}
7013%}
7014
7015//----------MemBar Instructions-----------------------------------------------
7016// Memory barrier flavors
7017
7018instruct membar_acquire() %{
7019  match(LoadFence);
7020  ins_cost(4*MEMORY_REF_COST);
7021
7022  format %{ "MEMBAR-acquire" %}
7023  size(4);
7024  ins_encode %{
7025    // TODO: PPC port $archOpcode(ppc64Opcode_lwsync);
7026    __ acquire();
7027  %}
7028  ins_pipe(pipe_class_default);
7029%}
7030
7031instruct unnecessary_membar_acquire() %{
7032  match(MemBarAcquire);
7033  ins_cost(0);
7034
7035  format %{ " -- \t// redundant MEMBAR-acquire - empty" %}
7036  size(0);
7037  ins_encode( /*empty*/ );
7038  ins_pipe(pipe_class_default);
7039%}
7040
7041instruct membar_acquire_lock() %{
7042  match(MemBarAcquireLock);
7043  ins_cost(0);
7044
7045  format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %}
7046  size(0);
7047  ins_encode( /*empty*/ );
7048  ins_pipe(pipe_class_default);
7049%}
7050
7051instruct membar_release() %{
7052  match(MemBarRelease);
7053  match(StoreFence);
7054  ins_cost(4*MEMORY_REF_COST);
7055
7056  format %{ "MEMBAR-release" %}
7057  size(4);
7058  ins_encode %{
7059    // TODO: PPC port $archOpcode(ppc64Opcode_lwsync);
7060    __ release();
7061  %}
7062  ins_pipe(pipe_class_default);
7063%}
7064
7065instruct membar_storestore() %{
7066  match(MemBarStoreStore);
7067  ins_cost(4*MEMORY_REF_COST);
7068
7069  format %{ "MEMBAR-store-store" %}
7070  size(4);
7071  ins_encode %{
7072    // TODO: PPC port $archOpcode(ppc64Opcode_lwsync);
7073    __ membar(Assembler::StoreStore);
7074  %}
7075  ins_pipe(pipe_class_default);
7076%}
7077
7078instruct membar_release_lock() %{
7079  match(MemBarReleaseLock);
7080  ins_cost(0);
7081
7082  format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %}
7083  size(0);
7084  ins_encode( /*empty*/ );
7085  ins_pipe(pipe_class_default);
7086%}
7087
7088instruct membar_volatile() %{
7089  match(MemBarVolatile);
7090  ins_cost(4*MEMORY_REF_COST);
7091
7092  format %{ "MEMBAR-volatile" %}
7093  size(4);
7094  ins_encode %{
7095    // TODO: PPC port $archOpcode(ppc64Opcode_sync);
7096    __ fence();
7097  %}
7098  ins_pipe(pipe_class_default);
7099%}
7100
7101// This optimization is wrong on PPC. The following pattern is not supported:
7102//  MemBarVolatile
7103//   ^        ^
7104//   |        |
7105//  CtrlProj MemProj
7106//   ^        ^
7107//   |        |
7108//   |       Load
7109//   |
7110//  MemBarVolatile
7111//
7112//  The first MemBarVolatile could get optimized out! According to
7113//  Vladimir, this pattern can not occur on Oracle platforms.
7114//  However, it does occur on PPC64 (because of membars in
7115//  inline_unsafe_load_store).
7116//
7117// Add this node again if we found a good solution for inline_unsafe_load_store().
7118// Don't forget to look at the implementation of post_store_load_barrier again,
7119// we did other fixes in that method.
7120//instruct unnecessary_membar_volatile() %{
7121//  match(MemBarVolatile);
7122//  predicate(Matcher::post_store_load_barrier(n));
7123//  ins_cost(0);
7124//
7125//  format %{ " -- \t// redundant MEMBAR-volatile - empty" %}
7126//  size(0);
7127//  ins_encode( /*empty*/ );
7128//  ins_pipe(pipe_class_default);
7129//%}
7130
7131instruct membar_CPUOrder() %{
7132  match(MemBarCPUOrder);
7133  ins_cost(0);
7134
7135  format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %}
7136  size(0);
7137  ins_encode( /*empty*/ );
7138  ins_pipe(pipe_class_default);
7139%}
7140
7141//----------Conditional Move---------------------------------------------------
7142
7143// Cmove using isel.
7144instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7145  match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7146  predicate(VM_Version::has_isel());
7147  ins_cost(DEFAULT_COST);
7148
7149  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7150  size(4);
7151  ins_encode %{
7152    // This is a Power7 instruction for which no machine description
7153    // exists. Anyways, the scheduler should be off on Power7.
7154    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7155    int cc        = $cmp$$cmpcode;
7156    __ isel($dst$$Register, $crx$$CondRegister,
7157            (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7158  %}
7159  ins_pipe(pipe_class_default);
7160%}
7161
7162instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
7163  match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7164  predicate(!VM_Version::has_isel());
7165  ins_cost(DEFAULT_COST+BRANCH_COST);
7166
7167  ins_variable_size_depending_on_alignment(true);
7168
7169  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7170  // Worst case is branch + move + stop, no stop without scheduler
7171  size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7172  ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7173  ins_pipe(pipe_class_default);
7174%}
7175
7176instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{
7177  match(Set dst (CMoveI (Binary cmp crx) (Binary dst src)));
7178  ins_cost(DEFAULT_COST+BRANCH_COST);
7179
7180  ins_variable_size_depending_on_alignment(true);
7181
7182  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7183  // Worst case is branch + move + stop, no stop without scheduler
7184  size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7185  ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7186  ins_pipe(pipe_class_default);
7187%}
7188
7189// Cmove using isel.
7190instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7191  match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7192  predicate(VM_Version::has_isel());
7193  ins_cost(DEFAULT_COST);
7194
7195  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7196  size(4);
7197  ins_encode %{
7198    // This is a Power7 instruction for which no machine description
7199    // exists. Anyways, the scheduler should be off on Power7.
7200    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7201    int cc        = $cmp$$cmpcode;
7202    __ isel($dst$$Register, $crx$$CondRegister,
7203            (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7204  %}
7205  ins_pipe(pipe_class_default);
7206%}
7207
7208instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
7209  match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7210  predicate(!VM_Version::has_isel());
7211  ins_cost(DEFAULT_COST+BRANCH_COST);
7212
7213  ins_variable_size_depending_on_alignment(true);
7214
7215  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7216  // Worst case is branch + move + stop, no stop without scheduler.
7217  size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7218  ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7219  ins_pipe(pipe_class_default);
7220%}
7221
7222instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{
7223  match(Set dst (CMoveL (Binary cmp crx) (Binary dst src)));
7224  ins_cost(DEFAULT_COST+BRANCH_COST);
7225
7226  ins_variable_size_depending_on_alignment(true);
7227
7228  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7229  // Worst case is branch + move + stop, no stop without scheduler.
7230  size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7231  ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7232  ins_pipe(pipe_class_default);
7233%}
7234
7235// Cmove using isel.
7236instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7237  match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7238  predicate(VM_Version::has_isel());
7239  ins_cost(DEFAULT_COST);
7240
7241  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7242  size(4);
7243  ins_encode %{
7244    // This is a Power7 instruction for which no machine description
7245    // exists. Anyways, the scheduler should be off on Power7.
7246    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7247    int cc        = $cmp$$cmpcode;
7248    __ isel($dst$$Register, $crx$$CondRegister,
7249            (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7250  %}
7251  ins_pipe(pipe_class_default);
7252%}
7253
7254// Conditional move for RegN. Only cmov(reg, reg).
7255instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
7256  match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7257  predicate(!VM_Version::has_isel());
7258  ins_cost(DEFAULT_COST+BRANCH_COST);
7259
7260  ins_variable_size_depending_on_alignment(true);
7261
7262  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7263  // Worst case is branch + move + stop, no stop without scheduler.
7264  size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7265  ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7266  ins_pipe(pipe_class_default);
7267%}
7268
7269instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{
7270  match(Set dst (CMoveN (Binary cmp crx) (Binary dst src)));
7271  ins_cost(DEFAULT_COST+BRANCH_COST);
7272
7273  ins_variable_size_depending_on_alignment(true);
7274
7275  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7276  // Worst case is branch + move + stop, no stop without scheduler.
7277  size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7278  ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7279  ins_pipe(pipe_class_default);
7280%}
7281
7282// Cmove using isel.
7283instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{
7284  match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7285  predicate(VM_Version::has_isel());
7286  ins_cost(DEFAULT_COST);
7287
7288  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7289  size(4);
7290  ins_encode %{
7291    // This is a Power7 instruction for which no machine description
7292    // exists. Anyways, the scheduler should be off on Power7.
7293    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7294    int cc        = $cmp$$cmpcode;
7295    __ isel($dst$$Register, $crx$$CondRegister,
7296            (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
7297  %}
7298  ins_pipe(pipe_class_default);
7299%}
7300
7301instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{
7302  match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7303  predicate(!VM_Version::has_isel());
7304  ins_cost(DEFAULT_COST+BRANCH_COST);
7305
7306  ins_variable_size_depending_on_alignment(true);
7307
7308  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7309  // Worst case is branch + move + stop, no stop without scheduler.
7310  size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7311  ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
7312  ins_pipe(pipe_class_default);
7313%}
7314
7315instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{
7316  match(Set dst (CMoveP (Binary cmp crx) (Binary dst src)));
7317  ins_cost(DEFAULT_COST+BRANCH_COST);
7318
7319  ins_variable_size_depending_on_alignment(true);
7320
7321  format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
7322  // Worst case is branch + move + stop, no stop without scheduler.
7323  size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
7324  ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
7325  ins_pipe(pipe_class_default);
7326%}
7327
7328instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
7329  match(Set dst (CMoveF (Binary cmp crx) (Binary dst src)));
7330  ins_cost(DEFAULT_COST+BRANCH_COST);
7331
7332  ins_variable_size_depending_on_alignment(true);
7333
7334  format %{ "CMOVEF  $cmp, $crx, $dst, $src\n\t" %}
7335  // Worst case is branch + move + stop, no stop without scheduler.
7336  size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
7337  ins_encode %{
7338    // TODO: PPC port $archOpcode(ppc64Opcode_cmovef);
7339    Label done;
7340    assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7341    // Branch if not (cmp crx).
7342    __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7343    __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7344    // TODO PPC port __ endgroup_if_needed(_size == 12);
7345    __ bind(done);
7346  %}
7347  ins_pipe(pipe_class_default);
7348%}
7349
7350instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
7351  match(Set dst (CMoveD (Binary cmp crx) (Binary dst src)));
7352  ins_cost(DEFAULT_COST+BRANCH_COST);
7353
7354  ins_variable_size_depending_on_alignment(true);
7355
7356  format %{ "CMOVEF  $cmp, $crx, $dst, $src\n\t" %}
7357  // Worst case is branch + move + stop, no stop without scheduler.
7358  size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
7359  ins_encode %{
7360    // TODO: PPC port $archOpcode(ppc64Opcode_cmovef);
7361    Label done;
7362    assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
7363    // Branch if not (cmp crx).
7364    __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
7365    __ fmr($dst$$FloatRegister, $src$$FloatRegister);
7366    // TODO PPC port __ endgroup_if_needed(_size == 12);
7367    __ bind(done);
7368  %}
7369  ins_pipe(pipe_class_default);
7370%}
7371
7372//----------Conditional_store--------------------------------------------------
7373// Conditional-store of the updated heap-top.
7374// Used during allocation of the shared heap.
7375// Sets flags (EQ) on success. Implemented with a CASA on Sparc.
7376
7377// As compareAndSwapL, but return flag register instead of boolean value in
7378// int register.
7379// Used by sun/misc/AtomicLongCSImpl.java.
7380// Mem_ptr must be a memory operand, else this node does not get
7381// Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7382// can be rematerialized which leads to errors.
7383instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{
7384  match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal)));
7385  effect(TEMP cr0);
7386  format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7387  ins_encode %{
7388    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7389    __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
7390                MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(),
7391                noreg, NULL, true);
7392  %}
7393  ins_pipe(pipe_class_default);
7394%}
7395
7396// As compareAndSwapP, but return flag register instead of boolean value in
7397// int register.
7398// This instruction is matched if UseTLAB is off.
7399// Mem_ptr must be a memory operand, else this node does not get
7400// Flag_needs_anti_dependence_check set by adlc. If this is not set this node
7401// can be rematerialized which leads to errors.
7402instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{
7403  match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal)));
7404  ins_cost(2*MEMORY_REF_COST);
7405
7406  format %{ "STDCX_  if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
7407  ins_encode %{
7408    // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_);
7409    __ stdcx_($newVal$$Register, $mem_ptr$$Register);
7410  %}
7411  ins_pipe(pipe_class_memory);
7412%}
7413
7414// Implement LoadPLocked. Must be ordered against changes of the memory location
7415// by storePConditional.
7416// Don't know whether this is ever used.
7417instruct loadPLocked(iRegPdst dst, memory mem) %{
7418  match(Set dst (LoadPLocked mem));
7419  ins_cost(2*MEMORY_REF_COST);
7420
7421  format %{ "LDARX   $dst, $mem \t// loadPLocked\n\t" %}
7422  size(4);
7423  ins_encode %{
7424    // TODO: PPC port $archOpcode(ppc64Opcode_ldarx);
7425    __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
7426  %}
7427  ins_pipe(pipe_class_memory);
7428%}
7429
7430//----------Compare-And-Swap---------------------------------------------------
7431
7432// CompareAndSwap{P,I,L} have more than one output, therefore "CmpI
7433// (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))"  cannot be
7434// matched.
7435
7436// Strong versions:
7437
7438instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7439  match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7440  predicate(VM_Version::has_lqarx());
7441  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7442  format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7443  ins_encode %{
7444    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7445    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7446    __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7447                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7448                $res$$Register, true);
7449    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7450      __ isync();
7451    } else {
7452      __ sync();
7453    }
7454  %}
7455  ins_pipe(pipe_class_default);
7456%}
7457
7458instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7459  match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2)));
7460  predicate(!VM_Version::has_lqarx());
7461  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7462  format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7463  ins_encode %{
7464    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7465    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7466    __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7467                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7468                $res$$Register, true);
7469    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7470      __ isync();
7471    } else {
7472      __ sync();
7473    }
7474  %}
7475  ins_pipe(pipe_class_default);
7476%}
7477
7478instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7479  match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7480  predicate(VM_Version::has_lqarx());
7481  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7482  format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7483  ins_encode %{
7484    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7485    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7486    __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7487                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7488                $res$$Register, true);
7489    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7490      __ isync();
7491    } else {
7492      __ sync();
7493    }
7494  %}
7495  ins_pipe(pipe_class_default);
7496%}
7497
7498instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7499  match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2)));
7500  predicate(!VM_Version::has_lqarx());
7501  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7502  format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7503  ins_encode %{
7504    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7505    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7506    __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7507                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7508                $res$$Register, true);
7509    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7510      __ isync();
7511    } else {
7512      __ sync();
7513    }
7514  %}
7515  ins_pipe(pipe_class_default);
7516%}
7517
7518instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7519  match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
7520  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7521  format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7522  ins_encode %{
7523    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7524    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7525    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7526                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7527                $res$$Register, true);
7528    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7529      __ isync();
7530    } else {
7531      __ sync();
7532    }
7533  %}
7534  ins_pipe(pipe_class_default);
7535%}
7536
7537instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7538  match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2)));
7539  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7540  format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7541  ins_encode %{
7542    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7543    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7544    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7545                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7546                $res$$Register, true);
7547    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7548      __ isync();
7549    } else {
7550      __ sync();
7551    }
7552  %}
7553  ins_pipe(pipe_class_default);
7554%}
7555
7556instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7557  match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2)));
7558  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7559  format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7560  ins_encode %{
7561    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7562    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7563    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7564                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7565                $res$$Register, NULL, true);
7566    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7567      __ isync();
7568    } else {
7569      __ sync();
7570    }
7571  %}
7572  ins_pipe(pipe_class_default);
7573%}
7574
7575instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7576  match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2)));
7577  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7578  format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7579  ins_encode %{
7580    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7581    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7582    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7583                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7584                $res$$Register, NULL, true);
7585    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7586      __ isync();
7587    } else {
7588      __ sync();
7589    }
7590  %}
7591  ins_pipe(pipe_class_default);
7592%}
7593
7594// Weak versions:
7595
7596instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7597  match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7598  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7599  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7600  format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7601  ins_encode %{
7602    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7603    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7604    __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7605                MacroAssembler::MemBarNone,
7606                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7607  %}
7608  ins_pipe(pipe_class_default);
7609%}
7610
7611instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7612  match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7613  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7614  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7615  format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
7616  ins_encode %{
7617    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7618    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7619    __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7620                MacroAssembler::MemBarNone,
7621                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7622  %}
7623  ins_pipe(pipe_class_default);
7624%}
7625
7626instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7627  match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7628  predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7629  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7630  format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7631  ins_encode %{
7632    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7633    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7634    __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7635                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7636                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7637  %}
7638  ins_pipe(pipe_class_default);
7639%}
7640
7641instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7642  match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2)));
7643  predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7644  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7645  format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
7646  ins_encode %{
7647    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7648    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7649    __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7650                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7651                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7652  %}
7653  ins_pipe(pipe_class_default);
7654%}
7655
7656instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7657  match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7658  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7659  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7660  format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7661  ins_encode %{
7662    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7663    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7664    __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7665                MacroAssembler::MemBarNone,
7666                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7667  %}
7668  ins_pipe(pipe_class_default);
7669%}
7670
7671instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7672  match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7673  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7674  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7675  format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
7676  ins_encode %{
7677    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7678    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7679    __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7680                MacroAssembler::MemBarNone,
7681                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7682  %}
7683  ins_pipe(pipe_class_default);
7684%}
7685
7686instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7687  match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7688  predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7689  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7690  format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7691  ins_encode %{
7692    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7693    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7694    __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7695                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7696                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7697  %}
7698  ins_pipe(pipe_class_default);
7699%}
7700
7701instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{
7702  match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2)));
7703  predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7704  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
7705  format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
7706  ins_encode %{
7707    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7708    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7709    __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
7710                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7711                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7712  %}
7713  ins_pipe(pipe_class_default);
7714%}
7715
7716instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7717  match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7718  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7719  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7720  format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7721  ins_encode %{
7722    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7723    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7724    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7725                MacroAssembler::MemBarNone,
7726                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7727  %}
7728  ins_pipe(pipe_class_default);
7729%}
7730
7731instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7732  match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
7733  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7734  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7735  format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7736  ins_encode %{
7737    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7738    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7739    // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7740    // value is never passed to caller.
7741    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7742                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7743                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7744  %}
7745  ins_pipe(pipe_class_default);
7746%}
7747
7748instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7749  match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7750  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7751  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7752  format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
7753  ins_encode %{
7754    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7755    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7756    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7757                MacroAssembler::MemBarNone,
7758                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7759  %}
7760  ins_pipe(pipe_class_default);
7761%}
7762
7763instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
7764  match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
7765  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7766  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7767  format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
7768  ins_encode %{
7769    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7770    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7771    // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7772    // value is never passed to caller.
7773    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7774                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7775                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
7776  %}
7777  ins_pipe(pipe_class_default);
7778%}
7779
7780instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7781  match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7782  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7783  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7784  format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
7785  ins_encode %{
7786    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7787    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7788    // value is never passed to caller.
7789    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7790                MacroAssembler::MemBarNone,
7791                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7792  %}
7793  ins_pipe(pipe_class_default);
7794%}
7795
7796instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
7797  match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
7798  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7799  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7800  format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
7801  ins_encode %{
7802    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7803    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7804    // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7805    // value is never passed to caller.
7806    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7807                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7808                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7809  %}
7810  ins_pipe(pipe_class_default);
7811%}
7812
7813instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7814  match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7815  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7816  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7817  format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7818  ins_encode %{
7819    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7820    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7821    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7822                MacroAssembler::MemBarNone,
7823                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7824  %}
7825  ins_pipe(pipe_class_default);
7826%}
7827
7828instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
7829  match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
7830  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
7831  effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
7832  format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
7833  ins_encode %{
7834    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7835    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7836    // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
7837    // value is never passed to caller.
7838    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
7839                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
7840                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
7841  %}
7842  ins_pipe(pipe_class_default);
7843%}
7844
7845// CompareAndExchange
7846
7847instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7848  match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7849  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7850  effect(TEMP_DEF res, TEMP cr0);
7851  format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7852  ins_encode %{
7853    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7854    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7855    __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7856                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7857                noreg, true);
7858  %}
7859  ins_pipe(pipe_class_default);
7860%}
7861
7862instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7863  match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7864  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7865  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7866  format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
7867  ins_encode %{
7868    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7869    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7870    __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7871                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7872                noreg, true);
7873  %}
7874  ins_pipe(pipe_class_default);
7875%}
7876
7877instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7878  match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7879  predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7880  effect(TEMP_DEF res, TEMP cr0);
7881  format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7882  ins_encode %{
7883    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7884    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7885    __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7886                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7887                noreg, true);
7888    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7889      __ isync();
7890    } else {
7891      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7892      __ sync();
7893    }
7894  %}
7895  ins_pipe(pipe_class_default);
7896%}
7897
7898instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7899  match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2)));
7900  predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7901  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7902  format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
7903  ins_encode %{
7904    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7905    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7906    __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7907                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7908                noreg, true);
7909    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7910      __ isync();
7911    } else {
7912      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7913      __ sync();
7914    }
7915  %}
7916  ins_pipe(pipe_class_default);
7917%}
7918
7919instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7920  match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7921  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx());
7922  effect(TEMP_DEF res, TEMP cr0);
7923  format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7924  ins_encode %{
7925    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7926    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7927    __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7928                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7929                noreg, true);
7930  %}
7931  ins_pipe(pipe_class_default);
7932%}
7933
7934instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7935  match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7936  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx());
7937  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7938  format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
7939  ins_encode %{
7940    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7941    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7942    __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7943                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7944                noreg, true);
7945  %}
7946  ins_pipe(pipe_class_default);
7947%}
7948
7949instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7950  match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7951  predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx());
7952  effect(TEMP_DEF res, TEMP cr0);
7953  format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7954  ins_encode %{
7955    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7956    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7957    __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
7958                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7959                noreg, true);
7960    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7961      __ isync();
7962    } else {
7963      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7964      __ sync();
7965    }
7966  %}
7967  ins_pipe(pipe_class_default);
7968%}
7969
7970instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{
7971  match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2)));
7972  predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx());
7973  effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
7974  format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
7975  ins_encode %{
7976    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7977    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7978    __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
7979                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
7980                noreg, true);
7981    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
7982      __ isync();
7983    } else {
7984      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
7985      __ sync();
7986    }
7987  %}
7988  ins_pipe(pipe_class_default);
7989%}
7990
7991instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
7992  match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
7993  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
7994  effect(TEMP_DEF res, TEMP cr0);
7995  format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
7996  ins_encode %{
7997    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
7998    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
7999    __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8000                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8001                noreg, true);
8002  %}
8003  ins_pipe(pipe_class_default);
8004%}
8005
8006instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
8007  match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
8008  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8009  effect(TEMP_DEF res, TEMP cr0);
8010  format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
8011  ins_encode %{
8012    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8013    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8014    __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8015                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8016                noreg, true);
8017    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8018      __ isync();
8019    } else {
8020      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8021      __ sync();
8022    }
8023  %}
8024  ins_pipe(pipe_class_default);
8025%}
8026
8027instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8028  match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8029  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8030  effect(TEMP_DEF res, TEMP cr0);
8031  format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8032  ins_encode %{
8033    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8034    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8035    __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8036                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8037                noreg, true);
8038  %}
8039  ins_pipe(pipe_class_default);
8040%}
8041
8042instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
8043  match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
8044  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8045  effect(TEMP_DEF res, TEMP cr0);
8046  format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
8047  ins_encode %{
8048    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8049    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8050    __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8051                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8052                noreg, true);
8053    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8054      __ isync();
8055    } else {
8056      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8057      __ sync();
8058    }
8059  %}
8060  ins_pipe(pipe_class_default);
8061%}
8062
8063instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8064  match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8065  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8066  effect(TEMP_DEF res, TEMP cr0);
8067  format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
8068  ins_encode %{
8069    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8070    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8071    __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8072                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8073                noreg, NULL, true);
8074  %}
8075  ins_pipe(pipe_class_default);
8076%}
8077
8078instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
8079  match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
8080  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8081  effect(TEMP_DEF res, TEMP cr0);
8082  format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
8083  ins_encode %{
8084    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8085    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8086    __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8087                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8088                noreg, NULL, true);
8089    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8090      __ isync();
8091    } else {
8092      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8093      __ sync();
8094    }
8095  %}
8096  ins_pipe(pipe_class_default);
8097%}
8098
8099instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8100  match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8101  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
8102  effect(TEMP_DEF res, TEMP cr0);
8103  format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8104  ins_encode %{
8105    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8106    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8107    __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8108                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8109                noreg, NULL, true);
8110  %}
8111  ins_pipe(pipe_class_default);
8112%}
8113
8114instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
8115  match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
8116  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
8117  effect(TEMP_DEF res, TEMP cr0);
8118  format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
8119  ins_encode %{
8120    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
8121    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
8122    __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
8123                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
8124                noreg, NULL, true);
8125    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8126      __ isync();
8127    } else {
8128      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
8129      __ sync();
8130    }
8131  %}
8132  ins_pipe(pipe_class_default);
8133%}
8134
8135// Special RMW
8136
8137instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8138  match(Set res (GetAndAddB mem_ptr src));
8139  predicate(VM_Version::has_lqarx());
8140  effect(TEMP_DEF res, TEMP cr0);
8141  format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8142  ins_encode %{
8143    __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8144                  R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8145    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8146      __ isync();
8147    } else {
8148      __ sync();
8149    }
8150  %}
8151  ins_pipe(pipe_class_default);
8152%}
8153
8154instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8155  match(Set res (GetAndAddB mem_ptr src));
8156  predicate(!VM_Version::has_lqarx());
8157  effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8158  format %{ "GetAndAddB $res, $mem_ptr, $src" %}
8159  ins_encode %{
8160    __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register,
8161                  R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8162    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8163      __ isync();
8164    } else {
8165      __ sync();
8166    }
8167  %}
8168  ins_pipe(pipe_class_default);
8169%}
8170
8171instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8172  match(Set res (GetAndAddS mem_ptr src));
8173  predicate(VM_Version::has_lqarx());
8174  effect(TEMP_DEF res, TEMP cr0);
8175  format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8176  ins_encode %{
8177    __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8178                  R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8179    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8180      __ isync();
8181    } else {
8182      __ sync();
8183    }
8184  %}
8185  ins_pipe(pipe_class_default);
8186%}
8187
8188instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8189  match(Set res (GetAndAddS mem_ptr src));
8190  predicate(!VM_Version::has_lqarx());
8191  effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8192  format %{ "GetAndAddS $res, $mem_ptr, $src" %}
8193  ins_encode %{
8194    __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register,
8195                  R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8196    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8197      __ isync();
8198    } else {
8199      __ sync();
8200    }
8201  %}
8202  ins_pipe(pipe_class_default);
8203%}
8204
8205instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8206  match(Set res (GetAndAddI mem_ptr src));
8207  effect(TEMP_DEF res, TEMP cr0);
8208  format %{ "GetAndAddI $res, $mem_ptr, $src" %}
8209  ins_encode %{
8210    __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register,
8211                  R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8212    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8213      __ isync();
8214    } else {
8215      __ sync();
8216    }
8217  %}
8218  ins_pipe(pipe_class_default);
8219%}
8220
8221instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8222  match(Set res (GetAndAddL mem_ptr src));
8223  effect(TEMP_DEF res, TEMP cr0);
8224  format %{ "GetAndAddL $res, $mem_ptr, $src" %}
8225  ins_encode %{
8226    __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register,
8227                  R0, MacroAssembler::cmpxchgx_hint_atomic_update());
8228    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8229      __ isync();
8230    } else {
8231      __ sync();
8232    }
8233  %}
8234  ins_pipe(pipe_class_default);
8235%}
8236
8237instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8238  match(Set res (GetAndSetB mem_ptr src));
8239  predicate(VM_Version::has_lqarx());
8240  effect(TEMP_DEF res, TEMP cr0);
8241  format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8242  ins_encode %{
8243    __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8244                  noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8245    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8246      __ isync();
8247    } else {
8248      __ sync();
8249    }
8250  %}
8251  ins_pipe(pipe_class_default);
8252%}
8253
8254instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8255  match(Set res (GetAndSetB mem_ptr src));
8256  predicate(!VM_Version::has_lqarx());
8257  effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8258  format %{ "GetAndSetB $res, $mem_ptr, $src" %}
8259  ins_encode %{
8260    __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register,
8261                  R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8262    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8263      __ isync();
8264    } else {
8265      __ sync();
8266    }
8267  %}
8268  ins_pipe(pipe_class_default);
8269%}
8270
8271instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8272  match(Set res (GetAndSetS mem_ptr src));
8273  predicate(VM_Version::has_lqarx());
8274  effect(TEMP_DEF res, TEMP cr0);
8275  format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8276  ins_encode %{
8277    __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8278                  noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update());
8279    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8280      __ isync();
8281    } else {
8282      __ sync();
8283    }
8284  %}
8285  ins_pipe(pipe_class_default);
8286%}
8287
8288instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{
8289  match(Set res (GetAndSetS mem_ptr src));
8290  predicate(!VM_Version::has_lqarx());
8291  effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0);
8292  format %{ "GetAndSetS $res, $mem_ptr, $src" %}
8293  ins_encode %{
8294    __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register,
8295                  R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
8296    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8297      __ isync();
8298    } else {
8299      __ sync();
8300    }
8301  %}
8302  ins_pipe(pipe_class_default);
8303%}
8304
8305instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
8306  match(Set res (GetAndSetI mem_ptr src));
8307  effect(TEMP_DEF res, TEMP cr0);
8308  format %{ "GetAndSetI $res, $mem_ptr, $src" %}
8309  ins_encode %{
8310    __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8311                  MacroAssembler::cmpxchgx_hint_atomic_update());
8312    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8313      __ isync();
8314    } else {
8315      __ sync();
8316    }
8317  %}
8318  ins_pipe(pipe_class_default);
8319%}
8320
8321instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{
8322  match(Set res (GetAndSetL mem_ptr src));
8323  effect(TEMP_DEF res, TEMP cr0);
8324  format %{ "GetAndSetL $res, $mem_ptr, $src" %}
8325  ins_encode %{
8326    __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8327                  MacroAssembler::cmpxchgx_hint_atomic_update());
8328    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8329      __ isync();
8330    } else {
8331      __ sync();
8332    }
8333  %}
8334  ins_pipe(pipe_class_default);
8335%}
8336
8337instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{
8338  match(Set res (GetAndSetP mem_ptr src));
8339  effect(TEMP_DEF res, TEMP cr0);
8340  format %{ "GetAndSetP $res, $mem_ptr, $src" %}
8341  ins_encode %{
8342    __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register,
8343                  MacroAssembler::cmpxchgx_hint_atomic_update());
8344    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8345      __ isync();
8346    } else {
8347      __ sync();
8348    }
8349  %}
8350  ins_pipe(pipe_class_default);
8351%}
8352
8353instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{
8354  match(Set res (GetAndSetN mem_ptr src));
8355  effect(TEMP_DEF res, TEMP cr0);
8356  format %{ "GetAndSetN $res, $mem_ptr, $src" %}
8357  ins_encode %{
8358    __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register,
8359                  MacroAssembler::cmpxchgx_hint_atomic_update());
8360    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
8361      __ isync();
8362    } else {
8363      __ sync();
8364    }
8365  %}
8366  ins_pipe(pipe_class_default);
8367%}
8368
8369//----------Arithmetic Instructions--------------------------------------------
8370// Addition Instructions
8371
8372// Register Addition
8373instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{
8374  match(Set dst (AddI src1 src2));
8375  format %{ "ADD     $dst, $src1, $src2" %}
8376  size(4);
8377  ins_encode %{
8378    // TODO: PPC port $archOpcode(ppc64Opcode_add);
8379    __ add($dst$$Register, $src1$$Register, $src2$$Register);
8380  %}
8381  ins_pipe(pipe_class_default);
8382%}
8383
8384// Expand does not work with above instruct. (??)
8385instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8386  // no match-rule
8387  effect(DEF dst, USE src1, USE src2);
8388  format %{ "ADD     $dst, $src1, $src2" %}
8389  size(4);
8390  ins_encode %{
8391    // TODO: PPC port $archOpcode(ppc64Opcode_add);
8392    __ add($dst$$Register, $src1$$Register, $src2$$Register);
8393  %}
8394  ins_pipe(pipe_class_default);
8395%}
8396
8397instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
8398  match(Set dst (AddI (AddI (AddI src1 src2) src3) src4));
8399  ins_cost(DEFAULT_COST*3);
8400
8401  expand %{
8402    // FIXME: we should do this in the ideal world.
8403    iRegIdst tmp1;
8404    iRegIdst tmp2;
8405    addI_reg_reg(tmp1, src1, src2);
8406    addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg.
8407    addI_reg_reg(dst, tmp1, tmp2);
8408  %}
8409%}
8410
8411// Immediate Addition
8412instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8413  match(Set dst (AddI src1 src2));
8414  format %{ "ADDI    $dst, $src1, $src2" %}
8415  size(4);
8416  ins_encode %{
8417    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
8418    __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8419  %}
8420  ins_pipe(pipe_class_default);
8421%}
8422
8423// Immediate Addition with 16-bit shifted operand
8424instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
8425  match(Set dst (AddI src1 src2));
8426  format %{ "ADDIS   $dst, $src1, $src2" %}
8427  size(4);
8428  ins_encode %{
8429    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
8430    __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8431  %}
8432  ins_pipe(pipe_class_default);
8433%}
8434
8435// Long Addition
8436instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8437  match(Set dst (AddL src1 src2));
8438  format %{ "ADD     $dst, $src1, $src2 \t// long" %}
8439  size(4);
8440  ins_encode %{
8441    // TODO: PPC port $archOpcode(ppc64Opcode_add);
8442    __ add($dst$$Register, $src1$$Register, $src2$$Register);
8443  %}
8444  ins_pipe(pipe_class_default);
8445%}
8446
8447// Expand does not work with above instruct. (??)
8448instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8449  // no match-rule
8450  effect(DEF dst, USE src1, USE src2);
8451  format %{ "ADD     $dst, $src1, $src2 \t// long" %}
8452  size(4);
8453  ins_encode %{
8454    // TODO: PPC port $archOpcode(ppc64Opcode_add);
8455    __ add($dst$$Register, $src1$$Register, $src2$$Register);
8456  %}
8457  ins_pipe(pipe_class_default);
8458%}
8459
8460instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{
8461  match(Set dst (AddL (AddL (AddL src1 src2) src3) src4));
8462  ins_cost(DEFAULT_COST*3);
8463
8464  expand %{
8465    // FIXME: we should do this in the ideal world.
8466    iRegLdst tmp1;
8467    iRegLdst tmp2;
8468    addL_reg_reg(tmp1, src1, src2);
8469    addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
8470    addL_reg_reg(dst, tmp1, tmp2);
8471  %}
8472%}
8473
8474// AddL + ConvL2I.
8475instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8476  match(Set dst (ConvL2I (AddL src1 src2)));
8477
8478  format %{ "ADD     $dst, $src1, $src2 \t// long + l2i" %}
8479  size(4);
8480  ins_encode %{
8481    // TODO: PPC port $archOpcode(ppc64Opcode_add);
8482    __ add($dst$$Register, $src1$$Register, $src2$$Register);
8483  %}
8484  ins_pipe(pipe_class_default);
8485%}
8486
8487// No constant pool entries required.
8488instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8489  match(Set dst (AddL src1 src2));
8490
8491  format %{ "ADDI    $dst, $src1, $src2" %}
8492  size(4);
8493  ins_encode %{
8494    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
8495    __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8496  %}
8497  ins_pipe(pipe_class_default);
8498%}
8499
8500// Long Immediate Addition with 16-bit shifted operand.
8501// No constant pool entries required.
8502instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
8503  match(Set dst (AddL src1 src2));
8504
8505  format %{ "ADDIS   $dst, $src1, $src2" %}
8506  size(4);
8507  ins_encode %{
8508    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
8509    __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8510  %}
8511  ins_pipe(pipe_class_default);
8512%}
8513
8514// Pointer Register Addition
8515instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
8516  match(Set dst (AddP src1 src2));
8517  format %{ "ADD     $dst, $src1, $src2" %}
8518  size(4);
8519  ins_encode %{
8520    // TODO: PPC port $archOpcode(ppc64Opcode_add);
8521    __ add($dst$$Register, $src1$$Register, $src2$$Register);
8522  %}
8523  ins_pipe(pipe_class_default);
8524%}
8525
8526// Pointer Immediate Addition
8527// No constant pool entries required.
8528instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
8529  match(Set dst (AddP src1 src2));
8530
8531  format %{ "ADDI    $dst, $src1, $src2" %}
8532  size(4);
8533  ins_encode %{
8534    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
8535    __ addi($dst$$Register, $src1$$Register, $src2$$constant);
8536  %}
8537  ins_pipe(pipe_class_default);
8538%}
8539
8540// Pointer Immediate Addition with 16-bit shifted operand.
8541// No constant pool entries required.
8542instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
8543  match(Set dst (AddP src1 src2));
8544
8545  format %{ "ADDIS   $dst, $src1, $src2" %}
8546  size(4);
8547  ins_encode %{
8548    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
8549    __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
8550  %}
8551  ins_pipe(pipe_class_default);
8552%}
8553
8554//---------------------
8555// Subtraction Instructions
8556
8557// Register Subtraction
8558instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8559  match(Set dst (SubI src1 src2));
8560  format %{ "SUBF    $dst, $src2, $src1" %}
8561  size(4);
8562  ins_encode %{
8563    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
8564    __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8565  %}
8566  ins_pipe(pipe_class_default);
8567%}
8568
8569// Immediate Subtraction
8570// Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal),
8571// Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16.
8572
8573// SubI from constant (using subfic).
8574instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
8575  match(Set dst (SubI src1 src2));
8576  format %{ "SUBI    $dst, $src1, $src2" %}
8577
8578  size(4);
8579  ins_encode %{
8580    // TODO: PPC port $archOpcode(ppc64Opcode_subfic);
8581    __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
8582  %}
8583  ins_pipe(pipe_class_default);
8584%}
8585
8586// Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for
8587// positive integers and 0xF...F for negative ones.
8588instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
8589  // no match-rule, false predicate
8590  effect(DEF dst, USE src);
8591  predicate(false);
8592
8593  format %{ "SRAWI   $dst, $src, #31" %}
8594  size(4);
8595  ins_encode %{
8596    // TODO: PPC port $archOpcode(ppc64Opcode_srawi);
8597    __ srawi($dst$$Register, $src$$Register, 0x1f);
8598  %}
8599  ins_pipe(pipe_class_default);
8600%}
8601
8602instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{
8603  match(Set dst (AbsI src));
8604  ins_cost(DEFAULT_COST*3);
8605
8606  expand %{
8607    iRegIdst tmp1;
8608    iRegIdst tmp2;
8609    signmask32I_regI(tmp1, src);
8610    xorI_reg_reg(tmp2, tmp1, src);
8611    subI_reg_reg(dst, tmp2, tmp1);
8612  %}
8613%}
8614
8615instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
8616  match(Set dst (SubI zero src2));
8617  format %{ "NEG     $dst, $src2" %}
8618  size(4);
8619  ins_encode %{
8620    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
8621    __ neg($dst$$Register, $src2$$Register);
8622  %}
8623  ins_pipe(pipe_class_default);
8624%}
8625
8626// Long subtraction
8627instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8628  match(Set dst (SubL src1 src2));
8629  format %{ "SUBF    $dst, $src2, $src1 \t// long" %}
8630  size(4);
8631  ins_encode %{
8632    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
8633    __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8634  %}
8635  ins_pipe(pipe_class_default);
8636%}
8637
8638// SubL + convL2I.
8639instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
8640  match(Set dst (ConvL2I (SubL src1 src2)));
8641
8642  format %{ "SUBF    $dst, $src2, $src1 \t// long + l2i" %}
8643  size(4);
8644  ins_encode %{
8645    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
8646    __ subf($dst$$Register, $src2$$Register, $src1$$Register);
8647  %}
8648  ins_pipe(pipe_class_default);
8649%}
8650
8651// Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8652// positive longs and 0xF...F for negative ones.
8653instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
8654  // no match-rule, false predicate
8655  effect(DEF dst, USE src);
8656  predicate(false);
8657
8658  format %{ "SRADI   $dst, $src, #63" %}
8659  size(4);
8660  ins_encode %{
8661    // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
8662    __ sradi($dst$$Register, $src$$Register, 0x3f);
8663  %}
8664  ins_pipe(pipe_class_default);
8665%}
8666
8667// Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
8668// positive longs and 0xF...F for negative ones.
8669instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
8670  // no match-rule, false predicate
8671  effect(DEF dst, USE src);
8672  predicate(false);
8673
8674  format %{ "SRADI   $dst, $src, #63" %}
8675  size(4);
8676  ins_encode %{
8677    // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
8678    __ sradi($dst$$Register, $src$$Register, 0x3f);
8679  %}
8680  ins_pipe(pipe_class_default);
8681%}
8682
8683// Long negation
8684instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
8685  match(Set dst (SubL zero src2));
8686  format %{ "NEG     $dst, $src2 \t// long" %}
8687  size(4);
8688  ins_encode %{
8689    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
8690    __ neg($dst$$Register, $src2$$Register);
8691  %}
8692  ins_pipe(pipe_class_default);
8693%}
8694
8695// NegL + ConvL2I.
8696instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
8697  match(Set dst (ConvL2I (SubL zero src2)));
8698
8699  format %{ "NEG     $dst, $src2 \t// long + l2i" %}
8700  size(4);
8701  ins_encode %{
8702    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
8703    __ neg($dst$$Register, $src2$$Register);
8704  %}
8705  ins_pipe(pipe_class_default);
8706%}
8707
8708// Multiplication Instructions
8709// Integer Multiplication
8710
8711// Register Multiplication
8712instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8713  match(Set dst (MulI src1 src2));
8714  ins_cost(DEFAULT_COST);
8715
8716  format %{ "MULLW   $dst, $src1, $src2" %}
8717  size(4);
8718  ins_encode %{
8719    // TODO: PPC port $archOpcode(ppc64Opcode_mullw);
8720    __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
8721  %}
8722  ins_pipe(pipe_class_default);
8723%}
8724
8725// Immediate Multiplication
8726instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
8727  match(Set dst (MulI src1 src2));
8728  ins_cost(DEFAULT_COST);
8729
8730  format %{ "MULLI   $dst, $src1, $src2" %}
8731  size(4);
8732  ins_encode %{
8733    // TODO: PPC port $archOpcode(ppc64Opcode_mulli);
8734    __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8735  %}
8736  ins_pipe(pipe_class_default);
8737%}
8738
8739instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8740  match(Set dst (MulL src1 src2));
8741  ins_cost(DEFAULT_COST);
8742
8743  format %{ "MULLD   $dst $src1, $src2 \t// long" %}
8744  size(4);
8745  ins_encode %{
8746    // TODO: PPC port $archOpcode(ppc64Opcode_mulld);
8747    __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
8748  %}
8749  ins_pipe(pipe_class_default);
8750%}
8751
8752// Multiply high for optimized long division by constant.
8753instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8754  match(Set dst (MulHiL src1 src2));
8755  ins_cost(DEFAULT_COST);
8756
8757  format %{ "MULHD   $dst $src1, $src2 \t// long" %}
8758  size(4);
8759  ins_encode %{
8760    // TODO: PPC port $archOpcode(ppc64Opcode_mulhd);
8761    __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
8762  %}
8763  ins_pipe(pipe_class_default);
8764%}
8765
8766// Immediate Multiplication
8767instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
8768  match(Set dst (MulL src1 src2));
8769  ins_cost(DEFAULT_COST);
8770
8771  format %{ "MULLI   $dst, $src1, $src2" %}
8772  size(4);
8773  ins_encode %{
8774    // TODO: PPC port $archOpcode(ppc64Opcode_mulli);
8775    __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
8776  %}
8777  ins_pipe(pipe_class_default);
8778%}
8779
8780// Integer Division with Immediate -1: Negate.
8781instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
8782  match(Set dst (DivI src1 src2));
8783  ins_cost(DEFAULT_COST);
8784
8785  format %{ "NEG     $dst, $src1 \t// /-1" %}
8786  size(4);
8787  ins_encode %{
8788    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
8789    __ neg($dst$$Register, $src1$$Register);
8790  %}
8791  ins_pipe(pipe_class_default);
8792%}
8793
8794// Integer Division with constant, but not -1.
8795// We should be able to improve this by checking the type of src2.
8796// It might well be that src2 is known to be positive.
8797instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8798  match(Set dst (DivI src1 src2));
8799  predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1
8800  ins_cost(2*DEFAULT_COST);
8801
8802  format %{ "DIVW    $dst, $src1, $src2 \t// /not-1" %}
8803  size(4);
8804  ins_encode %{
8805    // TODO: PPC port $archOpcode(ppc64Opcode_divw);
8806    __ divw($dst$$Register, $src1$$Register, $src2$$Register);
8807  %}
8808  ins_pipe(pipe_class_default);
8809%}
8810
8811instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
8812  effect(USE_DEF dst, USE src1, USE crx);
8813  predicate(false);
8814
8815  ins_variable_size_depending_on_alignment(true);
8816
8817  format %{ "CMOVE   $dst, neg($src1), $crx" %}
8818  // Worst case is branch + move + stop, no stop without scheduler.
8819  size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
8820  ins_encode %{
8821    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
8822    Label done;
8823    __ bne($crx$$CondRegister, done);
8824    __ neg($dst$$Register, $src1$$Register);
8825    // TODO PPC port __ endgroup_if_needed(_size == 12);
8826    __ bind(done);
8827  %}
8828  ins_pipe(pipe_class_default);
8829%}
8830
8831// Integer Division with Registers not containing constants.
8832instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8833  match(Set dst (DivI src1 src2));
8834  ins_cost(10*DEFAULT_COST);
8835
8836  expand %{
8837    immI16 imm %{ (int)-1 %}
8838    flagsReg tmp1;
8839    cmpI_reg_imm16(tmp1, src2, imm);          // check src2 == -1
8840    divI_reg_regnotMinus1(dst, src1, src2);   // dst = src1 / src2
8841    cmovI_bne_negI_reg(dst, tmp1, src1);      // cmove dst = neg(src1) if src2 == -1
8842  %}
8843%}
8844
8845// Long Division with Immediate -1: Negate.
8846instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
8847  match(Set dst (DivL src1 src2));
8848  ins_cost(DEFAULT_COST);
8849
8850  format %{ "NEG     $dst, $src1 \t// /-1, long" %}
8851  size(4);
8852  ins_encode %{
8853    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
8854    __ neg($dst$$Register, $src1$$Register);
8855  %}
8856  ins_pipe(pipe_class_default);
8857%}
8858
8859// Long Division with constant, but not -1.
8860instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8861  match(Set dst (DivL src1 src2));
8862  predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1.
8863  ins_cost(2*DEFAULT_COST);
8864
8865  format %{ "DIVD    $dst, $src1, $src2 \t// /not-1, long" %}
8866  size(4);
8867  ins_encode %{
8868    // TODO: PPC port $archOpcode(ppc64Opcode_divd);
8869    __ divd($dst$$Register, $src1$$Register, $src2$$Register);
8870  %}
8871  ins_pipe(pipe_class_default);
8872%}
8873
8874instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
8875  effect(USE_DEF dst, USE src1, USE crx);
8876  predicate(false);
8877
8878  ins_variable_size_depending_on_alignment(true);
8879
8880  format %{ "CMOVE   $dst, neg($src1), $crx" %}
8881  // Worst case is branch + move + stop, no stop without scheduler.
8882  size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
8883  ins_encode %{
8884    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
8885    Label done;
8886    __ bne($crx$$CondRegister, done);
8887    __ neg($dst$$Register, $src1$$Register);
8888    // TODO PPC port __ endgroup_if_needed(_size == 12);
8889    __ bind(done);
8890  %}
8891  ins_pipe(pipe_class_default);
8892%}
8893
8894// Long Division with Registers not containing constants.
8895instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8896  match(Set dst (DivL src1 src2));
8897  ins_cost(10*DEFAULT_COST);
8898
8899  expand %{
8900    immL16 imm %{ (int)-1 %}
8901    flagsReg tmp1;
8902    cmpL_reg_imm16(tmp1, src2, imm);          // check src2 == -1
8903    divL_reg_regnotMinus1(dst, src1, src2);   // dst = src1 / src2
8904    cmovL_bne_negL_reg(dst, tmp1, src1);      // cmove dst = neg(src1) if src2 == -1
8905  %}
8906%}
8907
8908// Integer Remainder with registers.
8909instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8910  match(Set dst (ModI src1 src2));
8911  ins_cost(10*DEFAULT_COST);
8912
8913  expand %{
8914    immI16 imm %{ (int)-1 %}
8915    flagsReg tmp1;
8916    iRegIdst tmp2;
8917    iRegIdst tmp3;
8918    cmpI_reg_imm16(tmp1, src2, imm);           // check src2 == -1
8919    divI_reg_regnotMinus1(tmp2, src1, src2);   // tmp2 = src1 / src2
8920    cmovI_bne_negI_reg(tmp2, tmp1, src1);      // cmove tmp2 = neg(src1) if src2 == -1
8921    mulI_reg_reg(tmp3, src2, tmp2);            // tmp3 = src2 * tmp2
8922    subI_reg_reg(dst, src1, tmp3);             // dst = src1 - tmp3
8923  %}
8924%}
8925
8926// Long Remainder with registers
8927instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
8928  match(Set dst (ModL src1 src2));
8929  ins_cost(10*DEFAULT_COST);
8930
8931  expand %{
8932    immL16 imm %{ (int)-1 %}
8933    flagsReg tmp1;
8934    iRegLdst tmp2;
8935    iRegLdst tmp3;
8936    cmpL_reg_imm16(tmp1, src2, imm);             // check src2 == -1
8937    divL_reg_regnotMinus1(tmp2, src1, src2);     // tmp2 = src1 / src2
8938    cmovL_bne_negL_reg(tmp2, tmp1, src1);        // cmove tmp2 = neg(src1) if src2 == -1
8939    mulL_reg_reg(tmp3, src2, tmp2);              // tmp3 = src2 * tmp2
8940    subL_reg_reg(dst, src1, tmp3);               // dst = src1 - tmp3
8941  %}
8942%}
8943
8944// Integer Shift Instructions
8945
8946// Register Shift Left
8947
8948// Clear all but the lowest #mask bits.
8949// Used to normalize shift amounts in registers.
8950instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
8951  // no match-rule, false predicate
8952  effect(DEF dst, USE src, USE mask);
8953  predicate(false);
8954
8955  format %{ "MASK    $dst, $src, $mask \t// clear $mask upper bits" %}
8956  size(4);
8957  ins_encode %{
8958    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
8959    __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
8960  %}
8961  ins_pipe(pipe_class_default);
8962%}
8963
8964instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8965  // no match-rule, false predicate
8966  effect(DEF dst, USE src1, USE src2);
8967  predicate(false);
8968
8969  format %{ "SLW     $dst, $src1, $src2" %}
8970  size(4);
8971  ins_encode %{
8972    // TODO: PPC port $archOpcode(ppc64Opcode_slw);
8973    __ slw($dst$$Register, $src1$$Register, $src2$$Register);
8974  %}
8975  ins_pipe(pipe_class_default);
8976%}
8977
8978instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
8979  match(Set dst (LShiftI src1 src2));
8980  ins_cost(DEFAULT_COST*2);
8981  expand %{
8982    uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
8983    iRegIdst tmpI;
8984    maskI_reg_imm(tmpI, src2, mask);
8985    lShiftI_reg_reg(dst, src1, tmpI);
8986  %}
8987%}
8988
8989// Register Shift Left Immediate
8990instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
8991  match(Set dst (LShiftI src1 src2));
8992
8993  format %{ "SLWI    $dst, $src1, ($src2 & 0x1f)" %}
8994  size(4);
8995  ins_encode %{
8996    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
8997    __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
8998  %}
8999  ins_pipe(pipe_class_default);
9000%}
9001
9002// AndI with negpow2-constant + LShiftI
9003instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
9004  match(Set dst (LShiftI (AndI src1 src2) src3));
9005  predicate(UseRotateAndMaskInstructionsPPC64);
9006
9007  format %{ "RLWINM  $dst, lShiftI(AndI($src1, $src2), $src3)" %}
9008  size(4);
9009  ins_encode %{
9010    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi
9011    long src2      = $src2$$constant;
9012    long src3      = $src3$$constant;
9013    long maskbits  = src3 + log2_long((jlong) (julong) (juint) -src2);
9014    if (maskbits >= 32) {
9015      __ li($dst$$Register, 0); // addi
9016    } else {
9017      __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f);
9018    }
9019  %}
9020  ins_pipe(pipe_class_default);
9021%}
9022
9023// RShiftI + AndI with negpow2-constant + LShiftI
9024instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{
9025  match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3));
9026  predicate(UseRotateAndMaskInstructionsPPC64);
9027
9028  format %{ "RLWINM  $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
9029  size(4);
9030  ins_encode %{
9031    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi
9032    long src2      = $src2$$constant;
9033    long src3      = $src3$$constant;
9034    long maskbits  = src3 + log2_long((jlong) (julong) (juint) -src2);
9035    if (maskbits >= 32) {
9036      __ li($dst$$Register, 0); // addi
9037    } else {
9038      __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f);
9039    }
9040  %}
9041  ins_pipe(pipe_class_default);
9042%}
9043
9044instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9045  // no match-rule, false predicate
9046  effect(DEF dst, USE src1, USE src2);
9047  predicate(false);
9048
9049  format %{ "SLD     $dst, $src1, $src2" %}
9050  size(4);
9051  ins_encode %{
9052    // TODO: PPC port $archOpcode(ppc64Opcode_sld);
9053    __ sld($dst$$Register, $src1$$Register, $src2$$Register);
9054  %}
9055  ins_pipe(pipe_class_default);
9056%}
9057
9058// Register Shift Left
9059instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9060  match(Set dst (LShiftL src1 src2));
9061  ins_cost(DEFAULT_COST*2);
9062  expand %{
9063    uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
9064    iRegIdst tmpI;
9065    maskI_reg_imm(tmpI, src2, mask);
9066    lShiftL_regL_regI(dst, src1, tmpI);
9067  %}
9068%}
9069
9070// Register Shift Left Immediate
9071instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
9072  match(Set dst (LShiftL src1 src2));
9073  format %{ "SLDI    $dst, $src1, ($src2 & 0x3f)" %}
9074  size(4);
9075  ins_encode %{
9076    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
9077    __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9078  %}
9079  ins_pipe(pipe_class_default);
9080%}
9081
9082// If we shift more than 32 bits, we need not convert I2L.
9083instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
9084  match(Set dst (LShiftL (ConvI2L src1) src2));
9085  ins_cost(DEFAULT_COST);
9086
9087  size(4);
9088  format %{ "SLDI    $dst, i2l($src1), $src2" %}
9089  ins_encode %{
9090    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
9091    __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9092  %}
9093  ins_pipe(pipe_class_default);
9094%}
9095
9096// Shift a postivie int to the left.
9097// Clrlsldi clears the upper 32 bits and shifts.
9098instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{
9099  match(Set dst (LShiftL (ConvI2L src1) src2));
9100  predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int());
9101
9102  format %{ "SLDI    $dst, i2l(positive_int($src1)), $src2" %}
9103  size(4);
9104  ins_encode %{
9105    // TODO: PPC port $archOpcode(ppc64Opcode_rldic);
9106    __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
9107  %}
9108  ins_pipe(pipe_class_default);
9109%}
9110
9111instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9112  // no match-rule, false predicate
9113  effect(DEF dst, USE src1, USE src2);
9114  predicate(false);
9115
9116  format %{ "SRAW    $dst, $src1, $src2" %}
9117  size(4);
9118  ins_encode %{
9119    // TODO: PPC port $archOpcode(ppc64Opcode_sraw);
9120    __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
9121  %}
9122  ins_pipe(pipe_class_default);
9123%}
9124
9125// Register Arithmetic Shift Right
9126instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9127  match(Set dst (RShiftI src1 src2));
9128  ins_cost(DEFAULT_COST*2);
9129  expand %{
9130    uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
9131    iRegIdst tmpI;
9132    maskI_reg_imm(tmpI, src2, mask);
9133    arShiftI_reg_reg(dst, src1, tmpI);
9134  %}
9135%}
9136
9137// Register Arithmetic Shift Right Immediate
9138instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
9139  match(Set dst (RShiftI src1 src2));
9140
9141  format %{ "SRAWI   $dst, $src1, ($src2 & 0x1f)" %}
9142  size(4);
9143  ins_encode %{
9144    // TODO: PPC port $archOpcode(ppc64Opcode_srawi);
9145    __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
9146  %}
9147  ins_pipe(pipe_class_default);
9148%}
9149
9150instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9151  // no match-rule, false predicate
9152  effect(DEF dst, USE src1, USE src2);
9153  predicate(false);
9154
9155  format %{ "SRAD    $dst, $src1, $src2" %}
9156  size(4);
9157  ins_encode %{
9158    // TODO: PPC port $archOpcode(ppc64Opcode_srad);
9159    __ srad($dst$$Register, $src1$$Register, $src2$$Register);
9160  %}
9161  ins_pipe(pipe_class_default);
9162%}
9163
9164// Register Shift Right Arithmetic Long
9165instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9166  match(Set dst (RShiftL src1 src2));
9167  ins_cost(DEFAULT_COST*2);
9168
9169  expand %{
9170    uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
9171    iRegIdst tmpI;
9172    maskI_reg_imm(tmpI, src2, mask);
9173    arShiftL_regL_regI(dst, src1, tmpI);
9174  %}
9175%}
9176
9177// Register Shift Right Immediate
9178instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
9179  match(Set dst (RShiftL src1 src2));
9180
9181  format %{ "SRADI   $dst, $src1, ($src2 & 0x3f)" %}
9182  size(4);
9183  ins_encode %{
9184    // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
9185    __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9186  %}
9187  ins_pipe(pipe_class_default);
9188%}
9189
9190// RShiftL + ConvL2I
9191instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
9192  match(Set dst (ConvL2I (RShiftL src1 src2)));
9193
9194  format %{ "SRADI   $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
9195  size(4);
9196  ins_encode %{
9197    // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
9198    __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9199  %}
9200  ins_pipe(pipe_class_default);
9201%}
9202
9203instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9204  // no match-rule, false predicate
9205  effect(DEF dst, USE src1, USE src2);
9206  predicate(false);
9207
9208  format %{ "SRW     $dst, $src1, $src2" %}
9209  size(4);
9210  ins_encode %{
9211    // TODO: PPC port $archOpcode(ppc64Opcode_srw);
9212    __ srw($dst$$Register, $src1$$Register, $src2$$Register);
9213  %}
9214  ins_pipe(pipe_class_default);
9215%}
9216
9217// Register Shift Right
9218instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9219  match(Set dst (URShiftI src1 src2));
9220  ins_cost(DEFAULT_COST*2);
9221
9222  expand %{
9223    uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %}
9224    iRegIdst tmpI;
9225    maskI_reg_imm(tmpI, src2, mask);
9226    urShiftI_reg_reg(dst, src1, tmpI);
9227  %}
9228%}
9229
9230// Register Shift Right Immediate
9231instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
9232  match(Set dst (URShiftI src1 src2));
9233
9234  format %{ "SRWI    $dst, $src1, ($src2 & 0x1f)" %}
9235  size(4);
9236  ins_encode %{
9237    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
9238    __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
9239  %}
9240  ins_pipe(pipe_class_default);
9241%}
9242
9243instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9244  // no match-rule, false predicate
9245  effect(DEF dst, USE src1, USE src2);
9246  predicate(false);
9247
9248  format %{ "SRD     $dst, $src1, $src2" %}
9249  size(4);
9250  ins_encode %{
9251    // TODO: PPC port $archOpcode(ppc64Opcode_srd);
9252    __ srd($dst$$Register, $src1$$Register, $src2$$Register);
9253  %}
9254  ins_pipe(pipe_class_default);
9255%}
9256
9257// Register Shift Right
9258instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
9259  match(Set dst (URShiftL src1 src2));
9260  ins_cost(DEFAULT_COST*2);
9261
9262  expand %{
9263    uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %}
9264    iRegIdst tmpI;
9265    maskI_reg_imm(tmpI, src2, mask);
9266    urShiftL_regL_regI(dst, src1, tmpI);
9267  %}
9268%}
9269
9270// Register Shift Right Immediate
9271instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
9272  match(Set dst (URShiftL src1 src2));
9273
9274  format %{ "SRDI    $dst, $src1, ($src2 & 0x3f)" %}
9275  size(4);
9276  ins_encode %{
9277    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
9278    __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9279  %}
9280  ins_pipe(pipe_class_default);
9281%}
9282
9283// URShiftL + ConvL2I.
9284instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
9285  match(Set dst (ConvL2I (URShiftL src1 src2)));
9286
9287  format %{ "SRDI    $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
9288  size(4);
9289  ins_encode %{
9290    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
9291    __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9292  %}
9293  ins_pipe(pipe_class_default);
9294%}
9295
9296// Register Shift Right Immediate with a CastP2X
9297instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
9298  match(Set dst (URShiftL (CastP2X src1) src2));
9299
9300  format %{ "SRDI    $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
9301  size(4);
9302  ins_encode %{
9303    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
9304    __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
9305  %}
9306  ins_pipe(pipe_class_default);
9307%}
9308
9309instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
9310  match(Set dst (ConvL2I (ConvI2L src)));
9311
9312  format %{ "EXTSW   $dst, $src \t// int->int" %}
9313  size(4);
9314  ins_encode %{
9315    // TODO: PPC port $archOpcode(ppc64Opcode_extsw);
9316    __ extsw($dst$$Register, $src$$Register);
9317  %}
9318  ins_pipe(pipe_class_default);
9319%}
9320
9321//----------Rotate Instructions------------------------------------------------
9322
9323// Rotate Left by 8-bit immediate
9324instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{
9325  match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift)));
9326  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9327
9328  format %{ "ROTLWI  $dst, $src, $lshift" %}
9329  size(4);
9330  ins_encode %{
9331    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
9332    __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
9333  %}
9334  ins_pipe(pipe_class_default);
9335%}
9336
9337// Rotate Right by 8-bit immediate
9338instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{
9339  match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift)));
9340  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9341
9342  format %{ "ROTRWI  $dst, $rshift" %}
9343  size(4);
9344  ins_encode %{
9345    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
9346    __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
9347  %}
9348  ins_pipe(pipe_class_default);
9349%}
9350
9351//----------Floating Point Arithmetic Instructions-----------------------------
9352
9353// Add float single precision
9354instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
9355  match(Set dst (AddF src1 src2));
9356
9357  format %{ "FADDS   $dst, $src1, $src2" %}
9358  size(4);
9359  ins_encode %{
9360    // TODO: PPC port $archOpcode(ppc64Opcode_fadds);
9361    __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9362  %}
9363  ins_pipe(pipe_class_default);
9364%}
9365
9366// Add float double precision
9367instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
9368  match(Set dst (AddD src1 src2));
9369
9370  format %{ "FADD    $dst, $src1, $src2" %}
9371  size(4);
9372  ins_encode %{
9373    // TODO: PPC port $archOpcode(ppc64Opcode_fadd);
9374    __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9375  %}
9376  ins_pipe(pipe_class_default);
9377%}
9378
9379// Sub float single precision
9380instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
9381  match(Set dst (SubF src1 src2));
9382
9383  format %{ "FSUBS   $dst, $src1, $src2" %}
9384  size(4);
9385  ins_encode %{
9386    // TODO: PPC port $archOpcode(ppc64Opcode_fsubs);
9387    __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9388  %}
9389  ins_pipe(pipe_class_default);
9390%}
9391
9392// Sub float double precision
9393instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
9394  match(Set dst (SubD src1 src2));
9395  format %{ "FSUB    $dst, $src1, $src2" %}
9396  size(4);
9397  ins_encode %{
9398    // TODO: PPC port $archOpcode(ppc64Opcode_fsub);
9399    __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9400  %}
9401  ins_pipe(pipe_class_default);
9402%}
9403
9404// Mul float single precision
9405instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
9406  match(Set dst (MulF src1 src2));
9407  format %{ "FMULS   $dst, $src1, $src2" %}
9408  size(4);
9409  ins_encode %{
9410    // TODO: PPC port $archOpcode(ppc64Opcode_fmuls);
9411    __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9412  %}
9413  ins_pipe(pipe_class_default);
9414%}
9415
9416// Mul float double precision
9417instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
9418  match(Set dst (MulD src1 src2));
9419  format %{ "FMUL    $dst, $src1, $src2" %}
9420  size(4);
9421  ins_encode %{
9422    // TODO: PPC port $archOpcode(ppc64Opcode_fmul);
9423    __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9424  %}
9425  ins_pipe(pipe_class_default);
9426%}
9427
9428// Div float single precision
9429instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
9430  match(Set dst (DivF src1 src2));
9431  format %{ "FDIVS   $dst, $src1, $src2" %}
9432  size(4);
9433  ins_encode %{
9434    // TODO: PPC port $archOpcode(ppc64Opcode_fdivs);
9435    __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9436  %}
9437  ins_pipe(pipe_class_default);
9438%}
9439
9440// Div float double precision
9441instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
9442  match(Set dst (DivD src1 src2));
9443  format %{ "FDIV    $dst, $src1, $src2" %}
9444  size(4);
9445  ins_encode %{
9446    // TODO: PPC port $archOpcode(ppc64Opcode_fdiv);
9447    __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
9448  %}
9449  ins_pipe(pipe_class_default);
9450%}
9451
9452// Absolute float single precision
9453instruct absF_reg(regF dst, regF src) %{
9454  match(Set dst (AbsF src));
9455  format %{ "FABS    $dst, $src \t// float" %}
9456  size(4);
9457  ins_encode %{
9458    // TODO: PPC port $archOpcode(ppc64Opcode_fabs);
9459    __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9460  %}
9461  ins_pipe(pipe_class_default);
9462%}
9463
9464// Absolute float double precision
9465instruct absD_reg(regD dst, regD src) %{
9466  match(Set dst (AbsD src));
9467  format %{ "FABS    $dst, $src \t// double" %}
9468  size(4);
9469  ins_encode %{
9470    // TODO: PPC port $archOpcode(ppc64Opcode_fabs);
9471    __ fabs($dst$$FloatRegister, $src$$FloatRegister);
9472  %}
9473  ins_pipe(pipe_class_default);
9474%}
9475
9476instruct negF_reg(regF dst, regF src) %{
9477  match(Set dst (NegF src));
9478  format %{ "FNEG    $dst, $src \t// float" %}
9479  size(4);
9480  ins_encode %{
9481    // TODO: PPC port $archOpcode(ppc64Opcode_fneg);
9482    __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9483  %}
9484  ins_pipe(pipe_class_default);
9485%}
9486
9487instruct negD_reg(regD dst, regD src) %{
9488  match(Set dst (NegD src));
9489  format %{ "FNEG    $dst, $src \t// double" %}
9490  size(4);
9491  ins_encode %{
9492    // TODO: PPC port $archOpcode(ppc64Opcode_fneg);
9493    __ fneg($dst$$FloatRegister, $src$$FloatRegister);
9494  %}
9495  ins_pipe(pipe_class_default);
9496%}
9497
9498// AbsF + NegF.
9499instruct negF_absF_reg(regF dst, regF src) %{
9500  match(Set dst (NegF (AbsF src)));
9501  format %{ "FNABS   $dst, $src \t// float" %}
9502  size(4);
9503  ins_encode %{
9504    // TODO: PPC port $archOpcode(ppc64Opcode_fnabs);
9505    __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9506  %}
9507  ins_pipe(pipe_class_default);
9508%}
9509
9510// AbsD + NegD.
9511instruct negD_absD_reg(regD dst, regD src) %{
9512  match(Set dst (NegD (AbsD src)));
9513  format %{ "FNABS   $dst, $src \t// double" %}
9514  size(4);
9515  ins_encode %{
9516    // TODO: PPC port $archOpcode(ppc64Opcode_fnabs);
9517    __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
9518  %}
9519  ins_pipe(pipe_class_default);
9520%}
9521
9522// VM_Version::has_fsqrt() decides if this node will be used.
9523// Sqrt float double precision
9524instruct sqrtD_reg(regD dst, regD src) %{
9525  match(Set dst (SqrtD src));
9526  format %{ "FSQRT   $dst, $src" %}
9527  size(4);
9528  ins_encode %{
9529    // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt);
9530    __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
9531  %}
9532  ins_pipe(pipe_class_default);
9533%}
9534
9535// Single-precision sqrt.
9536instruct sqrtF_reg(regF dst, regF src) %{
9537  match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
9538  predicate(VM_Version::has_fsqrts());
9539  ins_cost(DEFAULT_COST);
9540
9541  format %{ "FSQRTS  $dst, $src" %}
9542  size(4);
9543  ins_encode %{
9544    // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts);
9545    __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
9546  %}
9547  ins_pipe(pipe_class_default);
9548%}
9549
9550instruct roundDouble_nop(regD dst) %{
9551  match(Set dst (RoundDouble dst));
9552  ins_cost(0);
9553
9554  format %{ " -- \t// RoundDouble not needed - empty" %}
9555  size(0);
9556  // PPC results are already "rounded" (i.e., normal-format IEEE).
9557  ins_encode( /*empty*/ );
9558  ins_pipe(pipe_class_default);
9559%}
9560
9561instruct roundFloat_nop(regF dst) %{
9562  match(Set dst (RoundFloat dst));
9563  ins_cost(0);
9564
9565  format %{ " -- \t// RoundFloat not needed - empty" %}
9566  size(0);
9567  // PPC results are already "rounded" (i.e., normal-format IEEE).
9568  ins_encode( /*empty*/ );
9569  ins_pipe(pipe_class_default);
9570%}
9571
9572
9573// Multiply-Accumulate
9574// src1 * src2 + src3
9575instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9576  match(Set dst (FmaF src3 (Binary src1 src2)));
9577
9578  format %{ "FMADDS  $dst, $src1, $src2, $src3" %}
9579  size(4);
9580  ins_encode %{
9581    // TODO: PPC port $archOpcode(ppc64Opcode_fmadds);
9582    __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9583  %}
9584  ins_pipe(pipe_class_default);
9585%}
9586
9587// src1 * src2 + src3
9588instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9589  match(Set dst (FmaD src3 (Binary src1 src2)));
9590
9591  format %{ "FMADD   $dst, $src1, $src2, $src3" %}
9592  size(4);
9593  ins_encode %{
9594    // TODO: PPC port $archOpcode(ppc64Opcode_fmadd);
9595    __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9596  %}
9597  ins_pipe(pipe_class_default);
9598%}
9599
9600// -src1 * src2 + src3 = -(src1*src2-src3)
9601instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9602  match(Set dst (FmaF src3 (Binary (NegF src1) src2)));
9603  match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
9604
9605  format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
9606  size(4);
9607  ins_encode %{
9608    // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs);
9609    __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9610  %}
9611  ins_pipe(pipe_class_default);
9612%}
9613
9614// -src1 * src2 + src3 = -(src1*src2-src3)
9615instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9616  match(Set dst (FmaD src3 (Binary (NegD src1) src2)));
9617  match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
9618
9619  format %{ "FNMSUB  $dst, $src1, $src2, $src3" %}
9620  size(4);
9621  ins_encode %{
9622    // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub);
9623    __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9624  %}
9625  ins_pipe(pipe_class_default);
9626%}
9627
9628// -src1 * src2 - src3 = -(src1*src2+src3)
9629instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9630  match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2)));
9631  match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
9632
9633  format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
9634  size(4);
9635  ins_encode %{
9636    // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds);
9637    __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9638  %}
9639  ins_pipe(pipe_class_default);
9640%}
9641
9642// -src1 * src2 - src3 = -(src1*src2+src3)
9643instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9644  match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2)));
9645  match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
9646
9647  format %{ "FNMADD  $dst, $src1, $src2, $src3" %}
9648  size(4);
9649  ins_encode %{
9650    // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd);
9651    __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9652  %}
9653  ins_pipe(pipe_class_default);
9654%}
9655
9656// src1 * src2 - src3
9657instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
9658  match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
9659
9660  format %{ "FMSUBS  $dst, $src1, $src2, $src3" %}
9661  size(4);
9662  ins_encode %{
9663    // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs);
9664    __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9665  %}
9666  ins_pipe(pipe_class_default);
9667%}
9668
9669// src1 * src2 - src3
9670instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
9671  match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
9672
9673  format %{ "FMSUB   $dst, $src1, $src2, $src3" %}
9674  size(4);
9675  ins_encode %{
9676    // TODO: PPC port $archOpcode(ppc64Opcode_fmsub);
9677    __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
9678  %}
9679  ins_pipe(pipe_class_default);
9680%}
9681
9682
9683//----------Logical Instructions-----------------------------------------------
9684
9685// And Instructions
9686
9687// Register And
9688instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9689  match(Set dst (AndI src1 src2));
9690  format %{ "AND     $dst, $src1, $src2" %}
9691  size(4);
9692  ins_encode %{
9693    // TODO: PPC port $archOpcode(ppc64Opcode_and);
9694    __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9695  %}
9696  ins_pipe(pipe_class_default);
9697%}
9698
9699// Left shifted Immediate And
9700instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16  src2, flagsRegCR0 cr0) %{
9701  match(Set dst (AndI src1 src2));
9702  effect(KILL cr0);
9703  format %{ "ANDIS   $dst, $src1, $src2.hi" %}
9704  size(4);
9705  ins_encode %{
9706    // TODO: PPC port $archOpcode(ppc64Opcode_andis_);
9707    __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
9708  %}
9709  ins_pipe(pipe_class_default);
9710%}
9711
9712// Immediate And
9713instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{
9714  match(Set dst (AndI src1 src2));
9715  effect(KILL cr0);
9716
9717  format %{ "ANDI    $dst, $src1, $src2" %}
9718  size(4);
9719  ins_encode %{
9720    // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
9721    // FIXME: avoid andi_ ?
9722    __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9723  %}
9724  ins_pipe(pipe_class_default);
9725%}
9726
9727// Immediate And where the immediate is a negative power of 2.
9728instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
9729  match(Set dst (AndI src1 src2));
9730  format %{ "ANDWI   $dst, $src1, $src2" %}
9731  size(4);
9732  ins_encode %{
9733    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
9734    __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant)));
9735  %}
9736  ins_pipe(pipe_class_default);
9737%}
9738
9739instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{
9740  match(Set dst (AndI src1 src2));
9741  format %{ "ANDWI   $dst, $src1, $src2" %}
9742  size(4);
9743  ins_encode %{
9744    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
9745    __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1)));
9746  %}
9747  ins_pipe(pipe_class_default);
9748%}
9749
9750instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{
9751  match(Set dst (AndI src1 src2));
9752  predicate(UseRotateAndMaskInstructionsPPC64);
9753  format %{ "ANDWI   $dst, $src1, $src2" %}
9754  size(4);
9755  ins_encode %{
9756    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
9757    __ rlwinm($dst$$Register, $src1$$Register, 0,
9758              (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f);
9759  %}
9760  ins_pipe(pipe_class_default);
9761%}
9762
9763// Register And Long
9764instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9765  match(Set dst (AndL src1 src2));
9766  ins_cost(DEFAULT_COST);
9767
9768  format %{ "AND     $dst, $src1, $src2 \t// long" %}
9769  size(4);
9770  ins_encode %{
9771    // TODO: PPC port $archOpcode(ppc64Opcode_and);
9772    __ andr($dst$$Register, $src1$$Register, $src2$$Register);
9773  %}
9774  ins_pipe(pipe_class_default);
9775%}
9776
9777// Immediate And long
9778instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
9779  match(Set dst (AndL src1 src2));
9780  effect(KILL cr0);
9781
9782  format %{ "ANDI    $dst, $src1, $src2 \t// long" %}
9783  size(4);
9784  ins_encode %{
9785    // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
9786    // FIXME: avoid andi_ ?
9787    __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
9788  %}
9789  ins_pipe(pipe_class_default);
9790%}
9791
9792// Immediate And Long where the immediate is a negative power of 2.
9793instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
9794  match(Set dst (AndL src1 src2));
9795  format %{ "ANDDI   $dst, $src1, $src2" %}
9796  size(4);
9797  ins_encode %{
9798    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
9799    __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant));
9800  %}
9801  ins_pipe(pipe_class_default);
9802%}
9803
9804instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9805  match(Set dst (AndL src1 src2));
9806  format %{ "ANDDI   $dst, $src1, $src2" %}
9807  size(4);
9808  ins_encode %{
9809    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
9810    __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1)));
9811  %}
9812  ins_pipe(pipe_class_default);
9813%}
9814
9815// AndL + ConvL2I.
9816instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
9817  match(Set dst (ConvL2I (AndL src1 src2)));
9818  ins_cost(DEFAULT_COST);
9819
9820  format %{ "ANDDI   $dst, $src1, $src2 \t// long + l2i" %}
9821  size(4);
9822  ins_encode %{
9823    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
9824    __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1)));
9825  %}
9826  ins_pipe(pipe_class_default);
9827%}
9828
9829// Or Instructions
9830
9831// Register Or
9832instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9833  match(Set dst (OrI src1 src2));
9834  format %{ "OR      $dst, $src1, $src2" %}
9835  size(4);
9836  ins_encode %{
9837    // TODO: PPC port $archOpcode(ppc64Opcode_or);
9838    __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9839  %}
9840  ins_pipe(pipe_class_default);
9841%}
9842
9843// Expand does not work with above instruct. (??)
9844instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9845  // no match-rule
9846  effect(DEF dst, USE src1, USE src2);
9847  format %{ "OR      $dst, $src1, $src2" %}
9848  size(4);
9849  ins_encode %{
9850    // TODO: PPC port $archOpcode(ppc64Opcode_or);
9851    __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9852  %}
9853  ins_pipe(pipe_class_default);
9854%}
9855
9856instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9857  match(Set dst (OrI (OrI (OrI src1 src2) src3) src4));
9858  ins_cost(DEFAULT_COST*3);
9859
9860  expand %{
9861    // FIXME: we should do this in the ideal world.
9862    iRegIdst tmp1;
9863    iRegIdst tmp2;
9864    orI_reg_reg(tmp1, src1, src2);
9865    orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg.
9866    orI_reg_reg(dst, tmp1, tmp2);
9867  %}
9868%}
9869
9870// Immediate Or
9871instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9872  match(Set dst (OrI src1 src2));
9873  format %{ "ORI     $dst, $src1, $src2" %}
9874  size(4);
9875  ins_encode %{
9876    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
9877    __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
9878  %}
9879  ins_pipe(pipe_class_default);
9880%}
9881
9882// Register Or Long
9883instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9884  match(Set dst (OrL src1 src2));
9885  ins_cost(DEFAULT_COST);
9886
9887  size(4);
9888  format %{ "OR      $dst, $src1, $src2 \t// long" %}
9889  ins_encode %{
9890    // TODO: PPC port $archOpcode(ppc64Opcode_or);
9891    __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9892  %}
9893  ins_pipe(pipe_class_default);
9894%}
9895
9896// OrL + ConvL2I.
9897instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9898  match(Set dst (ConvL2I (OrL src1 src2)));
9899  ins_cost(DEFAULT_COST);
9900
9901  format %{ "OR      $dst, $src1, $src2 \t// long + l2i" %}
9902  size(4);
9903  ins_encode %{
9904    // TODO: PPC port $archOpcode(ppc64Opcode_or);
9905    __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
9906  %}
9907  ins_pipe(pipe_class_default);
9908%}
9909
9910// Immediate Or long
9911instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
9912  match(Set dst (OrL src1 con));
9913  ins_cost(DEFAULT_COST);
9914
9915  format %{ "ORI     $dst, $src1, $con \t// long" %}
9916  size(4);
9917  ins_encode %{
9918    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
9919    __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
9920  %}
9921  ins_pipe(pipe_class_default);
9922%}
9923
9924// Xor Instructions
9925
9926// Register Xor
9927instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9928  match(Set dst (XorI src1 src2));
9929  format %{ "XOR     $dst, $src1, $src2" %}
9930  size(4);
9931  ins_encode %{
9932    // TODO: PPC port $archOpcode(ppc64Opcode_xor);
9933    __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9934  %}
9935  ins_pipe(pipe_class_default);
9936%}
9937
9938// Expand does not work with above instruct. (??)
9939instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
9940  // no match-rule
9941  effect(DEF dst, USE src1, USE src2);
9942  format %{ "XOR     $dst, $src1, $src2" %}
9943  size(4);
9944  ins_encode %{
9945    // TODO: PPC port $archOpcode(ppc64Opcode_xor);
9946    __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9947  %}
9948  ins_pipe(pipe_class_default);
9949%}
9950
9951instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{
9952  match(Set dst (XorI (XorI (XorI src1 src2) src3) src4));
9953  ins_cost(DEFAULT_COST*3);
9954
9955  expand %{
9956    // FIXME: we should do this in the ideal world.
9957    iRegIdst tmp1;
9958    iRegIdst tmp2;
9959    xorI_reg_reg(tmp1, src1, src2);
9960    xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg.
9961    xorI_reg_reg(dst, tmp1, tmp2);
9962  %}
9963%}
9964
9965// Immediate Xor
9966instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
9967  match(Set dst (XorI src1 src2));
9968  format %{ "XORI    $dst, $src1, $src2" %}
9969  size(4);
9970  ins_encode %{
9971    // TODO: PPC port $archOpcode(ppc64Opcode_xori);
9972    __ xori($dst$$Register, $src1$$Register, $src2$$constant);
9973  %}
9974  ins_pipe(pipe_class_default);
9975%}
9976
9977// Register Xor Long
9978instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
9979  match(Set dst (XorL src1 src2));
9980  ins_cost(DEFAULT_COST);
9981
9982  format %{ "XOR     $dst, $src1, $src2 \t// long" %}
9983  size(4);
9984  ins_encode %{
9985    // TODO: PPC port $archOpcode(ppc64Opcode_xor);
9986    __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
9987  %}
9988  ins_pipe(pipe_class_default);
9989%}
9990
9991// XorL + ConvL2I.
9992instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
9993  match(Set dst (ConvL2I (XorL src1 src2)));
9994  ins_cost(DEFAULT_COST);
9995
9996  format %{ "XOR     $dst, $src1, $src2 \t// long + l2i" %}
9997  size(4);
9998  ins_encode %{
9999    // TODO: PPC port $archOpcode(ppc64Opcode_xor);
10000    __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
10001  %}
10002  ins_pipe(pipe_class_default);
10003%}
10004
10005// Immediate Xor Long
10006instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
10007  match(Set dst (XorL src1 src2));
10008  ins_cost(DEFAULT_COST);
10009
10010  format %{ "XORI    $dst, $src1, $src2 \t// long" %}
10011  size(4);
10012  ins_encode %{
10013    // TODO: PPC port $archOpcode(ppc64Opcode_xori);
10014    __ xori($dst$$Register, $src1$$Register, $src2$$constant);
10015  %}
10016  ins_pipe(pipe_class_default);
10017%}
10018
10019instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
10020  match(Set dst (XorI src1 src2));
10021  ins_cost(DEFAULT_COST);
10022
10023  format %{ "NOT     $dst, $src1 ($src2)" %}
10024  size(4);
10025  ins_encode %{
10026    // TODO: PPC port $archOpcode(ppc64Opcode_nor);
10027    __ nor($dst$$Register, $src1$$Register, $src1$$Register);
10028  %}
10029  ins_pipe(pipe_class_default);
10030%}
10031
10032instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
10033  match(Set dst (XorL src1 src2));
10034  ins_cost(DEFAULT_COST);
10035
10036  format %{ "NOT     $dst, $src1 ($src2) \t// long" %}
10037  size(4);
10038  ins_encode %{
10039    // TODO: PPC port $archOpcode(ppc64Opcode_nor);
10040    __ nor($dst$$Register, $src1$$Register, $src1$$Register);
10041  %}
10042  ins_pipe(pipe_class_default);
10043%}
10044
10045// And-complement
10046instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{
10047  match(Set dst (AndI (XorI src1 src2) src3));
10048  ins_cost(DEFAULT_COST);
10049
10050  format %{ "ANDW    $dst, xori($src1, $src2), $src3" %}
10051  size(4);
10052  ins_encode( enc_andc(dst, src3, src1) );
10053  ins_pipe(pipe_class_default);
10054%}
10055
10056// And-complement
10057instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
10058  // no match-rule, false predicate
10059  effect(DEF dst, USE src1, USE src2);
10060  predicate(false);
10061
10062  format %{ "ANDC    $dst, $src1, $src2" %}
10063  size(4);
10064  ins_encode %{
10065    // TODO: PPC port $archOpcode(ppc64Opcode_andc);
10066    __ andc($dst$$Register, $src1$$Register, $src2$$Register);
10067  %}
10068  ins_pipe(pipe_class_default);
10069%}
10070
10071//----------Moves between int/long and float/double----------------------------
10072//
10073// The following rules move values from int/long registers/stack-locations
10074// to float/double registers/stack-locations and vice versa, without doing any
10075// conversions. These rules are used to implement the bit-conversion methods
10076// of java.lang.Float etc., e.g.
10077//   int   floatToIntBits(float value)
10078//   float intBitsToFloat(int bits)
10079//
10080// Notes on the implementation on ppc64:
10081// We only provide rules which move between a register and a stack-location,
10082// because we always have to go through memory when moving between a float
10083// register and an integer register.
10084
10085//---------- Chain stack slots between similar types --------
10086
10087// These are needed so that the rules below can match.
10088
10089// Load integer from stack slot
10090instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{
10091  match(Set dst src);
10092  ins_cost(MEMORY_REF_COST);
10093
10094  format %{ "LWZ     $dst, $src" %}
10095  size(4);
10096  ins_encode( enc_lwz(dst, src) );
10097  ins_pipe(pipe_class_memory);
10098%}
10099
10100// Store integer to stack slot
10101instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{
10102  match(Set dst src);
10103  ins_cost(MEMORY_REF_COST);
10104
10105  format %{ "STW     $src, $dst \t// stk" %}
10106  size(4);
10107  ins_encode( enc_stw(src, dst) ); // rs=rt
10108  ins_pipe(pipe_class_memory);
10109%}
10110
10111// Load long from stack slot
10112instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{
10113  match(Set dst src);
10114  ins_cost(MEMORY_REF_COST);
10115
10116  format %{ "LD      $dst, $src \t// long" %}
10117  size(4);
10118  ins_encode( enc_ld(dst, src) );
10119  ins_pipe(pipe_class_memory);
10120%}
10121
10122// Store long to stack slot
10123instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{
10124  match(Set dst src);
10125  ins_cost(MEMORY_REF_COST);
10126
10127  format %{ "STD     $src, $dst \t// long" %}
10128  size(4);
10129  ins_encode( enc_std(src, dst) ); // rs=rt
10130  ins_pipe(pipe_class_memory);
10131%}
10132
10133//----------Moves between int and float
10134
10135// Move float value from float stack-location to integer register.
10136instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{
10137  match(Set dst (MoveF2I src));
10138  ins_cost(MEMORY_REF_COST);
10139
10140  format %{ "LWZ     $dst, $src \t// MoveF2I" %}
10141  size(4);
10142  ins_encode( enc_lwz(dst, src) );
10143  ins_pipe(pipe_class_memory);
10144%}
10145
10146// Move float value from float register to integer stack-location.
10147instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{
10148  match(Set dst (MoveF2I src));
10149  ins_cost(MEMORY_REF_COST);
10150
10151  format %{ "STFS    $src, $dst \t// MoveF2I" %}
10152  size(4);
10153  ins_encode( enc_stfs(src, dst) );
10154  ins_pipe(pipe_class_memory);
10155%}
10156
10157// Move integer value from integer stack-location to float register.
10158instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
10159  match(Set dst (MoveI2F src));
10160  ins_cost(MEMORY_REF_COST);
10161
10162  format %{ "LFS     $dst, $src \t// MoveI2F" %}
10163  size(4);
10164  ins_encode %{
10165    // TODO: PPC port $archOpcode(ppc64Opcode_lfs);
10166    int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
10167    __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
10168  %}
10169  ins_pipe(pipe_class_memory);
10170%}
10171
10172// Move integer value from integer register to float stack-location.
10173instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{
10174  match(Set dst (MoveI2F src));
10175  ins_cost(MEMORY_REF_COST);
10176
10177  format %{ "STW     $src, $dst \t// MoveI2F" %}
10178  size(4);
10179  ins_encode( enc_stw(src, dst) );
10180  ins_pipe(pipe_class_memory);
10181%}
10182
10183//----------Moves between long and float
10184
10185instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{
10186  // no match-rule, false predicate
10187  effect(DEF dst, USE src);
10188  predicate(false);
10189
10190  format %{ "storeD  $src, $dst \t// STACK" %}
10191  size(4);
10192  ins_encode( enc_stfd(src, dst) );
10193  ins_pipe(pipe_class_default);
10194%}
10195
10196//----------Moves between long and double
10197
10198// Move double value from double stack-location to long register.
10199instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{
10200  match(Set dst (MoveD2L src));
10201  ins_cost(MEMORY_REF_COST);
10202  size(4);
10203  format %{ "LD      $dst, $src \t// MoveD2L" %}
10204  ins_encode( enc_ld(dst, src) );
10205  ins_pipe(pipe_class_memory);
10206%}
10207
10208// Move double value from double register to long stack-location.
10209instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{
10210  match(Set dst (MoveD2L src));
10211  effect(DEF dst, USE src);
10212  ins_cost(MEMORY_REF_COST);
10213
10214  format %{ "STFD    $src, $dst \t// MoveD2L" %}
10215  size(4);
10216  ins_encode( enc_stfd(src, dst) );
10217  ins_pipe(pipe_class_memory);
10218%}
10219
10220// Move long value from long stack-location to double register.
10221instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{
10222  match(Set dst (MoveL2D src));
10223  ins_cost(MEMORY_REF_COST);
10224
10225  format %{ "LFD     $dst, $src \t// MoveL2D" %}
10226  size(4);
10227  ins_encode( enc_lfd(dst, src) );
10228  ins_pipe(pipe_class_memory);
10229%}
10230
10231// Move long value from long register to double stack-location.
10232instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{
10233  match(Set dst (MoveL2D src));
10234  ins_cost(MEMORY_REF_COST);
10235
10236  format %{ "STD     $src, $dst \t// MoveL2D" %}
10237  size(4);
10238  ins_encode( enc_std(src, dst) );
10239  ins_pipe(pipe_class_memory);
10240%}
10241
10242//----------Register Move Instructions-----------------------------------------
10243
10244// Replicate for Superword
10245
10246instruct moveReg(iRegLdst dst, iRegIsrc src) %{
10247  predicate(false);
10248  effect(DEF dst, USE src);
10249
10250  format %{ "MR      $dst, $src \t// replicate " %}
10251  // variable size, 0 or 4.
10252  ins_encode %{
10253    // TODO: PPC port $archOpcode(ppc64Opcode_or);
10254    __ mr_if_needed($dst$$Register, $src$$Register);
10255  %}
10256  ins_pipe(pipe_class_default);
10257%}
10258
10259//----------Cast instructions (Java-level type cast)---------------------------
10260
10261// Cast Long to Pointer for unsafe natives.
10262instruct castX2P(iRegPdst dst, iRegLsrc src) %{
10263  match(Set dst (CastX2P src));
10264
10265  format %{ "MR      $dst, $src \t// Long->Ptr" %}
10266  // variable size, 0 or 4.
10267  ins_encode %{
10268    // TODO: PPC port $archOpcode(ppc64Opcode_or);
10269    __ mr_if_needed($dst$$Register, $src$$Register);
10270  %}
10271 ins_pipe(pipe_class_default);
10272%}
10273
10274// Cast Pointer to Long for unsafe natives.
10275instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
10276  match(Set dst (CastP2X src));
10277
10278  format %{ "MR      $dst, $src \t// Ptr->Long" %}
10279  // variable size, 0 or 4.
10280  ins_encode %{
10281    // TODO: PPC port $archOpcode(ppc64Opcode_or);
10282    __ mr_if_needed($dst$$Register, $src$$Register);
10283  %}
10284  ins_pipe(pipe_class_default);
10285%}
10286
10287instruct castPP(iRegPdst dst) %{
10288  match(Set dst (CastPP dst));
10289  format %{ " -- \t// castPP of $dst" %}
10290  size(0);
10291  ins_encode( /*empty*/ );
10292  ins_pipe(pipe_class_default);
10293%}
10294
10295instruct castII(iRegIdst dst) %{
10296  match(Set dst (CastII dst));
10297  format %{ " -- \t// castII of $dst" %}
10298  size(0);
10299  ins_encode( /*empty*/ );
10300  ins_pipe(pipe_class_default);
10301%}
10302
10303instruct checkCastPP(iRegPdst dst) %{
10304  match(Set dst (CheckCastPP dst));
10305  format %{ " -- \t// checkcastPP of $dst" %}
10306  size(0);
10307  ins_encode( /*empty*/ );
10308  ins_pipe(pipe_class_default);
10309%}
10310
10311//----------Convert instructions-----------------------------------------------
10312
10313// Convert to boolean.
10314
10315// int_to_bool(src) : { 1   if src != 0
10316//                    { 0   else
10317//
10318// strategy:
10319// 1) Count leading zeros of 32 bit-value src,
10320//    this returns 32 (0b10.0000) iff src == 0 and <32 otherwise.
10321// 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
10322// 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
10323
10324// convI2Bool
10325instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{
10326  match(Set dst (Conv2B src));
10327  predicate(UseCountLeadingZerosInstructionsPPC64);
10328  ins_cost(DEFAULT_COST);
10329
10330  expand %{
10331    immI shiftAmount %{ 0x5 %}
10332    uimmI16 mask %{ 0x1 %}
10333    iRegIdst tmp1;
10334    iRegIdst tmp2;
10335    countLeadingZerosI(tmp1, src);
10336    urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10337    xorI_reg_uimm16(dst, tmp2, mask);
10338  %}
10339%}
10340
10341instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{
10342  match(Set dst (Conv2B src));
10343  effect(TEMP crx);
10344  predicate(!UseCountLeadingZerosInstructionsPPC64);
10345  ins_cost(DEFAULT_COST);
10346
10347  format %{ "CMPWI   $crx, $src, #0 \t// convI2B"
10348            "LI      $dst, #0\n\t"
10349            "BEQ     $crx, done\n\t"
10350            "LI      $dst, #1\n"
10351            "done:" %}
10352  size(16);
10353  ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) );
10354  ins_pipe(pipe_class_compare);
10355%}
10356
10357// ConvI2B + XorI
10358instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{
10359  match(Set dst (XorI (Conv2B src) mask));
10360  predicate(UseCountLeadingZerosInstructionsPPC64);
10361  ins_cost(DEFAULT_COST);
10362
10363  expand %{
10364    immI shiftAmount %{ 0x5 %}
10365    iRegIdst tmp1;
10366    countLeadingZerosI(tmp1, src);
10367    urShiftI_reg_imm(dst, tmp1, shiftAmount);
10368  %}
10369%}
10370
10371instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{
10372  match(Set dst (XorI (Conv2B src) mask));
10373  effect(TEMP crx);
10374  predicate(!UseCountLeadingZerosInstructionsPPC64);
10375  ins_cost(DEFAULT_COST);
10376
10377  format %{ "CMPWI   $crx, $src, #0 \t// Xor(convI2B($src), $mask)"
10378            "LI      $dst, #1\n\t"
10379            "BEQ     $crx, done\n\t"
10380            "LI      $dst, #0\n"
10381            "done:" %}
10382  size(16);
10383  ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) );
10384  ins_pipe(pipe_class_compare);
10385%}
10386
10387// AndI 0b0..010..0 + ConvI2B
10388instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{
10389  match(Set dst (Conv2B (AndI src mask)));
10390  predicate(UseRotateAndMaskInstructionsPPC64);
10391  ins_cost(DEFAULT_COST);
10392
10393  format %{ "RLWINM  $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
10394  size(4);
10395  ins_encode %{
10396    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
10397    __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31);
10398  %}
10399  ins_pipe(pipe_class_default);
10400%}
10401
10402// Convert pointer to boolean.
10403//
10404// ptr_to_bool(src) : { 1   if src != 0
10405//                    { 0   else
10406//
10407// strategy:
10408// 1) Count leading zeros of 64 bit-value src,
10409//    this returns 64 (0b100.0000) iff src == 0 and <64 otherwise.
10410// 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise.
10411// 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0.
10412
10413// ConvP2B
10414instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{
10415  match(Set dst (Conv2B src));
10416  predicate(UseCountLeadingZerosInstructionsPPC64);
10417  ins_cost(DEFAULT_COST);
10418
10419  expand %{
10420    immI shiftAmount %{ 0x6 %}
10421    uimmI16 mask %{ 0x1 %}
10422    iRegIdst tmp1;
10423    iRegIdst tmp2;
10424    countLeadingZerosP(tmp1, src);
10425    urShiftI_reg_imm(tmp2, tmp1, shiftAmount);
10426    xorI_reg_uimm16(dst, tmp2, mask);
10427  %}
10428%}
10429
10430instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{
10431  match(Set dst (Conv2B src));
10432  effect(TEMP crx);
10433  predicate(!UseCountLeadingZerosInstructionsPPC64);
10434  ins_cost(DEFAULT_COST);
10435
10436  format %{ "CMPDI   $crx, $src, #0 \t// convP2B"
10437            "LI      $dst, #0\n\t"
10438            "BEQ     $crx, done\n\t"
10439            "LI      $dst, #1\n"
10440            "done:" %}
10441  size(16);
10442  ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) );
10443  ins_pipe(pipe_class_compare);
10444%}
10445
10446// ConvP2B + XorI
10447instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{
10448  match(Set dst (XorI (Conv2B src) mask));
10449  predicate(UseCountLeadingZerosInstructionsPPC64);
10450  ins_cost(DEFAULT_COST);
10451
10452  expand %{
10453    immI shiftAmount %{ 0x6 %}
10454    iRegIdst tmp1;
10455    countLeadingZerosP(tmp1, src);
10456    urShiftI_reg_imm(dst, tmp1, shiftAmount);
10457  %}
10458%}
10459
10460instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{
10461  match(Set dst (XorI (Conv2B src) mask));
10462  effect(TEMP crx);
10463  predicate(!UseCountLeadingZerosInstructionsPPC64);
10464  ins_cost(DEFAULT_COST);
10465
10466  format %{ "CMPDI   $crx, $src, #0 \t// XorI(convP2B($src), $mask)"
10467            "LI      $dst, #1\n\t"
10468            "BEQ     $crx, done\n\t"
10469            "LI      $dst, #0\n"
10470            "done:" %}
10471  size(16);
10472  ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) );
10473  ins_pipe(pipe_class_compare);
10474%}
10475
10476// if src1 < src2, return -1 else return 0
10477instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
10478  match(Set dst (CmpLTMask src1 src2));
10479  ins_cost(DEFAULT_COST*4);
10480
10481  expand %{
10482    iRegLdst src1s;
10483    iRegLdst src2s;
10484    iRegLdst diff;
10485    convI2L_reg(src1s, src1); // Ensure proper sign extension.
10486    convI2L_reg(src2s, src2); // Ensure proper sign extension.
10487    subL_reg_reg(diff, src1s, src2s);
10488    // Need to consider >=33 bit result, therefore we need signmaskL.
10489    signmask64I_regL(dst, diff);
10490  %}
10491%}
10492
10493instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
10494  match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0
10495  format %{ "SRAWI   $dst, $src1, $src2 \t// CmpLTMask" %}
10496  size(4);
10497  ins_encode %{
10498    // TODO: PPC port $archOpcode(ppc64Opcode_srawi);
10499    __ srawi($dst$$Register, $src1$$Register, 0x1f);
10500  %}
10501  ins_pipe(pipe_class_default);
10502%}
10503
10504//----------Arithmetic Conversion Instructions---------------------------------
10505
10506// Convert to Byte  -- nop
10507// Convert to Short -- nop
10508
10509// Convert to Int
10510
10511instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
10512  match(Set dst (RShiftI (LShiftI src amount) amount));
10513  format %{ "EXTSB   $dst, $src \t// byte->int" %}
10514  size(4);
10515  ins_encode %{
10516    // TODO: PPC port $archOpcode(ppc64Opcode_extsb);
10517    __ extsb($dst$$Register, $src$$Register);
10518  %}
10519  ins_pipe(pipe_class_default);
10520%}
10521
10522// LShiftI 16 + RShiftI 16 converts short to int.
10523instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
10524  match(Set dst (RShiftI (LShiftI src amount) amount));
10525  format %{ "EXTSH   $dst, $src \t// short->int" %}
10526  size(4);
10527  ins_encode %{
10528    // TODO: PPC port $archOpcode(ppc64Opcode_extsh);
10529    __ extsh($dst$$Register, $src$$Register);
10530  %}
10531  ins_pipe(pipe_class_default);
10532%}
10533
10534// ConvL2I + ConvI2L: Sign extend int in long register.
10535instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
10536  match(Set dst (ConvI2L (ConvL2I src)));
10537
10538  format %{ "EXTSW   $dst, $src \t// long->long" %}
10539  size(4);
10540  ins_encode %{
10541    // TODO: PPC port $archOpcode(ppc64Opcode_extsw);
10542    __ extsw($dst$$Register, $src$$Register);
10543  %}
10544  ins_pipe(pipe_class_default);
10545%}
10546
10547instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
10548  match(Set dst (ConvL2I src));
10549  format %{ "MR      $dst, $src \t// long->int" %}
10550  // variable size, 0 or 4
10551  ins_encode %{
10552    // TODO: PPC port $archOpcode(ppc64Opcode_or);
10553    __ mr_if_needed($dst$$Register, $src$$Register);
10554  %}
10555  ins_pipe(pipe_class_default);
10556%}
10557
10558instruct convD2IRaw_regD(regD dst, regD src) %{
10559  // no match-rule, false predicate
10560  effect(DEF dst, USE src);
10561  predicate(false);
10562
10563  format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
10564  size(4);
10565  ins_encode %{
10566    // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);;
10567    __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10568  %}
10569  ins_pipe(pipe_class_default);
10570%}
10571
10572instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
10573  // no match-rule, false predicate
10574  effect(DEF dst, USE crx, USE src);
10575  predicate(false);
10576
10577  ins_variable_size_depending_on_alignment(true);
10578
10579  format %{ "cmovI   $crx, $dst, $src" %}
10580  // Worst case is branch + move + stop, no stop without scheduler.
10581  size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
10582  ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10583  ins_pipe(pipe_class_default);
10584%}
10585
10586instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{
10587  // no match-rule, false predicate
10588  effect(DEF dst, USE crx, USE mem);
10589  predicate(false);
10590
10591  format %{ "CmovI   $dst, $crx, $mem \t// postalloc expanded" %}
10592  postalloc_expand %{
10593    //
10594    // replaces
10595    //
10596    //   region  dst  crx  mem
10597    //    \       |    |   /
10598    //     dst=cmovI_bso_stackSlotL_conLvalue0
10599    //
10600    // with
10601    //
10602    //   region  dst
10603    //    \       /
10604    //     dst=loadConI16(0)
10605    //      |
10606    //      ^  region  dst  crx  mem
10607    //      |   \       |    |    /
10608    //      dst=cmovI_bso_stackSlotL
10609    //
10610
10611    // Create new nodes.
10612    MachNode *m1 = new loadConI16Node();
10613    MachNode *m2 = new cmovI_bso_stackSlotLNode();
10614
10615    // inputs for new nodes
10616    m1->add_req(n_region);
10617    m2->add_req(n_region, n_crx, n_mem);
10618
10619    // precedences for new nodes
10620    m2->add_prec(m1);
10621
10622    // operands for new nodes
10623    m1->_opnds[0] = op_dst;
10624    m1->_opnds[1] = new immI16Oper(0);
10625
10626    m2->_opnds[0] = op_dst;
10627    m2->_opnds[1] = op_crx;
10628    m2->_opnds[2] = op_mem;
10629
10630    // registers for new nodes
10631    ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10632    ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10633
10634    // Insert new nodes.
10635    nodes->push(m1);
10636    nodes->push(m2);
10637  %}
10638%}
10639
10640// Double to Int conversion, NaN is mapped to 0.
10641instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{
10642  match(Set dst (ConvD2I src));
10643  ins_cost(DEFAULT_COST);
10644
10645  expand %{
10646    regD tmpD;
10647    stackSlotL tmpS;
10648    flagsReg crx;
10649    cmpDUnordered_reg_reg(crx, src, src);               // Check whether src is NaN.
10650    convD2IRaw_regD(tmpD, src);                         // Convert float to int (speculated).
10651    moveD2L_reg_stack(tmpS, tmpD);                      // Store float to stack (speculated).
10652    cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
10653  %}
10654%}
10655
10656instruct convF2IRaw_regF(regF dst, regF src) %{
10657  // no match-rule, false predicate
10658  effect(DEF dst, USE src);
10659  predicate(false);
10660
10661  format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
10662  size(4);
10663  ins_encode %{
10664    // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);
10665    __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
10666  %}
10667  ins_pipe(pipe_class_default);
10668%}
10669
10670// Float to Int conversion, NaN is mapped to 0.
10671instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{
10672  match(Set dst (ConvF2I src));
10673  ins_cost(DEFAULT_COST);
10674
10675  expand %{
10676    regF tmpF;
10677    stackSlotL tmpS;
10678    flagsReg crx;
10679    cmpFUnordered_reg_reg(crx, src, src);               // Check whether src is NaN.
10680    convF2IRaw_regF(tmpF, src);                         // Convert float to int (speculated).
10681    moveF2L_reg_stack(tmpS, tmpF);                      // Store float to stack (speculated).
10682    cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
10683  %}
10684%}
10685
10686// Convert to Long
10687
10688instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
10689  match(Set dst (ConvI2L src));
10690  format %{ "EXTSW   $dst, $src \t// int->long" %}
10691  size(4);
10692  ins_encode %{
10693    // TODO: PPC port $archOpcode(ppc64Opcode_extsw);
10694    __ extsw($dst$$Register, $src$$Register);
10695  %}
10696  ins_pipe(pipe_class_default);
10697%}
10698
10699// Zero-extend: convert unsigned int to long (convUI2L).
10700instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
10701  match(Set dst (AndL (ConvI2L src) mask));
10702  ins_cost(DEFAULT_COST);
10703
10704  format %{ "CLRLDI  $dst, $src, #32 \t// zero-extend int to long" %}
10705  size(4);
10706  ins_encode %{
10707    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
10708    __ clrldi($dst$$Register, $src$$Register, 32);
10709  %}
10710  ins_pipe(pipe_class_default);
10711%}
10712
10713// Zero-extend: convert unsigned int to long in long register.
10714instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
10715  match(Set dst (AndL src mask));
10716  ins_cost(DEFAULT_COST);
10717
10718  format %{ "CLRLDI  $dst, $src, #32 \t// zero-extend int to long" %}
10719  size(4);
10720  ins_encode %{
10721    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
10722    __ clrldi($dst$$Register, $src$$Register, 32);
10723  %}
10724  ins_pipe(pipe_class_default);
10725%}
10726
10727instruct convF2LRaw_regF(regF dst, regF src) %{
10728  // no match-rule, false predicate
10729  effect(DEF dst, USE src);
10730  predicate(false);
10731
10732  format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
10733  size(4);
10734  ins_encode %{
10735    // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);
10736    __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10737  %}
10738  ins_pipe(pipe_class_default);
10739%}
10740
10741instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
10742  // no match-rule, false predicate
10743  effect(DEF dst, USE crx, USE src);
10744  predicate(false);
10745
10746  ins_variable_size_depending_on_alignment(true);
10747
10748  format %{ "cmovL   $crx, $dst, $src" %}
10749  // Worst case is branch + move + stop, no stop without scheduler.
10750  size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
10751  ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
10752  ins_pipe(pipe_class_default);
10753%}
10754
10755instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{
10756  // no match-rule, false predicate
10757  effect(DEF dst, USE crx, USE mem);
10758  predicate(false);
10759
10760  format %{ "CmovL   $dst, $crx, $mem \t// postalloc expanded" %}
10761  postalloc_expand %{
10762    //
10763    // replaces
10764    //
10765    //   region  dst  crx  mem
10766    //    \       |    |   /
10767    //     dst=cmovL_bso_stackSlotL_conLvalue0
10768    //
10769    // with
10770    //
10771    //   region  dst
10772    //    \       /
10773    //     dst=loadConL16(0)
10774    //      |
10775    //      ^  region  dst  crx  mem
10776    //      |   \       |    |    /
10777    //      dst=cmovL_bso_stackSlotL
10778    //
10779
10780    // Create new nodes.
10781    MachNode *m1 = new loadConL16Node();
10782    MachNode *m2 = new cmovL_bso_stackSlotLNode();
10783
10784    // inputs for new nodes
10785    m1->add_req(n_region);
10786    m2->add_req(n_region, n_crx, n_mem);
10787    m2->add_prec(m1);
10788
10789    // operands for new nodes
10790    m1->_opnds[0] = op_dst;
10791    m1->_opnds[1] = new immL16Oper(0);
10792    m2->_opnds[0] = op_dst;
10793    m2->_opnds[1] = op_crx;
10794    m2->_opnds[2] = op_mem;
10795
10796    // registers for new nodes
10797    ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10798    ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
10799
10800    // Insert new nodes.
10801    nodes->push(m1);
10802    nodes->push(m2);
10803  %}
10804%}
10805
10806// Float to Long conversion, NaN is mapped to 0.
10807instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{
10808  match(Set dst (ConvF2L src));
10809  ins_cost(DEFAULT_COST);
10810
10811  expand %{
10812    regF tmpF;
10813    stackSlotL tmpS;
10814    flagsReg crx;
10815    cmpFUnordered_reg_reg(crx, src, src);               // Check whether src is NaN.
10816    convF2LRaw_regF(tmpF, src);                         // Convert float to long (speculated).
10817    moveF2L_reg_stack(tmpS, tmpF);                      // Store float to stack (speculated).
10818    cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
10819  %}
10820%}
10821
10822instruct convD2LRaw_regD(regD dst, regD src) %{
10823  // no match-rule, false predicate
10824  effect(DEF dst, USE src);
10825  predicate(false);
10826
10827  format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
10828  size(4);
10829  ins_encode %{
10830    // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);
10831    __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
10832  %}
10833  ins_pipe(pipe_class_default);
10834%}
10835
10836// Double to Long conversion, NaN is mapped to 0.
10837instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{
10838  match(Set dst (ConvD2L src));
10839  ins_cost(DEFAULT_COST);
10840
10841  expand %{
10842    regD tmpD;
10843    stackSlotL tmpS;
10844    flagsReg crx;
10845    cmpDUnordered_reg_reg(crx, src, src);               // Check whether src is NaN.
10846    convD2LRaw_regD(tmpD, src);                         // Convert float to long (speculated).
10847    moveD2L_reg_stack(tmpS, tmpD);                      // Store float to stack (speculated).
10848    cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
10849  %}
10850%}
10851
10852// Convert to Float
10853
10854// Placed here as needed in expand.
10855instruct convL2DRaw_regD(regD dst, regD src) %{
10856  // no match-rule, false predicate
10857  effect(DEF dst, USE src);
10858  predicate(false);
10859
10860  format %{ "FCFID $dst, $src \t// convL2D" %}
10861  size(4);
10862  ins_encode %{
10863    // TODO: PPC port $archOpcode(ppc64Opcode_fcfid);
10864    __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
10865  %}
10866  ins_pipe(pipe_class_default);
10867%}
10868
10869// Placed here as needed in expand.
10870instruct convD2F_reg(regF dst, regD src) %{
10871  match(Set dst (ConvD2F src));
10872  format %{ "FRSP    $dst, $src \t// convD2F" %}
10873  size(4);
10874  ins_encode %{
10875    // TODO: PPC port $archOpcode(ppc64Opcode_frsp);
10876    __ frsp($dst$$FloatRegister, $src$$FloatRegister);
10877  %}
10878  ins_pipe(pipe_class_default);
10879%}
10880
10881// Integer to Float conversion.
10882instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{
10883  match(Set dst (ConvI2F src));
10884  predicate(!VM_Version::has_fcfids());
10885  ins_cost(DEFAULT_COST);
10886
10887  expand %{
10888    iRegLdst tmpL;
10889    stackSlotL tmpS;
10890    regD tmpD;
10891    regD tmpD2;
10892    convI2L_reg(tmpL, src);              // Sign-extension int to long.
10893    regL_to_stkL(tmpS, tmpL);            // Store long to stack.
10894    moveL2D_stack_reg(tmpD, tmpS);       // Load long into double register.
10895    convL2DRaw_regD(tmpD2, tmpD);        // Convert to double.
10896    convD2F_reg(dst, tmpD2);             // Convert double to float.
10897  %}
10898%}
10899
10900instruct convL2FRaw_regF(regF dst, regD src) %{
10901  // no match-rule, false predicate
10902  effect(DEF dst, USE src);
10903  predicate(false);
10904
10905  format %{ "FCFIDS $dst, $src \t// convL2F" %}
10906  size(4);
10907  ins_encode %{
10908    // TODO: PPC port $archOpcode(ppc64Opcode_fcfid);
10909    __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
10910  %}
10911  ins_pipe(pipe_class_default);
10912%}
10913
10914// Integer to Float conversion. Special version for Power7.
10915instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{
10916  match(Set dst (ConvI2F src));
10917  predicate(VM_Version::has_fcfids());
10918  ins_cost(DEFAULT_COST);
10919
10920  expand %{
10921    iRegLdst tmpL;
10922    stackSlotL tmpS;
10923    regD tmpD;
10924    convI2L_reg(tmpL, src);              // Sign-extension int to long.
10925    regL_to_stkL(tmpS, tmpL);            // Store long to stack.
10926    moveL2D_stack_reg(tmpD, tmpS);       // Load long into double register.
10927    convL2FRaw_regF(dst, tmpD);          // Convert to float.
10928  %}
10929%}
10930
10931// L2F to avoid runtime call.
10932instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{
10933  match(Set dst (ConvL2F src));
10934  predicate(VM_Version::has_fcfids());
10935  ins_cost(DEFAULT_COST);
10936
10937  expand %{
10938    stackSlotL tmpS;
10939    regD tmpD;
10940    regL_to_stkL(tmpS, src);             // Store long to stack.
10941    moveL2D_stack_reg(tmpD, tmpS);       // Load long into double register.
10942    convL2FRaw_regF(dst, tmpD);          // Convert to float.
10943  %}
10944%}
10945
10946// Moved up as used in expand.
10947//instruct convD2F_reg(regF dst, regD src) %{%}
10948
10949// Convert to Double
10950
10951// Integer to Double conversion.
10952instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{
10953  match(Set dst (ConvI2D src));
10954  ins_cost(DEFAULT_COST);
10955
10956  expand %{
10957    iRegLdst tmpL;
10958    stackSlotL tmpS;
10959    regD tmpD;
10960    convI2L_reg(tmpL, src);              // Sign-extension int to long.
10961    regL_to_stkL(tmpS, tmpL);            // Store long to stack.
10962    moveL2D_stack_reg(tmpD, tmpS);       // Load long into double register.
10963    convL2DRaw_regD(dst, tmpD);          // Convert to double.
10964  %}
10965%}
10966
10967// Long to Double conversion
10968instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{
10969  match(Set dst (ConvL2D src));
10970  ins_cost(DEFAULT_COST + MEMORY_REF_COST);
10971
10972  expand %{
10973    regD tmpD;
10974    moveL2D_stack_reg(tmpD, src);
10975    convL2DRaw_regD(dst, tmpD);
10976  %}
10977%}
10978
10979instruct convF2D_reg(regD dst, regF src) %{
10980  match(Set dst (ConvF2D src));
10981  format %{ "FMR     $dst, $src \t// float->double" %}
10982  // variable size, 0 or 4
10983  ins_encode %{
10984    // TODO: PPC port $archOpcode(ppc64Opcode_fmr);
10985    __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
10986  %}
10987  ins_pipe(pipe_class_default);
10988%}
10989
10990//----------Control Flow Instructions------------------------------------------
10991// Compare Instructions
10992
10993// Compare Integers
10994instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
10995  match(Set crx (CmpI src1 src2));
10996  size(4);
10997  format %{ "CMPW    $crx, $src1, $src2" %}
10998  ins_encode %{
10999    // TODO: PPC port $archOpcode(ppc64Opcode_cmp);
11000    __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
11001  %}
11002  ins_pipe(pipe_class_compare);
11003%}
11004
11005instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
11006  match(Set crx (CmpI src1 src2));
11007  format %{ "CMPWI   $crx, $src1, $src2" %}
11008  size(4);
11009  ins_encode %{
11010    // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
11011    __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11012  %}
11013  ins_pipe(pipe_class_compare);
11014%}
11015
11016// (src1 & src2) == 0?
11017instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{
11018  match(Set cr0 (CmpI (AndI src1 src2) zero));
11019  // r0 is killed
11020  format %{ "ANDI    R0, $src1, $src2 \t// BTST int" %}
11021  size(4);
11022  ins_encode %{
11023    // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
11024    __ andi_(R0, $src1$$Register, $src2$$constant);
11025  %}
11026  ins_pipe(pipe_class_compare);
11027%}
11028
11029instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
11030  match(Set crx (CmpL src1 src2));
11031  format %{ "CMPD    $crx, $src1, $src2" %}
11032  size(4);
11033  ins_encode %{
11034    // TODO: PPC port $archOpcode(ppc64Opcode_cmp);
11035    __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
11036  %}
11037  ins_pipe(pipe_class_compare);
11038%}
11039
11040instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
11041  match(Set crx (CmpL src1 src2));
11042  format %{ "CMPDI   $crx, $src1, $src2" %}
11043  size(4);
11044  ins_encode %{
11045    // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
11046    __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11047  %}
11048  ins_pipe(pipe_class_compare);
11049%}
11050
11051// Added CmpUL for LoopPredicate.
11052instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
11053  match(Set crx (CmpUL src1 src2));
11054  format %{ "CMPLD   $crx, $src1, $src2" %}
11055  size(4);
11056  ins_encode %{
11057    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
11058    __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
11059  %}
11060  ins_pipe(pipe_class_compare);
11061%}
11062
11063instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
11064  match(Set crx (CmpUL src1 src2));
11065  format %{ "CMPLDI  $crx, $src1, $src2" %}
11066  size(4);
11067  ins_encode %{
11068    // TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
11069    __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11070  %}
11071  ins_pipe(pipe_class_compare);
11072%}
11073
11074instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
11075  match(Set cr0 (CmpL (AndL src1 src2) zero));
11076  // r0 is killed
11077  format %{ "AND     R0, $src1, $src2 \t// BTST long" %}
11078  size(4);
11079  ins_encode %{
11080    // TODO: PPC port $archOpcode(ppc64Opcode_and_);
11081    __ and_(R0, $src1$$Register, $src2$$Register);
11082  %}
11083  ins_pipe(pipe_class_compare);
11084%}
11085
11086instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{
11087  match(Set cr0 (CmpL (AndL src1 src2) zero));
11088  // r0 is killed
11089  format %{ "ANDI    R0, $src1, $src2 \t// BTST long" %}
11090  size(4);
11091  ins_encode %{
11092    // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
11093    __ andi_(R0, $src1$$Register, $src2$$constant);
11094  %}
11095  ins_pipe(pipe_class_compare);
11096%}
11097
11098instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{
11099  // no match-rule, false predicate
11100  effect(DEF dst, USE crx);
11101  predicate(false);
11102
11103  ins_variable_size_depending_on_alignment(true);
11104
11105  format %{ "cmovI   $crx, $dst, -1, 0, +1" %}
11106  // Worst case is branch + move + branch + move + stop, no stop without scheduler.
11107  size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16);
11108  ins_encode %{
11109    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
11110    Label done;
11111    // li(Rdst, 0);              // equal -> 0
11112    __ beq($crx$$CondRegister, done);
11113    __ li($dst$$Register, 1);    // greater -> +1
11114    __ bgt($crx$$CondRegister, done);
11115    __ li($dst$$Register, -1);   // unordered or less -> -1
11116    // TODO: PPC port__ endgroup_if_needed(_size == 20);
11117    __ bind(done);
11118  %}
11119  ins_pipe(pipe_class_compare);
11120%}
11121
11122instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{
11123  // no match-rule, false predicate
11124  effect(DEF dst, USE crx);
11125  predicate(false);
11126
11127  format %{ "CmovI    $crx, $dst, -1, 0, +1 \t// postalloc expanded" %}
11128  postalloc_expand %{
11129    //
11130    // replaces
11131    //
11132    //   region  crx
11133    //    \       |
11134    //     dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1
11135    //
11136    // with
11137    //
11138    //   region
11139    //    \
11140    //     dst=loadConI16(0)
11141    //      |
11142    //      ^  region  crx
11143    //      |   \       |
11144    //      dst=cmovI_conIvalueMinus1_conIvalue1
11145    //
11146
11147    // Create new nodes.
11148    MachNode *m1 = new loadConI16Node();
11149    MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node();
11150
11151    // inputs for new nodes
11152    m1->add_req(n_region);
11153    m2->add_req(n_region, n_crx);
11154    m2->add_prec(m1);
11155
11156    // operands for new nodes
11157    m1->_opnds[0] = op_dst;
11158    m1->_opnds[1] = new immI16Oper(0);
11159    m2->_opnds[0] = op_dst;
11160    m2->_opnds[1] = op_crx;
11161
11162    // registers for new nodes
11163    ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11164    ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
11165
11166    // Insert new nodes.
11167    nodes->push(m1);
11168    nodes->push(m2);
11169  %}
11170%}
11171
11172// Manifest a CmpL3 result in an integer register. Very painful.
11173// This is the test to avoid.
11174// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
11175instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
11176  match(Set dst (CmpL3 src1 src2));
11177  ins_cost(DEFAULT_COST*5+BRANCH_COST);
11178
11179  expand %{
11180    flagsReg tmp1;
11181    cmpL_reg_reg(tmp1, src1, src2);
11182    cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1);
11183  %}
11184%}
11185
11186// Implicit range checks.
11187// A range check in the ideal world has one of the following shapes:
11188//  - (If le (CmpU length index)), (IfTrue  throw exception)
11189//  - (If lt (CmpU index length)), (IfFalse throw exception)
11190//
11191// Match range check 'If le (CmpU length index)'.
11192instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{
11193  match(If cmp (CmpU src_length index));
11194  effect(USE labl);
11195  predicate(TrapBasedRangeChecks &&
11196            _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le &&
11197            PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS &&
11198            (Matcher::branches_to_uncommon_trap(_leaf)));
11199
11200  ins_is_TrapBasedCheckNode(true);
11201
11202  format %{ "TWI     $index $cmp $src_length \t// RangeCheck => trap $labl" %}
11203  size(4);
11204  ins_encode %{
11205    // TODO: PPC port $archOpcode(ppc64Opcode_twi);
11206    if ($cmp$$cmpcode == 0x1 /* less_equal */) {
11207      __ trap_range_check_le($src_length$$Register, $index$$constant);
11208    } else {
11209      // Both successors are uncommon traps, probability is 0.
11210      // Node got flipped during fixup flow.
11211      assert($cmp$$cmpcode == 0x9, "must be greater");
11212      __ trap_range_check_g($src_length$$Register, $index$$constant);
11213    }
11214  %}
11215  ins_pipe(pipe_class_trap);
11216%}
11217
11218// Match range check 'If lt (CmpU index length)'.
11219instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{
11220  match(If cmp (CmpU src_index src_length));
11221  effect(USE labl);
11222  predicate(TrapBasedRangeChecks &&
11223            _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
11224            _leaf->as_If()->_prob >= PROB_ALWAYS &&
11225            (Matcher::branches_to_uncommon_trap(_leaf)));
11226
11227  ins_is_TrapBasedCheckNode(true);
11228
11229  format %{ "TW      $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
11230  size(4);
11231  ins_encode %{
11232    // TODO: PPC port $archOpcode(ppc64Opcode_tw);
11233    if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
11234      __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
11235    } else {
11236      // Both successors are uncommon traps, probability is 0.
11237      // Node got flipped during fixup flow.
11238      assert($cmp$$cmpcode == 0x8, "must be less");
11239      __ trap_range_check_l($src_index$$Register, $src_length$$Register);
11240    }
11241  %}
11242  ins_pipe(pipe_class_trap);
11243%}
11244
11245// Match range check 'If lt (CmpU index length)'.
11246instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{
11247  match(If cmp (CmpU src_index length));
11248  effect(USE labl);
11249  predicate(TrapBasedRangeChecks &&
11250            _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt &&
11251            _leaf->as_If()->_prob >= PROB_ALWAYS &&
11252            (Matcher::branches_to_uncommon_trap(_leaf)));
11253
11254  ins_is_TrapBasedCheckNode(true);
11255
11256  format %{ "TWI     $src_index $cmp $length \t// RangeCheck => trap $labl" %}
11257  size(4);
11258  ins_encode %{
11259    // TODO: PPC port $archOpcode(ppc64Opcode_twi);
11260    if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
11261      __ trap_range_check_ge($src_index$$Register, $length$$constant);
11262    } else {
11263      // Both successors are uncommon traps, probability is 0.
11264      // Node got flipped during fixup flow.
11265      assert($cmp$$cmpcode == 0x8, "must be less");
11266      __ trap_range_check_l($src_index$$Register, $length$$constant);
11267    }
11268  %}
11269  ins_pipe(pipe_class_trap);
11270%}
11271
11272instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
11273  match(Set crx (CmpU src1 src2));
11274  format %{ "CMPLW   $crx, $src1, $src2 \t// unsigned" %}
11275  size(4);
11276  ins_encode %{
11277    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
11278    __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
11279  %}
11280  ins_pipe(pipe_class_compare);
11281%}
11282
11283instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
11284  match(Set crx (CmpU src1 src2));
11285  size(4);
11286  format %{ "CMPLWI  $crx, $src1, $src2" %}
11287  ins_encode %{
11288    // TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
11289    __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11290  %}
11291  ins_pipe(pipe_class_compare);
11292%}
11293
11294// Implicit zero checks (more implicit null checks).
11295// No constant pool entries required.
11296instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{
11297  match(If cmp (CmpN value zero));
11298  effect(USE labl);
11299  predicate(TrapBasedNullChecks &&
11300            _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
11301            _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
11302            Matcher::branches_to_uncommon_trap(_leaf));
11303  ins_cost(1);
11304
11305  ins_is_TrapBasedCheckNode(true);
11306
11307  format %{ "TDI     $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
11308  size(4);
11309  ins_encode %{
11310    // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
11311    if ($cmp$$cmpcode == 0xA) {
11312      __ trap_null_check($value$$Register);
11313    } else {
11314      // Both successors are uncommon traps, probability is 0.
11315      // Node got flipped during fixup flow.
11316      assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
11317      __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
11318    }
11319  %}
11320  ins_pipe(pipe_class_trap);
11321%}
11322
11323// Compare narrow oops.
11324instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
11325  match(Set crx (CmpN src1 src2));
11326
11327  size(4);
11328  ins_cost(2);
11329  format %{ "CMPLW   $crx, $src1, $src2 \t// compressed ptr" %}
11330  ins_encode %{
11331    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
11332    __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
11333  %}
11334  ins_pipe(pipe_class_compare);
11335%}
11336
11337instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
11338  match(Set crx (CmpN src1 src2));
11339  // Make this more expensive than zeroCheckN_iReg_imm0.
11340  ins_cost(2);
11341
11342  format %{ "CMPLWI  $crx, $src1, $src2 \t// compressed ptr" %}
11343  size(4);
11344  ins_encode %{
11345    // TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
11346    __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11347  %}
11348  ins_pipe(pipe_class_compare);
11349%}
11350
11351// Implicit zero checks (more implicit null checks).
11352// No constant pool entries required.
11353instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{
11354  match(If cmp (CmpP value zero));
11355  effect(USE labl);
11356  predicate(TrapBasedNullChecks &&
11357            _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne &&
11358            _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) &&
11359            Matcher::branches_to_uncommon_trap(_leaf));
11360  ins_cost(1); // Should not be cheaper than zeroCheckN.
11361
11362  ins_is_TrapBasedCheckNode(true);
11363
11364  format %{ "TDI     $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
11365  size(4);
11366  ins_encode %{
11367    // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
11368    if ($cmp$$cmpcode == 0xA) {
11369      __ trap_null_check($value$$Register);
11370    } else {
11371      // Both successors are uncommon traps, probability is 0.
11372      // Node got flipped during fixup flow.
11373      assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)");
11374      __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned);
11375    }
11376  %}
11377  ins_pipe(pipe_class_trap);
11378%}
11379
11380// Compare Pointers
11381instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
11382  match(Set crx (CmpP src1 src2));
11383  format %{ "CMPLD   $crx, $src1, $src2 \t// ptr" %}
11384  size(4);
11385  ins_encode %{
11386    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
11387    __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
11388  %}
11389  ins_pipe(pipe_class_compare);
11390%}
11391
11392instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
11393  match(Set crx (CmpP src1 src2));
11394  format %{ "CMPLDI   $crx, $src1, $src2 \t// ptr" %}
11395  size(4);
11396  ins_encode %{
11397    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
11398    __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
11399  %}
11400  ins_pipe(pipe_class_compare);
11401%}
11402
11403// Used in postalloc expand.
11404instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
11405  // This match rule prevents reordering of node before a safepoint.
11406  // This only makes sense if this instructions is used exclusively
11407  // for the expansion of EncodeP!
11408  match(Set crx (CmpP src1 src2));
11409  predicate(false);
11410
11411  format %{ "CMPDI   $crx, $src1, $src2" %}
11412  size(4);
11413  ins_encode %{
11414    // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
11415    __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
11416  %}
11417  ins_pipe(pipe_class_compare);
11418%}
11419
11420//----------Float Compares----------------------------------------------------
11421
11422instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
11423  // Needs matchrule, see cmpDUnordered.
11424  match(Set crx (CmpF src1 src2));
11425  // no match-rule, false predicate
11426  predicate(false);
11427
11428  format %{ "cmpFUrd $crx, $src1, $src2" %}
11429  size(4);
11430  ins_encode %{
11431    // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu);
11432    __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11433  %}
11434  ins_pipe(pipe_class_default);
11435%}
11436
11437instruct cmov_bns_less(flagsReg crx) %{
11438  // no match-rule, false predicate
11439  effect(DEF crx);
11440  predicate(false);
11441
11442  ins_variable_size_depending_on_alignment(true);
11443
11444  format %{ "cmov    $crx" %}
11445  // Worst case is branch + move + stop, no stop without scheduler.
11446  size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12);
11447  ins_encode %{
11448    // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr);
11449    Label done;
11450    __ bns($crx$$CondRegister, done);        // not unordered -> keep crx
11451    __ li(R0, 0);
11452    __ cmpwi($crx$$CondRegister, R0, 1);     // unordered -> set crx to 'less'
11453    // TODO PPC port __ endgroup_if_needed(_size == 16);
11454    __ bind(done);
11455  %}
11456  ins_pipe(pipe_class_default);
11457%}
11458
11459// Compare floating, generate condition code.
11460instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{
11461  // FIXME: should we match 'If cmp (CmpF src1 src2))' ??
11462  //
11463  // The following code sequence occurs a lot in mpegaudio:
11464  //
11465  // block BXX:
11466  // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0):
11467  //    cmpFUrd CCR6, F11, F9
11468  // 4: instruct cmov_bns_less (cmpF_reg_reg-1):
11469  //    cmov CCR6
11470  // 8: instruct branchConSched:
11471  //    B_FARle CCR6, B56  P=0.500000 C=-1.000000
11472  match(Set crx (CmpF src1 src2));
11473  ins_cost(DEFAULT_COST+BRANCH_COST);
11474
11475  format %{ "CmpF    $crx, $src1, $src2 \t// postalloc expanded" %}
11476  postalloc_expand %{
11477    //
11478    // replaces
11479    //
11480    //   region  src1  src2
11481    //    \       |     |
11482    //     crx=cmpF_reg_reg
11483    //
11484    // with
11485    //
11486    //   region  src1  src2
11487    //    \       |     |
11488    //     crx=cmpFUnordered_reg_reg
11489    //      |
11490    //      ^  region
11491    //      |   \
11492    //      crx=cmov_bns_less
11493    //
11494
11495    // Create new nodes.
11496    MachNode *m1 = new cmpFUnordered_reg_regNode();
11497    MachNode *m2 = new cmov_bns_lessNode();
11498
11499    // inputs for new nodes
11500    m1->add_req(n_region, n_src1, n_src2);
11501    m2->add_req(n_region);
11502    m2->add_prec(m1);
11503
11504    // operands for new nodes
11505    m1->_opnds[0] = op_crx;
11506    m1->_opnds[1] = op_src1;
11507    m1->_opnds[2] = op_src2;
11508    m2->_opnds[0] = op_crx;
11509
11510    // registers for new nodes
11511    ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11512    ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11513
11514    // Insert new nodes.
11515    nodes->push(m1);
11516    nodes->push(m2);
11517  %}
11518%}
11519
11520// Compare float, generate -1,0,1
11521instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{
11522  match(Set dst (CmpF3 src1 src2));
11523  ins_cost(DEFAULT_COST*5+BRANCH_COST);
11524
11525  expand %{
11526    flagsReg tmp1;
11527    cmpFUnordered_reg_reg(tmp1, src1, src2);
11528    cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1);
11529  %}
11530%}
11531
11532instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
11533  // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the
11534  // node right before the conditional move using it.
11535  // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7,
11536  // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle
11537  // crashed in register allocation where the flags Reg between cmpDUnoredered and a
11538  // conditional move was supposed to be spilled.
11539  match(Set crx (CmpD src1 src2));
11540  // False predicate, shall not be matched.
11541  predicate(false);
11542
11543  format %{ "cmpFUrd $crx, $src1, $src2" %}
11544  size(4);
11545  ins_encode %{
11546    // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu);
11547    __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
11548  %}
11549  ins_pipe(pipe_class_default);
11550%}
11551
11552instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{
11553  match(Set crx (CmpD src1 src2));
11554  ins_cost(DEFAULT_COST+BRANCH_COST);
11555
11556  format %{ "CmpD    $crx, $src1, $src2 \t// postalloc expanded" %}
11557  postalloc_expand %{
11558    //
11559    // replaces
11560    //
11561    //   region  src1  src2
11562    //    \       |     |
11563    //     crx=cmpD_reg_reg
11564    //
11565    // with
11566    //
11567    //   region  src1  src2
11568    //    \       |     |
11569    //     crx=cmpDUnordered_reg_reg
11570    //      |
11571    //      ^  region
11572    //      |   \
11573    //      crx=cmov_bns_less
11574    //
11575
11576    // create new nodes
11577    MachNode *m1 = new cmpDUnordered_reg_regNode();
11578    MachNode *m2 = new cmov_bns_lessNode();
11579
11580    // inputs for new nodes
11581    m1->add_req(n_region, n_src1, n_src2);
11582    m2->add_req(n_region);
11583    m2->add_prec(m1);
11584
11585    // operands for new nodes
11586    m1->_opnds[0] = op_crx;
11587    m1->_opnds[1] = op_src1;
11588    m1->_opnds[2] = op_src2;
11589    m2->_opnds[0] = op_crx;
11590
11591    // registers for new nodes
11592    ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11593    ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx
11594
11595    // Insert new nodes.
11596    nodes->push(m1);
11597    nodes->push(m2);
11598  %}
11599%}
11600
11601// Compare double, generate -1,0,1
11602instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{
11603  match(Set dst (CmpD3 src1 src2));
11604  ins_cost(DEFAULT_COST*5+BRANCH_COST);
11605
11606  expand %{
11607    flagsReg tmp1;
11608    cmpDUnordered_reg_reg(tmp1, src1, src2);
11609    cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1);
11610  %}
11611%}
11612
11613//----------Branches---------------------------------------------------------
11614// Jump
11615
11616// Direct Branch.
11617instruct branch(label labl) %{
11618  match(Goto);
11619  effect(USE labl);
11620  ins_cost(BRANCH_COST);
11621
11622  format %{ "B       $labl" %}
11623  size(4);
11624  ins_encode %{
11625    // TODO: PPC port $archOpcode(ppc64Opcode_b);
11626     Label d;    // dummy
11627     __ bind(d);
11628     Label* p = $labl$$label;
11629     // `p' is `NULL' when this encoding class is used only to
11630     // determine the size of the encoded instruction.
11631     Label& l = (NULL == p)? d : *(p);
11632     __ b(l);
11633  %}
11634  ins_pipe(pipe_class_default);
11635%}
11636
11637// Conditional Near Branch
11638instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11639  // Same match rule as `branchConFar'.
11640  match(If cmp crx);
11641  effect(USE lbl);
11642  ins_cost(BRANCH_COST);
11643
11644  // If set to 1 this indicates that the current instruction is a
11645  // short variant of a long branch. This avoids using this
11646  // instruction in first-pass matching. It will then only be used in
11647  // the `Shorten_branches' pass.
11648  ins_short_branch(1);
11649
11650  format %{ "B$cmp     $crx, $lbl" %}
11651  size(4);
11652  ins_encode( enc_bc(crx, cmp, lbl) );
11653  ins_pipe(pipe_class_default);
11654%}
11655
11656// This is for cases when the ppc64 `bc' instruction does not
11657// reach far enough. So we emit a far branch here, which is more
11658// expensive.
11659//
11660// Conditional Far Branch
11661instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11662  // Same match rule as `branchCon'.
11663  match(If cmp crx);
11664  effect(USE crx, USE lbl);
11665  predicate(!false /* TODO: PPC port HB_Schedule*/);
11666  // Higher cost than `branchCon'.
11667  ins_cost(5*BRANCH_COST);
11668
11669  // This is not a short variant of a branch, but the long variant.
11670  ins_short_branch(0);
11671
11672  format %{ "B_FAR$cmp $crx, $lbl" %}
11673  size(8);
11674  ins_encode( enc_bc_far(crx, cmp, lbl) );
11675  ins_pipe(pipe_class_default);
11676%}
11677
11678// Conditional Branch used with Power6 scheduler (can be far or short).
11679instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{
11680  // Same match rule as `branchCon'.
11681  match(If cmp crx);
11682  effect(USE crx, USE lbl);
11683  predicate(false /* TODO: PPC port HB_Schedule*/);
11684  // Higher cost than `branchCon'.
11685  ins_cost(5*BRANCH_COST);
11686
11687  // Actually size doesn't depend on alignment but on shortening.
11688  ins_variable_size_depending_on_alignment(true);
11689  // long variant.
11690  ins_short_branch(0);
11691
11692  format %{ "B_FAR$cmp $crx, $lbl" %}
11693  size(8); // worst case
11694  ins_encode( enc_bc_short_far(crx, cmp, lbl) );
11695  ins_pipe(pipe_class_default);
11696%}
11697
11698instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
11699  match(CountedLoopEnd cmp crx);
11700  effect(USE labl);
11701  ins_cost(BRANCH_COST);
11702
11703  // short variant.
11704  ins_short_branch(1);
11705
11706  format %{ "B$cmp     $crx, $labl \t// counted loop end" %}
11707  size(4);
11708  ins_encode( enc_bc(crx, cmp, labl) );
11709  ins_pipe(pipe_class_default);
11710%}
11711
11712instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
11713  match(CountedLoopEnd cmp crx);
11714  effect(USE labl);
11715  predicate(!false /* TODO: PPC port HB_Schedule */);
11716  ins_cost(BRANCH_COST);
11717
11718  // Long variant.
11719  ins_short_branch(0);
11720
11721  format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
11722  size(8);
11723  ins_encode( enc_bc_far(crx, cmp, labl) );
11724  ins_pipe(pipe_class_default);
11725%}
11726
11727// Conditional Branch used with Power6 scheduler (can be far or short).
11728instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{
11729  match(CountedLoopEnd cmp crx);
11730  effect(USE labl);
11731  predicate(false /* TODO: PPC port HB_Schedule */);
11732  // Higher cost than `branchCon'.
11733  ins_cost(5*BRANCH_COST);
11734
11735  // Actually size doesn't depend on alignment but on shortening.
11736  ins_variable_size_depending_on_alignment(true);
11737  // Long variant.
11738  ins_short_branch(0);
11739
11740  format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
11741  size(8); // worst case
11742  ins_encode( enc_bc_short_far(crx, cmp, labl) );
11743  ins_pipe(pipe_class_default);
11744%}
11745
11746// ============================================================================
11747// Java runtime operations, intrinsics and other complex operations.
11748
11749// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
11750// array for an instance of the superklass. Set a hidden internal cache on a
11751// hit (cache is checked with exposed code in gen_subtype_check()). Return
11752// not zero for a miss or zero for a hit. The encoding ALSO sets flags.
11753//
11754// GL TODO: Improve this.
11755// - result should not be a TEMP
11756// - Add match rule as on sparc avoiding additional Cmp.
11757instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass,
11758                             iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{
11759  match(Set result (PartialSubtypeCheck subklass superklass));
11760  effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr);
11761  ins_cost(DEFAULT_COST*10);
11762
11763  format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
11764  ins_encode %{
11765    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11766    __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
11767                                     $tmp_klass$$Register, NULL, $result$$Register);
11768  %}
11769  ins_pipe(pipe_class_default);
11770%}
11771
11772// inlined locking and unlocking
11773
11774instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{
11775  match(Set crx (FastLock oop box));
11776  effect(TEMP tmp1, TEMP tmp2);
11777  predicate(!Compile::current()->use_rtm());
11778
11779  format %{ "FASTLOCK  $oop, $box, $tmp1, $tmp2" %}
11780  ins_encode %{
11781    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11782    __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
11783                                 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0,
11784                                 UseBiasedLocking && !UseOptoBiasInlining);
11785    // If locking was successfull, crx should indicate 'EQ'.
11786    // The compiler generates a branch to the runtime call to
11787    // _complete_monitor_locking_Java for the case where crx is 'NE'.
11788  %}
11789  ins_pipe(pipe_class_compare);
11790%}
11791
11792// Separate version for TM. Use bound register for box to enable USE_KILL.
11793instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11794  match(Set crx (FastLock oop box));
11795  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box);
11796  predicate(Compile::current()->use_rtm());
11797
11798  format %{ "FASTLOCK  $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %}
11799  ins_encode %{
11800    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11801    __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
11802                                 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11803                                 /*Biased Locking*/ false,
11804                                 _rtm_counters, _stack_rtm_counters,
11805                                 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(),
11806                                 /*TM*/ true, ra_->C->profile_rtm());
11807    // If locking was successfull, crx should indicate 'EQ'.
11808    // The compiler generates a branch to the runtime call to
11809    // _complete_monitor_locking_Java for the case where crx is 'NE'.
11810  %}
11811  ins_pipe(pipe_class_compare);
11812%}
11813
11814instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11815  match(Set crx (FastUnlock oop box));
11816  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11817  predicate(!Compile::current()->use_rtm());
11818
11819  format %{ "FASTUNLOCK  $oop, $box, $tmp1, $tmp2" %}
11820  ins_encode %{
11821    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11822    __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
11823                                   $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11824                                   UseBiasedLocking && !UseOptoBiasInlining,
11825                                   false);
11826    // If unlocking was successfull, crx should indicate 'EQ'.
11827    // The compiler generates a branch to the runtime call to
11828    // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11829  %}
11830  ins_pipe(pipe_class_compare);
11831%}
11832
11833instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
11834  match(Set crx (FastUnlock oop box));
11835  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
11836  predicate(Compile::current()->use_rtm());
11837
11838  format %{ "FASTUNLOCK  $oop, $box, $tmp1, $tmp2 (TM)" %}
11839  ins_encode %{
11840    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11841    __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
11842                                   $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
11843                                   /*Biased Locking*/ false, /*TM*/ true);
11844    // If unlocking was successfull, crx should indicate 'EQ'.
11845    // The compiler generates a branch to the runtime call to
11846    // _complete_monitor_unlocking_Java for the case where crx is 'NE'.
11847  %}
11848  ins_pipe(pipe_class_compare);
11849%}
11850
11851// Align address.
11852instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
11853  match(Set dst (CastX2P (AndL (CastP2X src) mask)));
11854
11855  format %{ "ANDDI   $dst, $src, $mask \t// next aligned address" %}
11856  size(4);
11857  ins_encode %{
11858    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
11859    __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant));
11860  %}
11861  ins_pipe(pipe_class_default);
11862%}
11863
11864// Array size computation.
11865instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11866  match(Set dst (SubL (CastP2X end) (CastP2X start)));
11867
11868  format %{ "SUB     $dst, $end, $start \t// array size in bytes" %}
11869  size(4);
11870  ins_encode %{
11871    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
11872    __ subf($dst$$Register, $start$$Register, $end$$Register);
11873  %}
11874  ins_pipe(pipe_class_default);
11875%}
11876
11877// Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11878instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11879  match(Set dummy (ClearArray cnt base));
11880  effect(USE_KILL base, KILL ctr);
11881  ins_cost(2 * MEMORY_REF_COST);
11882
11883  format %{ "ClearArray $cnt, $base" %}
11884  ins_encode %{
11885    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11886    __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11887  %}
11888  ins_pipe(pipe_class_default);
11889%}
11890
11891// Clear-array with constant large array length.
11892instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11893  match(Set dummy (ClearArray cnt base));
11894  effect(USE_KILL base, TEMP tmp, KILL ctr);
11895  ins_cost(3 * MEMORY_REF_COST);
11896
11897  format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11898  ins_encode %{
11899    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11900    __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11901  %}
11902  ins_pipe(pipe_class_default);
11903%}
11904
11905// Clear-array with dynamic array length.
11906instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11907  match(Set dummy (ClearArray cnt base));
11908  effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11909  ins_cost(4 * MEMORY_REF_COST);
11910
11911  format %{ "ClearArray $cnt, $base" %}
11912  ins_encode %{
11913    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11914    __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11915  %}
11916  ins_pipe(pipe_class_default);
11917%}
11918
11919instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11920                         iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11921  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11922  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11923  effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11924  ins_cost(300);
11925  format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11926  ins_encode %{
11927    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11928    __ string_compare($str1$$Register, $str2$$Register,
11929                      $cnt1$$Register, $cnt2$$Register,
11930                      $tmp$$Register,
11931                      $result$$Register, StrIntrinsicNode::LL);
11932  %}
11933  ins_pipe(pipe_class_default);
11934%}
11935
11936instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11937                         iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11938  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
11939  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11940  effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11941  ins_cost(300);
11942  format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11943  ins_encode %{
11944    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11945    __ string_compare($str1$$Register, $str2$$Register,
11946                      $cnt1$$Register, $cnt2$$Register,
11947                      $tmp$$Register,
11948                      $result$$Register, StrIntrinsicNode::UU);
11949  %}
11950  ins_pipe(pipe_class_default);
11951%}
11952
11953instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11954                          iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11955  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
11956  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11957  effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11958  ins_cost(300);
11959  format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11960  ins_encode %{
11961    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11962    __ string_compare($str1$$Register, $str2$$Register,
11963                      $cnt1$$Register, $cnt2$$Register,
11964                      $tmp$$Register,
11965                      $result$$Register, StrIntrinsicNode::LU);
11966  %}
11967  ins_pipe(pipe_class_default);
11968%}
11969
11970instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11971                          iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11972  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
11973  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11974  effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11975  ins_cost(300);
11976  format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11977  ins_encode %{
11978    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11979    __ string_compare($str2$$Register, $str1$$Register,
11980                      $cnt2$$Register, $cnt1$$Register,
11981                      $tmp$$Register,
11982                      $result$$Register, StrIntrinsicNode::UL);
11983  %}
11984  ins_pipe(pipe_class_default);
11985%}
11986
11987instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
11988                        iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11989  predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11990  match(Set result (StrEquals (Binary str1 str2) cnt));
11991  effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
11992  ins_cost(300);
11993  format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
11994  ins_encode %{
11995    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11996    __ array_equals(false, $str1$$Register, $str2$$Register,
11997                    $cnt$$Register, $tmp$$Register,
11998                    $result$$Register, true /* byte */);
11999  %}
12000  ins_pipe(pipe_class_default);
12001%}
12002
12003instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
12004                        iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
12005  predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
12006  match(Set result (StrEquals (Binary str1 str2) cnt));
12007  effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
12008  ins_cost(300);
12009  format %{ "String Equals char[]  $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
12010  ins_encode %{
12011    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12012    __ array_equals(false, $str1$$Register, $str2$$Register,
12013                    $cnt$$Register, $tmp$$Register,
12014                    $result$$Register, false /* byte */);
12015  %}
12016  ins_pipe(pipe_class_default);
12017%}
12018
12019instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
12020                       iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
12021  predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
12022  match(Set result (AryEq ary1 ary2));
12023  effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
12024  ins_cost(300);
12025  format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
12026  ins_encode %{
12027    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12028    __ array_equals(true, $ary1$$Register, $ary2$$Register,
12029                    $tmp1$$Register, $tmp2$$Register,
12030                    $result$$Register, true /* byte */);
12031  %}
12032  ins_pipe(pipe_class_default);
12033%}
12034
12035instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
12036                       iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
12037  predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
12038  match(Set result (AryEq ary1 ary2));
12039  effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
12040  ins_cost(300);
12041  format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
12042  ins_encode %{
12043    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12044    __ array_equals(true, $ary1$$Register, $ary2$$Register,
12045                    $tmp1$$Register, $tmp2$$Register,
12046                    $result$$Register, false /* byte */);
12047  %}
12048  ins_pipe(pipe_class_default);
12049%}
12050
12051instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12052                             immP needleImm, immL offsetImm, immI_1 needlecntImm,
12053                             iRegIdst tmp1, iRegIdst tmp2,
12054                             flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12055  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
12056  effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12057  // Required for EA: check if it is still a type_array.
12058  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
12059  ins_cost(150);
12060
12061  format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
12062            "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12063
12064  ins_encode %{
12065    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12066    immPOper *needleOper = (immPOper *)$needleImm;
12067    const TypeOopPtr *t = needleOper->type()->isa_oopptr();
12068    ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
12069    jchar chr;
12070#ifdef VM_LITTLE_ENDIAN
12071    chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
12072           ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
12073#else
12074    chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
12075           ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
12076#endif
12077    __ string_indexof_char($result$$Register,
12078                           $haystack$$Register, $haycnt$$Register,
12079                           R0, chr,
12080                           $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12081  %}
12082  ins_pipe(pipe_class_compare);
12083%}
12084
12085instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12086                             immP needleImm, immL offsetImm, immI_1 needlecntImm,
12087                             iRegIdst tmp1, iRegIdst tmp2,
12088                             flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12089  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
12090  effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12091  // Required for EA: check if it is still a type_array.
12092  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
12093  ins_cost(150);
12094
12095  format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
12096            "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12097
12098  ins_encode %{
12099    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12100    immPOper *needleOper = (immPOper *)$needleImm;
12101    const TypeOopPtr *t = needleOper->type()->isa_oopptr();
12102    ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
12103    jchar chr = (jchar)needle_values->element_value(0).as_byte();
12104    __ string_indexof_char($result$$Register,
12105                           $haystack$$Register, $haycnt$$Register,
12106                           R0, chr,
12107                           $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
12108  %}
12109  ins_pipe(pipe_class_compare);
12110%}
12111
12112instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12113                              immP needleImm, immL offsetImm, immI_1 needlecntImm,
12114                              iRegIdst tmp1, iRegIdst tmp2,
12115                              flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12116  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
12117  effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12118  // Required for EA: check if it is still a type_array.
12119  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
12120  ins_cost(150);
12121
12122  format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
12123            "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12124
12125  ins_encode %{
12126    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12127    immPOper *needleOper = (immPOper *)$needleImm;
12128    const TypeOopPtr *t = needleOper->type()->isa_oopptr();
12129    ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
12130    jchar chr = (jchar)needle_values->element_value(0).as_byte();
12131    __ string_indexof_char($result$$Register,
12132                           $haystack$$Register, $haycnt$$Register,
12133                           R0, chr,
12134                           $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12135  %}
12136  ins_pipe(pipe_class_compare);
12137%}
12138
12139instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12140                        rscratch2RegP needle, immI_1 needlecntImm,
12141                        iRegIdst tmp1, iRegIdst tmp2,
12142                        flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12143  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12144  effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12145  // Required for EA: check if it is still a type_array.
12146  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
12147            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12148            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12149  ins_cost(180);
12150
12151  format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12152            " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
12153  ins_encode %{
12154    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12155    Node *ndl = in(operand_index($needle));  // The node that defines needle.
12156    ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12157    guarantee(needle_values, "sanity");
12158    jchar chr;
12159#ifdef VM_LITTLE_ENDIAN
12160    chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
12161           ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
12162#else
12163    chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
12164           ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
12165#endif
12166    __ string_indexof_char($result$$Register,
12167                           $haystack$$Register, $haycnt$$Register,
12168                           R0, chr,
12169                           $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12170  %}
12171  ins_pipe(pipe_class_compare);
12172%}
12173
12174instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12175                        rscratch2RegP needle, immI_1 needlecntImm,
12176                        iRegIdst tmp1, iRegIdst tmp2,
12177                        flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12178  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12179  effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12180  // Required for EA: check if it is still a type_array.
12181  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
12182            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12183            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12184  ins_cost(180);
12185
12186  format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12187            " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
12188  ins_encode %{
12189    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12190    Node *ndl = in(operand_index($needle));  // The node that defines needle.
12191    ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12192    guarantee(needle_values, "sanity");
12193    jchar chr = (jchar)needle_values->element_value(0).as_byte();
12194    __ string_indexof_char($result$$Register,
12195                           $haystack$$Register, $haycnt$$Register,
12196                           R0, chr,
12197                           $tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
12198  %}
12199  ins_pipe(pipe_class_compare);
12200%}
12201
12202instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12203                         rscratch2RegP needle, immI_1 needlecntImm,
12204                         iRegIdst tmp1, iRegIdst tmp2,
12205                         flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12206  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12207  effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12208  // Required for EA: check if it is still a type_array.
12209  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
12210            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12211            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12212  ins_cost(180);
12213
12214  format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12215            " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
12216  ins_encode %{
12217    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12218    Node *ndl = in(operand_index($needle));  // The node that defines needle.
12219    ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12220    guarantee(needle_values, "sanity");
12221    jchar chr = (jchar)needle_values->element_value(0).as_byte();
12222    __ string_indexof_char($result$$Register,
12223                           $haystack$$Register, $haycnt$$Register,
12224                           R0, chr,
12225                           $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12226  %}
12227  ins_pipe(pipe_class_compare);
12228%}
12229
12230instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
12231                       iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
12232                       flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
12233  match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
12234  effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
12235  ins_cost(180);
12236
12237  format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
12238            " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
12239  ins_encode %{
12240    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12241    __ string_indexof_char($result$$Register,
12242                           $haystack$$Register, $haycnt$$Register,
12243                           $ch$$Register, 0 /* this is not used if the character is already in a register */,
12244                           $tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
12245  %}
12246  ins_pipe(pipe_class_compare);
12247%}
12248
12249instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12250                       iRegPsrc needle, uimmI15 needlecntImm,
12251                       iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12252                       flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12253  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12254  effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12255         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12256  // Required for EA: check if it is still a type_array.
12257  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
12258            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12259            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12260  ins_cost(250);
12261
12262  format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12263            " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12264  ins_encode %{
12265    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12266    Node *ndl = in(operand_index($needle));  // The node that defines needle.
12267    ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12268
12269    __ string_indexof($result$$Register,
12270                      $haystack$$Register, $haycnt$$Register,
12271                      $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12272                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12273  %}
12274  ins_pipe(pipe_class_compare);
12275%}
12276
12277instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12278                       iRegPsrc needle, uimmI15 needlecntImm,
12279                       iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12280                       flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12281  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12282  effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12283         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12284  // Required for EA: check if it is still a type_array.
12285  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
12286            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12287            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12288  ins_cost(250);
12289
12290  format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12291            " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12292  ins_encode %{
12293    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12294    Node *ndl = in(operand_index($needle));  // The node that defines needle.
12295    ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12296
12297    __ string_indexof($result$$Register,
12298                      $haystack$$Register, $haycnt$$Register,
12299                      $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12300                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12301  %}
12302  ins_pipe(pipe_class_compare);
12303%}
12304
12305instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
12306                        iRegPsrc needle, uimmI15 needlecntImm,
12307                        iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
12308                        flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12309  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
12310  effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
12311         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12312  // Required for EA: check if it is still a type_array.
12313  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
12314            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
12315            n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
12316  ins_cost(250);
12317
12318  format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
12319            " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
12320  ins_encode %{
12321    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12322    Node *ndl = in(operand_index($needle));  // The node that defines needle.
12323    ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
12324
12325    __ string_indexof($result$$Register,
12326                      $haystack$$Register, $haycnt$$Register,
12327                      $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
12328                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12329  %}
12330  ins_pipe(pipe_class_compare);
12331%}
12332
12333instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12334                   iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12335                   flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12336  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12337  effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12338         TEMP_DEF result,
12339         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12340  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
12341  ins_cost(300);
12342
12343  format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12344             " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12345  ins_encode %{
12346    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12347    __ string_indexof($result$$Register,
12348                      $haystack$$Register, $haycnt$$Register,
12349                      $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
12350                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
12351  %}
12352  ins_pipe(pipe_class_compare);
12353%}
12354
12355instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12356                   iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12357                   flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12358  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12359  effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12360         TEMP_DEF result,
12361         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12362  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
12363  ins_cost(300);
12364
12365  format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12366             " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12367  ins_encode %{
12368    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12369    __ string_indexof($result$$Register,
12370                      $haystack$$Register, $haycnt$$Register,
12371                      $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
12372                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
12373  %}
12374  ins_pipe(pipe_class_compare);
12375%}
12376
12377instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
12378                    iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
12379                    flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
12380  match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
12381  effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
12382         TEMP_DEF result,
12383         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
12384  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
12385  ins_cost(300);
12386
12387  format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
12388             " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
12389  ins_encode %{
12390    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12391    __ string_indexof($result$$Register,
12392                      $haystack$$Register, $haycnt$$Register,
12393                      $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
12394                      $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
12395  %}
12396  ins_pipe(pipe_class_compare);
12397%}
12398
12399// char[] to byte[] compression
12400instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12401                         iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12402  match(Set result (StrCompressedCopy src (Binary dst len)));
12403  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12404         USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12405  ins_cost(300);
12406  format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12407  ins_encode %{
12408    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12409    Label Lskip, Ldone;
12410    __ li($result$$Register, 0);
12411    __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
12412                          $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone);
12413    __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
12414    __ beq(CCR0, Lskip);
12415    __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone);
12416    __ bind(Lskip);
12417    __ mr($result$$Register, $len$$Register);
12418    __ bind(Ldone);
12419  %}
12420  ins_pipe(pipe_class_default);
12421%}
12422
12423// byte[] to char[] inflation
12424instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
12425                        iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12426  match(Set dummy (StrInflatedCopy src (Binary dst len)));
12427  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12428  ins_cost(300);
12429  format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12430  ins_encode %{
12431    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12432    Label Ldone;
12433    __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
12434                         $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
12435    __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
12436    __ beq(CCR0, Ldone);
12437    __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
12438    __ bind(Ldone);
12439  %}
12440  ins_pipe(pipe_class_default);
12441%}
12442
12443// StringCoding.java intrinsics
12444instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
12445                       regCTR ctr, flagsRegCR0 cr0)
12446%{
12447  match(Set result (HasNegatives ary1 len));
12448  effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
12449  ins_cost(300);
12450  format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
12451  ins_encode %{
12452    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12453    __ has_negatives($ary1$$Register, $len$$Register, $result$$Register,
12454                     $tmp1$$Register, $tmp2$$Register);
12455  %}
12456  ins_pipe(pipe_class_default);
12457%}
12458
12459// encode char[] to byte[] in ISO_8859_1
12460instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
12461                          iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
12462  match(Set result (EncodeISOArray src (Binary dst len)));
12463  effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
12464         USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
12465  ins_cost(300);
12466  format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
12467  ins_encode %{
12468    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12469    Label Lslow, Lfailure1, Lfailure2, Ldone;
12470    __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
12471                          $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1);
12472    __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters.
12473    __ beq(CCR0, Ldone);
12474    __ bind(Lslow);
12475    __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2);
12476    __ li($result$$Register, 0);
12477    __ b(Ldone);
12478
12479    __ bind(Lfailure1);
12480    __ mr($result$$Register, $len$$Register);
12481    __ mfctr($tmp1$$Register);
12482    __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters.
12483    __ beq(CCR0, Ldone);
12484    __ b(Lslow);
12485
12486    __ bind(Lfailure2);
12487    __ mfctr($result$$Register); // Remaining characters.
12488
12489    __ bind(Ldone);
12490    __ subf($result$$Register, $result$$Register, $len$$Register);
12491  %}
12492  ins_pipe(pipe_class_default);
12493%}
12494
12495
12496//---------- Min/Max Instructions ---------------------------------------------
12497
12498instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
12499  match(Set dst (MinI src1 src2));
12500  ins_cost(DEFAULT_COST*6);
12501
12502  expand %{
12503    iRegLdst src1s;
12504    iRegLdst src2s;
12505    iRegLdst diff;
12506    iRegLdst sm;
12507    iRegLdst doz; // difference or zero
12508    convI2L_reg(src1s, src1); // Ensure proper sign extension.
12509    convI2L_reg(src2s, src2); // Ensure proper sign extension.
12510    subL_reg_reg(diff, src2s, src1s);
12511    // Need to consider >=33 bit result, therefore we need signmaskL.
12512    signmask64L_regL(sm, diff);
12513    andL_reg_reg(doz, diff, sm); // <=0
12514    addI_regL_regL(dst, doz, src1s);
12515  %}
12516%}
12517
12518instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12519  match(Set dst (MinI src1 src2));
12520  effect(KILL cr0);
12521  predicate(VM_Version::has_isel());
12522  ins_cost(DEFAULT_COST*2);
12523
12524  ins_encode %{
12525    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12526    __ cmpw(CCR0, $src1$$Register, $src2$$Register);
12527    __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
12528  %}
12529  ins_pipe(pipe_class_default);
12530%}
12531
12532instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
12533  match(Set dst (MaxI src1 src2));
12534  ins_cost(DEFAULT_COST*6);
12535
12536  expand %{
12537    iRegLdst src1s;
12538    iRegLdst src2s;
12539    iRegLdst diff;
12540    iRegLdst sm;
12541    iRegLdst doz; // difference or zero
12542    convI2L_reg(src1s, src1); // Ensure proper sign extension.
12543    convI2L_reg(src2s, src2); // Ensure proper sign extension.
12544    subL_reg_reg(diff, src2s, src1s);
12545    // Need to consider >=33 bit result, therefore we need signmaskL.
12546    signmask64L_regL(sm, diff);
12547    andcL_reg_reg(doz, diff, sm); // >=0
12548    addI_regL_regL(dst, doz, src1s);
12549  %}
12550%}
12551
12552instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
12553  match(Set dst (MaxI src1 src2));
12554  effect(KILL cr0);
12555  predicate(VM_Version::has_isel());
12556  ins_cost(DEFAULT_COST*2);
12557
12558  ins_encode %{
12559    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12560    __ cmpw(CCR0, $src1$$Register, $src2$$Register);
12561    __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
12562  %}
12563  ins_pipe(pipe_class_default);
12564%}
12565
12566//---------- Population Count Instructions ------------------------------------
12567
12568// Popcnt for Power7.
12569instruct popCountI(iRegIdst dst, iRegIsrc src) %{
12570  match(Set dst (PopCountI src));
12571  predicate(UsePopCountInstruction && VM_Version::has_popcntw());
12572  ins_cost(DEFAULT_COST);
12573
12574  format %{ "POPCNTW $dst, $src" %}
12575  size(4);
12576  ins_encode %{
12577    // TODO: PPC port $archOpcode(ppc64Opcode_popcntb);
12578    __ popcntw($dst$$Register, $src$$Register);
12579  %}
12580  ins_pipe(pipe_class_default);
12581%}
12582
12583// Popcnt for Power7.
12584instruct popCountL(iRegIdst dst, iRegLsrc src) %{
12585  predicate(UsePopCountInstruction && VM_Version::has_popcntw());
12586  match(Set dst (PopCountL src));
12587  ins_cost(DEFAULT_COST);
12588
12589  format %{ "POPCNTD $dst, $src" %}
12590  size(4);
12591  ins_encode %{
12592    // TODO: PPC port $archOpcode(ppc64Opcode_popcntb);
12593    __ popcntd($dst$$Register, $src$$Register);
12594  %}
12595  ins_pipe(pipe_class_default);
12596%}
12597
12598instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
12599  match(Set dst (CountLeadingZerosI src));
12600  predicate(UseCountLeadingZerosInstructionsPPC64);  // See Matcher::match_rule_supported.
12601  ins_cost(DEFAULT_COST);
12602
12603  format %{ "CNTLZW  $dst, $src" %}
12604  size(4);
12605  ins_encode %{
12606    // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw);
12607    __ cntlzw($dst$$Register, $src$$Register);
12608  %}
12609  ins_pipe(pipe_class_default);
12610%}
12611
12612instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
12613  match(Set dst (CountLeadingZerosL src));
12614  predicate(UseCountLeadingZerosInstructionsPPC64);  // See Matcher::match_rule_supported.
12615  ins_cost(DEFAULT_COST);
12616
12617  format %{ "CNTLZD  $dst, $src" %}
12618  size(4);
12619  ins_encode %{
12620    // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd);
12621    __ cntlzd($dst$$Register, $src$$Register);
12622  %}
12623  ins_pipe(pipe_class_default);
12624%}
12625
12626instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
12627  // no match-rule, false predicate
12628  effect(DEF dst, USE src);
12629  predicate(false);
12630
12631  format %{ "CNTLZD  $dst, $src" %}
12632  size(4);
12633  ins_encode %{
12634    // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd);
12635    __ cntlzd($dst$$Register, $src$$Register);
12636  %}
12637  ins_pipe(pipe_class_default);
12638%}
12639
12640instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{
12641  match(Set dst (CountTrailingZerosI src));
12642  predicate(UseCountLeadingZerosInstructionsPPC64);
12643  ins_cost(DEFAULT_COST);
12644
12645  expand %{
12646    immI16 imm1 %{ (int)-1 %}
12647    immI16 imm2 %{ (int)32 %}
12648    immI_minus1 m1 %{ -1 %}
12649    iRegIdst tmpI1;
12650    iRegIdst tmpI2;
12651    iRegIdst tmpI3;
12652    addI_reg_imm16(tmpI1, src, imm1);
12653    andcI_reg_reg(tmpI2, src, m1, tmpI1);
12654    countLeadingZerosI(tmpI3, tmpI2);
12655    subI_imm16_reg(dst, imm2, tmpI3);
12656  %}
12657%}
12658
12659instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{
12660  match(Set dst (CountTrailingZerosL src));
12661  predicate(UseCountLeadingZerosInstructionsPPC64);
12662  ins_cost(DEFAULT_COST);
12663
12664  expand %{
12665    immL16 imm1 %{ (long)-1 %}
12666    immI16 imm2 %{ (int)64 %}
12667    iRegLdst tmpL1;
12668    iRegLdst tmpL2;
12669    iRegIdst tmpL3;
12670    addL_reg_imm16(tmpL1, src, imm1);
12671    andcL_reg_reg(tmpL2, tmpL1, src);
12672    countLeadingZerosL(tmpL3, tmpL2);
12673    subI_imm16_reg(dst, imm2, tmpL3);
12674 %}
12675%}
12676
12677// Expand nodes for byte_reverse_int.
12678instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{
12679  effect(DEF dst, USE src, USE pos, USE shift);
12680  predicate(false);
12681
12682  format %{ "INSRWI  $dst, $src, $pos, $shift" %}
12683  size(4);
12684  ins_encode %{
12685    // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi);
12686    __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant);
12687  %}
12688  ins_pipe(pipe_class_default);
12689%}
12690
12691// As insrwi_a, but with USE_DEF.
12692instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{
12693  effect(USE_DEF dst, USE src, USE pos, USE shift);
12694  predicate(false);
12695
12696  format %{ "INSRWI  $dst, $src, $pos, $shift" %}
12697  size(4);
12698  ins_encode %{
12699    // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi);
12700    __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant);
12701  %}
12702  ins_pipe(pipe_class_default);
12703%}
12704
12705// Just slightly faster than java implementation.
12706instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
12707  match(Set dst (ReverseBytesI src));
12708  predicate(UseCountLeadingZerosInstructionsPPC64);
12709  ins_cost(DEFAULT_COST);
12710
12711  expand %{
12712    immI16 imm24 %{ (int) 24 %}
12713    immI16 imm16 %{ (int) 16 %}
12714    immI16  imm8 %{ (int)  8 %}
12715    immI16  imm4 %{ (int)  4 %}
12716    immI16  imm0 %{ (int)  0 %}
12717    iRegLdst tmpI1;
12718    iRegLdst tmpI2;
12719    iRegLdst tmpI3;
12720
12721    urShiftI_reg_imm(tmpI1, src, imm24);
12722    insrwi_a(dst, tmpI1, imm24, imm8);
12723    urShiftI_reg_imm(tmpI2, src, imm16);
12724    insrwi(dst, tmpI2, imm8, imm16);
12725    urShiftI_reg_imm(tmpI3, src, imm8);
12726    insrwi(dst, tmpI3, imm8, imm8);
12727    insrwi(dst, src, imm0, imm8);
12728  %}
12729%}
12730
12731//---------- Replicate Vector Instructions ------------------------------------
12732
12733// Insrdi does replicate if src == dst.
12734instruct repl32(iRegLdst dst) %{
12735  predicate(false);
12736  effect(USE_DEF dst);
12737
12738  format %{ "INSRDI  $dst, #0, $dst, #32 \t// replicate" %}
12739  size(4);
12740  ins_encode %{
12741    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
12742    __ insrdi($dst$$Register, $dst$$Register, 32, 0);
12743  %}
12744  ins_pipe(pipe_class_default);
12745%}
12746
12747// Insrdi does replicate if src == dst.
12748instruct repl48(iRegLdst dst) %{
12749  predicate(false);
12750  effect(USE_DEF dst);
12751
12752  format %{ "INSRDI  $dst, #0, $dst, #48 \t// replicate" %}
12753  size(4);
12754  ins_encode %{
12755    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
12756    __ insrdi($dst$$Register, $dst$$Register, 48, 0);
12757  %}
12758  ins_pipe(pipe_class_default);
12759%}
12760
12761// Insrdi does replicate if src == dst.
12762instruct repl56(iRegLdst dst) %{
12763  predicate(false);
12764  effect(USE_DEF dst);
12765
12766  format %{ "INSRDI  $dst, #0, $dst, #56 \t// replicate" %}
12767  size(4);
12768  ins_encode %{
12769    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
12770    __ insrdi($dst$$Register, $dst$$Register, 56, 0);
12771  %}
12772  ins_pipe(pipe_class_default);
12773%}
12774
12775instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12776  match(Set dst (ReplicateB src));
12777  predicate(n->as_Vector()->length() == 8);
12778  expand %{
12779    moveReg(dst, src);
12780    repl56(dst);
12781    repl48(dst);
12782    repl32(dst);
12783  %}
12784%}
12785
12786instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
12787  match(Set dst (ReplicateB zero));
12788  predicate(n->as_Vector()->length() == 8);
12789  format %{ "LI      $dst, #0 \t// replicate8B" %}
12790  size(4);
12791  ins_encode %{
12792    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
12793    __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12794  %}
12795  ins_pipe(pipe_class_default);
12796%}
12797
12798instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
12799  match(Set dst (ReplicateB src));
12800  predicate(n->as_Vector()->length() == 8);
12801  format %{ "LI      $dst, #-1 \t// replicate8B" %}
12802  size(4);
12803  ins_encode %{
12804    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
12805    __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12806  %}
12807  ins_pipe(pipe_class_default);
12808%}
12809
12810instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12811  match(Set dst (ReplicateS src));
12812  predicate(n->as_Vector()->length() == 4);
12813  expand %{
12814    moveReg(dst, src);
12815    repl48(dst);
12816    repl32(dst);
12817  %}
12818%}
12819
12820instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
12821  match(Set dst (ReplicateS zero));
12822  predicate(n->as_Vector()->length() == 4);
12823  format %{ "LI      $dst, #0 \t// replicate4C" %}
12824  size(4);
12825  ins_encode %{
12826    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
12827    __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12828  %}
12829  ins_pipe(pipe_class_default);
12830%}
12831
12832instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
12833  match(Set dst (ReplicateS src));
12834  predicate(n->as_Vector()->length() == 4);
12835  format %{ "LI      $dst, -1 \t// replicate4C" %}
12836  size(4);
12837  ins_encode %{
12838    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
12839    __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12840  %}
12841  ins_pipe(pipe_class_default);
12842%}
12843
12844instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{
12845  match(Set dst (ReplicateI src));
12846  predicate(n->as_Vector()->length() == 2);
12847  ins_cost(2 * DEFAULT_COST);
12848  expand %{
12849    moveReg(dst, src);
12850    repl32(dst);
12851  %}
12852%}
12853
12854instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
12855  match(Set dst (ReplicateI zero));
12856  predicate(n->as_Vector()->length() == 2);
12857  format %{ "LI      $dst, #0 \t// replicate4C" %}
12858  size(4);
12859  ins_encode %{
12860    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
12861    __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
12862  %}
12863  ins_pipe(pipe_class_default);
12864%}
12865
12866instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
12867  match(Set dst (ReplicateI src));
12868  predicate(n->as_Vector()->length() == 2);
12869  format %{ "LI      $dst, -1 \t// replicate4C" %}
12870  size(4);
12871  ins_encode %{
12872    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
12873    __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
12874  %}
12875  ins_pipe(pipe_class_default);
12876%}
12877
12878// Move float to int register via stack, replicate.
12879instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{
12880  match(Set dst (ReplicateF src));
12881  predicate(n->as_Vector()->length() == 2);
12882  ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST);
12883  expand %{
12884    stackSlotL tmpS;
12885    iRegIdst tmpI;
12886    moveF2I_reg_stack(tmpS, src);   // Move float to stack.
12887    moveF2I_stack_reg(tmpI, tmpS);  // Move stack to int reg.
12888    moveReg(dst, tmpI);             // Move int to long reg.
12889    repl32(dst);                    // Replicate bitpattern.
12890  %}
12891%}
12892
12893// Replicate scalar constant to packed float values in Double register
12894instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{
12895  match(Set dst (ReplicateF src));
12896  predicate(n->as_Vector()->length() == 2);
12897  ins_cost(5 * DEFAULT_COST);
12898
12899  format %{ "LD      $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %}
12900  postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) );
12901%}
12902
12903// Replicate scalar zero constant to packed float values in Double register
12904instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
12905  match(Set dst (ReplicateF zero));
12906  predicate(n->as_Vector()->length() == 2);
12907
12908  format %{ "LI      $dst, #0 \t// replicate2F" %}
12909  ins_encode %{
12910    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
12911    __ li($dst$$Register, 0x0);
12912  %}
12913  ins_pipe(pipe_class_default);
12914%}
12915
12916
12917//----------Overflow Math Instructions-----------------------------------------
12918
12919// Note that we have to make sure that XER.SO is reset before using overflow instructions.
12920// Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc).
12921// Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.)
12922
12923instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
12924  match(Set cr0 (OverflowAddL op1 op2));
12925
12926  format %{ "add_    $op1, $op2\t# overflow check long" %}
12927  ins_encode %{
12928    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12929    __ li(R0, 0);
12930    __ mtxer(R0); // clear XER.SO
12931    __ addo_(R0, $op1$$Register, $op2$$Register);
12932  %}
12933  ins_pipe(pipe_class_default);
12934%}
12935
12936instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
12937  match(Set cr0 (OverflowSubL op1 op2));
12938
12939  format %{ "subfo_  R0, $op2, $op1\t# overflow check long" %}
12940  ins_encode %{
12941    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12942    __ li(R0, 0);
12943    __ mtxer(R0); // clear XER.SO
12944    __ subfo_(R0, $op2$$Register, $op1$$Register);
12945  %}
12946  ins_pipe(pipe_class_default);
12947%}
12948
12949instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
12950  match(Set cr0 (OverflowSubL zero op2));
12951
12952  format %{ "nego_   R0, $op2\t# overflow check long" %}
12953  ins_encode %{
12954    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12955    __ li(R0, 0);
12956    __ mtxer(R0); // clear XER.SO
12957    __ nego_(R0, $op2$$Register);
12958  %}
12959  ins_pipe(pipe_class_default);
12960%}
12961
12962instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
12963  match(Set cr0 (OverflowMulL op1 op2));
12964
12965  format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %}
12966  ins_encode %{
12967    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
12968    __ li(R0, 0);
12969    __ mtxer(R0); // clear XER.SO
12970    __ mulldo_(R0, $op1$$Register, $op2$$Register);
12971  %}
12972  ins_pipe(pipe_class_default);
12973%}
12974
12975
12976// ============================================================================
12977// Safepoint Instruction
12978
12979instruct safePoint_poll(iRegPdst poll) %{
12980  match(SafePoint poll);
12981  predicate(LoadPollAddressFromThread);
12982
12983  // It caused problems to add the effect that r0 is killed, but this
12984  // effect no longer needs to be mentioned, since r0 is not contained
12985  // in a reg_class.
12986
12987  format %{ "LD      R0, #0, $poll \t// Safepoint poll for GC" %}
12988  size(4);
12989  ins_encode( enc_poll(0x0, poll) );
12990  ins_pipe(pipe_class_default);
12991%}
12992
12993// Safepoint without per-thread support. Load address of page to poll
12994// as constant.
12995// Rscratch2RegP is R12.
12996// LoadConPollAddr node is added in pd_post_matching_hook(). It must be
12997// a seperate node so that the oop map is at the right location.
12998instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{
12999  match(SafePoint poll);
13000  predicate(!LoadPollAddressFromThread);
13001
13002  // It caused problems to add the effect that r0 is killed, but this
13003  // effect no longer needs to be mentioned, since r0 is not contained
13004  // in a reg_class.
13005
13006  format %{ "LD      R0, #0, R12 \t// Safepoint poll for GC" %}
13007  ins_encode( enc_poll(0x0, poll) );
13008  ins_pipe(pipe_class_default);
13009%}
13010
13011// ============================================================================
13012// Call Instructions
13013
13014// Call Java Static Instruction
13015
13016// Schedulable version of call static node.
13017instruct CallStaticJavaDirect(method meth) %{
13018  match(CallStaticJava);
13019  effect(USE meth);
13020  ins_cost(CALL_COST);
13021
13022  ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */);
13023
13024  format %{ "CALL,static $meth \t// ==> " %}
13025  size(4);
13026  ins_encode( enc_java_static_call(meth) );
13027  ins_pipe(pipe_class_call);
13028%}
13029
13030// Call Java Dynamic Instruction
13031
13032// Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call).
13033// Loading of IC was postalloc expanded. The nodes loading the IC are reachable
13034// via fields ins_field_load_ic_hi_node and ins_field_load_ic_node.
13035// The call destination must still be placed in the constant pool.
13036instruct CallDynamicJavaDirectSched(method meth) %{
13037  match(CallDynamicJava); // To get all the data fields we need ...
13038  effect(USE meth);
13039  predicate(false);       // ... but never match.
13040
13041  ins_field_load_ic_hi_node(loadConL_hiNode*);
13042  ins_field_load_ic_node(loadConLNode*);
13043  ins_num_consts(1 /* 1 patchable constant: call destination */);
13044
13045  format %{ "BL        \t// dynamic $meth ==> " %}
13046  size(4);
13047  ins_encode( enc_java_dynamic_call_sched(meth) );
13048  ins_pipe(pipe_class_call);
13049%}
13050
13051// Schedulable (i.e. postalloc expanded) version of call dynamic java.
13052// We use postalloc expanded calls if we use inline caches
13053// and do not update method data.
13054//
13055// This instruction has two constants: inline cache (IC) and call destination.
13056// Loading the inline cache will be postalloc expanded, thus leaving a call with
13057// one constant.
13058instruct CallDynamicJavaDirectSched_Ex(method meth) %{
13059  match(CallDynamicJava);
13060  effect(USE meth);
13061  predicate(UseInlineCaches);
13062  ins_cost(CALL_COST);
13063
13064  ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */);
13065
13066  format %{ "CALL,dynamic $meth \t// postalloc expanded" %}
13067  postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) );
13068%}
13069
13070// Compound version of call dynamic java
13071// We use postalloc expanded calls if we use inline caches
13072// and do not update method data.
13073instruct CallDynamicJavaDirect(method meth) %{
13074  match(CallDynamicJava);
13075  effect(USE meth);
13076  predicate(!UseInlineCaches);
13077  ins_cost(CALL_COST);
13078
13079  // Enc_java_to_runtime_call needs up to 4 constants (method data oop).
13080  ins_num_consts(4);
13081
13082  format %{ "CALL,dynamic $meth \t// ==> " %}
13083  ins_encode( enc_java_dynamic_call(meth, constanttablebase) );
13084  ins_pipe(pipe_class_call);
13085%}
13086
13087// Call Runtime Instruction
13088
13089instruct CallRuntimeDirect(method meth) %{
13090  match(CallRuntime);
13091  effect(USE meth);
13092  ins_cost(CALL_COST);
13093
13094  // Enc_java_to_runtime_call needs up to 3 constants: call target,
13095  // env for callee, C-toc.
13096  ins_num_consts(3);
13097
13098  format %{ "CALL,runtime" %}
13099  ins_encode( enc_java_to_runtime_call(meth) );
13100  ins_pipe(pipe_class_call);
13101%}
13102
13103// Call Leaf
13104
13105// Used by postalloc expand of CallLeafDirect_Ex (mtctr).
13106instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{
13107  effect(DEF dst, USE src);
13108
13109  ins_num_consts(1);
13110
13111  format %{ "MTCTR   $src" %}
13112  size(4);
13113  ins_encode( enc_leaf_call_mtctr(src) );
13114  ins_pipe(pipe_class_default);
13115%}
13116
13117// Used by postalloc expand of CallLeafDirect_Ex (actual call).
13118instruct CallLeafDirect(method meth) %{
13119  match(CallLeaf);   // To get the data all the data fields we need ...
13120  effect(USE meth);
13121  predicate(false);  // but never match.
13122
13123  format %{ "BCTRL     \t// leaf call $meth ==> " %}
13124  size(4);
13125  ins_encode %{
13126    // TODO: PPC port $archOpcode(ppc64Opcode_bctrl);
13127    __ bctrl();
13128  %}
13129  ins_pipe(pipe_class_call);
13130%}
13131
13132// postalloc expand of CallLeafDirect.
13133// Load adress to call from TOC, then bl to it.
13134instruct CallLeafDirect_Ex(method meth) %{
13135  match(CallLeaf);
13136  effect(USE meth);
13137  ins_cost(CALL_COST);
13138
13139  // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target,
13140  // env for callee, C-toc.
13141  ins_num_consts(3);
13142
13143  format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %}
13144  postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13145%}
13146
13147// Call runtime without safepoint - same as CallLeaf.
13148// postalloc expand of CallLeafNoFPDirect.
13149// Load adress to call from TOC, then bl to it.
13150instruct CallLeafNoFPDirect_Ex(method meth) %{
13151  match(CallLeafNoFP);
13152  effect(USE meth);
13153  ins_cost(CALL_COST);
13154
13155  // Enc_java_to_runtime_call needs up to 3 constants: call target,
13156  // env for callee, C-toc.
13157  ins_num_consts(3);
13158
13159  format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %}
13160  postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) );
13161%}
13162
13163// Tail Call; Jump from runtime stub to Java code.
13164// Also known as an 'interprocedural jump'.
13165// Target of jump will eventually return to caller.
13166// TailJump below removes the return address.
13167instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{
13168  match(TailCall jump_target method_oop);
13169  ins_cost(CALL_COST);
13170
13171  format %{ "MTCTR   $jump_target \t// $method_oop holds method oop\n\t"
13172            "BCTR         \t// tail call" %}
13173  size(8);
13174  ins_encode %{
13175    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
13176    __ mtctr($jump_target$$Register);
13177    __ bctr();
13178  %}
13179  ins_pipe(pipe_class_call);
13180%}
13181
13182// Return Instruction
13183instruct Ret() %{
13184  match(Return);
13185  format %{ "BLR      \t// branch to link register" %}
13186  size(4);
13187  ins_encode %{
13188    // TODO: PPC port $archOpcode(ppc64Opcode_blr);
13189    // LR is restored in MachEpilogNode. Just do the RET here.
13190    __ blr();
13191  %}
13192  ins_pipe(pipe_class_default);
13193%}
13194
13195// Tail Jump; remove the return address; jump to target.
13196// TailCall above leaves the return address around.
13197// TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13198// ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13199// "restore" before this instruction (in Epilogue), we need to materialize it
13200// in %i0.
13201instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
13202  match(TailJump jump_target ex_oop);
13203  ins_cost(CALL_COST);
13204
13205  format %{ "LD      R4_ARG2 = LR\n\t"
13206            "MTCTR   $jump_target\n\t"
13207            "BCTR     \t// TailJump, exception oop: $ex_oop" %}
13208  size(12);
13209  ins_encode %{
13210    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
13211    __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP);
13212    __ mtctr($jump_target$$Register);
13213    __ bctr();
13214  %}
13215  ins_pipe(pipe_class_call);
13216%}
13217
13218// Create exception oop: created by stack-crawling runtime code.
13219// Created exception is now available to this handler, and is setup
13220// just prior to jumping to this handler. No code emitted.
13221instruct CreateException(rarg1RegP ex_oop) %{
13222  match(Set ex_oop (CreateEx));
13223  ins_cost(0);
13224
13225  format %{ " -- \t// exception oop; no code emitted" %}
13226  size(0);
13227  ins_encode( /*empty*/ );
13228  ins_pipe(pipe_class_default);
13229%}
13230
13231// Rethrow exception: The exception oop will come in the first
13232// argument position. Then JUMP (not call) to the rethrow stub code.
13233instruct RethrowException() %{
13234  match(Rethrow);
13235  ins_cost(CALL_COST);
13236
13237  format %{ "Jmp     rethrow_stub" %}
13238  ins_encode %{
13239    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
13240    cbuf.set_insts_mark();
13241    __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
13242  %}
13243  ins_pipe(pipe_class_call);
13244%}
13245
13246// Die now.
13247instruct ShouldNotReachHere() %{
13248  match(Halt);
13249  ins_cost(CALL_COST);
13250
13251  format %{ "ShouldNotReachHere" %}
13252  size(4);
13253  ins_encode %{
13254    // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
13255    __ trap_should_not_reach_here();
13256  %}
13257  ins_pipe(pipe_class_default);
13258%}
13259
13260// This name is KNOWN by the ADLC and cannot be changed.  The ADLC
13261// forces a 'TypeRawPtr::BOTTOM' output type for this guy.
13262// Get a DEF on threadRegP, no costs, no encoding, use
13263// 'ins_should_rematerialize(true)' to avoid spilling.
13264instruct tlsLoadP(threadRegP dst) %{
13265  match(Set dst (ThreadLocal));
13266  ins_cost(0);
13267
13268  ins_should_rematerialize(true);
13269
13270  format %{ " -- \t// $dst=Thread::current(), empty" %}
13271  size(0);
13272  ins_encode( /*empty*/ );
13273  ins_pipe(pipe_class_empty);
13274%}
13275
13276//---Some PPC specific nodes---------------------------------------------------
13277
13278// Stop a group.
13279instruct endGroup() %{
13280  ins_cost(0);
13281
13282  ins_is_nop(true);
13283
13284  format %{ "End Bundle (ori r1, r1, 0)" %}
13285  size(4);
13286  ins_encode %{
13287    // TODO: PPC port $archOpcode(ppc64Opcode_endgroup);
13288    __ endgroup();
13289  %}
13290  ins_pipe(pipe_class_default);
13291%}
13292
13293// Nop instructions
13294
13295instruct fxNop() %{
13296  ins_cost(0);
13297
13298  ins_is_nop(true);
13299
13300  format %{ "fxNop" %}
13301  size(4);
13302  ins_encode %{
13303    // TODO: PPC port $archOpcode(ppc64Opcode_fmr);
13304    __ nop();
13305  %}
13306  ins_pipe(pipe_class_default);
13307%}
13308
13309instruct fpNop0() %{
13310  ins_cost(0);
13311
13312  ins_is_nop(true);
13313
13314  format %{ "fpNop0" %}
13315  size(4);
13316  ins_encode %{
13317    // TODO: PPC port $archOpcode(ppc64Opcode_fmr);
13318    __ fpnop0();
13319  %}
13320  ins_pipe(pipe_class_default);
13321%}
13322
13323instruct fpNop1() %{
13324  ins_cost(0);
13325
13326  ins_is_nop(true);
13327
13328  format %{ "fpNop1" %}
13329  size(4);
13330  ins_encode %{
13331    // TODO: PPC port $archOpcode(ppc64Opcode_fmr);
13332    __ fpnop1();
13333  %}
13334  ins_pipe(pipe_class_default);
13335%}
13336
13337instruct brNop0() %{
13338  ins_cost(0);
13339  size(4);
13340  format %{ "brNop0" %}
13341  ins_encode %{
13342    // TODO: PPC port $archOpcode(ppc64Opcode_mcrf);
13343    __ brnop0();
13344  %}
13345  ins_is_nop(true);
13346  ins_pipe(pipe_class_default);
13347%}
13348
13349instruct brNop1() %{
13350  ins_cost(0);
13351
13352  ins_is_nop(true);
13353
13354  format %{ "brNop1" %}
13355  size(4);
13356  ins_encode %{
13357    // TODO: PPC port $archOpcode(ppc64Opcode_mcrf);
13358    __ brnop1();
13359  %}
13360  ins_pipe(pipe_class_default);
13361%}
13362
13363instruct brNop2() %{
13364  ins_cost(0);
13365
13366  ins_is_nop(true);
13367
13368  format %{ "brNop2" %}
13369  size(4);
13370  ins_encode %{
13371    // TODO: PPC port $archOpcode(ppc64Opcode_mcrf);
13372    __ brnop2();
13373  %}
13374  ins_pipe(pipe_class_default);
13375%}
13376
13377//----------PEEPHOLE RULES-----------------------------------------------------
13378// These must follow all instruction definitions as they use the names
13379// defined in the instructions definitions.
13380//
13381// peepmatch ( root_instr_name [preceeding_instruction]* );
13382//
13383// peepconstraint %{
13384// (instruction_number.operand_name relational_op instruction_number.operand_name
13385//  [, ...] );
13386// // instruction numbers are zero-based using left to right order in peepmatch
13387//
13388// peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
13389// // provide an instruction_number.operand_name for each operand that appears
13390// // in the replacement instruction's match rule
13391//
13392// ---------VM FLAGS---------------------------------------------------------
13393//
13394// All peephole optimizations can be turned off using -XX:-OptoPeephole
13395//
13396// Each peephole rule is given an identifying number starting with zero and
13397// increasing by one in the order seen by the parser. An individual peephole
13398// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
13399// on the command-line.
13400//
13401// ---------CURRENT LIMITATIONS----------------------------------------------
13402//
13403// Only match adjacent instructions in same basic block
13404// Only equality constraints
13405// Only constraints between operands, not (0.dest_reg == EAX_enc)
13406// Only one replacement instruction
13407//
13408// ---------EXAMPLE----------------------------------------------------------
13409//
13410// // pertinent parts of existing instructions in architecture description
13411// instruct movI(eRegI dst, eRegI src) %{
13412//   match(Set dst (CopyI src));
13413// %}
13414//
13415// instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
13416//   match(Set dst (AddI dst src));
13417//   effect(KILL cr);
13418// %}
13419//
13420// // Change (inc mov) to lea
13421// peephole %{
13422//   // increment preceeded by register-register move
13423//   peepmatch ( incI_eReg movI );
13424//   // require that the destination register of the increment
13425//   // match the destination register of the move
13426//   peepconstraint ( 0.dst == 1.dst );
13427//   // construct a replacement instruction that sets
13428//   // the destination to ( move's source register + one )
13429//   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13430// %}
13431//
13432// Implementation no longer uses movX instructions since
13433// machine-independent system no longer uses CopyX nodes.
13434//
13435// peephole %{
13436//   peepmatch ( incI_eReg movI );
13437//   peepconstraint ( 0.dst == 1.dst );
13438//   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13439// %}
13440//
13441// peephole %{
13442//   peepmatch ( decI_eReg movI );
13443//   peepconstraint ( 0.dst == 1.dst );
13444//   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13445// %}
13446//
13447// peephole %{
13448//   peepmatch ( addI_eReg_imm movI );
13449//   peepconstraint ( 0.dst == 1.dst );
13450//   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13451// %}
13452//
13453// peephole %{
13454//   peepmatch ( addP_eReg_imm movP );
13455//   peepconstraint ( 0.dst == 1.dst );
13456//   peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
13457// %}
13458
13459// // Change load of spilled value to only a spill
13460// instruct storeI(memory mem, eRegI src) %{
13461//   match(Set mem (StoreI mem src));
13462// %}
13463//
13464// instruct loadI(eRegI dst, memory mem) %{
13465//   match(Set dst (LoadI mem));
13466// %}
13467//
13468peephole %{
13469  peepmatch ( loadI storeI );
13470  peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13471  peepreplace ( storeI( 1.mem 1.mem 1.src ) );
13472%}
13473
13474peephole %{
13475  peepmatch ( loadL storeL );
13476  peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13477  peepreplace ( storeL( 1.mem 1.mem 1.src ) );
13478%}
13479
13480peephole %{
13481  peepmatch ( loadP storeP );
13482  peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem );
13483  peepreplace ( storeP( 1.dst 1.dst 1.src ) );
13484%}
13485
13486//----------SMARTSPILL RULES---------------------------------------------------
13487// These must follow all instruction definitions as they use the names
13488// defined in the instructions definitions.
13489