Mercurial > hg > graal-compiler
annotate src/cpu/sparc/vm/sparc.ad @ 1708:a03ae377b2e8
6930581: G1: assert(ParallelGCThreads > 1 || n_yielded() == _hrrs->occupied(),"Should have yielded all the ..
Summary: During RSet updating, when ParallelGCThreads is zero, references that point into the collection set are added directly the referenced region's RSet. This can cause the sparse table in the RSet to expand. RSet scanning and the "occupied" routine will then operate on different instances of the sparse table causing the assert to trip. This may also cause some cards added post expansion to be missed during RSet scanning. When ParallelGCThreads is non-zero such references are recorded on the "references to be scanned" queue and the card containing the reference is recorded in a dirty card queue for use in the event of an evacuation failure. Employ the parallel code in the serial case to avoid expanding the RSets of regions in the collection set.
Reviewed-by: iveresov, ysr, tonyp
author | johnc |
---|---|
date | Fri, 06 Aug 2010 10:17:21 -0700 |
parents | e9ff18c4ace7 |
children | 3e8fbc61cee8 |
rev | line source |
---|---|
0 | 1 // |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1396
diff
changeset
|
2 // Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 // | |
5 // This code is free software; you can redistribute it and/or modify it | |
6 // under the terms of the GNU General Public License version 2 only, as | |
7 // published by the Free Software Foundation. | |
8 // | |
9 // This code is distributed in the hope that it will be useful, but WITHOUT | |
10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 // version 2 for more details (a copy is included in the LICENSE file that | |
13 // accompanied this code). | |
14 // | |
15 // You should have received a copy of the GNU General Public License version | |
16 // 2 along with this work; if not, write to the Free Software Foundation, | |
17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 // | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1396
diff
changeset
|
19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1396
diff
changeset
|
20 // or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1396
diff
changeset
|
21 // questions. |
0 | 22 // |
23 // | |
24 | |
25 // SPARC Architecture Description File | |
26 | |
27 //----------REGISTER DEFINITION BLOCK------------------------------------------ | |
28 // This information is used by the matcher and the register allocator to | |
29 // describe individual registers and classes of registers within the target | |
30 // archtecture. | |
31 register %{ | |
32 //----------Architecture Description Register Definitions---------------------- | |
33 // General Registers | |
34 // "reg_def" name ( register save type, C convention save type, | |
35 // ideal register type, encoding, vm name ); | |
36 // Register Save Types: | |
37 // | |
38 // NS = No-Save: The register allocator assumes that these registers | |
39 // can be used without saving upon entry to the method, & | |
40 // that they do not need to be saved at call sites. | |
41 // | |
42 // SOC = Save-On-Call: The register allocator assumes that these registers | |
43 // can be used without saving upon entry to the method, | |
44 // but that they must be saved at call sites. | |
45 // | |
46 // SOE = Save-On-Entry: The register allocator assumes that these registers | |
47 // must be saved before using them upon entry to the | |
48 // method, but they do not need to be saved at call | |
49 // sites. | |
50 // | |
51 // AS = Always-Save: The register allocator assumes that these registers | |
52 // must be saved before using them upon entry to the | |
53 // method, & that they must be saved at call sites. | |
54 // | |
55 // Ideal Register Type is used to determine how to save & restore a | |
56 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get | |
57 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. | |
58 // | |
59 // The encoding number is the actual bit-pattern placed into the opcodes. | |
60 | |
61 | |
62 // ---------------------------- | |
63 // Integer/Long Registers | |
64 // ---------------------------- | |
65 | |
66 // Need to expose the hi/lo aspect of 64-bit registers | |
67 // This register set is used for both the 64-bit build and | |
68 // the 32-bit build with 1-register longs. | |
69 | |
70 // Global Registers 0-7 | |
71 reg_def R_G0H( NS, NS, Op_RegI,128, G0->as_VMReg()->next()); | |
72 reg_def R_G0 ( NS, NS, Op_RegI, 0, G0->as_VMReg()); | |
73 reg_def R_G1H(SOC, SOC, Op_RegI,129, G1->as_VMReg()->next()); | |
74 reg_def R_G1 (SOC, SOC, Op_RegI, 1, G1->as_VMReg()); | |
75 reg_def R_G2H( NS, NS, Op_RegI,130, G2->as_VMReg()->next()); | |
76 reg_def R_G2 ( NS, NS, Op_RegI, 2, G2->as_VMReg()); | |
77 reg_def R_G3H(SOC, SOC, Op_RegI,131, G3->as_VMReg()->next()); | |
78 reg_def R_G3 (SOC, SOC, Op_RegI, 3, G3->as_VMReg()); | |
79 reg_def R_G4H(SOC, SOC, Op_RegI,132, G4->as_VMReg()->next()); | |
80 reg_def R_G4 (SOC, SOC, Op_RegI, 4, G4->as_VMReg()); | |
81 reg_def R_G5H(SOC, SOC, Op_RegI,133, G5->as_VMReg()->next()); | |
82 reg_def R_G5 (SOC, SOC, Op_RegI, 5, G5->as_VMReg()); | |
83 reg_def R_G6H( NS, NS, Op_RegI,134, G6->as_VMReg()->next()); | |
84 reg_def R_G6 ( NS, NS, Op_RegI, 6, G6->as_VMReg()); | |
85 reg_def R_G7H( NS, NS, Op_RegI,135, G7->as_VMReg()->next()); | |
86 reg_def R_G7 ( NS, NS, Op_RegI, 7, G7->as_VMReg()); | |
87 | |
88 // Output Registers 0-7 | |
89 reg_def R_O0H(SOC, SOC, Op_RegI,136, O0->as_VMReg()->next()); | |
90 reg_def R_O0 (SOC, SOC, Op_RegI, 8, O0->as_VMReg()); | |
91 reg_def R_O1H(SOC, SOC, Op_RegI,137, O1->as_VMReg()->next()); | |
92 reg_def R_O1 (SOC, SOC, Op_RegI, 9, O1->as_VMReg()); | |
93 reg_def R_O2H(SOC, SOC, Op_RegI,138, O2->as_VMReg()->next()); | |
94 reg_def R_O2 (SOC, SOC, Op_RegI, 10, O2->as_VMReg()); | |
95 reg_def R_O3H(SOC, SOC, Op_RegI,139, O3->as_VMReg()->next()); | |
96 reg_def R_O3 (SOC, SOC, Op_RegI, 11, O3->as_VMReg()); | |
97 reg_def R_O4H(SOC, SOC, Op_RegI,140, O4->as_VMReg()->next()); | |
98 reg_def R_O4 (SOC, SOC, Op_RegI, 12, O4->as_VMReg()); | |
99 reg_def R_O5H(SOC, SOC, Op_RegI,141, O5->as_VMReg()->next()); | |
100 reg_def R_O5 (SOC, SOC, Op_RegI, 13, O5->as_VMReg()); | |
101 reg_def R_SPH( NS, NS, Op_RegI,142, SP->as_VMReg()->next()); | |
102 reg_def R_SP ( NS, NS, Op_RegI, 14, SP->as_VMReg()); | |
103 reg_def R_O7H(SOC, SOC, Op_RegI,143, O7->as_VMReg()->next()); | |
104 reg_def R_O7 (SOC, SOC, Op_RegI, 15, O7->as_VMReg()); | |
105 | |
106 // Local Registers 0-7 | |
107 reg_def R_L0H( NS, NS, Op_RegI,144, L0->as_VMReg()->next()); | |
108 reg_def R_L0 ( NS, NS, Op_RegI, 16, L0->as_VMReg()); | |
109 reg_def R_L1H( NS, NS, Op_RegI,145, L1->as_VMReg()->next()); | |
110 reg_def R_L1 ( NS, NS, Op_RegI, 17, L1->as_VMReg()); | |
111 reg_def R_L2H( NS, NS, Op_RegI,146, L2->as_VMReg()->next()); | |
112 reg_def R_L2 ( NS, NS, Op_RegI, 18, L2->as_VMReg()); | |
113 reg_def R_L3H( NS, NS, Op_RegI,147, L3->as_VMReg()->next()); | |
114 reg_def R_L3 ( NS, NS, Op_RegI, 19, L3->as_VMReg()); | |
115 reg_def R_L4H( NS, NS, Op_RegI,148, L4->as_VMReg()->next()); | |
116 reg_def R_L4 ( NS, NS, Op_RegI, 20, L4->as_VMReg()); | |
117 reg_def R_L5H( NS, NS, Op_RegI,149, L5->as_VMReg()->next()); | |
118 reg_def R_L5 ( NS, NS, Op_RegI, 21, L5->as_VMReg()); | |
119 reg_def R_L6H( NS, NS, Op_RegI,150, L6->as_VMReg()->next()); | |
120 reg_def R_L6 ( NS, NS, Op_RegI, 22, L6->as_VMReg()); | |
121 reg_def R_L7H( NS, NS, Op_RegI,151, L7->as_VMReg()->next()); | |
122 reg_def R_L7 ( NS, NS, Op_RegI, 23, L7->as_VMReg()); | |
123 | |
124 // Input Registers 0-7 | |
125 reg_def R_I0H( NS, NS, Op_RegI,152, I0->as_VMReg()->next()); | |
126 reg_def R_I0 ( NS, NS, Op_RegI, 24, I0->as_VMReg()); | |
127 reg_def R_I1H( NS, NS, Op_RegI,153, I1->as_VMReg()->next()); | |
128 reg_def R_I1 ( NS, NS, Op_RegI, 25, I1->as_VMReg()); | |
129 reg_def R_I2H( NS, NS, Op_RegI,154, I2->as_VMReg()->next()); | |
130 reg_def R_I2 ( NS, NS, Op_RegI, 26, I2->as_VMReg()); | |
131 reg_def R_I3H( NS, NS, Op_RegI,155, I3->as_VMReg()->next()); | |
132 reg_def R_I3 ( NS, NS, Op_RegI, 27, I3->as_VMReg()); | |
133 reg_def R_I4H( NS, NS, Op_RegI,156, I4->as_VMReg()->next()); | |
134 reg_def R_I4 ( NS, NS, Op_RegI, 28, I4->as_VMReg()); | |
135 reg_def R_I5H( NS, NS, Op_RegI,157, I5->as_VMReg()->next()); | |
136 reg_def R_I5 ( NS, NS, Op_RegI, 29, I5->as_VMReg()); | |
137 reg_def R_FPH( NS, NS, Op_RegI,158, FP->as_VMReg()->next()); | |
138 reg_def R_FP ( NS, NS, Op_RegI, 30, FP->as_VMReg()); | |
139 reg_def R_I7H( NS, NS, Op_RegI,159, I7->as_VMReg()->next()); | |
140 reg_def R_I7 ( NS, NS, Op_RegI, 31, I7->as_VMReg()); | |
141 | |
142 // ---------------------------- | |
143 // Float/Double Registers | |
144 // ---------------------------- | |
145 | |
146 // Float Registers | |
147 reg_def R_F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg()); | |
148 reg_def R_F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg()); | |
149 reg_def R_F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg()); | |
150 reg_def R_F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg()); | |
151 reg_def R_F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg()); | |
152 reg_def R_F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg()); | |
153 reg_def R_F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg()); | |
154 reg_def R_F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg()); | |
155 reg_def R_F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg()); | |
156 reg_def R_F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg()); | |
157 reg_def R_F10( SOC, SOC, Op_RegF, 10, F10->as_VMReg()); | |
158 reg_def R_F11( SOC, SOC, Op_RegF, 11, F11->as_VMReg()); | |
159 reg_def R_F12( SOC, SOC, Op_RegF, 12, F12->as_VMReg()); | |
160 reg_def R_F13( SOC, SOC, Op_RegF, 13, F13->as_VMReg()); | |
161 reg_def R_F14( SOC, SOC, Op_RegF, 14, F14->as_VMReg()); | |
162 reg_def R_F15( SOC, SOC, Op_RegF, 15, F15->as_VMReg()); | |
163 reg_def R_F16( SOC, SOC, Op_RegF, 16, F16->as_VMReg()); | |
164 reg_def R_F17( SOC, SOC, Op_RegF, 17, F17->as_VMReg()); | |
165 reg_def R_F18( SOC, SOC, Op_RegF, 18, F18->as_VMReg()); | |
166 reg_def R_F19( SOC, SOC, Op_RegF, 19, F19->as_VMReg()); | |
167 reg_def R_F20( SOC, SOC, Op_RegF, 20, F20->as_VMReg()); | |
168 reg_def R_F21( SOC, SOC, Op_RegF, 21, F21->as_VMReg()); | |
169 reg_def R_F22( SOC, SOC, Op_RegF, 22, F22->as_VMReg()); | |
170 reg_def R_F23( SOC, SOC, Op_RegF, 23, F23->as_VMReg()); | |
171 reg_def R_F24( SOC, SOC, Op_RegF, 24, F24->as_VMReg()); | |
172 reg_def R_F25( SOC, SOC, Op_RegF, 25, F25->as_VMReg()); | |
173 reg_def R_F26( SOC, SOC, Op_RegF, 26, F26->as_VMReg()); | |
174 reg_def R_F27( SOC, SOC, Op_RegF, 27, F27->as_VMReg()); | |
175 reg_def R_F28( SOC, SOC, Op_RegF, 28, F28->as_VMReg()); | |
176 reg_def R_F29( SOC, SOC, Op_RegF, 29, F29->as_VMReg()); | |
177 reg_def R_F30( SOC, SOC, Op_RegF, 30, F30->as_VMReg()); | |
178 reg_def R_F31( SOC, SOC, Op_RegF, 31, F31->as_VMReg()); | |
179 | |
180 // Double Registers | |
181 // The rules of ADL require that double registers be defined in pairs. | |
182 // Each pair must be two 32-bit values, but not necessarily a pair of | |
183 // single float registers. In each pair, ADLC-assigned register numbers | |
184 // must be adjacent, with the lower number even. Finally, when the | |
185 // CPU stores such a register pair to memory, the word associated with | |
186 // the lower ADLC-assigned number must be stored to the lower address. | |
187 | |
188 // These definitions specify the actual bit encodings of the sparc | |
189 // double fp register numbers. FloatRegisterImpl in register_sparc.hpp | |
190 // wants 0-63, so we have to convert every time we want to use fp regs | |
191 // with the macroassembler, using reg_to_DoubleFloatRegister_object(). | |
605 | 192 // 255 is a flag meaning "don't go here". |
0 | 193 // I believe we can't handle callee-save doubles D32 and up until |
194 // the place in the sparc stack crawler that asserts on the 255 is | |
195 // fixed up. | |
1007
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
196 reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
197 reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
198 reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
199 reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
200 reg_def R_D36 (SOC, SOC, Op_RegD, 5, F36->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
201 reg_def R_D36x(SOC, SOC, Op_RegD,255, F36->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
202 reg_def R_D38 (SOC, SOC, Op_RegD, 7, F38->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
203 reg_def R_D38x(SOC, SOC, Op_RegD,255, F38->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
204 reg_def R_D40 (SOC, SOC, Op_RegD, 9, F40->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
205 reg_def R_D40x(SOC, SOC, Op_RegD,255, F40->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
206 reg_def R_D42 (SOC, SOC, Op_RegD, 11, F42->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
207 reg_def R_D42x(SOC, SOC, Op_RegD,255, F42->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
208 reg_def R_D44 (SOC, SOC, Op_RegD, 13, F44->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
209 reg_def R_D44x(SOC, SOC, Op_RegD,255, F44->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
210 reg_def R_D46 (SOC, SOC, Op_RegD, 15, F46->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
211 reg_def R_D46x(SOC, SOC, Op_RegD,255, F46->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
212 reg_def R_D48 (SOC, SOC, Op_RegD, 17, F48->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
213 reg_def R_D48x(SOC, SOC, Op_RegD,255, F48->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
214 reg_def R_D50 (SOC, SOC, Op_RegD, 19, F50->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
215 reg_def R_D50x(SOC, SOC, Op_RegD,255, F50->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
216 reg_def R_D52 (SOC, SOC, Op_RegD, 21, F52->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
217 reg_def R_D52x(SOC, SOC, Op_RegD,255, F52->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
218 reg_def R_D54 (SOC, SOC, Op_RegD, 23, F54->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
219 reg_def R_D54x(SOC, SOC, Op_RegD,255, F54->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
220 reg_def R_D56 (SOC, SOC, Op_RegD, 25, F56->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
221 reg_def R_D56x(SOC, SOC, Op_RegD,255, F56->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
222 reg_def R_D58 (SOC, SOC, Op_RegD, 27, F58->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
223 reg_def R_D58x(SOC, SOC, Op_RegD,255, F58->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
224 reg_def R_D60 (SOC, SOC, Op_RegD, 29, F60->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
225 reg_def R_D60x(SOC, SOC, Op_RegD,255, F60->as_VMReg()->next()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
226 reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg()); |
1ce3281a8e93
6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents:
986
diff
changeset
|
227 reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg()->next()); |
0 | 228 |
229 | |
230 // ---------------------------- | |
231 // Special Registers | |
232 // Condition Codes Flag Registers | |
233 // I tried to break out ICC and XCC but it's not very pretty. | |
234 // Every Sparc instruction which defs/kills one also kills the other. | |
235 // Hence every compare instruction which defs one kind of flags ends | |
236 // up needing a kill of the other. | |
237 reg_def CCR (SOC, SOC, Op_RegFlags, 0, VMRegImpl::Bad()); | |
238 | |
239 reg_def FCC0(SOC, SOC, Op_RegFlags, 0, VMRegImpl::Bad()); | |
240 reg_def FCC1(SOC, SOC, Op_RegFlags, 1, VMRegImpl::Bad()); | |
241 reg_def FCC2(SOC, SOC, Op_RegFlags, 2, VMRegImpl::Bad()); | |
242 reg_def FCC3(SOC, SOC, Op_RegFlags, 3, VMRegImpl::Bad()); | |
243 | |
244 // ---------------------------- | |
245 // Specify the enum values for the registers. These enums are only used by the | |
246 // OptoReg "class". We can convert these enum values at will to VMReg when needed | |
247 // for visibility to the rest of the vm. The order of this enum influences the | |
248 // register allocator so having the freedom to set this order and not be stuck | |
249 // with the order that is natural for the rest of the vm is worth it. | |
250 alloc_class chunk0( | |
251 R_L0,R_L0H, R_L1,R_L1H, R_L2,R_L2H, R_L3,R_L3H, R_L4,R_L4H, R_L5,R_L5H, R_L6,R_L6H, R_L7,R_L7H, | |
252 R_G0,R_G0H, R_G1,R_G1H, R_G2,R_G2H, R_G3,R_G3H, R_G4,R_G4H, R_G5,R_G5H, R_G6,R_G6H, R_G7,R_G7H, | |
253 R_O7,R_O7H, R_SP,R_SPH, R_O0,R_O0H, R_O1,R_O1H, R_O2,R_O2H, R_O3,R_O3H, R_O4,R_O4H, R_O5,R_O5H, | |
254 R_I0,R_I0H, R_I1,R_I1H, R_I2,R_I2H, R_I3,R_I3H, R_I4,R_I4H, R_I5,R_I5H, R_FP,R_FPH, R_I7,R_I7H); | |
255 | |
256 // Note that a register is not allocatable unless it is also mentioned | |
257 // in a widely-used reg_class below. Thus, R_G7 and R_G0 are outside i_reg. | |
258 | |
259 alloc_class chunk1( | |
260 // The first registers listed here are those most likely to be used | |
261 // as temporaries. We move F0..F7 away from the front of the list, | |
262 // to reduce the likelihood of interferences with parameters and | |
263 // return values. Likewise, we avoid using F0/F1 for parameters, | |
264 // since they are used for return values. | |
265 // This FPU fine-tuning is worth about 1% on the SPEC geomean. | |
266 R_F8 ,R_F9 ,R_F10,R_F11,R_F12,R_F13,R_F14,R_F15, | |
267 R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23, | |
268 R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31, | |
269 R_F0 ,R_F1 ,R_F2 ,R_F3 ,R_F4 ,R_F5 ,R_F6 ,R_F7 , // used for arguments and return values | |
270 R_D32,R_D32x,R_D34,R_D34x,R_D36,R_D36x,R_D38,R_D38x, | |
271 R_D40,R_D40x,R_D42,R_D42x,R_D44,R_D44x,R_D46,R_D46x, | |
272 R_D48,R_D48x,R_D50,R_D50x,R_D52,R_D52x,R_D54,R_D54x, | |
273 R_D56,R_D56x,R_D58,R_D58x,R_D60,R_D60x,R_D62,R_D62x); | |
274 | |
275 alloc_class chunk2(CCR, FCC0, FCC1, FCC2, FCC3); | |
276 | |
277 //----------Architecture Description Register Classes-------------------------- | |
278 // Several register classes are automatically defined based upon information in | |
279 // this architecture description. | |
280 // 1) reg_class inline_cache_reg ( as defined in frame section ) | |
281 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) | |
282 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) | |
283 // | |
284 | |
285 // G0 is not included in integer class since it has special meaning. | |
286 reg_class g0_reg(R_G0); | |
287 | |
288 // ---------------------------- | |
289 // Integer Register Classes | |
290 // ---------------------------- | |
291 // Exclusions from i_reg: | |
292 // R_G0: hardwired zero | |
293 // R_G2: reserved by HotSpot to the TLS register (invariant within Java) | |
294 // R_G6: reserved by Solaris ABI to tools | |
295 // R_G7: reserved by Solaris ABI to libthread | |
296 // R_O7: Used as a temp in many encodings | |
297 reg_class int_reg(R_G1,R_G3,R_G4,R_G5,R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7,R_I0,R_I1,R_I2,R_I3,R_I4,R_I5); | |
298 | |
299 // Class for all integer registers, except the G registers. This is used for | |
300 // encodings which use G registers as temps. The regular inputs to such | |
301 // instructions use a "notemp_" prefix, as a hack to ensure that the allocator | |
302 // will not put an input into a temp register. | |
303 reg_class notemp_int_reg(R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7,R_I0,R_I1,R_I2,R_I3,R_I4,R_I5); | |
304 | |
305 reg_class g1_regI(R_G1); | |
306 reg_class g3_regI(R_G3); | |
307 reg_class g4_regI(R_G4); | |
308 reg_class o0_regI(R_O0); | |
309 reg_class o7_regI(R_O7); | |
310 | |
311 // ---------------------------- | |
312 // Pointer Register Classes | |
313 // ---------------------------- | |
314 #ifdef _LP64 | |
315 // 64-bit build means 64-bit pointers means hi/lo pairs | |
316 reg_class ptr_reg( R_G1H,R_G1, R_G3H,R_G3, R_G4H,R_G4, R_G5H,R_G5, | |
317 R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5, | |
318 R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7, | |
319 R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5 ); | |
320 // Lock encodings use G3 and G4 internally | |
321 reg_class lock_ptr_reg( R_G1H,R_G1, R_G5H,R_G5, | |
322 R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5, | |
323 R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7, | |
324 R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5 ); | |
325 // Special class for storeP instructions, which can store SP or RPC to TLS. | |
326 // It is also used for memory addressing, allowing direct TLS addressing. | |
327 reg_class sp_ptr_reg( R_G1H,R_G1, R_G2H,R_G2, R_G3H,R_G3, R_G4H,R_G4, R_G5H,R_G5, | |
328 R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5, R_SPH,R_SP, | |
329 R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7, | |
330 R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5, R_FPH,R_FP ); | |
331 // R_L7 is the lowest-priority callee-save (i.e., NS) register | |
332 // We use it to save R_G2 across calls out of Java. | |
333 reg_class l7_regP(R_L7H,R_L7); | |
334 | |
335 // Other special pointer regs | |
336 reg_class g1_regP(R_G1H,R_G1); | |
337 reg_class g2_regP(R_G2H,R_G2); | |
338 reg_class g3_regP(R_G3H,R_G3); | |
339 reg_class g4_regP(R_G4H,R_G4); | |
340 reg_class g5_regP(R_G5H,R_G5); | |
341 reg_class i0_regP(R_I0H,R_I0); | |
342 reg_class o0_regP(R_O0H,R_O0); | |
343 reg_class o1_regP(R_O1H,R_O1); | |
344 reg_class o2_regP(R_O2H,R_O2); | |
345 reg_class o7_regP(R_O7H,R_O7); | |
346 | |
347 #else // _LP64 | |
348 // 32-bit build means 32-bit pointers means 1 register. | |
349 reg_class ptr_reg( R_G1, R_G3,R_G4,R_G5, | |
350 R_O0,R_O1,R_O2,R_O3,R_O4,R_O5, | |
351 R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7, | |
352 R_I0,R_I1,R_I2,R_I3,R_I4,R_I5); | |
353 // Lock encodings use G3 and G4 internally | |
354 reg_class lock_ptr_reg(R_G1, R_G5, | |
355 R_O0,R_O1,R_O2,R_O3,R_O4,R_O5, | |
356 R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7, | |
357 R_I0,R_I1,R_I2,R_I3,R_I4,R_I5); | |
358 // Special class for storeP instructions, which can store SP or RPC to TLS. | |
359 // It is also used for memory addressing, allowing direct TLS addressing. | |
360 reg_class sp_ptr_reg( R_G1,R_G2,R_G3,R_G4,R_G5, | |
361 R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,R_SP, | |
362 R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7, | |
363 R_I0,R_I1,R_I2,R_I3,R_I4,R_I5,R_FP); | |
364 // R_L7 is the lowest-priority callee-save (i.e., NS) register | |
365 // We use it to save R_G2 across calls out of Java. | |
366 reg_class l7_regP(R_L7); | |
367 | |
368 // Other special pointer regs | |
369 reg_class g1_regP(R_G1); | |
370 reg_class g2_regP(R_G2); | |
371 reg_class g3_regP(R_G3); | |
372 reg_class g4_regP(R_G4); | |
373 reg_class g5_regP(R_G5); | |
374 reg_class i0_regP(R_I0); | |
375 reg_class o0_regP(R_O0); | |
376 reg_class o1_regP(R_O1); | |
377 reg_class o2_regP(R_O2); | |
378 reg_class o7_regP(R_O7); | |
379 #endif // _LP64 | |
380 | |
381 | |
382 // ---------------------------- | |
383 // Long Register Classes | |
384 // ---------------------------- | |
385 // Longs in 1 register. Aligned adjacent hi/lo pairs. | |
386 // Note: O7 is never in this class; it is sometimes used as an encoding temp. | |
387 reg_class long_reg( R_G1H,R_G1, R_G3H,R_G3, R_G4H,R_G4, R_G5H,R_G5 | |
388 ,R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5 | |
389 #ifdef _LP64 | |
390 // 64-bit, longs in 1 register: use all 64-bit integer registers | |
391 // 32-bit, longs in 1 register: cannot use I's and L's. Restrict to O's and G's. | |
392 ,R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7 | |
393 ,R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5 | |
394 #endif // _LP64 | |
395 ); | |
396 | |
397 reg_class g1_regL(R_G1H,R_G1); | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
398 reg_class g3_regL(R_G3H,R_G3); |
0 | 399 reg_class o2_regL(R_O2H,R_O2); |
400 reg_class o7_regL(R_O7H,R_O7); | |
401 | |
402 // ---------------------------- | |
403 // Special Class for Condition Code Flags Register | |
404 reg_class int_flags(CCR); | |
405 reg_class float_flags(FCC0,FCC1,FCC2,FCC3); | |
406 reg_class float_flag0(FCC0); | |
407 | |
408 | |
409 // ---------------------------- | |
410 // Float Point Register Classes | |
411 // ---------------------------- | |
412 // Skip F30/F31, they are reserved for mem-mem copies | |
413 reg_class sflt_reg(R_F0,R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,R_F10,R_F11,R_F12,R_F13,R_F14,R_F15,R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29); | |
414 | |
415 // Paired floating point registers--they show up in the same order as the floats, | |
416 // but they are used with the "Op_RegD" type, and always occur in even/odd pairs. | |
417 reg_class dflt_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R_F10,R_F11,R_F12,R_F13,R_F14,R_F15, | |
418 R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29, | |
419 /* Use extra V9 double registers; this AD file does not support V8 */ | |
420 R_D32,R_D32x,R_D34,R_D34x,R_D36,R_D36x,R_D38,R_D38x,R_D40,R_D40x,R_D42,R_D42x,R_D44,R_D44x,R_D46,R_D46x, | |
421 R_D48,R_D48x,R_D50,R_D50x,R_D52,R_D52x,R_D54,R_D54x,R_D56,R_D56x,R_D58,R_D58x,R_D60,R_D60x,R_D62,R_D62x | |
422 ); | |
423 | |
424 // Paired floating point registers--they show up in the same order as the floats, | |
425 // but they are used with the "Op_RegD" type, and always occur in even/odd pairs. | |
426 // This class is usable for mis-aligned loads as happen in I2C adapters. | |
427 reg_class dflt_low_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R_F10,R_F11,R_F12,R_F13,R_F14,R_F15, | |
428 R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31 ); | |
429 %} | |
430 | |
431 //----------DEFINITION BLOCK--------------------------------------------------- | |
432 // Define name --> value mappings to inform the ADLC of an integer valued name | |
433 // Current support includes integer values in the range [0, 0x7FFFFFFF] | |
434 // Format: | |
435 // int_def <name> ( <int_value>, <expression>); | |
436 // Generated Code in ad_<arch>.hpp | |
437 // #define <name> (<expression>) | |
438 // // value == <int_value> | |
439 // Generated code in ad_<arch>.cpp adlc_verification() | |
440 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); | |
441 // | |
442 definitions %{ | |
443 // The default cost (of an ALU instruction). | |
444 int_def DEFAULT_COST ( 100, 100); | |
445 int_def HUGE_COST (1000000, 1000000); | |
446 | |
447 // Memory refs are twice as expensive as run-of-the-mill. | |
448 int_def MEMORY_REF_COST ( 200, DEFAULT_COST * 2); | |
449 | |
450 // Branches are even more expensive. | |
451 int_def BRANCH_COST ( 300, DEFAULT_COST * 3); | |
452 int_def CALL_COST ( 300, DEFAULT_COST * 3); | |
453 %} | |
454 | |
455 | |
456 //----------SOURCE BLOCK------------------------------------------------------- | |
457 // This is a block of C++ code which provides values, functions, and | |
458 // definitions necessary in the rest of the architecture description | |
459 source_hpp %{ | |
460 // Must be visible to the DFA in dfa_sparc.cpp | |
461 extern bool can_branch_register( Node *bol, Node *cmp ); | |
462 | |
463 // Macros to extract hi & lo halves from a long pair. | |
464 // G0 is not part of any long pair, so assert on that. | |
605 | 465 // Prevents accidentally using G1 instead of G0. |
0 | 466 #define LONG_HI_REG(x) (x) |
467 #define LONG_LO_REG(x) (x) | |
468 | |
469 %} | |
470 | |
471 source %{ | |
472 #define __ _masm. | |
473 | |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
474 // Block initializing store |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
475 #define ASI_BLK_INIT_QUAD_LDD_P 0xE2 |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
476 |
0 | 477 // tertiary op of a LoadP or StoreP encoding |
478 #define REGP_OP true | |
479 | |
480 static FloatRegister reg_to_SingleFloatRegister_object(int register_encoding); | |
481 static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding); | |
482 static Register reg_to_register_object(int register_encoding); | |
483 | |
484 // Used by the DFA in dfa_sparc.cpp. | |
485 // Check for being able to use a V9 branch-on-register. Requires a | |
486 // compare-vs-zero, equal/not-equal, of a value which was zero- or sign- | |
487 // extended. Doesn't work following an integer ADD, for example, because of | |
488 // overflow (-1 incremented yields 0 plus a carry in the high-order word). On | |
489 // 32-bit V9 systems, interrupts currently blow away the high-order 32 bits and | |
490 // replace them with zero, which could become sign-extension in a different OS | |
491 // release. There's no obvious reason why an interrupt will ever fill these | |
492 // bits with non-zero junk (the registers are reloaded with standard LD | |
493 // instructions which either zero-fill or sign-fill). | |
494 bool can_branch_register( Node *bol, Node *cmp ) { | |
495 if( !BranchOnRegister ) return false; | |
496 #ifdef _LP64 | |
497 if( cmp->Opcode() == Op_CmpP ) | |
498 return true; // No problems with pointer compares | |
499 #endif | |
500 if( cmp->Opcode() == Op_CmpL ) | |
501 return true; // No problems with long compares | |
502 | |
503 if( !SparcV9RegsHiBitsZero ) return false; | |
504 if( bol->as_Bool()->_test._test != BoolTest::ne && | |
505 bol->as_Bool()->_test._test != BoolTest::eq ) | |
506 return false; | |
507 | |
508 // Check for comparing against a 'safe' value. Any operation which | |
509 // clears out the high word is safe. Thus, loads and certain shifts | |
510 // are safe, as are non-negative constants. Any operation which | |
511 // preserves zero bits in the high word is safe as long as each of its | |
512 // inputs are safe. Thus, phis and bitwise booleans are safe if their | |
513 // inputs are safe. At present, the only important case to recognize | |
514 // seems to be loads. Constants should fold away, and shifts & | |
515 // logicals can use the 'cc' forms. | |
516 Node *x = cmp->in(1); | |
517 if( x->is_Load() ) return true; | |
518 if( x->is_Phi() ) { | |
519 for( uint i = 1; i < x->req(); i++ ) | |
520 if( !x->in(i)->is_Load() ) | |
521 return false; | |
522 return true; | |
523 } | |
524 return false; | |
525 } | |
526 | |
527 // **************************************************************************** | |
528 | |
529 // REQUIRED FUNCTIONALITY | |
530 | |
531 // !!!!! Special hack to get all type of calls to specify the byte offset | |
532 // from the start of the call to the point where the return address | |
533 // will point. | |
534 // The "return address" is the address of the call instruction, plus 8. | |
535 | |
536 int MachCallStaticJavaNode::ret_addr_offset() { | |
1567 | 537 int offset = NativeCall::instruction_size; // call; delay slot |
538 if (_method_handle_invoke) | |
539 offset += 4; // restore SP | |
540 return offset; | |
0 | 541 } |
542 | |
543 int MachCallDynamicJavaNode::ret_addr_offset() { | |
544 int vtable_index = this->_vtable_index; | |
545 if (vtable_index < 0) { | |
546 // must be invalid_vtable_index, not nonvirtual_vtable_index | |
547 assert(vtable_index == methodOopDesc::invalid_vtable_index, "correct sentinel value"); | |
548 return (NativeMovConstReg::instruction_size + | |
549 NativeCall::instruction_size); // sethi; setlo; call; delay slot | |
550 } else { | |
551 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); | |
552 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); | |
553 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
554 int klass_load_size; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
555 if (UseCompressedOops) { |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
556 assert(Universe::heap() != NULL, "java heap should be initialized"); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
557 if (Universe::narrow_oop_base() == NULL) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
558 klass_load_size = 2*BytesPerInstWord; // see MacroAssembler::load_klass() |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
559 else |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
560 klass_load_size = 3*BytesPerInstWord; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
561 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
562 klass_load_size = 1*BytesPerInstWord; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
563 } |
0 | 564 if( Assembler::is_simm13(v_off) ) { |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
565 return klass_load_size + |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
566 (2*BytesPerInstWord + // ld_ptr, ld_ptr |
0 | 567 NativeCall::instruction_size); // call; delay slot |
568 } else { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
569 return klass_load_size + |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
570 (4*BytesPerInstWord + // set_hi, set, ld_ptr, ld_ptr |
0 | 571 NativeCall::instruction_size); // call; delay slot |
572 } | |
573 } | |
574 } | |
575 | |
576 int MachCallRuntimeNode::ret_addr_offset() { | |
577 #ifdef _LP64 | |
578 return NativeFarCall::instruction_size; // farcall; delay slot | |
579 #else | |
580 return NativeCall::instruction_size; // call; delay slot | |
581 #endif | |
582 } | |
583 | |
584 // Indicate if the safepoint node needs the polling page as an input. | |
585 // Since Sparc does not have absolute addressing, it does. | |
586 bool SafePointNode::needs_polling_address_input() { | |
587 return true; | |
588 } | |
589 | |
590 // emit an interrupt that is caught by the debugger (for debugging compiler) | |
591 void emit_break(CodeBuffer &cbuf) { | |
592 MacroAssembler _masm(&cbuf); | |
593 __ breakpoint_trap(); | |
594 } | |
595 | |
596 #ifndef PRODUCT | |
597 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const { | |
598 st->print("TA"); | |
599 } | |
600 #endif | |
601 | |
602 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | |
603 emit_break(cbuf); | |
604 } | |
605 | |
606 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { | |
607 return MachNode::size(ra_); | |
608 } | |
609 | |
610 // Traceable jump | |
611 void emit_jmpl(CodeBuffer &cbuf, int jump_target) { | |
612 MacroAssembler _masm(&cbuf); | |
613 Register rdest = reg_to_register_object(jump_target); | |
614 __ JMP(rdest, 0); | |
615 __ delayed()->nop(); | |
616 } | |
617 | |
618 // Traceable jump and set exception pc | |
619 void emit_jmpl_set_exception_pc(CodeBuffer &cbuf, int jump_target) { | |
620 MacroAssembler _masm(&cbuf); | |
621 Register rdest = reg_to_register_object(jump_target); | |
622 __ JMP(rdest, 0); | |
623 __ delayed()->add(O7, frame::pc_return_offset, Oissuing_pc ); | |
624 } | |
625 | |
626 void emit_nop(CodeBuffer &cbuf) { | |
627 MacroAssembler _masm(&cbuf); | |
628 __ nop(); | |
629 } | |
630 | |
631 void emit_illtrap(CodeBuffer &cbuf) { | |
632 MacroAssembler _masm(&cbuf); | |
633 __ illtrap(0); | |
634 } | |
635 | |
636 | |
637 intptr_t get_offset_from_base(const MachNode* n, const TypePtr* atype, int disp32) { | |
638 assert(n->rule() != loadUB_rule, ""); | |
639 | |
640 intptr_t offset = 0; | |
641 const TypePtr *adr_type = TYPE_PTR_SENTINAL; // Check for base==RegI, disp==immP | |
642 const Node* addr = n->get_base_and_disp(offset, adr_type); | |
643 assert(adr_type == (const TypePtr*)-1, "VerifyOops: no support for sparc operands with base==RegI, disp==immP"); | |
644 assert(addr != NULL && addr != (Node*)-1, "invalid addr"); | |
645 assert(addr->bottom_type()->isa_oopptr() == atype, ""); | |
646 atype = atype->add_offset(offset); | |
647 assert(disp32 == offset, "wrong disp32"); | |
648 return atype->_offset; | |
649 } | |
650 | |
651 | |
652 intptr_t get_offset_from_base_2(const MachNode* n, const TypePtr* atype, int disp32) { | |
653 assert(n->rule() != loadUB_rule, ""); | |
654 | |
655 intptr_t offset = 0; | |
656 Node* addr = n->in(2); | |
657 assert(addr->bottom_type()->isa_oopptr() == atype, ""); | |
658 if (addr->is_Mach() && addr->as_Mach()->ideal_Opcode() == Op_AddP) { | |
659 Node* a = addr->in(2/*AddPNode::Address*/); | |
660 Node* o = addr->in(3/*AddPNode::Offset*/); | |
661 offset = o->is_Con() ? o->bottom_type()->is_intptr_t()->get_con() : Type::OffsetBot; | |
662 atype = a->bottom_type()->is_ptr()->add_offset(offset); | |
663 assert(atype->isa_oop_ptr(), "still an oop"); | |
664 } | |
665 offset = atype->is_ptr()->_offset; | |
666 if (offset != Type::OffsetBot) offset += disp32; | |
667 return offset; | |
668 } | |
669 | |
670 // Standard Sparc opcode form2 field breakdown | |
671 static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) { | |
672 f0 &= (1<<19)-1; // Mask displacement to 19 bits | |
673 int op = (f30 << 30) | | |
674 (f29 << 29) | | |
675 (f25 << 25) | | |
676 (f22 << 22) | | |
677 (f20 << 20) | | |
678 (f19 << 19) | | |
679 (f0 << 0); | |
680 *((int*)(cbuf.code_end())) = op; | |
681 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
682 } | |
683 | |
684 // Standard Sparc opcode form2 field breakdown | |
685 static inline void emit2_22(CodeBuffer &cbuf, int f30, int f25, int f22, int f0 ) { | |
686 f0 >>= 10; // Drop 10 bits | |
687 f0 &= (1<<22)-1; // Mask displacement to 22 bits | |
688 int op = (f30 << 30) | | |
689 (f25 << 25) | | |
690 (f22 << 22) | | |
691 (f0 << 0); | |
692 *((int*)(cbuf.code_end())) = op; | |
693 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
694 } | |
695 | |
696 // Standard Sparc opcode form3 field breakdown | |
697 static inline void emit3(CodeBuffer &cbuf, int f30, int f25, int f19, int f14, int f5, int f0 ) { | |
698 int op = (f30 << 30) | | |
699 (f25 << 25) | | |
700 (f19 << 19) | | |
701 (f14 << 14) | | |
702 (f5 << 5) | | |
703 (f0 << 0); | |
704 *((int*)(cbuf.code_end())) = op; | |
705 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
706 } | |
707 | |
708 // Standard Sparc opcode form3 field breakdown | |
709 static inline void emit3_simm13(CodeBuffer &cbuf, int f30, int f25, int f19, int f14, int simm13 ) { | |
710 simm13 &= (1<<13)-1; // Mask to 13 bits | |
711 int op = (f30 << 30) | | |
712 (f25 << 25) | | |
713 (f19 << 19) | | |
714 (f14 << 14) | | |
715 (1 << 13) | // bit to indicate immediate-mode | |
716 (simm13<<0); | |
717 *((int*)(cbuf.code_end())) = op; | |
718 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
719 } | |
720 | |
721 static inline void emit3_simm10(CodeBuffer &cbuf, int f30, int f25, int f19, int f14, int simm10 ) { | |
722 simm10 &= (1<<10)-1; // Mask to 10 bits | |
723 emit3_simm13(cbuf,f30,f25,f19,f14,simm10); | |
724 } | |
725 | |
726 #ifdef ASSERT | |
727 // Helper function for VerifyOops in emit_form3_mem_reg | |
728 void verify_oops_warning(const MachNode *n, int ideal_op, int mem_op) { | |
729 warning("VerifyOops encountered unexpected instruction:"); | |
730 n->dump(2); | |
731 warning("Instruction has ideal_Opcode==Op_%s and op_ld==Op_%s \n", NodeClassNames[ideal_op], NodeClassNames[mem_op]); | |
732 } | |
733 #endif | |
734 | |
735 | |
736 void emit_form3_mem_reg(CodeBuffer &cbuf, const MachNode* n, int primary, int tertiary, | |
737 int src1_enc, int disp32, int src2_enc, int dst_enc) { | |
738 | |
739 #ifdef ASSERT | |
740 // The following code implements the +VerifyOops feature. | |
741 // It verifies oop values which are loaded into or stored out of | |
742 // the current method activation. +VerifyOops complements techniques | |
743 // like ScavengeALot, because it eagerly inspects oops in transit, | |
744 // as they enter or leave the stack, as opposed to ScavengeALot, | |
745 // which inspects oops "at rest", in the stack or heap, at safepoints. | |
746 // For this reason, +VerifyOops can sometimes detect bugs very close | |
747 // to their point of creation. It can also serve as a cross-check | |
748 // on the validity of oop maps, when used toegether with ScavengeALot. | |
749 | |
750 // It would be good to verify oops at other points, especially | |
751 // when an oop is used as a base pointer for a load or store. | |
752 // This is presently difficult, because it is hard to know when | |
753 // a base address is biased or not. (If we had such information, | |
754 // it would be easy and useful to make a two-argument version of | |
755 // verify_oop which unbiases the base, and performs verification.) | |
756 | |
757 assert((uint)tertiary == 0xFFFFFFFF || tertiary == REGP_OP, "valid tertiary"); | |
758 bool is_verified_oop_base = false; | |
759 bool is_verified_oop_load = false; | |
760 bool is_verified_oop_store = false; | |
761 int tmp_enc = -1; | |
762 if (VerifyOops && src1_enc != R_SP_enc) { | |
763 // classify the op, mainly for an assert check | |
764 int st_op = 0, ld_op = 0; | |
765 switch (primary) { | |
766 case Assembler::stb_op3: st_op = Op_StoreB; break; | |
767 case Assembler::sth_op3: st_op = Op_StoreC; break; | |
768 case Assembler::stx_op3: // may become StoreP or stay StoreI or StoreD0 | |
769 case Assembler::stw_op3: st_op = Op_StoreI; break; | |
770 case Assembler::std_op3: st_op = Op_StoreL; break; | |
771 case Assembler::stf_op3: st_op = Op_StoreF; break; | |
772 case Assembler::stdf_op3: st_op = Op_StoreD; break; | |
773 | |
774 case Assembler::ldsb_op3: ld_op = Op_LoadB; break; | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
551
diff
changeset
|
775 case Assembler::lduh_op3: ld_op = Op_LoadUS; break; |
0 | 776 case Assembler::ldsh_op3: ld_op = Op_LoadS; break; |
777 case Assembler::ldx_op3: // may become LoadP or stay LoadI | |
778 case Assembler::ldsw_op3: // may become LoadP or stay LoadI | |
779 case Assembler::lduw_op3: ld_op = Op_LoadI; break; | |
780 case Assembler::ldd_op3: ld_op = Op_LoadL; break; | |
781 case Assembler::ldf_op3: ld_op = Op_LoadF; break; | |
782 case Assembler::lddf_op3: ld_op = Op_LoadD; break; | |
783 case Assembler::ldub_op3: ld_op = Op_LoadB; break; | |
784 case Assembler::prefetch_op3: ld_op = Op_LoadI; break; | |
785 | |
786 default: ShouldNotReachHere(); | |
787 } | |
788 if (tertiary == REGP_OP) { | |
789 if (st_op == Op_StoreI) st_op = Op_StoreP; | |
790 else if (ld_op == Op_LoadI) ld_op = Op_LoadP; | |
791 else ShouldNotReachHere(); | |
792 if (st_op) { | |
793 // a store | |
794 // inputs are (0:control, 1:memory, 2:address, 3:value) | |
795 Node* n2 = n->in(3); | |
796 if (n2 != NULL) { | |
797 const Type* t = n2->bottom_type(); | |
798 is_verified_oop_store = t->isa_oop_ptr() ? (t->is_ptr()->_offset==0) : false; | |
799 } | |
800 } else { | |
801 // a load | |
802 const Type* t = n->bottom_type(); | |
803 is_verified_oop_load = t->isa_oop_ptr() ? (t->is_ptr()->_offset==0) : false; | |
804 } | |
805 } | |
806 | |
807 if (ld_op) { | |
808 // a Load | |
809 // inputs are (0:control, 1:memory, 2:address) | |
810 if (!(n->ideal_Opcode()==ld_op) && // Following are special cases | |
811 !(n->ideal_Opcode()==Op_LoadLLocked && ld_op==Op_LoadI) && | |
812 !(n->ideal_Opcode()==Op_LoadPLocked && ld_op==Op_LoadP) && | |
813 !(n->ideal_Opcode()==Op_LoadI && ld_op==Op_LoadF) && | |
814 !(n->ideal_Opcode()==Op_LoadF && ld_op==Op_LoadI) && | |
815 !(n->ideal_Opcode()==Op_LoadRange && ld_op==Op_LoadI) && | |
816 !(n->ideal_Opcode()==Op_LoadKlass && ld_op==Op_LoadP) && | |
817 !(n->ideal_Opcode()==Op_LoadL && ld_op==Op_LoadI) && | |
818 !(n->ideal_Opcode()==Op_LoadL_unaligned && ld_op==Op_LoadI) && | |
819 !(n->ideal_Opcode()==Op_LoadD_unaligned && ld_op==Op_LoadF) && | |
820 !(n->ideal_Opcode()==Op_ConvI2F && ld_op==Op_LoadF) && | |
821 !(n->ideal_Opcode()==Op_ConvI2D && ld_op==Op_LoadF) && | |
822 !(n->ideal_Opcode()==Op_PrefetchRead && ld_op==Op_LoadI) && | |
823 !(n->ideal_Opcode()==Op_PrefetchWrite && ld_op==Op_LoadI) && | |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
824 !(n->ideal_Opcode()==Op_Load2I && ld_op==Op_LoadD) && |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
825 !(n->ideal_Opcode()==Op_Load4C && ld_op==Op_LoadD) && |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
826 !(n->ideal_Opcode()==Op_Load4S && ld_op==Op_LoadD) && |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
827 !(n->ideal_Opcode()==Op_Load8B && ld_op==Op_LoadD) && |
0 | 828 !(n->rule() == loadUB_rule)) { |
829 verify_oops_warning(n, n->ideal_Opcode(), ld_op); | |
830 } | |
831 } else if (st_op) { | |
832 // a Store | |
833 // inputs are (0:control, 1:memory, 2:address, 3:value) | |
834 if (!(n->ideal_Opcode()==st_op) && // Following are special cases | |
835 !(n->ideal_Opcode()==Op_StoreCM && st_op==Op_StoreB) && | |
836 !(n->ideal_Opcode()==Op_StoreI && st_op==Op_StoreF) && | |
837 !(n->ideal_Opcode()==Op_StoreF && st_op==Op_StoreI) && | |
838 !(n->ideal_Opcode()==Op_StoreL && st_op==Op_StoreI) && | |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
839 !(n->ideal_Opcode()==Op_Store2I && st_op==Op_StoreD) && |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
840 !(n->ideal_Opcode()==Op_Store4C && st_op==Op_StoreD) && |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1567
diff
changeset
|
841 !(n->ideal_Opcode()==Op_Store8B && st_op==Op_StoreD) && |
0 | 842 !(n->ideal_Opcode()==Op_StoreD && st_op==Op_StoreI && n->rule() == storeD0_rule)) { |
843 verify_oops_warning(n, n->ideal_Opcode(), st_op); | |
844 } | |
845 } | |
846 | |
847 if (src2_enc == R_G0_enc && n->rule() != loadUB_rule && n->ideal_Opcode() != Op_StoreCM ) { | |
848 Node* addr = n->in(2); | |
849 if (!(addr->is_Mach() && addr->as_Mach()->ideal_Opcode() == Op_AddP)) { | |
850 const TypeOopPtr* atype = addr->bottom_type()->isa_instptr(); // %%% oopptr? | |
851 if (atype != NULL) { | |
852 intptr_t offset = get_offset_from_base(n, atype, disp32); | |
853 intptr_t offset_2 = get_offset_from_base_2(n, atype, disp32); | |
854 if (offset != offset_2) { | |
855 get_offset_from_base(n, atype, disp32); | |
856 get_offset_from_base_2(n, atype, disp32); | |
857 } | |
858 assert(offset == offset_2, "different offsets"); | |
859 if (offset == disp32) { | |
860 // we now know that src1 is a true oop pointer | |
861 is_verified_oop_base = true; | |
862 if (ld_op && src1_enc == dst_enc && ld_op != Op_LoadF && ld_op != Op_LoadD) { | |
863 if( primary == Assembler::ldd_op3 ) { | |
864 is_verified_oop_base = false; // Cannot 'ldd' into O7 | |
865 } else { | |
866 tmp_enc = dst_enc; | |
867 dst_enc = R_O7_enc; // Load into O7; preserve source oop | |
868 assert(src1_enc != dst_enc, ""); | |
869 } | |
870 } | |
871 } | |
872 if (st_op && (( offset == oopDesc::klass_offset_in_bytes()) | |
873 || offset == oopDesc::mark_offset_in_bytes())) { | |
874 // loading the mark should not be allowed either, but | |
875 // we don't check this since it conflicts with InlineObjectHash | |
876 // usage of LoadINode to get the mark. We could keep the | |
877 // check if we create a new LoadMarkNode | |
878 // but do not verify the object before its header is initialized | |
879 ShouldNotReachHere(); | |
880 } | |
881 } | |
882 } | |
883 } | |
884 } | |
885 #endif | |
886 | |
887 uint instr; | |
888 instr = (Assembler::ldst_op << 30) | |
889 | (dst_enc << 25) | |
890 | (primary << 19) | |
891 | (src1_enc << 14); | |
892 | |
893 uint index = src2_enc; | |
894 int disp = disp32; | |
895 | |
896 if (src1_enc == R_SP_enc || src1_enc == R_FP_enc) | |
897 disp += STACK_BIAS; | |
898 | |
899 // We should have a compiler bailout here rather than a guarantee. | |
900 // Better yet would be some mechanism to handle variable-size matches correctly. | |
901 guarantee(Assembler::is_simm13(disp), "Do not match large constant offsets" ); | |
902 | |
903 if( disp == 0 ) { | |
904 // use reg-reg form | |
905 // bit 13 is already zero | |
906 instr |= index; | |
907 } else { | |
908 // use reg-imm form | |
909 instr |= 0x00002000; // set bit 13 to one | |
910 instr |= disp & 0x1FFF; | |
911 } | |
912 | |
913 uint *code = (uint*)cbuf.code_end(); | |
914 *code = instr; | |
915 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
916 | |
917 #ifdef ASSERT | |
918 { | |
919 MacroAssembler _masm(&cbuf); | |
920 if (is_verified_oop_base) { | |
921 __ verify_oop(reg_to_register_object(src1_enc)); | |
922 } | |
923 if (is_verified_oop_store) { | |
924 __ verify_oop(reg_to_register_object(dst_enc)); | |
925 } | |
926 if (tmp_enc != -1) { | |
927 __ mov(O7, reg_to_register_object(tmp_enc)); | |
928 } | |
929 if (is_verified_oop_load) { | |
930 __ verify_oop(reg_to_register_object(dst_enc)); | |
931 } | |
932 } | |
933 #endif | |
934 } | |
935 | |
936 void emit_call_reloc(CodeBuffer &cbuf, intptr_t entry_point, relocInfo::relocType rtype, bool preserve_g2 = false, bool force_far_call = false) { | |
937 // The method which records debug information at every safepoint | |
938 // expects the call to be the first instruction in the snippet as | |
939 // it creates a PcDesc structure which tracks the offset of a call | |
940 // from the start of the codeBlob. This offset is computed as | |
941 // code_end() - code_begin() of the code which has been emitted | |
942 // so far. | |
943 // In this particular case we have skirted around the problem by | |
944 // putting the "mov" instruction in the delay slot but the problem | |
945 // may bite us again at some other point and a cleaner/generic | |
946 // solution using relocations would be needed. | |
947 MacroAssembler _masm(&cbuf); | |
948 __ set_inst_mark(); | |
949 | |
950 // We flush the current window just so that there is a valid stack copy | |
951 // the fact that the current window becomes active again instantly is | |
952 // not a problem there is nothing live in it. | |
953 | |
954 #ifdef ASSERT | |
955 int startpos = __ offset(); | |
956 #endif /* ASSERT */ | |
957 | |
958 #ifdef _LP64 | |
959 // Calls to the runtime or native may not be reachable from compiled code, | |
960 // so we generate the far call sequence on 64 bit sparc. | |
961 // This code sequence is relocatable to any address, even on LP64. | |
962 if ( force_far_call ) { | |
963 __ relocate(rtype); | |
727 | 964 AddressLiteral dest(entry_point); |
965 __ jumpl_to(dest, O7, O7); | |
0 | 966 } |
967 else | |
968 #endif | |
969 { | |
970 __ call((address)entry_point, rtype); | |
971 } | |
972 | |
973 if (preserve_g2) __ delayed()->mov(G2, L7); | |
974 else __ delayed()->nop(); | |
975 | |
976 if (preserve_g2) __ mov(L7, G2); | |
977 | |
978 #ifdef ASSERT | |
979 if (preserve_g2 && (VerifyCompiledCode || VerifyOops)) { | |
980 #ifdef _LP64 | |
981 // Trash argument dump slots. | |
982 __ set(0xb0b8ac0db0b8ac0d, G1); | |
983 __ mov(G1, G5); | |
984 __ stx(G1, SP, STACK_BIAS + 0x80); | |
985 __ stx(G1, SP, STACK_BIAS + 0x88); | |
986 __ stx(G1, SP, STACK_BIAS + 0x90); | |
987 __ stx(G1, SP, STACK_BIAS + 0x98); | |
988 __ stx(G1, SP, STACK_BIAS + 0xA0); | |
989 __ stx(G1, SP, STACK_BIAS + 0xA8); | |
990 #else // _LP64 | |
991 // this is also a native call, so smash the first 7 stack locations, | |
992 // and the various registers | |
993 | |
994 // Note: [SP+0x40] is sp[callee_aggregate_return_pointer_sp_offset], | |
995 // while [SP+0x44..0x58] are the argument dump slots. | |
996 __ set((intptr_t)0xbaadf00d, G1); | |
997 __ mov(G1, G5); | |
998 __ sllx(G1, 32, G1); | |
999 __ or3(G1, G5, G1); | |
1000 __ mov(G1, G5); | |
1001 __ stx(G1, SP, 0x40); | |
1002 __ stx(G1, SP, 0x48); | |
1003 __ stx(G1, SP, 0x50); | |
1004 __ stw(G1, SP, 0x58); // Do not trash [SP+0x5C] which is a usable spill slot | |
1005 #endif // _LP64 | |
1006 } | |
1007 #endif /*ASSERT*/ | |
1008 } | |
1009 | |
1010 //============================================================================= | |
1011 // REQUIRED FUNCTIONALITY for encoding | |
1012 void emit_lo(CodeBuffer &cbuf, int val) { } | |
1013 void emit_hi(CodeBuffer &cbuf, int val) { } | |
1014 | |
1015 | |
1016 //============================================================================= | |
1017 | |
1018 #ifndef PRODUCT | |
1019 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { | |
1020 Compile* C = ra_->C; | |
1021 | |
1022 for (int i = 0; i < OptoPrologueNops; i++) { | |
1023 st->print_cr("NOP"); st->print("\t"); | |
1024 } | |
1025 | |
1026 if( VerifyThread ) { | |
1027 st->print_cr("Verify_Thread"); st->print("\t"); | |
1028 } | |
1029 | |
1030 size_t framesize = C->frame_slots() << LogBytesPerInt; | |
1031 | |
1032 // Calls to C2R adapters often do not accept exceptional returns. | |
1033 // We require that their callers must bang for them. But be careful, because | |
1034 // some VM calls (such as call site linkage) can use several kilobytes of | |
1035 // stack. But the stack safety zone should account for that. | |
1036 // See bugs 4446381, 4468289, 4497237. | |
1037 if (C->need_stack_bang(framesize)) { | |
1038 st->print_cr("! stack bang"); st->print("\t"); | |
1039 } | |
1040 | |
1041 if (Assembler::is_simm13(-framesize)) { | |
1042 st->print ("SAVE R_SP,-%d,R_SP",framesize); | |
1043 } else { | |
1044 st->print_cr("SETHI R_SP,hi%%(-%d),R_G3",framesize); st->print("\t"); | |
1045 st->print_cr("ADD R_G3,lo%%(-%d),R_G3",framesize); st->print("\t"); | |
1046 st->print ("SAVE R_SP,R_G3,R_SP"); | |
1047 } | |
1048 | |
1049 } | |
1050 #endif | |
1051 | |
1052 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | |
1053 Compile* C = ra_->C; | |
1054 MacroAssembler _masm(&cbuf); | |
1055 | |
1056 for (int i = 0; i < OptoPrologueNops; i++) { | |
1057 __ nop(); | |
1058 } | |
1059 | |
1060 __ verify_thread(); | |
1061 | |
1062 size_t framesize = C->frame_slots() << LogBytesPerInt; | |
1063 assert(framesize >= 16*wordSize, "must have room for reg. save area"); | |
1064 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); | |
1065 | |
1066 // Calls to C2R adapters often do not accept exceptional returns. | |
1067 // We require that their callers must bang for them. But be careful, because | |
1068 // some VM calls (such as call site linkage) can use several kilobytes of | |
1069 // stack. But the stack safety zone should account for that. | |
1070 // See bugs 4446381, 4468289, 4497237. | |
1071 if (C->need_stack_bang(framesize)) { | |
1072 __ generate_stack_overflow_check(framesize); | |
1073 } | |
1074 | |
1075 if (Assembler::is_simm13(-framesize)) { | |
1076 __ save(SP, -framesize, SP); | |
1077 } else { | |
1078 __ sethi(-framesize & ~0x3ff, G3); | |
1079 __ add(G3, -framesize & 0x3ff, G3); | |
1080 __ save(SP, G3, SP); | |
1081 } | |
1082 C->set_frame_complete( __ offset() ); | |
1083 } | |
1084 | |
1085 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { | |
1086 return MachNode::size(ra_); | |
1087 } | |
1088 | |
1089 int MachPrologNode::reloc() const { | |
1090 return 10; // a large enough number | |
1091 } | |
1092 | |
1093 //============================================================================= | |
1094 #ifndef PRODUCT | |
1095 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { | |
1096 Compile* C = ra_->C; | |
1097 | |
1098 if( do_polling() && ra_->C->is_method_compilation() ) { | |
1099 st->print("SETHI #PollAddr,L0\t! Load Polling address\n\t"); | |
1100 #ifdef _LP64 | |
1101 st->print("LDX [L0],G0\t!Poll for Safepointing\n\t"); | |
1102 #else | |
1103 st->print("LDUW [L0],G0\t!Poll for Safepointing\n\t"); | |
1104 #endif | |
1105 } | |
1106 | |
1107 if( do_polling() ) | |
1108 st->print("RET\n\t"); | |
1109 | |
1110 st->print("RESTORE"); | |
1111 } | |
1112 #endif | |
1113 | |
1114 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | |
1115 MacroAssembler _masm(&cbuf); | |
1116 Compile* C = ra_->C; | |
1117 | |
1118 __ verify_thread(); | |
1119 | |
1120 // If this does safepoint polling, then do it here | |
1121 if( do_polling() && ra_->C->is_method_compilation() ) { | |
727 | 1122 AddressLiteral polling_page(os::get_polling_page()); |
1123 __ sethi(polling_page, L0); | |
0 | 1124 __ relocate(relocInfo::poll_return_type); |
1125 __ ld_ptr( L0, 0, G0 ); | |
1126 } | |
1127 | |
1128 // If this is a return, then stuff the restore in the delay slot | |
1129 if( do_polling() ) { | |
1130 __ ret(); | |
1131 __ delayed()->restore(); | |
1132 } else { | |
1133 __ restore(); | |
1134 } | |
1135 } | |
1136 | |
1137 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { | |
1138 return MachNode::size(ra_); | |
1139 } | |
1140 | |
1141 int MachEpilogNode::reloc() const { | |
1142 return 16; // a large enough number | |
1143 } | |
1144 | |
1145 const Pipeline * MachEpilogNode::pipeline() const { | |
1146 return MachNode::pipeline_class(); | |
1147 } | |
1148 | |
1149 int MachEpilogNode::safepoint_offset() const { | |
1150 assert( do_polling(), "no return for this epilog node"); | |
1151 return MacroAssembler::size_of_sethi(os::get_polling_page()); | |
1152 } | |
1153 | |
1154 //============================================================================= | |
1155 | |
1156 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack | |
1157 enum RC { rc_bad, rc_int, rc_float, rc_stack }; | |
1158 static enum RC rc_class( OptoReg::Name reg ) { | |
1159 if( !OptoReg::is_valid(reg) ) return rc_bad; | |
1160 if (OptoReg::is_stack(reg)) return rc_stack; | |
1161 VMReg r = OptoReg::as_VMReg(reg); | |
1162 if (r->is_Register()) return rc_int; | |
1163 assert(r->is_FloatRegister(), "must be"); | |
1164 return rc_float; | |
1165 } | |
1166 | |
1167 static int impl_helper( const MachNode *mach, CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size, outputStream* st ) { | |
1168 if( cbuf ) { | |
1169 // Better yet would be some mechanism to handle variable-size matches correctly | |
1170 if (!Assembler::is_simm13(offset + STACK_BIAS)) { | |
1171 ra_->C->record_method_not_compilable("unable to handle large constant offsets"); | |
1172 } else { | |
1173 emit_form3_mem_reg(*cbuf, mach, opcode, -1, R_SP_enc, offset, 0, Matcher::_regEncode[reg]); | |
1174 } | |
1175 } | |
1176 #ifndef PRODUCT | |
1177 else if( !do_size ) { | |
1178 if( size != 0 ) st->print("\n\t"); | |
1179 if( is_load ) st->print("%s [R_SP + #%d],R_%s\t! spill",op_str,offset,OptoReg::regname(reg)); | |
1180 else st->print("%s R_%s,[R_SP + #%d]\t! spill",op_str,OptoReg::regname(reg),offset); | |
1181 } | |
1182 #endif | |
1183 return size+4; | |
1184 } | |
1185 | |
1186 static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int op1, int op2, const char *op_str, int size, outputStream* st ) { | |
1187 if( cbuf ) emit3( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst], op1, 0, op2, Matcher::_regEncode[src] ); | |
1188 #ifndef PRODUCT | |
1189 else if( !do_size ) { | |
1190 if( size != 0 ) st->print("\n\t"); | |
1191 st->print("%s R_%s,R_%s\t! spill",op_str,OptoReg::regname(src),OptoReg::regname(dst)); | |
1192 } | |
1193 #endif | |
1194 return size+4; | |
1195 } | |
1196 | |
1197 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, | |
1198 PhaseRegAlloc *ra_, | |
1199 bool do_size, | |
1200 outputStream* st ) const { | |
1201 // Get registers to move | |
1202 OptoReg::Name src_second = ra_->get_reg_second(in(1)); | |
1203 OptoReg::Name src_first = ra_->get_reg_first(in(1)); | |
1204 OptoReg::Name dst_second = ra_->get_reg_second(this ); | |
1205 OptoReg::Name dst_first = ra_->get_reg_first(this ); | |
1206 | |
1207 enum RC src_second_rc = rc_class(src_second); | |
1208 enum RC src_first_rc = rc_class(src_first); | |
1209 enum RC dst_second_rc = rc_class(dst_second); | |
1210 enum RC dst_first_rc = rc_class(dst_first); | |
1211 | |
1212 assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" ); | |
1213 | |
1214 // Generate spill code! | |
1215 int size = 0; | |
1216 | |
1217 if( src_first == dst_first && src_second == dst_second ) | |
1218 return size; // Self copy, no move | |
1219 | |
1220 // -------------------------------------- | |
1221 // Check for mem-mem move. Load into unused float registers and fall into | |
1222 // the float-store case. | |
1223 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { | |
1224 int offset = ra_->reg2offset(src_first); | |
1225 // Further check for aligned-adjacent pair, so we can use a double load | |
1226 if( (src_first&1)==0 && src_first+1 == src_second ) { | |
1227 src_second = OptoReg::Name(R_F31_num); | |
1228 src_second_rc = rc_float; | |
1229 size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F30_num,Assembler::lddf_op3,"LDDF",size, st); | |
1230 } else { | |
1231 size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F30_num,Assembler::ldf_op3 ,"LDF ",size, st); | |
1232 } | |
1233 src_first = OptoReg::Name(R_F30_num); | |
1234 src_first_rc = rc_float; | |
1235 } | |
1236 | |
1237 if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { | |
1238 int offset = ra_->reg2offset(src_second); | |
1239 size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F31_num,Assembler::ldf_op3,"LDF ",size, st); | |
1240 src_second = OptoReg::Name(R_F31_num); | |
1241 src_second_rc = rc_float; | |
1242 } | |
1243 | |
1244 // -------------------------------------- | |
1245 // Check for float->int copy; requires a trip through memory | |
1246 if( src_first_rc == rc_float && dst_first_rc == rc_int ) { | |
1247 int offset = frame::register_save_words*wordSize; | |
1248 if( cbuf ) { | |
1249 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16 ); | |
1250 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); | |
1251 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); | |
1252 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16 ); | |
1253 } | |
1254 #ifndef PRODUCT | |
1255 else if( !do_size ) { | |
1256 if( size != 0 ) st->print("\n\t"); | |
1257 st->print( "SUB R_SP,16,R_SP\n"); | |
1258 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); | |
1259 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); | |
1260 st->print("\tADD R_SP,16,R_SP\n"); | |
1261 } | |
1262 #endif | |
1263 size += 16; | |
1264 } | |
1265 | |
1266 // -------------------------------------- | |
1267 // In the 32-bit 1-reg-longs build ONLY, I see mis-aligned long destinations. | |
1268 // In such cases, I have to do the big-endian swap. For aligned targets, the | |
1269 // hardware does the flop for me. Doubles are always aligned, so no problem | |
1270 // there. Misaligned sources only come from native-long-returns (handled | |
1271 // special below). | |
1272 #ifndef _LP64 | |
1273 if( src_first_rc == rc_int && // source is already big-endian | |
1274 src_second_rc != rc_bad && // 64-bit move | |
1275 ((dst_first&1)!=0 || dst_second != dst_first+1) ) { // misaligned dst | |
1276 assert( (src_first&1)==0 && src_second == src_first+1, "source must be aligned" ); | |
1277 // Do the big-endian flop. | |
1278 OptoReg::Name tmp = dst_first ; dst_first = dst_second ; dst_second = tmp ; | |
1279 enum RC tmp_rc = dst_first_rc; dst_first_rc = dst_second_rc; dst_second_rc = tmp_rc; | |
1280 } | |
1281 #endif | |
1282 | |
1283 // -------------------------------------- | |
1284 // Check for integer reg-reg copy | |
1285 if( src_first_rc == rc_int && dst_first_rc == rc_int ) { | |
1286 #ifndef _LP64 | |
1287 if( src_first == R_O0_num && src_second == R_O1_num ) { // Check for the evil O0/O1 native long-return case | |
1288 // Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value | |
1289 // as stored in memory. On a big-endian machine like SPARC, this means that the _second | |
1290 // operand contains the least significant word of the 64-bit value and vice versa. | |
1291 OptoReg::Name tmp = OptoReg::Name(R_O7_num); | |
1292 assert( (dst_first&1)==0 && dst_second == dst_first+1, "return a native O0/O1 long to an aligned-adjacent 64-bit reg" ); | |
1293 // Shift O0 left in-place, zero-extend O1, then OR them into the dst | |
1294 if( cbuf ) { | |
1295 emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[tmp], Assembler::sllx_op3, Matcher::_regEncode[src_first], 0x1020 ); | |
1296 emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[src_second], Assembler::srl_op3, Matcher::_regEncode[src_second], 0x0000 ); | |
1297 emit3 ( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler:: or_op3, Matcher::_regEncode[tmp], 0, Matcher::_regEncode[src_second] ); | |
1298 #ifndef PRODUCT | |
1299 } else if( !do_size ) { | |
1300 if( size != 0 ) st->print("\n\t"); | |
1301 st->print("SLLX R_%s,32,R_%s\t! Move O0-first to O7-high\n\t", OptoReg::regname(src_first), OptoReg::regname(tmp)); | |
1302 st->print("SRL R_%s, 0,R_%s\t! Zero-extend O1\n\t", OptoReg::regname(src_second), OptoReg::regname(src_second)); | |
1303 st->print("OR R_%s,R_%s,R_%s\t! spill",OptoReg::regname(tmp), OptoReg::regname(src_second), OptoReg::regname(dst_first)); | |
1304 #endif | |
1305 } | |
1306 return size+12; | |
1307 } | |
1308 else if( dst_first == R_I0_num && dst_second == R_I1_num ) { | |
1309 // returning a long value in I0/I1 | |
1310 // a SpillCopy must be able to target a return instruction's reg_class | |
1311 // Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value | |
1312 // as stored in memory. On a big-endian machine like SPARC, this means that the _second | |
1313 // operand contains the least significant word of the 64-bit value and vice versa. | |
1314 OptoReg::Name tdest = dst_first; | |
1315 | |
1316 if (src_first == dst_first) { | |
1317 tdest = OptoReg::Name(R_O7_num); | |
1318 size += 4; | |
1319 } | |
1320 | |
1321 if( cbuf ) { | |
1322 assert( (src_first&1) == 0 && (src_first+1) == src_second, "return value was in an aligned-adjacent 64-bit reg"); | |
1323 // Shift value in upper 32-bits of src to lower 32-bits of I0; move lower 32-bits to I1 | |
1324 // ShrL_reg_imm6 | |
1325 emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[tdest], Assembler::srlx_op3, Matcher::_regEncode[src_second], 32 | 0x1000 ); | |
1326 // ShrR_reg_imm6 src, 0, dst | |
1327 emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srl_op3, Matcher::_regEncode[src_first], 0x0000 ); | |
1328 if (tdest != dst_first) { | |
1329 emit3 ( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler::or_op3, 0/*G0*/, 0/*op2*/, Matcher::_regEncode[tdest] ); | |
1330 } | |
1331 } | |
1332 #ifndef PRODUCT | |
1333 else if( !do_size ) { | |
1334 if( size != 0 ) st->print("\n\t"); // %%%%% !!!!! | |
1335 st->print("SRLX R_%s,32,R_%s\t! Extract MSW\n\t",OptoReg::regname(src_second),OptoReg::regname(tdest)); | |
1336 st->print("SRL R_%s, 0,R_%s\t! Extract LSW\n\t",OptoReg::regname(src_first),OptoReg::regname(dst_second)); | |
1337 if (tdest != dst_first) { | |
1338 st->print("MOV R_%s,R_%s\t! spill\n\t", OptoReg::regname(tdest), OptoReg::regname(dst_first)); | |
1339 } | |
1340 } | |
1341 #endif // PRODUCT | |
1342 return size+8; | |
1343 } | |
1344 #endif // !_LP64 | |
1345 // Else normal reg-reg copy | |
1346 assert( src_second != dst_first, "smashed second before evacuating it" ); | |
1347 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::or_op3,0,"MOV ",size, st); | |
1348 assert( (src_first&1) == 0 && (dst_first&1) == 0, "never move second-halves of int registers" ); | |
1349 // This moves an aligned adjacent pair. | |
1350 // See if we are done. | |
1351 if( src_first+1 == src_second && dst_first+1 == dst_second ) | |
1352 return size; | |
1353 } | |
1354 | |
1355 // Check for integer store | |
1356 if( src_first_rc == rc_int && dst_first_rc == rc_stack ) { | |
1357 int offset = ra_->reg2offset(dst_first); | |
1358 // Further check for aligned-adjacent pair, so we can use a double store | |
1359 if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) | |
1360 return impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stx_op3,"STX ",size, st); | |
1361 size = impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stw_op3,"STW ",size, st); | |
1362 } | |
1363 | |
1364 // Check for integer load | |
1365 if( dst_first_rc == rc_int && src_first_rc == rc_stack ) { | |
1366 int offset = ra_->reg2offset(src_first); | |
1367 // Further check for aligned-adjacent pair, so we can use a double load | |
1368 if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) | |
1369 return impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::ldx_op3 ,"LDX ",size, st); | |
1370 size = impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); | |
1371 } | |
1372 | |
1373 // Check for float reg-reg copy | |
1374 if( src_first_rc == rc_float && dst_first_rc == rc_float ) { | |
1375 // Further check for aligned-adjacent pair, so we can use a double move | |
1376 if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) | |
1377 return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::fpop1_op3,Assembler::fmovd_opf,"FMOVD",size, st); | |
1378 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::fpop1_op3,Assembler::fmovs_opf,"FMOVS",size, st); | |
1379 } | |
1380 | |
1381 // Check for float store | |
1382 if( src_first_rc == rc_float && dst_first_rc == rc_stack ) { | |
1383 int offset = ra_->reg2offset(dst_first); | |
1384 // Further check for aligned-adjacent pair, so we can use a double store | |
1385 if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) | |
1386 return impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stdf_op3,"STDF",size, st); | |
1387 size = impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); | |
1388 } | |
1389 | |
1390 // Check for float load | |
1391 if( dst_first_rc == rc_float && src_first_rc == rc_stack ) { | |
1392 int offset = ra_->reg2offset(src_first); | |
1393 // Further check for aligned-adjacent pair, so we can use a double load | |
1394 if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) | |
1395 return impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::lddf_op3,"LDDF",size, st); | |
1396 size = impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::ldf_op3 ,"LDF ",size, st); | |
1397 } | |
1398 | |
1399 // -------------------------------------------------------------------- | |
1400 // Check for hi bits still needing moving. Only happens for misaligned | |
1401 // arguments to native calls. | |
1402 if( src_second == dst_second ) | |
1403 return size; // Self copy; no move | |
1404 assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" ); | |
1405 | |
1406 #ifndef _LP64 | |
1407 // In the LP64 build, all registers can be moved as aligned/adjacent | |
605 | 1408 // pairs, so there's never any need to move the high bits separately. |
0 | 1409 // The 32-bit builds have to deal with the 32-bit ABI which can force |
1410 // all sorts of silly alignment problems. | |
1411 | |
1412 // Check for integer reg-reg copy. Hi bits are stuck up in the top | |
1413 // 32-bits of a 64-bit register, but are needed in low bits of another | |
1414 // register (else it's a hi-bits-to-hi-bits copy which should have | |
1415 // happened already as part of a 64-bit move) | |
1416 if( src_second_rc == rc_int && dst_second_rc == rc_int ) { | |
1417 assert( (src_second&1)==1, "its the evil O0/O1 native return case" ); | |
1418 assert( (dst_second&1)==0, "should have moved with 1 64-bit move" ); | |
1419 // Shift src_second down to dst_second's low bits. | |
1420 if( cbuf ) { | |
1421 emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020 ); | |
1422 #ifndef PRODUCT | |
1423 } else if( !do_size ) { | |
1424 if( size != 0 ) st->print("\n\t"); | |
1425 st->print("SRLX R_%s,32,R_%s\t! spill: Move high bits down low",OptoReg::regname(src_second-1),OptoReg::regname(dst_second)); | |
1426 #endif | |
1427 } | |
1428 return size+4; | |
1429 } | |
1430 | |
1431 // Check for high word integer store. Must down-shift the hi bits | |
1432 // into a temp register, then fall into the case of storing int bits. | |
1433 if( src_second_rc == rc_int && dst_second_rc == rc_stack && (src_second&1)==1 ) { | |
1434 // Shift src_second down to dst_second's low bits. | |
1435 if( cbuf ) { | |
1436 emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[R_O7_num], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020 ); | |
1437 #ifndef PRODUCT | |
1438 } else if( !do_size ) { | |
1439 if( size != 0 ) st->print("\n\t"); | |
1440 st->print("SRLX R_%s,32,R_%s\t! spill: Move high bits down low",OptoReg::regname(src_second-1),OptoReg::regname(R_O7_num)); | |
1441 #endif | |
1442 } | |
1443 size+=4; | |
1444 src_second = OptoReg::Name(R_O7_num); // Not R_O7H_num! | |
1445 } | |
1446 | |
1447 // Check for high word integer load | |
1448 if( dst_second_rc == rc_int && src_second_rc == rc_stack ) | |
1449 return impl_helper(this,cbuf,ra_,do_size,true ,ra_->reg2offset(src_second),dst_second,Assembler::lduw_op3,"LDUW",size, st); | |
1450 | |
1451 // Check for high word integer store | |
1452 if( src_second_rc == rc_int && dst_second_rc == rc_stack ) | |
1453 return impl_helper(this,cbuf,ra_,do_size,false,ra_->reg2offset(dst_second),src_second,Assembler::stw_op3 ,"STW ",size, st); | |
1454 | |
1455 // Check for high word float store | |
1456 if( src_second_rc == rc_float && dst_second_rc == rc_stack ) | |
1457 return impl_helper(this,cbuf,ra_,do_size,false,ra_->reg2offset(dst_second),src_second,Assembler::stf_op3 ,"STF ",size, st); | |
1458 | |
1459 #endif // !_LP64 | |
1460 | |
1461 Unimplemented(); | |
1462 } | |
1463 | |
1464 #ifndef PRODUCT | |
1465 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { | |
1466 implementation( NULL, ra_, false, st ); | |
1467 } | |
1468 #endif | |
1469 | |
1470 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | |
1471 implementation( &cbuf, ra_, false, NULL ); | |
1472 } | |
1473 | |
1474 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { | |
1475 return implementation( NULL, ra_, true, NULL ); | |
1476 } | |
1477 | |
1478 //============================================================================= | |
1479 #ifndef PRODUCT | |
1480 void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const { | |
1481 st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count); | |
1482 } | |
1483 #endif | |
1484 | |
1485 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const { | |
1486 MacroAssembler _masm(&cbuf); | |
1487 for(int i = 0; i < _count; i += 1) { | |
1488 __ nop(); | |
1489 } | |
1490 } | |
1491 | |
1492 uint MachNopNode::size(PhaseRegAlloc *ra_) const { | |
1493 return 4 * _count; | |
1494 } | |
1495 | |
1496 | |
1497 //============================================================================= | |
1498 #ifndef PRODUCT | |
1499 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { | |
1500 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); | |
1501 int reg = ra_->get_reg_first(this); | |
1502 st->print("LEA [R_SP+#%d+BIAS],%s",offset,Matcher::regName[reg]); | |
1503 } | |
1504 #endif | |
1505 | |
1506 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | |
1507 MacroAssembler _masm(&cbuf); | |
1508 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()) + STACK_BIAS; | |
1509 int reg = ra_->get_encode(this); | |
1510 | |
1511 if (Assembler::is_simm13(offset)) { | |
1512 __ add(SP, offset, reg_to_register_object(reg)); | |
1513 } else { | |
1514 __ set(offset, O7); | |
1515 __ add(SP, O7, reg_to_register_object(reg)); | |
1516 } | |
1517 } | |
1518 | |
1519 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { | |
1520 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_) | |
1521 assert(ra_ == ra_->C->regalloc(), "sanity"); | |
1522 return ra_->C->scratch_emit_size(this); | |
1523 } | |
1524 | |
1525 //============================================================================= | |
1526 | |
1527 // emit call stub, compiled java to interpretor | |
1528 void emit_java_to_interp(CodeBuffer &cbuf ) { | |
1529 | |
1530 // Stub is fixed up when the corresponding call is converted from calling | |
1531 // compiled code to calling interpreted code. | |
1532 // set (empty), G5 | |
1533 // jmp -1 | |
1534 | |
1535 address mark = cbuf.inst_mark(); // get mark within main instrs section | |
1536 | |
1537 MacroAssembler _masm(&cbuf); | |
1538 | |
1539 address base = | |
1540 __ start_a_stub(Compile::MAX_stubs_size); | |
1541 if (base == NULL) return; // CodeBuffer::expand failed | |
1542 | |
1543 // static stub relocation stores the instruction address of the call | |
1544 __ relocate(static_stub_Relocation::spec(mark)); | |
1545 | |
1546 __ set_oop(NULL, reg_to_register_object(Matcher::inline_cache_reg_encode())); | |
1547 | |
1548 __ set_inst_mark(); | |
727 | 1549 AddressLiteral addrlit(-1); |
1550 __ JUMP(addrlit, G3, 0); | |
0 | 1551 |
1552 __ delayed()->nop(); | |
1553 | |
1554 // Update current stubs pointer and restore code_end. | |
1555 __ end_a_stub(); | |
1556 } | |
1557 | |
1558 // size of call stub, compiled java to interpretor | |
1559 uint size_java_to_interp() { | |
1560 // This doesn't need to be accurate but it must be larger or equal to | |
1561 // the real size of the stub. | |
1562 return (NativeMovConstReg::instruction_size + // sethi/setlo; | |
1563 NativeJump::instruction_size + // sethi; jmp; nop | |
1564 (TraceJumps ? 20 * BytesPerInstWord : 0) ); | |
1565 } | |
1566 // relocation entries for call stub, compiled java to interpretor | |
1567 uint reloc_java_to_interp() { | |
1568 return 10; // 4 in emit_java_to_interp + 1 in Java_Static_Call | |
1569 } | |
1570 | |
1571 | |
1572 //============================================================================= | |
1573 #ifndef PRODUCT | |
1574 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { | |
1575 st->print_cr("\nUEP:"); | |
1576 #ifdef _LP64 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1577 if (UseCompressedOops) { |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
1578 assert(Universe::heap() != NULL, "java heap should be initialized"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1579 st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1580 st->print_cr("\tSLL R_G5,3,R_G5"); |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
1581 if (Universe::narrow_oop_base() != NULL) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
1582 st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1583 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1584 st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1585 } |
0 | 1586 st->print_cr("\tCMP R_G5,R_G3" ); |
1587 st->print ("\tTne xcc,R_G0+ST_RESERVED_FOR_USER_0+2"); | |
1588 #else // _LP64 | |
1589 st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); | |
1590 st->print_cr("\tCMP R_G5,R_G3" ); | |
1591 st->print ("\tTne icc,R_G0+ST_RESERVED_FOR_USER_0+2"); | |
1592 #endif // _LP64 | |
1593 } | |
1594 #endif | |
1595 | |
1596 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | |
1597 MacroAssembler _masm(&cbuf); | |
1598 Label L; | |
1599 Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); | |
1600 Register temp_reg = G3; | |
1601 assert( G5_ic_reg != temp_reg, "conflicting registers" ); | |
1602 | |
605 | 1603 // Load klass from receiver |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1604 __ load_klass(O0, temp_reg); |
0 | 1605 // Compare against expected klass |
1606 __ cmp(temp_reg, G5_ic_reg); | |
1607 // Branch to miss code, checks xcc or icc depending | |
1608 __ trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0+2); | |
1609 } | |
1610 | |
1611 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { | |
1612 return MachNode::size(ra_); | |
1613 } | |
1614 | |
1615 | |
1616 //============================================================================= | |
1617 | |
1618 uint size_exception_handler() { | |
1619 if (TraceJumps) { | |
1620 return (400); // just a guess | |
1621 } | |
1622 return ( NativeJump::instruction_size ); // sethi;jmp;nop | |
1623 } | |
1624 | |
1625 uint size_deopt_handler() { | |
1626 if (TraceJumps) { | |
1627 return (400); // just a guess | |
1628 } | |
1629 return ( 4+ NativeJump::instruction_size ); // save;sethi;jmp;restore | |
1630 } | |
1631 | |
1632 // Emit exception handler code. | |
1633 int emit_exception_handler(CodeBuffer& cbuf) { | |
1634 Register temp_reg = G3; | |
727 | 1635 AddressLiteral exception_blob(OptoRuntime::exception_blob()->instructions_begin()); |
0 | 1636 MacroAssembler _masm(&cbuf); |
1637 | |
1638 address base = | |
1639 __ start_a_stub(size_exception_handler()); | |
1640 if (base == NULL) return 0; // CodeBuffer::expand failed | |
1641 | |
1642 int offset = __ offset(); | |
1643 | |
727 | 1644 __ JUMP(exception_blob, temp_reg, 0); // sethi;jmp |
0 | 1645 __ delayed()->nop(); |
1646 | |
1647 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); | |
1648 | |
1649 __ end_a_stub(); | |
1650 | |
1651 return offset; | |
1652 } | |
1653 | |
1654 int emit_deopt_handler(CodeBuffer& cbuf) { | |
1655 // Can't use any of the current frame's registers as we may have deopted | |
1656 // at a poll and everything (including G3) can be live. | |
1657 Register temp_reg = L0; | |
727 | 1658 AddressLiteral deopt_blob(SharedRuntime::deopt_blob()->unpack()); |
0 | 1659 MacroAssembler _masm(&cbuf); |
1660 | |
1661 address base = | |
1662 __ start_a_stub(size_deopt_handler()); | |
1663 if (base == NULL) return 0; // CodeBuffer::expand failed | |
1664 | |
1665 int offset = __ offset(); | |
1666 __ save_frame(0); | |
727 | 1667 __ JUMP(deopt_blob, temp_reg, 0); // sethi;jmp |
0 | 1668 __ delayed()->restore(); |
1669 | |
1670 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); | |
1671 | |
1672 __ end_a_stub(); | |
1673 return offset; | |
1674 | |
1675 } | |
1676 | |
1677 // Given a register encoding, produce a Integer Register object | |
1678 static Register reg_to_register_object(int register_encoding) { | |
1679 assert(L5->encoding() == R_L5_enc && G1->encoding() == R_G1_enc, "right coding"); | |
1680 return as_Register(register_encoding); | |
1681 } | |
1682 | |
1683 // Given a register encoding, produce a single-precision Float Register object | |
1684 static FloatRegister reg_to_SingleFloatRegister_object(int register_encoding) { | |
1685 assert(F5->encoding(FloatRegisterImpl::S) == R_F5_enc && F12->encoding(FloatRegisterImpl::S) == R_F12_enc, "right coding"); | |
1686 return as_SingleFloatRegister(register_encoding); | |
1687 } | |
1688 | |
1689 // Given a register encoding, produce a double-precision Float Register object | |
1690 static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding) { | |
1691 assert(F4->encoding(FloatRegisterImpl::D) == R_F4_enc, "right coding"); | |
1692 assert(F32->encoding(FloatRegisterImpl::D) == R_D32_enc, "right coding"); | |
1693 return as_DoubleFloatRegister(register_encoding); | |
1694 } | |
1695 | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1696 const bool Matcher::match_rule_supported(int opcode) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1697 if (!has_match_rule(opcode)) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1698 return false; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1699 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1700 switch (opcode) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1701 case Op_CountLeadingZerosI: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1702 case Op_CountLeadingZerosL: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1703 case Op_CountTrailingZerosI: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1704 case Op_CountTrailingZerosL: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1705 if (!UsePopCountInstruction) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1706 return false; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1707 break; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1708 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1709 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1710 return true; // Per default match rules are supported. |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1711 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
1712 |
0 | 1713 int Matcher::regnum_to_fpu_offset(int regnum) { |
1714 return regnum - 32; // The FP registers are in the second chunk | |
1715 } | |
1716 | |
1717 #ifdef ASSERT | |
1718 address last_rethrow = NULL; // debugging aid for Rethrow encoding | |
1719 #endif | |
1720 | |
1721 // Vector width in bytes | |
1722 const uint Matcher::vector_width_in_bytes(void) { | |
1723 return 8; | |
1724 } | |
1725 | |
1726 // Vector ideal reg | |
1727 const uint Matcher::vector_ideal_reg(void) { | |
1728 return Op_RegD; | |
1729 } | |
1730 | |
1731 // USII supports fxtof through the whole range of number, USIII doesn't | |
1732 const bool Matcher::convL2FSupported(void) { | |
1733 return VM_Version::has_fast_fxtof(); | |
1734 } | |
1735 | |
1736 // Is this branch offset short enough that a short branch can be used? | |
1737 // | |
1738 // NOTE: If the platform does not provide any short branch variants, then | |
1739 // this method should return false for offset 0. | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1740 bool Matcher::is_short_branch_offset(int rule, int offset) { |
0 | 1741 return false; |
1742 } | |
1743 | |
1744 const bool Matcher::isSimpleConstant64(jlong value) { | |
1745 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. | |
1746 // Depends on optimizations in MacroAssembler::setx. | |
1747 int hi = (int)(value >> 32); | |
1748 int lo = (int)(value & ~0); | |
1749 return (hi == 0) || (hi == -1) || (lo == 0); | |
1750 } | |
1751 | |
1752 // No scaling for the parameter the ClearArray node. | |
1753 const bool Matcher::init_array_count_is_in_bytes = true; | |
1754 | |
1755 // Threshold size for cleararray. | |
1756 const int Matcher::init_array_short_size = 8 * BytesPerLong; | |
1757 | |
1758 // Should the Matcher clone shifts on addressing modes, expecting them to | |
1759 // be subsumed into complex addressing expressions or compute them into | |
1760 // registers? True for Intel but false for most RISCs | |
1761 const bool Matcher::clone_shift_expressions = false; | |
1762 | |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1763 bool Matcher::narrow_oop_use_complex_address() { |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1764 NOT_LP64(ShouldNotCallThis()); |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1765 assert(UseCompressedOops, "only for compressed oops code"); |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1766 return false; |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1767 } |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1571
diff
changeset
|
1768 |
0 | 1769 // Is it better to copy float constants, or load them directly from memory? |
1770 // Intel can load a float constant from a direct address, requiring no | |
1771 // extra registers. Most RISCs will have to materialize an address into a | |
1772 // register first, so they would do better to copy the constant from stack. | |
1773 const bool Matcher::rematerialize_float_constants = false; | |
1774 | |
1775 // If CPU can load and store mis-aligned doubles directly then no fixup is | |
1776 // needed. Else we split the double into 2 integer pieces and move it | |
1777 // piece-by-piece. Only happens when passing doubles into C code as the | |
1778 // Java calling convention forces doubles to be aligned. | |
1779 #ifdef _LP64 | |
1780 const bool Matcher::misaligned_doubles_ok = true; | |
1781 #else | |
1782 const bool Matcher::misaligned_doubles_ok = false; | |
1783 #endif | |
1784 | |
1785 // No-op on SPARC. | |
1786 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { | |
1787 } | |
1788 | |
1789 // Advertise here if the CPU requires explicit rounding operations | |
1790 // to implement the UseStrictFP mode. | |
1791 const bool Matcher::strict_fp_requires_explicit_rounding = false; | |
1792 | |
1274
2883969d09e7
6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents:
1160
diff
changeset
|
1793 // Are floats conerted to double when stored to stack during deoptimization? |
2883969d09e7
6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents:
1160
diff
changeset
|
1794 // Sparc does not handle callee-save floats. |
2883969d09e7
6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents:
1160
diff
changeset
|
1795 bool Matcher::float_in_double() { return false; } |
0 | 1796 |
1797 // Do ints take an entire long register or just half? | |
1798 // Note that we if-def off of _LP64. | |
1799 // The relevant question is how the int is callee-saved. In _LP64 | |
1800 // the whole long is written but de-opt'ing will have to extract | |
1801 // the relevant 32 bits, in not-_LP64 only the low 32 bits is written. | |
1802 #ifdef _LP64 | |
1803 const bool Matcher::int_in_long = true; | |
1804 #else | |
1805 const bool Matcher::int_in_long = false; | |
1806 #endif | |
1807 | |
1808 // Return whether or not this register is ever used as an argument. This | |
1809 // function is used on startup to build the trampoline stubs in generateOptoStub. | |
1810 // Registers not mentioned will be killed by the VM call in the trampoline, and | |
1811 // arguments in those registers not be available to the callee. | |
1812 bool Matcher::can_be_java_arg( int reg ) { | |
1813 // Standard sparc 6 args in registers | |
1814 if( reg == R_I0_num || | |
1815 reg == R_I1_num || | |
1816 reg == R_I2_num || | |
1817 reg == R_I3_num || | |
1818 reg == R_I4_num || | |
1819 reg == R_I5_num ) return true; | |
1820 #ifdef _LP64 | |
1821 // 64-bit builds can pass 64-bit pointers and longs in | |
1822 // the high I registers | |
1823 if( reg == R_I0H_num || | |
1824 reg == R_I1H_num || | |
1825 reg == R_I2H_num || | |
1826 reg == R_I3H_num || | |
1827 reg == R_I4H_num || | |
1828 reg == R_I5H_num ) return true; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1829 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1830 if ((UseCompressedOops) && (reg == R_G6_num || reg == R_G6H_num)) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1831 return true; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1832 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
1833 |
0 | 1834 #else |
1835 // 32-bit builds with longs-in-one-entry pass longs in G1 & G4. | |
1836 // Longs cannot be passed in O regs, because O regs become I regs | |
1837 // after a 'save' and I regs get their high bits chopped off on | |
1838 // interrupt. | |
1839 if( reg == R_G1H_num || reg == R_G1_num ) return true; | |
1840 if( reg == R_G4H_num || reg == R_G4_num ) return true; | |
1841 #endif | |
1842 // A few float args in registers | |
1843 if( reg >= R_F0_num && reg <= R_F7_num ) return true; | |
1844 | |
1845 return false; | |
1846 } | |
1847 | |
1848 bool Matcher::is_spillable_arg( int reg ) { | |
1849 return can_be_java_arg(reg); | |
1850 } | |
1851 | |
1852 // Register for DIVI projection of divmodI | |
1853 RegMask Matcher::divI_proj_mask() { | |
1854 ShouldNotReachHere(); | |
1855 return RegMask(); | |
1856 } | |
1857 | |
1858 // Register for MODI projection of divmodI | |
1859 RegMask Matcher::modI_proj_mask() { | |
1860 ShouldNotReachHere(); | |
1861 return RegMask(); | |
1862 } | |
1863 | |
1864 // Register for DIVL projection of divmodL | |
1865 RegMask Matcher::divL_proj_mask() { | |
1866 ShouldNotReachHere(); | |
1867 return RegMask(); | |
1868 } | |
1869 | |
1870 // Register for MODL projection of divmodL | |
1871 RegMask Matcher::modL_proj_mask() { | |
1872 ShouldNotReachHere(); | |
1873 return RegMask(); | |
1874 } | |
1875 | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1041
diff
changeset
|
1876 const RegMask Matcher::method_handle_invoke_SP_save_mask() { |
1567 | 1877 return L7_REGP_mask; |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1041
diff
changeset
|
1878 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1041
diff
changeset
|
1879 |
0 | 1880 %} |
1881 | |
1882 | |
1883 // The intptr_t operand types, defined by textual substitution. | |
1884 // (Cf. opto/type.hpp. This lets us avoid many, many other ifdefs.) | |
1885 #ifdef _LP64 | |
824 | 1886 #define immX immL |
1887 #define immX13 immL13 | |
1888 #define immX13m7 immL13m7 | |
1889 #define iRegX iRegL | |
1890 #define g1RegX g1RegL | |
0 | 1891 #else |
824 | 1892 #define immX immI |
1893 #define immX13 immI13 | |
1894 #define immX13m7 immI13m7 | |
1895 #define iRegX iRegI | |
1896 #define g1RegX g1RegI | |
0 | 1897 #endif |
1898 | |
1899 //----------ENCODING BLOCK----------------------------------------------------- | |
1900 // This block specifies the encoding classes used by the compiler to output | |
1901 // byte streams. Encoding classes are parameterized macros used by | |
1902 // Machine Instruction Nodes in order to generate the bit encoding of the | |
1903 // instruction. Operands specify their base encoding interface with the | |
1904 // interface keyword. There are currently supported four interfaces, | |
1905 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an | |
1906 // operand to generate a function which returns its register number when | |
1907 // queried. CONST_INTER causes an operand to generate a function which | |
1908 // returns the value of the constant when queried. MEMORY_INTER causes an | |
1909 // operand to generate four functions which return the Base Register, the | |
1910 // Index Register, the Scale Value, and the Offset Value of the operand when | |
1911 // queried. COND_INTER causes an operand to generate six functions which | |
1912 // return the encoding code (ie - encoding bits for the instruction) | |
1913 // associated with each basic boolean condition for a conditional instruction. | |
1914 // | |
1915 // Instructions specify two basic values for encoding. Again, a function | |
1916 // is available to check if the constant displacement is an oop. They use the | |
1917 // ins_encode keyword to specify their encoding classes (which must be | |
1918 // a sequence of enc_class names, and their parameters, specified in | |
1919 // the encoding block), and they use the | |
1920 // opcode keyword to specify, in order, their primary, secondary, and | |
1921 // tertiary opcode. Only the opcode sections which a particular instruction | |
1922 // needs for encoding need to be specified. | |
1923 encode %{ | |
1924 enc_class enc_untested %{ | |
1925 #ifdef ASSERT | |
1926 MacroAssembler _masm(&cbuf); | |
1927 __ untested("encoding"); | |
1928 #endif | |
1929 %} | |
1930 | |
1931 enc_class form3_mem_reg( memory mem, iRegI dst ) %{ | |
1932 emit_form3_mem_reg(cbuf, this, $primary, $tertiary, | |
1933 $mem$$base, $mem$$disp, $mem$$index, $dst$$reg); | |
1934 %} | |
1935 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1936 enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{ |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1937 emit_form3_mem_reg(cbuf, this, $primary, -1, |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1938 $mem$$base, $mem$$disp, $mem$$index, $dst$$reg); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1939 %} |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1940 |
0 | 1941 enc_class form3_mem_prefetch_read( memory mem ) %{ |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1942 emit_form3_mem_reg(cbuf, this, $primary, -1, |
0 | 1943 $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/); |
1944 %} | |
1945 | |
1946 enc_class form3_mem_prefetch_write( memory mem ) %{ | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1947 emit_form3_mem_reg(cbuf, this, $primary, -1, |
0 | 1948 $mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/); |
1949 %} | |
1950 | |
1951 enc_class form3_mem_reg_long_unaligned_marshal( memory mem, iRegL reg ) %{ | |
1952 assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" ); | |
1953 assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" ); | |
1954 guarantee($mem$$index == R_G0_enc, "double index?"); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1955 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc ); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1956 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg ); |
0 | 1957 emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 ); |
1958 emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc ); | |
1959 %} | |
1960 | |
1961 enc_class form3_mem_reg_double_unaligned( memory mem, RegD_low reg ) %{ | |
1962 assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" ); | |
1963 assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" ); | |
1964 guarantee($mem$$index == R_G0_enc, "double index?"); | |
1965 // Load long with 2 instructions | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1966 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 ); |
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1967 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 ); |
0 | 1968 %} |
1969 | |
1970 //%%% form3_mem_plus_4_reg is a hack--get rid of it | |
1971 enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{ | |
1972 guarantee($mem$$disp, "cannot offset a reg-reg operand by 4"); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
1973 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg); |
0 | 1974 %} |
1975 | |
1976 enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{ | |
1977 // Encode a reg-reg copy. If it is useless, then empty encoding. | |
1978 if( $rs2$$reg != $rd$$reg ) | |
1979 emit3( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0, $rs2$$reg ); | |
1980 %} | |
1981 | |
1982 // Target lo half of long | |
1983 enc_class form3_g0_rs2_rd_move_lo( iRegI rs2, iRegL rd ) %{ | |
1984 // Encode a reg-reg copy. If it is useless, then empty encoding. | |
1985 if( $rs2$$reg != LONG_LO_REG($rd$$reg) ) | |
1986 emit3( cbuf, Assembler::arith_op, LONG_LO_REG($rd$$reg), Assembler::or_op3, 0, 0, $rs2$$reg ); | |
1987 %} | |
1988 | |
1989 // Source lo half of long | |
1990 enc_class form3_g0_rs2_rd_move_lo2( iRegL rs2, iRegI rd ) %{ | |
1991 // Encode a reg-reg copy. If it is useless, then empty encoding. | |
1992 if( LONG_LO_REG($rs2$$reg) != $rd$$reg ) | |
1993 emit3( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0, LONG_LO_REG($rs2$$reg) ); | |
1994 %} | |
1995 | |
1996 // Target hi half of long | |
1997 enc_class form3_rs1_rd_copysign_hi( iRegI rs1, iRegL rd ) %{ | |
1998 emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::sra_op3, $rs1$$reg, 31 ); | |
1999 %} | |
2000 | |
2001 // Source lo half of long, and leave it sign extended. | |
2002 enc_class form3_rs1_rd_signextend_lo1( iRegL rs1, iRegI rd ) %{ | |
2003 // Sign extend low half | |
2004 emit3( cbuf, Assembler::arith_op, $rd$$reg, Assembler::sra_op3, $rs1$$reg, 0, 0 ); | |
2005 %} | |
2006 | |
2007 // Source hi half of long, and leave it sign extended. | |
2008 enc_class form3_rs1_rd_copy_hi1( iRegL rs1, iRegI rd ) %{ | |
2009 // Shift high half to low half | |
2010 emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::srlx_op3, $rs1$$reg, 32 ); | |
2011 %} | |
2012 | |
2013 // Source hi half of long | |
2014 enc_class form3_g0_rs2_rd_move_hi2( iRegL rs2, iRegI rd ) %{ | |
2015 // Encode a reg-reg copy. If it is useless, then empty encoding. | |
2016 if( LONG_HI_REG($rs2$$reg) != $rd$$reg ) | |
2017 emit3( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0, LONG_HI_REG($rs2$$reg) ); | |
2018 %} | |
2019 | |
2020 enc_class form3_rs1_rs2_rd( iRegI rs1, iRegI rs2, iRegI rd ) %{ | |
2021 emit3( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, 0, $rs2$$reg ); | |
2022 %} | |
2023 | |
2024 enc_class enc_to_bool( iRegI src, iRegI dst ) %{ | |
2025 emit3 ( cbuf, Assembler::arith_op, 0, Assembler::subcc_op3, 0, 0, $src$$reg ); | |
2026 emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::addc_op3 , 0, 0 ); | |
2027 %} | |
2028 | |
2029 enc_class enc_ltmask( iRegI p, iRegI q, iRegI dst ) %{ | |
2030 emit3 ( cbuf, Assembler::arith_op, 0, Assembler::subcc_op3, $p$$reg, 0, $q$$reg ); | |
2031 // clear if nothing else is happening | |
2032 emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3, 0, 0 ); | |
2033 // blt,a,pn done | |
2034 emit2_19 ( cbuf, Assembler::branch_op, 1/*annul*/, Assembler::less, Assembler::bp_op2, Assembler::icc, 0/*predict not taken*/, 2 ); | |
2035 // mov dst,-1 in delay slot | |
2036 emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3, 0, -1 ); | |
2037 %} | |
2038 | |
2039 enc_class form3_rs1_imm5_rd( iRegI rs1, immU5 imm5, iRegI rd ) %{ | |
2040 emit3_simm13( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, $imm5$$constant & 0x1F ); | |
2041 %} | |
2042 | |
2043 enc_class form3_sd_rs1_imm6_rd( iRegL rs1, immU6 imm6, iRegL rd ) %{ | |
2044 emit3_simm13( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, ($imm6$$constant & 0x3F) | 0x1000 ); | |
2045 %} | |
2046 | |
2047 enc_class form3_sd_rs1_rs2_rd( iRegL rs1, iRegI rs2, iRegL rd ) %{ | |
2048 emit3( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, 0x80, $rs2$$reg ); | |
2049 %} | |
2050 | |
2051 enc_class form3_rs1_simm13_rd( iRegI rs1, immI13 simm13, iRegI rd ) %{ | |
2052 emit3_simm13( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, $simm13$$constant ); | |
2053 %} | |
2054 | |
2055 enc_class move_return_pc_to_o1() %{ | |
2056 emit3_simm13( cbuf, Assembler::arith_op, R_O1_enc, Assembler::add_op3, R_O7_enc, frame::pc_return_offset ); | |
2057 %} | |
2058 | |
2059 #ifdef _LP64 | |
2060 /* %%% merge with enc_to_bool */ | |
2061 enc_class enc_convP2B( iRegI dst, iRegP src ) %{ | |
2062 MacroAssembler _masm(&cbuf); | |
2063 | |
2064 Register src_reg = reg_to_register_object($src$$reg); | |
2065 Register dst_reg = reg_to_register_object($dst$$reg); | |
2066 __ movr(Assembler::rc_nz, src_reg, 1, dst_reg); | |
2067 %} | |
2068 #endif | |
2069 | |
2070 enc_class enc_cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, iRegI tmp ) %{ | |
2071 // (Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))) | |
2072 MacroAssembler _masm(&cbuf); | |
2073 | |
2074 Register p_reg = reg_to_register_object($p$$reg); | |
2075 Register q_reg = reg_to_register_object($q$$reg); | |
2076 Register y_reg = reg_to_register_object($y$$reg); | |
2077 Register tmp_reg = reg_to_register_object($tmp$$reg); | |
2078 | |
2079 __ subcc( p_reg, q_reg, p_reg ); | |
2080 __ add ( p_reg, y_reg, tmp_reg ); | |
2081 __ movcc( Assembler::less, false, Assembler::icc, tmp_reg, p_reg ); | |
2082 %} | |
2083 | |
2084 enc_class form_d2i_helper(regD src, regF dst) %{ | |
2085 // fcmp %fcc0,$src,$src | |
2086 emit3( cbuf, Assembler::arith_op , Assembler::fcc0, Assembler::fpop2_op3, $src$$reg, Assembler::fcmpd_opf, $src$$reg ); | |
2087 // branch %fcc0 not-nan, predict taken | |
2088 emit2_19( cbuf, Assembler::branch_op, 0/*annul*/, Assembler::f_ordered, Assembler::fbp_op2, Assembler::fcc0, 1/*predict taken*/, 4 ); | |
2089 // fdtoi $src,$dst | |
2090 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fdtoi_opf, $src$$reg ); | |
2091 // fitos $dst,$dst (if nan) | |
2092 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fitos_opf, $dst$$reg ); | |
2093 // clear $dst (if nan) | |
2094 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, $dst$$reg, Assembler::fsubs_opf, $dst$$reg ); | |
2095 // carry on here... | |
2096 %} | |
2097 | |
2098 enc_class form_d2l_helper(regD src, regD dst) %{ | |
2099 // fcmp %fcc0,$src,$src check for NAN | |
2100 emit3( cbuf, Assembler::arith_op , Assembler::fcc0, Assembler::fpop2_op3, $src$$reg, Assembler::fcmpd_opf, $src$$reg ); | |
2101 // branch %fcc0 not-nan, predict taken | |
2102 emit2_19( cbuf, Assembler::branch_op, 0/*annul*/, Assembler::f_ordered, Assembler::fbp_op2, Assembler::fcc0, 1/*predict taken*/, 4 ); | |
2103 // fdtox $src,$dst convert in delay slot | |
2104 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fdtox_opf, $src$$reg ); | |
2105 // fxtod $dst,$dst (if nan) | |
2106 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fxtod_opf, $dst$$reg ); | |
2107 // clear $dst (if nan) | |
2108 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, $dst$$reg, Assembler::fsubd_opf, $dst$$reg ); | |
2109 // carry on here... | |
2110 %} | |
2111 | |
2112 enc_class form_f2i_helper(regF src, regF dst) %{ | |
2113 // fcmps %fcc0,$src,$src | |
2114 emit3( cbuf, Assembler::arith_op , Assembler::fcc0, Assembler::fpop2_op3, $src$$reg, Assembler::fcmps_opf, $src$$reg ); | |
2115 // branch %fcc0 not-nan, predict taken | |
2116 emit2_19( cbuf, Assembler::branch_op, 0/*annul*/, Assembler::f_ordered, Assembler::fbp_op2, Assembler::fcc0, 1/*predict taken*/, 4 ); | |
2117 // fstoi $src,$dst | |
2118 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fstoi_opf, $src$$reg ); | |
2119 // fitos $dst,$dst (if nan) | |
2120 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fitos_opf, $dst$$reg ); | |
2121 // clear $dst (if nan) | |
2122 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, $dst$$reg, Assembler::fsubs_opf, $dst$$reg ); | |
2123 // carry on here... | |
2124 %} | |
2125 | |
2126 enc_class form_f2l_helper(regF src, regD dst) %{ | |
2127 // fcmps %fcc0,$src,$src | |
2128 emit3( cbuf, Assembler::arith_op , Assembler::fcc0, Assembler::fpop2_op3, $src$$reg, Assembler::fcmps_opf, $src$$reg ); | |
2129 // branch %fcc0 not-nan, predict taken | |
2130 emit2_19( cbuf, Assembler::branch_op, 0/*annul*/, Assembler::f_ordered, Assembler::fbp_op2, Assembler::fcc0, 1/*predict taken*/, 4 ); | |
2131 // fstox $src,$dst | |
2132 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fstox_opf, $src$$reg ); | |
2133 // fxtod $dst,$dst (if nan) | |
2134 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fxtod_opf, $dst$$reg ); | |
2135 // clear $dst (if nan) | |
2136 emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, $dst$$reg, Assembler::fsubd_opf, $dst$$reg ); | |
2137 // carry on here... | |
2138 %} | |
2139 | |
2140 enc_class form3_opf_rs2F_rdF(regF rs2, regF rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} | |
2141 enc_class form3_opf_rs2F_rdD(regF rs2, regD rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} | |
2142 enc_class form3_opf_rs2D_rdF(regD rs2, regF rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} | |
2143 enc_class form3_opf_rs2D_rdD(regD rs2, regD rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} | |
2144 | |
2145 enc_class form3_opf_rs2D_lo_rdF(regD rs2, regF rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg+1); %} | |
2146 | |
2147 enc_class form3_opf_rs2D_hi_rdD_hi(regD rs2, regD rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} | |
2148 enc_class form3_opf_rs2D_lo_rdD_lo(regD rs2, regD rd) %{ emit3(cbuf,$secondary,$rd$$reg+1,$primary,0,$tertiary,$rs2$$reg+1); %} | |
2149 | |
2150 enc_class form3_opf_rs1F_rs2F_rdF( regF rs1, regF rs2, regF rd ) %{ | |
2151 emit3( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, $tertiary, $rs2$$reg ); | |
2152 %} | |
2153 | |
2154 enc_class form3_opf_rs1D_rs2D_rdD( regD rs1, regD rs2, regD rd ) %{ | |
2155 emit3( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, $tertiary, $rs2$$reg ); | |
2156 %} | |
2157 | |
2158 enc_class form3_opf_rs1F_rs2F_fcc( regF rs1, regF rs2, flagsRegF fcc ) %{ | |
2159 emit3( cbuf, $secondary, $fcc$$reg, $primary, $rs1$$reg, $tertiary, $rs2$$reg ); | |
2160 %} | |
2161 | |
2162 enc_class form3_opf_rs1D_rs2D_fcc( regD rs1, regD rs2, flagsRegF fcc ) %{ | |
2163 emit3( cbuf, $secondary, $fcc$$reg, $primary, $rs1$$reg, $tertiary, $rs2$$reg ); | |
2164 %} | |
2165 | |
2166 enc_class form3_convI2F(regF rs2, regF rd) %{ | |
2167 emit3(cbuf,Assembler::arith_op,$rd$$reg,Assembler::fpop1_op3,0,$secondary,$rs2$$reg); | |
2168 %} | |
2169 | |
2170 // Encloding class for traceable jumps | |
2171 enc_class form_jmpl(g3RegP dest) %{ | |
2172 emit_jmpl(cbuf, $dest$$reg); | |
2173 %} | |
2174 | |
2175 enc_class form_jmpl_set_exception_pc(g1RegP dest) %{ | |
2176 emit_jmpl_set_exception_pc(cbuf, $dest$$reg); | |
2177 %} | |
2178 | |
2179 enc_class form2_nop() %{ | |
2180 emit_nop(cbuf); | |
2181 %} | |
2182 | |
2183 enc_class form2_illtrap() %{ | |
2184 emit_illtrap(cbuf); | |
2185 %} | |
2186 | |
2187 | |
2188 // Compare longs and convert into -1, 0, 1. | |
2189 enc_class cmpl_flag( iRegL src1, iRegL src2, iRegI dst ) %{ | |
2190 // CMP $src1,$src2 | |
2191 emit3( cbuf, Assembler::arith_op, 0, Assembler::subcc_op3, $src1$$reg, 0, $src2$$reg ); | |
2192 // blt,a,pn done | |
2193 emit2_19( cbuf, Assembler::branch_op, 1/*annul*/, Assembler::less , Assembler::bp_op2, Assembler::xcc, 0/*predict not taken*/, 5 ); | |
2194 // mov dst,-1 in delay slot | |
2195 emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3, 0, -1 ); | |
2196 // bgt,a,pn done | |
2197 emit2_19( cbuf, Assembler::branch_op, 1/*annul*/, Assembler::greater, Assembler::bp_op2, Assembler::xcc, 0/*predict not taken*/, 3 ); | |
2198 // mov dst,1 in delay slot | |
2199 emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3, 0, 1 ); | |
2200 // CLR $dst | |
2201 emit3( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3 , 0, 0, 0 ); | |
2202 %} | |
2203 | |
2204 enc_class enc_PartialSubtypeCheck() %{ | |
2205 MacroAssembler _masm(&cbuf); | |
2206 __ call(StubRoutines::Sparc::partial_subtype_check(), relocInfo::runtime_call_type); | |
2207 __ delayed()->nop(); | |
2208 %} | |
2209 | |
2210 enc_class enc_bp( Label labl, cmpOp cmp, flagsReg cc ) %{ | |
2211 MacroAssembler _masm(&cbuf); | |
2212 Label &L = *($labl$$label); | |
2213 Assembler::Predict predict_taken = | |
2214 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2215 | |
2216 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, L); | |
2217 __ delayed()->nop(); | |
2218 %} | |
2219 | |
2220 enc_class enc_bpl( Label labl, cmpOp cmp, flagsRegL cc ) %{ | |
2221 MacroAssembler _masm(&cbuf); | |
2222 Label &L = *($labl$$label); | |
2223 Assembler::Predict predict_taken = | |
2224 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2225 | |
2226 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, L); | |
2227 __ delayed()->nop(); | |
2228 %} | |
2229 | |
2230 enc_class enc_bpx( Label labl, cmpOp cmp, flagsRegP cc ) %{ | |
2231 MacroAssembler _masm(&cbuf); | |
2232 Label &L = *($labl$$label); | |
2233 Assembler::Predict predict_taken = | |
2234 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2235 | |
2236 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, L); | |
2237 __ delayed()->nop(); | |
2238 %} | |
2239 | |
2240 enc_class enc_fbp( Label labl, cmpOpF cmp, flagsRegF cc ) %{ | |
2241 MacroAssembler _masm(&cbuf); | |
2242 Label &L = *($labl$$label); | |
2243 Assembler::Predict predict_taken = | |
2244 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2245 | |
2246 __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($cc$$reg), predict_taken, L); | |
2247 __ delayed()->nop(); | |
2248 %} | |
2249 | |
2250 enc_class jump_enc( iRegX switch_val, o7RegI table) %{ | |
2251 MacroAssembler _masm(&cbuf); | |
2252 | |
2253 Register switch_reg = as_Register($switch_val$$reg); | |
2254 Register table_reg = O7; | |
2255 | |
2256 address table_base = __ address_table_constant(_index2label); | |
2257 RelocationHolder rspec = internal_word_Relocation::spec(table_base); | |
2258 | |
727 | 2259 // Move table address into a register. |
2260 __ set(table_base, table_reg, rspec); | |
0 | 2261 |
2262 // Jump to base address + switch value | |
2263 __ ld_ptr(table_reg, switch_reg, table_reg); | |
2264 __ jmp(table_reg, G0); | |
2265 __ delayed()->nop(); | |
2266 | |
2267 %} | |
2268 | |
2269 enc_class enc_ba( Label labl ) %{ | |
2270 MacroAssembler _masm(&cbuf); | |
2271 Label &L = *($labl$$label); | |
2272 __ ba(false, L); | |
2273 __ delayed()->nop(); | |
2274 %} | |
2275 | |
2276 enc_class enc_bpr( Label labl, cmpOp_reg cmp, iRegI op1 ) %{ | |
2277 MacroAssembler _masm(&cbuf); | |
2278 Label &L = *$labl$$label; | |
2279 Assembler::Predict predict_taken = | |
2280 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2281 | |
2282 __ bpr( (Assembler::RCondition)($cmp$$cmpcode), false, predict_taken, as_Register($op1$$reg), L); | |
2283 __ delayed()->nop(); | |
2284 %} | |
2285 | |
2286 enc_class enc_cmov_reg( cmpOp cmp, iRegI dst, iRegI src, immI pcc) %{ | |
2287 int op = (Assembler::arith_op << 30) | | |
2288 ($dst$$reg << 25) | | |
2289 (Assembler::movcc_op3 << 19) | | |
2290 (1 << 18) | // cc2 bit for 'icc' | |
2291 ($cmp$$cmpcode << 14) | | |
2292 (0 << 13) | // select register move | |
2293 ($pcc$$constant << 11) | // cc1, cc0 bits for 'icc' or 'xcc' | |
2294 ($src$$reg << 0); | |
2295 *((int*)(cbuf.code_end())) = op; | |
2296 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
2297 %} | |
2298 | |
2299 enc_class enc_cmov_imm( cmpOp cmp, iRegI dst, immI11 src, immI pcc ) %{ | |
2300 int simm11 = $src$$constant & ((1<<11)-1); // Mask to 11 bits | |
2301 int op = (Assembler::arith_op << 30) | | |
2302 ($dst$$reg << 25) | | |
2303 (Assembler::movcc_op3 << 19) | | |
2304 (1 << 18) | // cc2 bit for 'icc' | |
2305 ($cmp$$cmpcode << 14) | | |
2306 (1 << 13) | // select immediate move | |
2307 ($pcc$$constant << 11) | // cc1, cc0 bits for 'icc' | |
2308 (simm11 << 0); | |
2309 *((int*)(cbuf.code_end())) = op; | |
2310 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
2311 %} | |
2312 | |
2313 enc_class enc_cmov_reg_f( cmpOpF cmp, iRegI dst, iRegI src, flagsRegF fcc ) %{ | |
2314 int op = (Assembler::arith_op << 30) | | |
2315 ($dst$$reg << 25) | | |
2316 (Assembler::movcc_op3 << 19) | | |
2317 (0 << 18) | // cc2 bit for 'fccX' | |
2318 ($cmp$$cmpcode << 14) | | |
2319 (0 << 13) | // select register move | |
2320 ($fcc$$reg << 11) | // cc1, cc0 bits for fcc0-fcc3 | |
2321 ($src$$reg << 0); | |
2322 *((int*)(cbuf.code_end())) = op; | |
2323 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
2324 %} | |
2325 | |
2326 enc_class enc_cmov_imm_f( cmpOp cmp, iRegI dst, immI11 src, flagsRegF fcc ) %{ | |
2327 int simm11 = $src$$constant & ((1<<11)-1); // Mask to 11 bits | |
2328 int op = (Assembler::arith_op << 30) | | |
2329 ($dst$$reg << 25) | | |
2330 (Assembler::movcc_op3 << 19) | | |
2331 (0 << 18) | // cc2 bit for 'fccX' | |
2332 ($cmp$$cmpcode << 14) | | |
2333 (1 << 13) | // select immediate move | |
2334 ($fcc$$reg << 11) | // cc1, cc0 bits for fcc0-fcc3 | |
2335 (simm11 << 0); | |
2336 *((int*)(cbuf.code_end())) = op; | |
2337 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
2338 %} | |
2339 | |
2340 enc_class enc_cmovf_reg( cmpOp cmp, regD dst, regD src, immI pcc ) %{ | |
2341 int op = (Assembler::arith_op << 30) | | |
2342 ($dst$$reg << 25) | | |
2343 (Assembler::fpop2_op3 << 19) | | |
2344 (0 << 18) | | |
2345 ($cmp$$cmpcode << 14) | | |
2346 (1 << 13) | // select register move | |
2347 ($pcc$$constant << 11) | // cc1-cc0 bits for 'icc' or 'xcc' | |
2348 ($primary << 5) | // select single, double or quad | |
2349 ($src$$reg << 0); | |
2350 *((int*)(cbuf.code_end())) = op; | |
2351 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
2352 %} | |
2353 | |
2354 enc_class enc_cmovff_reg( cmpOpF cmp, flagsRegF fcc, regD dst, regD src ) %{ | |
2355 int op = (Assembler::arith_op << 30) | | |
2356 ($dst$$reg << 25) | | |
2357 (Assembler::fpop2_op3 << 19) | | |
2358 (0 << 18) | | |
2359 ($cmp$$cmpcode << 14) | | |
2360 ($fcc$$reg << 11) | // cc2-cc0 bits for 'fccX' | |
2361 ($primary << 5) | // select single, double or quad | |
2362 ($src$$reg << 0); | |
2363 *((int*)(cbuf.code_end())) = op; | |
2364 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
2365 %} | |
2366 | |
2367 // Used by the MIN/MAX encodings. Same as a CMOV, but | |
2368 // the condition comes from opcode-field instead of an argument. | |
2369 enc_class enc_cmov_reg_minmax( iRegI dst, iRegI src ) %{ | |
2370 int op = (Assembler::arith_op << 30) | | |
2371 ($dst$$reg << 25) | | |
2372 (Assembler::movcc_op3 << 19) | | |
2373 (1 << 18) | // cc2 bit for 'icc' | |
2374 ($primary << 14) | | |
2375 (0 << 13) | // select register move | |
2376 (0 << 11) | // cc1, cc0 bits for 'icc' | |
2377 ($src$$reg << 0); | |
2378 *((int*)(cbuf.code_end())) = op; | |
2379 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
2380 %} | |
2381 | |
2382 enc_class enc_cmov_reg_minmax_long( iRegL dst, iRegL src ) %{ | |
2383 int op = (Assembler::arith_op << 30) | | |
2384 ($dst$$reg << 25) | | |
2385 (Assembler::movcc_op3 << 19) | | |
2386 (6 << 16) | // cc2 bit for 'xcc' | |
2387 ($primary << 14) | | |
2388 (0 << 13) | // select register move | |
2389 (0 << 11) | // cc1, cc0 bits for 'icc' | |
2390 ($src$$reg << 0); | |
2391 *((int*)(cbuf.code_end())) = op; | |
2392 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
2393 %} | |
2394 | |
2395 // Utility encoding for loading a 64 bit Pointer into a register | |
2396 // The 64 bit pointer is stored in the generated code stream | |
2397 enc_class SetPtr( immP src, iRegP rd ) %{ | |
2398 Register dest = reg_to_register_object($rd$$reg); | |
727 | 2399 MacroAssembler _masm(&cbuf); |
0 | 2400 // [RGV] This next line should be generated from ADLC |
2401 if ( _opnds[1]->constant_is_oop() ) { | |
2402 intptr_t val = $src$$constant; | |
2403 __ set_oop_constant((jobject)val, dest); | |
2404 } else { // non-oop pointers, e.g. card mark base, heap top | |
727 | 2405 __ set($src$$constant, dest); |
0 | 2406 } |
2407 %} | |
2408 | |
2409 enc_class Set13( immI13 src, iRegI rd ) %{ | |
2410 emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, $src$$constant ); | |
2411 %} | |
2412 | |
2413 enc_class SetHi22( immI src, iRegI rd ) %{ | |
2414 emit2_22( cbuf, Assembler::branch_op, $rd$$reg, Assembler::sethi_op2, $src$$constant ); | |
2415 %} | |
2416 | |
2417 enc_class Set32( immI src, iRegI rd ) %{ | |
2418 MacroAssembler _masm(&cbuf); | |
2419 __ set($src$$constant, reg_to_register_object($rd$$reg)); | |
2420 %} | |
2421 | |
2422 enc_class SetNull( iRegI rd ) %{ | |
2423 emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0 ); | |
2424 %} | |
2425 | |
2426 enc_class call_epilog %{ | |
2427 if( VerifyStackAtCalls ) { | |
2428 MacroAssembler _masm(&cbuf); | |
2429 int framesize = ra_->C->frame_slots() << LogBytesPerInt; | |
2430 Register temp_reg = G3; | |
2431 __ add(SP, framesize, temp_reg); | |
2432 __ cmp(temp_reg, FP); | |
2433 __ breakpoint_trap(Assembler::notEqual, Assembler::ptr_cc); | |
2434 } | |
2435 %} | |
2436 | |
2437 // Long values come back from native calls in O0:O1 in the 32-bit VM, copy the value | |
2438 // to G1 so the register allocator will not have to deal with the misaligned register | |
2439 // pair. | |
2440 enc_class adjust_long_from_native_call %{ | |
2441 #ifndef _LP64 | |
2442 if (returns_long()) { | |
2443 // sllx O0,32,O0 | |
2444 emit3_simm13( cbuf, Assembler::arith_op, R_O0_enc, Assembler::sllx_op3, R_O0_enc, 0x1020 ); | |
2445 // srl O1,0,O1 | |
2446 emit3_simm13( cbuf, Assembler::arith_op, R_O1_enc, Assembler::srl_op3, R_O1_enc, 0x0000 ); | |
2447 // or O0,O1,G1 | |
2448 emit3 ( cbuf, Assembler::arith_op, R_G1_enc, Assembler:: or_op3, R_O0_enc, 0, R_O1_enc ); | |
2449 } | |
2450 #endif | |
2451 %} | |
2452 | |
2453 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime | |
2454 // CALL directly to the runtime | |
2455 // The user of this is responsible for ensuring that R_L7 is empty (killed). | |
2456 emit_call_reloc(cbuf, $meth$$method, relocInfo::runtime_call_type, | |
2457 /*preserve_g2=*/true, /*force far call*/true); | |
2458 %} | |
2459 | |
1567 | 2460 enc_class preserve_SP %{ |
2461 MacroAssembler _masm(&cbuf); | |
2462 __ mov(SP, L7_mh_SP_save); | |
2463 %} | |
2464 | |
2465 enc_class restore_SP %{ | |
2466 MacroAssembler _masm(&cbuf); | |
2467 __ mov(L7_mh_SP_save, SP); | |
2468 %} | |
2469 | |
0 | 2470 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL |
2471 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine | |
2472 // who we intended to call. | |
2473 if ( !_method ) { | |
2474 emit_call_reloc(cbuf, $meth$$method, relocInfo::runtime_call_type); | |
2475 } else if (_optimized_virtual) { | |
2476 emit_call_reloc(cbuf, $meth$$method, relocInfo::opt_virtual_call_type); | |
2477 } else { | |
2478 emit_call_reloc(cbuf, $meth$$method, relocInfo::static_call_type); | |
2479 } | |
2480 if( _method ) { // Emit stub for static call | |
2481 emit_java_to_interp(cbuf); | |
2482 } | |
2483 %} | |
2484 | |
2485 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL | |
2486 MacroAssembler _masm(&cbuf); | |
2487 __ set_inst_mark(); | |
2488 int vtable_index = this->_vtable_index; | |
2489 // MachCallDynamicJavaNode::ret_addr_offset uses this same test | |
2490 if (vtable_index < 0) { | |
2491 // must be invalid_vtable_index, not nonvirtual_vtable_index | |
2492 assert(vtable_index == methodOopDesc::invalid_vtable_index, "correct sentinel value"); | |
2493 Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); | |
2494 assert(G5_ic_reg == G5_inline_cache_reg, "G5_inline_cache_reg used in assemble_ic_buffer_code()"); | |
2495 assert(G5_ic_reg == G5_megamorphic_method, "G5_megamorphic_method used in megamorphic call stub"); | |
2496 // !!!!! | |
2497 // Generate "set 0x01, R_G5", placeholder instruction to load oop-info | |
2498 // emit_call_dynamic_prologue( cbuf ); | |
2499 __ set_oop((jobject)Universe::non_oop_word(), G5_ic_reg); | |
2500 | |
2501 address virtual_call_oop_addr = __ inst_mark(); | |
2502 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine | |
2503 // who we intended to call. | |
2504 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr)); | |
2505 emit_call_reloc(cbuf, $meth$$method, relocInfo::none); | |
2506 } else { | |
2507 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); | |
2508 // Just go thru the vtable | |
2509 // get receiver klass (receiver already checked for non-null) | |
2510 // If we end up going thru a c2i adapter interpreter expects method in G5 | |
2511 int off = __ offset(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
2512 __ load_klass(O0, G3_scratch); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
2513 int klass_load_size; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
2514 if (UseCompressedOops) { |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
2515 assert(Universe::heap() != NULL, "java heap should be initialized"); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
2516 if (Universe::narrow_oop_base() == NULL) |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
2517 klass_load_size = 2*BytesPerInstWord; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
2518 else |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
2519 klass_load_size = 3*BytesPerInstWord; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
2520 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
2521 klass_load_size = 1*BytesPerInstWord; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
2522 } |
0 | 2523 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); |
2524 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); | |
2525 if( __ is_simm13(v_off) ) { | |
2526 __ ld_ptr(G3, v_off, G5_method); | |
2527 } else { | |
2528 // Generate 2 instructions | |
2529 __ Assembler::sethi(v_off & ~0x3ff, G5_method); | |
2530 __ or3(G5_method, v_off & 0x3ff, G5_method); | |
2531 // ld_ptr, set_hi, set | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
2532 assert(__ offset() - off == klass_load_size + 2*BytesPerInstWord, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
2533 "Unexpected instruction size(s)"); |
0 | 2534 __ ld_ptr(G3, G5_method, G5_method); |
2535 } | |
2536 // NOTE: for vtable dispatches, the vtable entry will never be null. | |
2537 // However it may very well end up in handle_wrong_method if the | |
2538 // method is abstract for the particular class. | |
2539 __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3_scratch); | |
2540 // jump to target (either compiled code or c2iadapter) | |
2541 __ jmpl(G3_scratch, G0, O7); | |
2542 __ delayed()->nop(); | |
2543 } | |
2544 %} | |
2545 | |
2546 enc_class Java_Compiled_Call (method meth) %{ // JAVA COMPILED CALL | |
2547 MacroAssembler _masm(&cbuf); | |
2548 | |
2549 Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); | |
2550 Register temp_reg = G3; // caller must kill G3! We cannot reuse G5_ic_reg here because | |
2551 // we might be calling a C2I adapter which needs it. | |
2552 | |
2553 assert(temp_reg != G5_ic_reg, "conflicting registers"); | |
2554 // Load nmethod | |
2555 __ ld_ptr(G5_ic_reg, in_bytes(methodOopDesc::from_compiled_offset()), temp_reg); | |
2556 | |
2557 // CALL to compiled java, indirect the contents of G3 | |
2558 __ set_inst_mark(); | |
2559 __ callr(temp_reg, G0); | |
2560 __ delayed()->nop(); | |
2561 %} | |
2562 | |
2563 enc_class idiv_reg(iRegIsafe src1, iRegIsafe src2, iRegIsafe dst) %{ | |
2564 MacroAssembler _masm(&cbuf); | |
2565 Register Rdividend = reg_to_register_object($src1$$reg); | |
2566 Register Rdivisor = reg_to_register_object($src2$$reg); | |
2567 Register Rresult = reg_to_register_object($dst$$reg); | |
2568 | |
2569 __ sra(Rdivisor, 0, Rdivisor); | |
2570 __ sra(Rdividend, 0, Rdividend); | |
2571 __ sdivx(Rdividend, Rdivisor, Rresult); | |
2572 %} | |
2573 | |
2574 enc_class idiv_imm(iRegIsafe src1, immI13 imm, iRegIsafe dst) %{ | |
2575 MacroAssembler _masm(&cbuf); | |
2576 | |
2577 Register Rdividend = reg_to_register_object($src1$$reg); | |
2578 int divisor = $imm$$constant; | |
2579 Register Rresult = reg_to_register_object($dst$$reg); | |
2580 | |
2581 __ sra(Rdividend, 0, Rdividend); | |
2582 __ sdivx(Rdividend, divisor, Rresult); | |
2583 %} | |
2584 | |
2585 enc_class enc_mul_hi(iRegIsafe dst, iRegIsafe src1, iRegIsafe src2) %{ | |
2586 MacroAssembler _masm(&cbuf); | |
2587 Register Rsrc1 = reg_to_register_object($src1$$reg); | |
2588 Register Rsrc2 = reg_to_register_object($src2$$reg); | |
2589 Register Rdst = reg_to_register_object($dst$$reg); | |
2590 | |
2591 __ sra( Rsrc1, 0, Rsrc1 ); | |
2592 __ sra( Rsrc2, 0, Rsrc2 ); | |
2593 __ mulx( Rsrc1, Rsrc2, Rdst ); | |
2594 __ srlx( Rdst, 32, Rdst ); | |
2595 %} | |
2596 | |
2597 enc_class irem_reg(iRegIsafe src1, iRegIsafe src2, iRegIsafe dst, o7RegL scratch) %{ | |
2598 MacroAssembler _masm(&cbuf); | |
2599 Register Rdividend = reg_to_register_object($src1$$reg); | |
2600 Register Rdivisor = reg_to_register_object($src2$$reg); | |
2601 Register Rresult = reg_to_register_object($dst$$reg); | |
2602 Register Rscratch = reg_to_register_object($scratch$$reg); | |
2603 | |
2604 assert(Rdividend != Rscratch, ""); | |
2605 assert(Rdivisor != Rscratch, ""); | |
2606 | |
2607 __ sra(Rdividend, 0, Rdividend); | |
2608 __ sra(Rdivisor, 0, Rdivisor); | |
2609 __ sdivx(Rdividend, Rdivisor, Rscratch); | |
2610 __ mulx(Rscratch, Rdivisor, Rscratch); | |
2611 __ sub(Rdividend, Rscratch, Rresult); | |
2612 %} | |
2613 | |
2614 enc_class irem_imm(iRegIsafe src1, immI13 imm, iRegIsafe dst, o7RegL scratch) %{ | |
2615 MacroAssembler _masm(&cbuf); | |
2616 | |
2617 Register Rdividend = reg_to_register_object($src1$$reg); | |
2618 int divisor = $imm$$constant; | |
2619 Register Rresult = reg_to_register_object($dst$$reg); | |
2620 Register Rscratch = reg_to_register_object($scratch$$reg); | |
2621 | |
2622 assert(Rdividend != Rscratch, ""); | |
2623 | |
2624 __ sra(Rdividend, 0, Rdividend); | |
2625 __ sdivx(Rdividend, divisor, Rscratch); | |
2626 __ mulx(Rscratch, divisor, Rscratch); | |
2627 __ sub(Rdividend, Rscratch, Rresult); | |
2628 %} | |
2629 | |
2630 enc_class fabss (sflt_reg dst, sflt_reg src) %{ | |
2631 MacroAssembler _masm(&cbuf); | |
2632 | |
2633 FloatRegister Fdst = reg_to_SingleFloatRegister_object($dst$$reg); | |
2634 FloatRegister Fsrc = reg_to_SingleFloatRegister_object($src$$reg); | |
2635 | |
2636 __ fabs(FloatRegisterImpl::S, Fsrc, Fdst); | |
2637 %} | |
2638 | |
2639 enc_class fabsd (dflt_reg dst, dflt_reg src) %{ | |
2640 MacroAssembler _masm(&cbuf); | |
2641 | |
2642 FloatRegister Fdst = reg_to_DoubleFloatRegister_object($dst$$reg); | |
2643 FloatRegister Fsrc = reg_to_DoubleFloatRegister_object($src$$reg); | |
2644 | |
2645 __ fabs(FloatRegisterImpl::D, Fsrc, Fdst); | |
2646 %} | |
2647 | |
2648 enc_class fnegd (dflt_reg dst, dflt_reg src) %{ | |
2649 MacroAssembler _masm(&cbuf); | |
2650 | |
2651 FloatRegister Fdst = reg_to_DoubleFloatRegister_object($dst$$reg); | |
2652 FloatRegister Fsrc = reg_to_DoubleFloatRegister_object($src$$reg); | |
2653 | |
2654 __ fneg(FloatRegisterImpl::D, Fsrc, Fdst); | |
2655 %} | |
2656 | |
2657 enc_class fsqrts (sflt_reg dst, sflt_reg src) %{ | |
2658 MacroAssembler _masm(&cbuf); | |
2659 | |
2660 FloatRegister Fdst = reg_to_SingleFloatRegister_object($dst$$reg); | |
2661 FloatRegister Fsrc = reg_to_SingleFloatRegister_object($src$$reg); | |
2662 | |
2663 __ fsqrt(FloatRegisterImpl::S, Fsrc, Fdst); | |
2664 %} | |
2665 | |
2666 enc_class fsqrtd (dflt_reg dst, dflt_reg src) %{ | |
2667 MacroAssembler _masm(&cbuf); | |
2668 | |
2669 FloatRegister Fdst = reg_to_DoubleFloatRegister_object($dst$$reg); | |
2670 FloatRegister Fsrc = reg_to_DoubleFloatRegister_object($src$$reg); | |
2671 | |
2672 __ fsqrt(FloatRegisterImpl::D, Fsrc, Fdst); | |
2673 %} | |
2674 | |
2675 enc_class fmovs (dflt_reg dst, dflt_reg src) %{ | |
2676 MacroAssembler _masm(&cbuf); | |
2677 | |
2678 FloatRegister Fdst = reg_to_SingleFloatRegister_object($dst$$reg); | |
2679 FloatRegister Fsrc = reg_to_SingleFloatRegister_object($src$$reg); | |
2680 | |
2681 __ fmov(FloatRegisterImpl::S, Fsrc, Fdst); | |
2682 %} | |
2683 | |
2684 enc_class fmovd (dflt_reg dst, dflt_reg src) %{ | |
2685 MacroAssembler _masm(&cbuf); | |
2686 | |
2687 FloatRegister Fdst = reg_to_DoubleFloatRegister_object($dst$$reg); | |
2688 FloatRegister Fsrc = reg_to_DoubleFloatRegister_object($src$$reg); | |
2689 | |
2690 __ fmov(FloatRegisterImpl::D, Fsrc, Fdst); | |
2691 %} | |
2692 | |
2693 enc_class Fast_Lock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{ | |
2694 MacroAssembler _masm(&cbuf); | |
2695 | |
2696 Register Roop = reg_to_register_object($oop$$reg); | |
2697 Register Rbox = reg_to_register_object($box$$reg); | |
2698 Register Rscratch = reg_to_register_object($scratch$$reg); | |
2699 Register Rmark = reg_to_register_object($scratch2$$reg); | |
2700 | |
2701 assert(Roop != Rscratch, ""); | |
2702 assert(Roop != Rmark, ""); | |
2703 assert(Rbox != Rscratch, ""); | |
2704 assert(Rbox != Rmark, ""); | |
2705 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
2706 __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters, UseBiasedLocking && !UseOptoBiasInlining); |
0 | 2707 %} |
2708 | |
2709 enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{ | |
2710 MacroAssembler _masm(&cbuf); | |
2711 | |
2712 Register Roop = reg_to_register_object($oop$$reg); | |
2713 Register Rbox = reg_to_register_object($box$$reg); | |
2714 Register Rscratch = reg_to_register_object($scratch$$reg); | |
2715 Register Rmark = reg_to_register_object($scratch2$$reg); | |
2716 | |
2717 assert(Roop != Rscratch, ""); | |
2718 assert(Roop != Rmark, ""); | |
2719 assert(Rbox != Rscratch, ""); | |
2720 assert(Rbox != Rmark, ""); | |
2721 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
2722 __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch, UseBiasedLocking && !UseOptoBiasInlining); |
0 | 2723 %} |
2724 | |
2725 enc_class enc_cas( iRegP mem, iRegP old, iRegP new ) %{ | |
2726 MacroAssembler _masm(&cbuf); | |
2727 Register Rmem = reg_to_register_object($mem$$reg); | |
2728 Register Rold = reg_to_register_object($old$$reg); | |
2729 Register Rnew = reg_to_register_object($new$$reg); | |
2730 | |
2731 // casx_under_lock picks 1 of 3 encodings: | |
2732 // For 32-bit pointers you get a 32-bit CAS | |
2733 // For 64-bit pointers you get a 64-bit CASX | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
2734 __ casn(Rmem, Rold, Rnew); // Swap(*Rmem,Rnew) if *Rmem == Rold |
0 | 2735 __ cmp( Rold, Rnew ); |
2736 %} | |
2737 | |
2738 enc_class enc_casx( iRegP mem, iRegL old, iRegL new) %{ | |
2739 Register Rmem = reg_to_register_object($mem$$reg); | |
2740 Register Rold = reg_to_register_object($old$$reg); | |
2741 Register Rnew = reg_to_register_object($new$$reg); | |
2742 | |
2743 MacroAssembler _masm(&cbuf); | |
2744 __ mov(Rnew, O7); | |
2745 __ casx(Rmem, Rold, O7); | |
2746 __ cmp( Rold, O7 ); | |
2747 %} | |
2748 | |
2749 // raw int cas, used for compareAndSwap | |
2750 enc_class enc_casi( iRegP mem, iRegL old, iRegL new) %{ | |
2751 Register Rmem = reg_to_register_object($mem$$reg); | |
2752 Register Rold = reg_to_register_object($old$$reg); | |
2753 Register Rnew = reg_to_register_object($new$$reg); | |
2754 | |
2755 MacroAssembler _masm(&cbuf); | |
2756 __ mov(Rnew, O7); | |
2757 __ cas(Rmem, Rold, O7); | |
2758 __ cmp( Rold, O7 ); | |
2759 %} | |
2760 | |
2761 enc_class enc_lflags_ne_to_boolean( iRegI res ) %{ | |
2762 Register Rres = reg_to_register_object($res$$reg); | |
2763 | |
2764 MacroAssembler _masm(&cbuf); | |
2765 __ mov(1, Rres); | |
2766 __ movcc( Assembler::notEqual, false, Assembler::xcc, G0, Rres ); | |
2767 %} | |
2768 | |
2769 enc_class enc_iflags_ne_to_boolean( iRegI res ) %{ | |
2770 Register Rres = reg_to_register_object($res$$reg); | |
2771 | |
2772 MacroAssembler _masm(&cbuf); | |
2773 __ mov(1, Rres); | |
2774 __ movcc( Assembler::notEqual, false, Assembler::icc, G0, Rres ); | |
2775 %} | |
2776 | |
2777 enc_class floating_cmp ( iRegP dst, regF src1, regF src2 ) %{ | |
2778 MacroAssembler _masm(&cbuf); | |
2779 Register Rdst = reg_to_register_object($dst$$reg); | |
2780 FloatRegister Fsrc1 = $primary ? reg_to_SingleFloatRegister_object($src1$$reg) | |
2781 : reg_to_DoubleFloatRegister_object($src1$$reg); | |
2782 FloatRegister Fsrc2 = $primary ? reg_to_SingleFloatRegister_object($src2$$reg) | |
2783 : reg_to_DoubleFloatRegister_object($src2$$reg); | |
2784 | |
2785 // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1) | |
2786 __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst); | |
2787 %} | |
2788 | |
2789 enc_class LdImmL (immL src, iRegL dst, o7RegL tmp) %{ // Load Immediate | |
2790 MacroAssembler _masm(&cbuf); | |
2791 Register dest = reg_to_register_object($dst$$reg); | |
2792 Register temp = reg_to_register_object($tmp$$reg); | |
2793 __ set64( $src$$constant, dest, temp ); | |
2794 %} | |
2795 | |
2796 enc_class LdReplImmI(immI src, regD dst, o7RegP tmp, int count, int width) %{ | |
2797 // Load a constant replicated "count" times with width "width" | |
2798 int bit_width = $width$$constant * 8; | |
2799 jlong elt_val = $src$$constant; | |
2800 elt_val &= (((jlong)1) << bit_width) - 1; // mask off sign bits | |
2801 jlong val = elt_val; | |
2802 for (int i = 0; i < $count$$constant - 1; i++) { | |
2803 val <<= bit_width; | |
2804 val |= elt_val; | |
2805 } | |
2806 jdouble dval = *(jdouble*)&val; // coerce to double type | |
727 | 2807 MacroAssembler _masm(&cbuf); |
2808 address double_address = __ double_constant(dval); | |
0 | 2809 RelocationHolder rspec = internal_word_Relocation::spec(double_address); |
727 | 2810 AddressLiteral addrlit(double_address, rspec); |
2811 | |
2812 __ sethi(addrlit, $tmp$$Register); | |
732
fb4c18a2ec66
6833573: C2 sparc: assert(c < 64 && (c & 1) == 0,"bad double float register")
never
parents:
727
diff
changeset
|
2813 // XXX This is a quick fix for 6833573. |
fb4c18a2ec66
6833573: C2 sparc: assert(c < 64 && (c & 1) == 0,"bad double float register")
never
parents:
727
diff
changeset
|
2814 //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); |
fb4c18a2ec66
6833573: C2 sparc: assert(c < 64 && (c & 1) == 0,"bad double float register")
never
parents:
727
diff
changeset
|
2815 __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec); |
0 | 2816 %} |
2817 | |
2818 // Compiler ensures base is doubleword aligned and cnt is count of doublewords | |
2819 enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{ | |
2820 MacroAssembler _masm(&cbuf); | |
2821 Register nof_bytes_arg = reg_to_register_object($cnt$$reg); | |
2822 Register nof_bytes_tmp = reg_to_register_object($temp$$reg); | |
2823 Register base_pointer_arg = reg_to_register_object($base$$reg); | |
2824 | |
2825 Label loop; | |
2826 __ mov(nof_bytes_arg, nof_bytes_tmp); | |
2827 | |
2828 // Loop and clear, walking backwards through the array. | |
2829 // nof_bytes_tmp (if >0) is always the number of bytes to zero | |
2830 __ bind(loop); | |
2831 __ deccc(nof_bytes_tmp, 8); | |
2832 __ br(Assembler::greaterEqual, true, Assembler::pt, loop); | |
2833 __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp); | |
2834 // %%%% this mini-loop must not cross a cache boundary! | |
2835 %} | |
2836 | |
2837 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2838 enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{ |
0 | 2839 Label Ldone, Lloop; |
2840 MacroAssembler _masm(&cbuf); | |
2841 | |
2842 Register str1_reg = reg_to_register_object($str1$$reg); | |
2843 Register str2_reg = reg_to_register_object($str2$$reg); | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2844 Register cnt1_reg = reg_to_register_object($cnt1$$reg); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2845 Register cnt2_reg = reg_to_register_object($cnt2$$reg); |
0 | 2846 Register result_reg = reg_to_register_object($result$$reg); |
2847 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2848 assert(result_reg != str1_reg && |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2849 result_reg != str2_reg && |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2850 result_reg != cnt1_reg && |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2851 result_reg != cnt2_reg , |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2852 "need different registers"); |
0 | 2853 |
2854 // Compute the minimum of the string lengths(str1_reg) and the | |
2855 // difference of the string lengths (stack) | |
2856 | |
2857 // See if the lengths are different, and calculate min in str1_reg. | |
2858 // Stash diff in O7 in case we need it for a tie-breaker. | |
2859 Label Lskip; | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2860 __ subcc(cnt1_reg, cnt2_reg, O7); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2861 __ sll(cnt1_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit |
0 | 2862 __ br(Assembler::greater, true, Assembler::pt, Lskip); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2863 // cnt2 is shorter, so use its count: |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2864 __ delayed()->sll(cnt2_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit |
0 | 2865 __ bind(Lskip); |
2866 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2867 // reallocate cnt1_reg, cnt2_reg, result_reg |
0 | 2868 // Note: limit_reg holds the string length pre-scaled by 2 |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2869 Register limit_reg = cnt1_reg; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2870 Register chr2_reg = cnt2_reg; |
0 | 2871 Register chr1_reg = result_reg; |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2872 // str{12} are the base pointers |
0 | 2873 |
2874 // Is the minimum length zero? | |
2875 __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity | |
2876 __ br(Assembler::equal, true, Assembler::pn, Ldone); | |
2877 __ delayed()->mov(O7, result_reg); // result is difference in lengths | |
2878 | |
2879 // Load first characters | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2880 __ lduh(str1_reg, 0, chr1_reg); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2881 __ lduh(str2_reg, 0, chr2_reg); |
0 | 2882 |
2883 // Compare first characters | |
2884 __ subcc(chr1_reg, chr2_reg, chr1_reg); | |
2885 __ br(Assembler::notZero, false, Assembler::pt, Ldone); | |
2886 assert(chr1_reg == result_reg, "result must be pre-placed"); | |
2887 __ delayed()->nop(); | |
2888 | |
2889 { | |
2890 // Check after comparing first character to see if strings are equivalent | |
2891 Label LSkip2; | |
2892 // Check if the strings start at same location | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2893 __ cmp(str1_reg, str2_reg); |
0 | 2894 __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2); |
2895 __ delayed()->nop(); | |
2896 | |
2897 // Check if the length difference is zero (in O7) | |
2898 __ cmp(G0, O7); | |
2899 __ br(Assembler::equal, true, Assembler::pn, Ldone); | |
2900 __ delayed()->mov(G0, result_reg); // result is zero | |
2901 | |
2902 // Strings might not be equal | |
2903 __ bind(LSkip2); | |
2904 } | |
2905 | |
2906 __ subcc(limit_reg, 1 * sizeof(jchar), chr1_reg); | |
2907 __ br(Assembler::equal, true, Assembler::pn, Ldone); | |
2908 __ delayed()->mov(O7, result_reg); // result is difference in lengths | |
2909 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2910 // Shift str1_reg and str2_reg to the end of the arrays, negate limit |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2911 __ add(str1_reg, limit_reg, str1_reg); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2912 __ add(str2_reg, limit_reg, str2_reg); |
0 | 2913 __ neg(chr1_reg, limit_reg); // limit = -(limit-2) |
2914 | |
2915 // Compare the rest of the characters | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2916 __ lduh(str1_reg, limit_reg, chr1_reg); |
0 | 2917 __ bind(Lloop); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2918 // __ lduh(str1_reg, limit_reg, chr1_reg); // hoisted |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2919 __ lduh(str2_reg, limit_reg, chr2_reg); |
0 | 2920 __ subcc(chr1_reg, chr2_reg, chr1_reg); |
2921 __ br(Assembler::notZero, false, Assembler::pt, Ldone); | |
2922 assert(chr1_reg == result_reg, "result must be pre-placed"); | |
2923 __ delayed()->inccc(limit_reg, sizeof(jchar)); | |
2924 // annul LDUH if branch is not taken to prevent access past end of string | |
2925 __ br(Assembler::notZero, true, Assembler::pt, Lloop); | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2926 __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted |
0 | 2927 |
2928 // If strings are equal up to min length, return the length difference. | |
2929 __ mov(O7, result_reg); | |
2930 | |
2931 // Otherwise, return the difference between the first mismatched chars. | |
2932 __ bind(Ldone); | |
2933 %} | |
2934 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2935 enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2936 Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone; |
681 | 2937 MacroAssembler _masm(&cbuf); |
2938 | |
2939 Register str1_reg = reg_to_register_object($str1$$reg); | |
2940 Register str2_reg = reg_to_register_object($str2$$reg); | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2941 Register cnt_reg = reg_to_register_object($cnt$$reg); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2942 Register tmp1_reg = O7; |
681 | 2943 Register result_reg = reg_to_register_object($result$$reg); |
2944 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2945 assert(result_reg != str1_reg && |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2946 result_reg != str2_reg && |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2947 result_reg != cnt_reg && |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2948 result_reg != tmp1_reg , |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2949 "need different registers"); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2950 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2951 __ cmp(str1_reg, str2_reg); //same char[] ? |
681 | 2952 __ brx(Assembler::equal, true, Assembler::pn, Ldone); |
2953 __ delayed()->add(G0, 1, result_reg); | |
2954 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2955 __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2956 __ delayed()->add(G0, 1, result_reg); // count == 0 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2957 |
681 | 2958 //rename registers |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2959 Register limit_reg = cnt_reg; |
681 | 2960 Register chr1_reg = result_reg; |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2961 Register chr2_reg = tmp1_reg; |
681 | 2962 |
2963 //check for alignment and position the pointers to the ends | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2964 __ or3(str1_reg, str2_reg, chr1_reg); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2965 __ andcc(chr1_reg, 0x3, chr1_reg); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2966 // notZero means at least one not 4-byte aligned. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2967 // We could optimize the case when both arrays are not aligned |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2968 // but it is not frequent case and it requires additional checks. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2969 __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2970 __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2971 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2972 // Compare char[] arrays aligned to 4 bytes. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2973 __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2974 chr1_reg, chr2_reg, Ldone); |
681 | 2975 __ ba(false,Ldone); |
2976 __ delayed()->add(G0, 1, result_reg); | |
2977 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2978 // char by char compare |
681 | 2979 __ bind(Lchar); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2980 __ add(str1_reg, limit_reg, str1_reg); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2981 __ add(str2_reg, limit_reg, str2_reg); |
681 | 2982 __ neg(limit_reg); //negate count |
2983 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2984 __ lduh(str1_reg, limit_reg, chr1_reg); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2985 // Lchar_loop |
681 | 2986 __ bind(Lchar_loop); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2987 __ lduh(str2_reg, limit_reg, chr2_reg); |
681 | 2988 __ cmp(chr1_reg, chr2_reg); |
2989 __ br(Assembler::notEqual, true, Assembler::pt, Ldone); | |
2990 __ delayed()->mov(G0, result_reg); //not equal | |
2991 __ inccc(limit_reg, sizeof(jchar)); | |
2992 // annul LDUH if branch is not taken to prevent access past end of string | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2993 __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
2994 __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted |
681 | 2995 |
2996 __ add(G0, 1, result_reg); //equal | |
2997 | |
2998 __ bind(Ldone); | |
2999 %} | |
3000 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
3001 enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI result) %{ |
681 | 3002 Label Lvector, Ldone, Lloop; |
3003 MacroAssembler _masm(&cbuf); | |
3004 | |
3005 Register ary1_reg = reg_to_register_object($ary1$$reg); | |
3006 Register ary2_reg = reg_to_register_object($ary2$$reg); | |
3007 Register tmp1_reg = reg_to_register_object($tmp1$$reg); | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
3008 Register tmp2_reg = O7; |
681 | 3009 Register result_reg = reg_to_register_object($result$$reg); |
3010 | |
3011 int length_offset = arrayOopDesc::length_offset_in_bytes(); | |
3012 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); | |
3013 | |
3014 // return true if the same array | |
3015 __ cmp(ary1_reg, ary2_reg); | |
1016 | 3016 __ brx(Assembler::equal, true, Assembler::pn, Ldone); |
681 | 3017 __ delayed()->add(G0, 1, result_reg); // equal |
3018 | |
3019 __ br_null(ary1_reg, true, Assembler::pn, Ldone); | |
3020 __ delayed()->mov(G0, result_reg); // not equal | |
3021 | |
3022 __ br_null(ary2_reg, true, Assembler::pn, Ldone); | |
3023 __ delayed()->mov(G0, result_reg); // not equal | |
3024 | |
3025 //load the lengths of arrays | |
727 | 3026 __ ld(Address(ary1_reg, length_offset), tmp1_reg); |
3027 __ ld(Address(ary2_reg, length_offset), tmp2_reg); | |
681 | 3028 |
3029 // return false if the two arrays are not equal length | |
3030 __ cmp(tmp1_reg, tmp2_reg); | |
3031 __ br(Assembler::notEqual, true, Assembler::pn, Ldone); | |
3032 __ delayed()->mov(G0, result_reg); // not equal | |
3033 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
3034 __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, tmp1_reg, Ldone); |
681 | 3035 __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal |
3036 | |
3037 // load array addresses | |
3038 __ add(ary1_reg, base_offset, ary1_reg); | |
3039 __ add(ary2_reg, base_offset, ary2_reg); | |
3040 | |
3041 // renaming registers | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
3042 Register chr1_reg = result_reg; // for characters in ary1 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
3043 Register chr2_reg = tmp2_reg; // for characters in ary2 |
681 | 3044 Register limit_reg = tmp1_reg; // length |
3045 | |
3046 // set byte count | |
3047 __ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
3048 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
3049 // Compare char[] arrays aligned to 4 bytes. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
3050 __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
3051 chr1_reg, chr2_reg, Ldone); |
681 | 3052 __ add(G0, 1, result_reg); // equals |
3053 | |
3054 __ bind(Ldone); | |
3055 %} | |
3056 | |
0 | 3057 enc_class enc_rethrow() %{ |
3058 cbuf.set_inst_mark(); | |
3059 Register temp_reg = G3; | |
727 | 3060 AddressLiteral rethrow_stub(OptoRuntime::rethrow_stub()); |
0 | 3061 assert(temp_reg != reg_to_register_object(R_I0_num), "temp must not break oop_reg"); |
3062 MacroAssembler _masm(&cbuf); | |
3063 #ifdef ASSERT | |
3064 __ save_frame(0); | |
727 | 3065 AddressLiteral last_rethrow_addrlit(&last_rethrow); |
3066 __ sethi(last_rethrow_addrlit, L1); | |
3067 Address addr(L1, last_rethrow_addrlit.low10()); | |
0 | 3068 __ get_pc(L2); |
3069 __ inc(L2, 3 * BytesPerInstWord); // skip this & 2 more insns to point at jump_to | |
727 | 3070 __ st_ptr(L2, addr); |
0 | 3071 __ restore(); |
3072 #endif | |
727 | 3073 __ JUMP(rethrow_stub, temp_reg, 0); // sethi;jmp |
0 | 3074 __ delayed()->nop(); |
3075 %} | |
3076 | |
3077 enc_class emit_mem_nop() %{ | |
3078 // Generates the instruction LDUXA [o6,g0],#0x82,g0 | |
3079 unsigned int *code = (unsigned int*)cbuf.code_end(); | |
3080 *code = (unsigned int)0xc0839040; | |
3081 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
3082 %} | |
3083 | |
3084 enc_class emit_fadd_nop() %{ | |
3085 // Generates the instruction FMOVS f31,f31 | |
3086 unsigned int *code = (unsigned int*)cbuf.code_end(); | |
3087 *code = (unsigned int)0xbfa0003f; | |
3088 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
3089 %} | |
3090 | |
3091 enc_class emit_br_nop() %{ | |
3092 // Generates the instruction BPN,PN . | |
3093 unsigned int *code = (unsigned int*)cbuf.code_end(); | |
3094 *code = (unsigned int)0x00400000; | |
3095 cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); | |
3096 %} | |
3097 | |
3098 enc_class enc_membar_acquire %{ | |
3099 MacroAssembler _masm(&cbuf); | |
3100 __ membar( Assembler::Membar_mask_bits(Assembler::LoadStore | Assembler::LoadLoad) ); | |
3101 %} | |
3102 | |
3103 enc_class enc_membar_release %{ | |
3104 MacroAssembler _masm(&cbuf); | |
3105 __ membar( Assembler::Membar_mask_bits(Assembler::LoadStore | Assembler::StoreStore) ); | |
3106 %} | |
3107 | |
3108 enc_class enc_membar_volatile %{ | |
3109 MacroAssembler _masm(&cbuf); | |
3110 __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) ); | |
3111 %} | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3112 |
0 | 3113 enc_class enc_repl8b( iRegI src, iRegL dst ) %{ |
3114 MacroAssembler _masm(&cbuf); | |
3115 Register src_reg = reg_to_register_object($src$$reg); | |
3116 Register dst_reg = reg_to_register_object($dst$$reg); | |
3117 __ sllx(src_reg, 56, dst_reg); | |
3118 __ srlx(dst_reg, 8, O7); | |
3119 __ or3 (dst_reg, O7, dst_reg); | |
3120 __ srlx(dst_reg, 16, O7); | |
3121 __ or3 (dst_reg, O7, dst_reg); | |
3122 __ srlx(dst_reg, 32, O7); | |
3123 __ or3 (dst_reg, O7, dst_reg); | |
3124 %} | |
3125 | |
3126 enc_class enc_repl4b( iRegI src, iRegL dst ) %{ | |
3127 MacroAssembler _masm(&cbuf); | |
3128 Register src_reg = reg_to_register_object($src$$reg); | |
3129 Register dst_reg = reg_to_register_object($dst$$reg); | |
3130 __ sll(src_reg, 24, dst_reg); | |
3131 __ srl(dst_reg, 8, O7); | |
3132 __ or3(dst_reg, O7, dst_reg); | |
3133 __ srl(dst_reg, 16, O7); | |
3134 __ or3(dst_reg, O7, dst_reg); | |
3135 %} | |
3136 | |
3137 enc_class enc_repl4s( iRegI src, iRegL dst ) %{ | |
3138 MacroAssembler _masm(&cbuf); | |
3139 Register src_reg = reg_to_register_object($src$$reg); | |
3140 Register dst_reg = reg_to_register_object($dst$$reg); | |
3141 __ sllx(src_reg, 48, dst_reg); | |
3142 __ srlx(dst_reg, 16, O7); | |
3143 __ or3 (dst_reg, O7, dst_reg); | |
3144 __ srlx(dst_reg, 32, O7); | |
3145 __ or3 (dst_reg, O7, dst_reg); | |
3146 %} | |
3147 | |
3148 enc_class enc_repl2i( iRegI src, iRegL dst ) %{ | |
3149 MacroAssembler _masm(&cbuf); | |
3150 Register src_reg = reg_to_register_object($src$$reg); | |
3151 Register dst_reg = reg_to_register_object($dst$$reg); | |
3152 __ sllx(src_reg, 32, dst_reg); | |
3153 __ srlx(dst_reg, 32, O7); | |
3154 __ or3 (dst_reg, O7, dst_reg); | |
3155 %} | |
3156 | |
3157 %} | |
3158 | |
3159 //----------FRAME-------------------------------------------------------------- | |
3160 // Definition of frame structure and management information. | |
3161 // | |
3162 // S T A C K L A Y O U T Allocators stack-slot number | |
3163 // | (to get allocators register number | |
3164 // G Owned by | | v add VMRegImpl::stack0) | |
3165 // r CALLER | | | |
3166 // o | +--------+ pad to even-align allocators stack-slot | |
3167 // w V | pad0 | numbers; owned by CALLER | |
3168 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned | |
3169 // h ^ | in | 5 | |
3170 // | | args | 4 Holes in incoming args owned by SELF | |
3171 // | | | | 3 | |
3172 // | | +--------+ | |
3173 // V | | old out| Empty on Intel, window on Sparc | |
3174 // | old |preserve| Must be even aligned. | |
3175 // | SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned | |
3176 // | | in | 3 area for Intel ret address | |
3177 // Owned by |preserve| Empty on Sparc. | |
3178 // SELF +--------+ | |
3179 // | | pad2 | 2 pad to align old SP | |
3180 // | +--------+ 1 | |
3181 // | | locks | 0 | |
3182 // | +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned | |
3183 // | | pad1 | 11 pad to align new SP | |
3184 // | +--------+ | |
3185 // | | | 10 | |
3186 // | | spills | 9 spills | |
3187 // V | | 8 (pad0 slot for callee) | |
3188 // -----------+--------+----> Matcher::_out_arg_limit, unaligned | |
3189 // ^ | out | 7 | |
3190 // | | args | 6 Holes in outgoing args owned by CALLEE | |
3191 // Owned by +--------+ | |
3192 // CALLEE | new out| 6 Empty on Intel, window on Sparc | |
3193 // | new |preserve| Must be even-aligned. | |
3194 // | SP-+--------+----> Matcher::_new_SP, even aligned | |
3195 // | | | | |
3196 // | |
3197 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is | |
3198 // known from SELF's arguments and the Java calling convention. | |
3199 // Region 6-7 is determined per call site. | |
3200 // Note 2: If the calling convention leaves holes in the incoming argument | |
3201 // area, those holes are owned by SELF. Holes in the outgoing area | |
3202 // are owned by the CALLEE. Holes should not be nessecary in the | |
3203 // incoming area, as the Java calling convention is completely under | |
3204 // the control of the AD file. Doubles can be sorted and packed to | |
3205 // avoid holes. Holes in the outgoing arguments may be nessecary for | |
3206 // varargs C calling conventions. | |
3207 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is | |
3208 // even aligned with pad0 as needed. | |
3209 // Region 6 is even aligned. Region 6-7 is NOT even aligned; | |
3210 // region 6-11 is even aligned; it may be padded out more so that | |
3211 // the region from SP to FP meets the minimum stack alignment. | |
3212 | |
3213 frame %{ | |
3214 // What direction does stack grow in (assumed to be same for native & Java) | |
3215 stack_direction(TOWARDS_LOW); | |
3216 | |
3217 // These two registers define part of the calling convention | |
3218 // between compiled code and the interpreter. | |
3219 inline_cache_reg(R_G5); // Inline Cache Register or methodOop for I2C | |
3220 interpreter_method_oop_reg(R_G5); // Method Oop Register when calling interpreter | |
3221 | |
3222 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset] | |
3223 cisc_spilling_operand_name(indOffset); | |
3224 | |
3225 // Number of stack slots consumed by a Monitor enter | |
3226 #ifdef _LP64 | |
3227 sync_stack_slots(2); | |
3228 #else | |
3229 sync_stack_slots(1); | |
3230 #endif | |
3231 | |
3232 // Compiled code's Frame Pointer | |
3233 frame_pointer(R_SP); | |
3234 | |
3235 // Stack alignment requirement | |
3236 stack_alignment(StackAlignmentInBytes); | |
3237 // LP64: Alignment size in bytes (128-bit -> 16 bytes) | |
3238 // !LP64: Alignment size in bytes (64-bit -> 8 bytes) | |
3239 | |
3240 // Number of stack slots between incoming argument block and the start of | |
3241 // a new frame. The PROLOG must add this many slots to the stack. The | |
3242 // EPILOG must remove this many slots. | |
3243 in_preserve_stack_slots(0); | |
3244 | |
3245 // Number of outgoing stack slots killed above the out_preserve_stack_slots | |
3246 // for calls to C. Supports the var-args backing area for register parms. | |
3247 // ADLC doesn't support parsing expressions, so I folded the math by hand. | |
3248 #ifdef _LP64 | |
3249 // (callee_register_argument_save_area_words (6) + callee_aggregate_return_pointer_words (0)) * 2-stack-slots-per-word | |
3250 varargs_C_out_slots_killed(12); | |
3251 #else | |
3252 // (callee_register_argument_save_area_words (6) + callee_aggregate_return_pointer_words (1)) * 1-stack-slots-per-word | |
3253 varargs_C_out_slots_killed( 7); | |
3254 #endif | |
3255 | |
3256 // The after-PROLOG location of the return address. Location of | |
3257 // return address specifies a type (REG or STACK) and a number | |
3258 // representing the register number (i.e. - use a register name) or | |
3259 // stack slot. | |
3260 return_addr(REG R_I7); // Ret Addr is in register I7 | |
3261 | |
3262 // Body of function which returns an OptoRegs array locating | |
3263 // arguments either in registers or in stack slots for calling | |
3264 // java | |
3265 calling_convention %{ | |
3266 (void) SharedRuntime::java_calling_convention(sig_bt, regs, length, is_outgoing); | |
3267 | |
3268 %} | |
3269 | |
3270 // Body of function which returns an OptoRegs array locating | |
3271 // arguments either in registers or in stack slots for callin | |
3272 // C. | |
3273 c_calling_convention %{ | |
3274 // This is obviously always outgoing | |
3275 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); | |
3276 %} | |
3277 | |
3278 // Location of native (C/C++) and interpreter return values. This is specified to | |
3279 // be the same as Java. In the 32-bit VM, long values are actually returned from | |
3280 // native calls in O0:O1 and returned to the interpreter in I0:I1. The copying | |
3281 // to and from the register pairs is done by the appropriate call and epilog | |
3282 // opcodes. This simplifies the register allocator. | |
3283 c_return_value %{ | |
3284 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); | |
3285 #ifdef _LP64 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3286 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3287 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3288 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3289 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; |
0 | 3290 #else // !_LP64 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3291 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3292 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3293 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3294 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; |
0 | 3295 #endif |
3296 return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], | |
3297 (is_outgoing?lo_out:lo_in)[ideal_reg] ); | |
3298 %} | |
3299 | |
3300 // Location of compiled Java return values. Same as C | |
3301 return_value %{ | |
3302 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); | |
3303 #ifdef _LP64 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3304 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3305 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3306 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3307 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; |
0 | 3308 #else // !_LP64 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3309 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3310 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3311 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3312 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; |
0 | 3313 #endif |
3314 return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], | |
3315 (is_outgoing?lo_out:lo_in)[ideal_reg] ); | |
3316 %} | |
3317 | |
3318 %} | |
3319 | |
3320 | |
3321 //----------ATTRIBUTES--------------------------------------------------------- | |
3322 //----------Operand Attributes------------------------------------------------- | |
3323 op_attrib op_cost(1); // Required cost attribute | |
3324 | |
3325 //----------Instruction Attributes--------------------------------------------- | |
3326 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute | |
3327 ins_attrib ins_size(32); // Required size attribute (in bits) | |
3328 ins_attrib ins_pc_relative(0); // Required PC Relative flag | |
3329 ins_attrib ins_short_branch(0); // Required flag: is this instruction a | |
3330 // non-matching short branch variant of some | |
3331 // long branch? | |
3332 | |
3333 //----------OPERANDS----------------------------------------------------------- | |
3334 // Operand definitions must precede instruction definitions for correct parsing | |
3335 // in the ADLC because operands constitute user defined types which are used in | |
3336 // instruction definitions. | |
3337 | |
3338 //----------Simple Operands---------------------------------------------------- | |
3339 // Immediate Operands | |
3340 // Integer Immediate: 32-bit | |
3341 operand immI() %{ | |
3342 match(ConI); | |
3343 | |
3344 op_cost(0); | |
3345 // formats are generated automatically for constants and base registers | |
3346 format %{ %} | |
3347 interface(CONST_INTER); | |
3348 %} | |
3349 | |
824 | 3350 // Integer Immediate: 8-bit |
3351 operand immI8() %{ | |
3352 predicate(Assembler::is_simm(n->get_int(), 8)); | |
3353 match(ConI); | |
3354 op_cost(0); | |
3355 format %{ %} | |
3356 interface(CONST_INTER); | |
3357 %} | |
3358 | |
0 | 3359 // Integer Immediate: 13-bit |
3360 operand immI13() %{ | |
3361 predicate(Assembler::is_simm13(n->get_int())); | |
3362 match(ConI); | |
3363 op_cost(0); | |
3364 | |
3365 format %{ %} | |
3366 interface(CONST_INTER); | |
3367 %} | |
3368 | |
785 | 3369 // Integer Immediate: 13-bit minus 7 |
3370 operand immI13m7() %{ | |
3371 predicate((-4096 < n->get_int()) && ((n->get_int() + 7) <= 4095)); | |
3372 match(ConI); | |
3373 op_cost(0); | |
3374 | |
3375 format %{ %} | |
3376 interface(CONST_INTER); | |
3377 %} | |
3378 | |
824 | 3379 // Integer Immediate: 16-bit |
3380 operand immI16() %{ | |
3381 predicate(Assembler::is_simm(n->get_int(), 16)); | |
3382 match(ConI); | |
3383 op_cost(0); | |
3384 format %{ %} | |
3385 interface(CONST_INTER); | |
3386 %} | |
3387 | |
0 | 3388 // Unsigned (positive) Integer Immediate: 13-bit |
3389 operand immU13() %{ | |
3390 predicate((0 <= n->get_int()) && Assembler::is_simm13(n->get_int())); | |
3391 match(ConI); | |
3392 op_cost(0); | |
3393 | |
3394 format %{ %} | |
3395 interface(CONST_INTER); | |
3396 %} | |
3397 | |
3398 // Integer Immediate: 6-bit | |
3399 operand immU6() %{ | |
3400 predicate(n->get_int() >= 0 && n->get_int() <= 63); | |
3401 match(ConI); | |
3402 op_cost(0); | |
3403 format %{ %} | |
3404 interface(CONST_INTER); | |
3405 %} | |
3406 | |
3407 // Integer Immediate: 11-bit | |
3408 operand immI11() %{ | |
3409 predicate(Assembler::is_simm(n->get_int(),11)); | |
3410 match(ConI); | |
3411 op_cost(0); | |
3412 format %{ %} | |
3413 interface(CONST_INTER); | |
3414 %} | |
3415 | |
3416 // Integer Immediate: 0-bit | |
3417 operand immI0() %{ | |
3418 predicate(n->get_int() == 0); | |
3419 match(ConI); | |
3420 op_cost(0); | |
3421 | |
3422 format %{ %} | |
3423 interface(CONST_INTER); | |
3424 %} | |
3425 | |
3426 // Integer Immediate: the value 10 | |
3427 operand immI10() %{ | |
3428 predicate(n->get_int() == 10); | |
3429 match(ConI); | |
3430 op_cost(0); | |
3431 | |
3432 format %{ %} | |
3433 interface(CONST_INTER); | |
3434 %} | |
3435 | |
3436 // Integer Immediate: the values 0-31 | |
3437 operand immU5() %{ | |
3438 predicate(n->get_int() >= 0 && n->get_int() <= 31); | |
3439 match(ConI); | |
3440 op_cost(0); | |
3441 | |
3442 format %{ %} | |
3443 interface(CONST_INTER); | |
3444 %} | |
3445 | |
3446 // Integer Immediate: the values 1-31 | |
3447 operand immI_1_31() %{ | |
3448 predicate(n->get_int() >= 1 && n->get_int() <= 31); | |
3449 match(ConI); | |
3450 op_cost(0); | |
3451 | |
3452 format %{ %} | |
3453 interface(CONST_INTER); | |
3454 %} | |
3455 | |
3456 // Integer Immediate: the values 32-63 | |
3457 operand immI_32_63() %{ | |
3458 predicate(n->get_int() >= 32 && n->get_int() <= 63); | |
3459 match(ConI); | |
3460 op_cost(0); | |
3461 | |
3462 format %{ %} | |
3463 interface(CONST_INTER); | |
3464 %} | |
3465 | |
785 | 3466 // Immediates for special shifts (sign extend) |
3467 | |
3468 // Integer Immediate: the value 16 | |
3469 operand immI_16() %{ | |
3470 predicate(n->get_int() == 16); | |
3471 match(ConI); | |
3472 op_cost(0); | |
3473 | |
3474 format %{ %} | |
3475 interface(CONST_INTER); | |
3476 %} | |
3477 | |
3478 // Integer Immediate: the value 24 | |
3479 operand immI_24() %{ | |
3480 predicate(n->get_int() == 24); | |
3481 match(ConI); | |
3482 op_cost(0); | |
3483 | |
3484 format %{ %} | |
3485 interface(CONST_INTER); | |
3486 %} | |
3487 | |
0 | 3488 // Integer Immediate: the value 255 |
3489 operand immI_255() %{ | |
3490 predicate( n->get_int() == 255 ); | |
3491 match(ConI); | |
3492 op_cost(0); | |
3493 | |
3494 format %{ %} | |
3495 interface(CONST_INTER); | |
3496 %} | |
3497 | |
785 | 3498 // Integer Immediate: the value 65535 |
3499 operand immI_65535() %{ | |
3500 predicate(n->get_int() == 65535); | |
3501 match(ConI); | |
3502 op_cost(0); | |
3503 | |
3504 format %{ %} | |
3505 interface(CONST_INTER); | |
3506 %} | |
3507 | |
0 | 3508 // Long Immediate: the value FF |
3509 operand immL_FF() %{ | |
3510 predicate( n->get_long() == 0xFFL ); | |
3511 match(ConL); | |
3512 op_cost(0); | |
3513 | |
3514 format %{ %} | |
3515 interface(CONST_INTER); | |
3516 %} | |
3517 | |
3518 // Long Immediate: the value FFFF | |
3519 operand immL_FFFF() %{ | |
3520 predicate( n->get_long() == 0xFFFFL ); | |
3521 match(ConL); | |
3522 op_cost(0); | |
3523 | |
3524 format %{ %} | |
3525 interface(CONST_INTER); | |
3526 %} | |
3527 | |
3528 // Pointer Immediate: 32 or 64-bit | |
3529 operand immP() %{ | |
3530 match(ConP); | |
3531 | |
3532 op_cost(5); | |
3533 // formats are generated automatically for constants and base registers | |
3534 format %{ %} | |
3535 interface(CONST_INTER); | |
3536 %} | |
3537 | |
3538 operand immP13() %{ | |
3539 predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095)); | |
3540 match(ConP); | |
3541 op_cost(0); | |
3542 | |
3543 format %{ %} | |
3544 interface(CONST_INTER); | |
3545 %} | |
3546 | |
3547 operand immP0() %{ | |
3548 predicate(n->get_ptr() == 0); | |
3549 match(ConP); | |
3550 op_cost(0); | |
3551 | |
3552 format %{ %} | |
3553 interface(CONST_INTER); | |
3554 %} | |
3555 | |
3556 operand immP_poll() %{ | |
3557 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page()); | |
3558 match(ConP); | |
3559 | |
3560 // formats are generated automatically for constants and base registers | |
3561 format %{ %} | |
3562 interface(CONST_INTER); | |
3563 %} | |
3564 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3565 // Pointer Immediate |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3566 operand immN() |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3567 %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3568 match(ConN); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3569 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3570 op_cost(10); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3571 format %{ %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3572 interface(CONST_INTER); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3573 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3574 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3575 // NULL Pointer Immediate |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3576 operand immN0() |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3577 %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3578 predicate(n->get_narrowcon() == 0); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3579 match(ConN); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3580 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3581 op_cost(0); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3582 format %{ %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3583 interface(CONST_INTER); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3584 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3585 |
0 | 3586 operand immL() %{ |
3587 match(ConL); | |
3588 op_cost(40); | |
3589 // formats are generated automatically for constants and base registers | |
3590 format %{ %} | |
3591 interface(CONST_INTER); | |
3592 %} | |
3593 | |
3594 operand immL0() %{ | |
3595 predicate(n->get_long() == 0L); | |
3596 match(ConL); | |
3597 op_cost(0); | |
3598 // formats are generated automatically for constants and base registers | |
3599 format %{ %} | |
3600 interface(CONST_INTER); | |
3601 %} | |
3602 | |
3603 // Long Immediate: 13-bit | |
3604 operand immL13() %{ | |
3605 predicate((-4096L < n->get_long()) && (n->get_long() <= 4095L)); | |
3606 match(ConL); | |
3607 op_cost(0); | |
3608 | |
3609 format %{ %} | |
3610 interface(CONST_INTER); | |
3611 %} | |
3612 | |
785 | 3613 // Long Immediate: 13-bit minus 7 |
3614 operand immL13m7() %{ | |
3615 predicate((-4096L < n->get_long()) && ((n->get_long() + 7L) <= 4095L)); | |
3616 match(ConL); | |
3617 op_cost(0); | |
3618 | |
3619 format %{ %} | |
3620 interface(CONST_INTER); | |
3621 %} | |
3622 | |
0 | 3623 // Long Immediate: low 32-bit mask |
3624 operand immL_32bits() %{ | |
3625 predicate(n->get_long() == 0xFFFFFFFFL); | |
3626 match(ConL); | |
3627 op_cost(0); | |
3628 | |
3629 format %{ %} | |
3630 interface(CONST_INTER); | |
3631 %} | |
3632 | |
3633 // Double Immediate | |
3634 operand immD() %{ | |
3635 match(ConD); | |
3636 | |
3637 op_cost(40); | |
3638 format %{ %} | |
3639 interface(CONST_INTER); | |
3640 %} | |
3641 | |
3642 operand immD0() %{ | |
3643 #ifdef _LP64 | |
3644 // on 64-bit architectures this comparision is faster | |
3645 predicate(jlong_cast(n->getd()) == 0); | |
3646 #else | |
3647 predicate((n->getd() == 0) && (fpclass(n->getd()) == FP_PZERO)); | |
3648 #endif | |
3649 match(ConD); | |
3650 | |
3651 op_cost(0); | |
3652 format %{ %} | |
3653 interface(CONST_INTER); | |
3654 %} | |
3655 | |
3656 // Float Immediate | |
3657 operand immF() %{ | |
3658 match(ConF); | |
3659 | |
3660 op_cost(20); | |
3661 format %{ %} | |
3662 interface(CONST_INTER); | |
3663 %} | |
3664 | |
3665 // Float Immediate: 0 | |
3666 operand immF0() %{ | |
3667 predicate((n->getf() == 0) && (fpclass(n->getf()) == FP_PZERO)); | |
3668 match(ConF); | |
3669 | |
3670 op_cost(0); | |
3671 format %{ %} | |
3672 interface(CONST_INTER); | |
3673 %} | |
3674 | |
3675 // Integer Register Operands | |
3676 // Integer Register | |
3677 operand iRegI() %{ | |
3678 constraint(ALLOC_IN_RC(int_reg)); | |
3679 match(RegI); | |
3680 | |
3681 match(notemp_iRegI); | |
3682 match(g1RegI); | |
3683 match(o0RegI); | |
3684 match(iRegIsafe); | |
3685 | |
3686 format %{ %} | |
3687 interface(REG_INTER); | |
3688 %} | |
3689 | |
3690 operand notemp_iRegI() %{ | |
3691 constraint(ALLOC_IN_RC(notemp_int_reg)); | |
3692 match(RegI); | |
3693 | |
3694 match(o0RegI); | |
3695 | |
3696 format %{ %} | |
3697 interface(REG_INTER); | |
3698 %} | |
3699 | |
3700 operand o0RegI() %{ | |
3701 constraint(ALLOC_IN_RC(o0_regI)); | |
3702 match(iRegI); | |
3703 | |
3704 format %{ %} | |
3705 interface(REG_INTER); | |
3706 %} | |
3707 | |
3708 // Pointer Register | |
3709 operand iRegP() %{ | |
3710 constraint(ALLOC_IN_RC(ptr_reg)); | |
3711 match(RegP); | |
3712 | |
3713 match(lock_ptr_RegP); | |
3714 match(g1RegP); | |
3715 match(g2RegP); | |
3716 match(g3RegP); | |
3717 match(g4RegP); | |
3718 match(i0RegP); | |
3719 match(o0RegP); | |
3720 match(o1RegP); | |
3721 match(l7RegP); | |
3722 | |
3723 format %{ %} | |
3724 interface(REG_INTER); | |
3725 %} | |
3726 | |
3727 operand sp_ptr_RegP() %{ | |
3728 constraint(ALLOC_IN_RC(sp_ptr_reg)); | |
3729 match(RegP); | |
3730 match(iRegP); | |
3731 | |
3732 format %{ %} | |
3733 interface(REG_INTER); | |
3734 %} | |
3735 | |
3736 operand lock_ptr_RegP() %{ | |
3737 constraint(ALLOC_IN_RC(lock_ptr_reg)); | |
3738 match(RegP); | |
3739 match(i0RegP); | |
3740 match(o0RegP); | |
3741 match(o1RegP); | |
3742 match(l7RegP); | |
3743 | |
3744 format %{ %} | |
3745 interface(REG_INTER); | |
3746 %} | |
3747 | |
3748 operand g1RegP() %{ | |
3749 constraint(ALLOC_IN_RC(g1_regP)); | |
3750 match(iRegP); | |
3751 | |
3752 format %{ %} | |
3753 interface(REG_INTER); | |
3754 %} | |
3755 | |
3756 operand g2RegP() %{ | |
3757 constraint(ALLOC_IN_RC(g2_regP)); | |
3758 match(iRegP); | |
3759 | |
3760 format %{ %} | |
3761 interface(REG_INTER); | |
3762 %} | |
3763 | |
3764 operand g3RegP() %{ | |
3765 constraint(ALLOC_IN_RC(g3_regP)); | |
3766 match(iRegP); | |
3767 | |
3768 format %{ %} | |
3769 interface(REG_INTER); | |
3770 %} | |
3771 | |
3772 operand g1RegI() %{ | |
3773 constraint(ALLOC_IN_RC(g1_regI)); | |
3774 match(iRegI); | |
3775 | |
3776 format %{ %} | |
3777 interface(REG_INTER); | |
3778 %} | |
3779 | |
3780 operand g3RegI() %{ | |
3781 constraint(ALLOC_IN_RC(g3_regI)); | |
3782 match(iRegI); | |
3783 | |
3784 format %{ %} | |
3785 interface(REG_INTER); | |
3786 %} | |
3787 | |
3788 operand g4RegI() %{ | |
3789 constraint(ALLOC_IN_RC(g4_regI)); | |
3790 match(iRegI); | |
3791 | |
3792 format %{ %} | |
3793 interface(REG_INTER); | |
3794 %} | |
3795 | |
3796 operand g4RegP() %{ | |
3797 constraint(ALLOC_IN_RC(g4_regP)); | |
3798 match(iRegP); | |
3799 | |
3800 format %{ %} | |
3801 interface(REG_INTER); | |
3802 %} | |
3803 | |
3804 operand i0RegP() %{ | |
3805 constraint(ALLOC_IN_RC(i0_regP)); | |
3806 match(iRegP); | |
3807 | |
3808 format %{ %} | |
3809 interface(REG_INTER); | |
3810 %} | |
3811 | |
3812 operand o0RegP() %{ | |
3813 constraint(ALLOC_IN_RC(o0_regP)); | |
3814 match(iRegP); | |
3815 | |
3816 format %{ %} | |
3817 interface(REG_INTER); | |
3818 %} | |
3819 | |
3820 operand o1RegP() %{ | |
3821 constraint(ALLOC_IN_RC(o1_regP)); | |
3822 match(iRegP); | |
3823 | |
3824 format %{ %} | |
3825 interface(REG_INTER); | |
3826 %} | |
3827 | |
3828 operand o2RegP() %{ | |
3829 constraint(ALLOC_IN_RC(o2_regP)); | |
3830 match(iRegP); | |
3831 | |
3832 format %{ %} | |
3833 interface(REG_INTER); | |
3834 %} | |
3835 | |
3836 operand o7RegP() %{ | |
3837 constraint(ALLOC_IN_RC(o7_regP)); | |
3838 match(iRegP); | |
3839 | |
3840 format %{ %} | |
3841 interface(REG_INTER); | |
3842 %} | |
3843 | |
3844 operand l7RegP() %{ | |
3845 constraint(ALLOC_IN_RC(l7_regP)); | |
3846 match(iRegP); | |
3847 | |
3848 format %{ %} | |
3849 interface(REG_INTER); | |
3850 %} | |
3851 | |
3852 operand o7RegI() %{ | |
3853 constraint(ALLOC_IN_RC(o7_regI)); | |
3854 match(iRegI); | |
3855 | |
3856 format %{ %} | |
3857 interface(REG_INTER); | |
3858 %} | |
3859 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3860 operand iRegN() %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3861 constraint(ALLOC_IN_RC(int_reg)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3862 match(RegN); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3863 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3864 format %{ %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3865 interface(REG_INTER); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3866 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
3867 |
0 | 3868 // Long Register |
3869 operand iRegL() %{ | |
3870 constraint(ALLOC_IN_RC(long_reg)); | |
3871 match(RegL); | |
3872 | |
3873 format %{ %} | |
3874 interface(REG_INTER); | |
3875 %} | |
3876 | |
3877 operand o2RegL() %{ | |
3878 constraint(ALLOC_IN_RC(o2_regL)); | |
3879 match(iRegL); | |
3880 | |
3881 format %{ %} | |
3882 interface(REG_INTER); | |
3883 %} | |
3884 | |
3885 operand o7RegL() %{ | |
3886 constraint(ALLOC_IN_RC(o7_regL)); | |
3887 match(iRegL); | |
3888 | |
3889 format %{ %} | |
3890 interface(REG_INTER); | |
3891 %} | |
3892 | |
3893 operand g1RegL() %{ | |
3894 constraint(ALLOC_IN_RC(g1_regL)); | |
3895 match(iRegL); | |
3896 | |
3897 format %{ %} | |
3898 interface(REG_INTER); | |
3899 %} | |
3900 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
3901 operand g3RegL() %{ |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
3902 constraint(ALLOC_IN_RC(g3_regL)); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
3903 match(iRegL); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
3904 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
3905 format %{ %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
3906 interface(REG_INTER); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
3907 %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
3908 |
0 | 3909 // Int Register safe |
3910 // This is 64bit safe | |
3911 operand iRegIsafe() %{ | |
3912 constraint(ALLOC_IN_RC(long_reg)); | |
3913 | |
3914 match(iRegI); | |
3915 | |
3916 format %{ %} | |
3917 interface(REG_INTER); | |
3918 %} | |
3919 | |
3920 // Condition Code Flag Register | |
3921 operand flagsReg() %{ | |
3922 constraint(ALLOC_IN_RC(int_flags)); | |
3923 match(RegFlags); | |
3924 | |
3925 format %{ "ccr" %} // both ICC and XCC | |
3926 interface(REG_INTER); | |
3927 %} | |
3928 | |
3929 // Condition Code Register, unsigned comparisons. | |
3930 operand flagsRegU() %{ | |
3931 constraint(ALLOC_IN_RC(int_flags)); | |
3932 match(RegFlags); | |
3933 | |
3934 format %{ "icc_U" %} | |
3935 interface(REG_INTER); | |
3936 %} | |
3937 | |
3938 // Condition Code Register, pointer comparisons. | |
3939 operand flagsRegP() %{ | |
3940 constraint(ALLOC_IN_RC(int_flags)); | |
3941 match(RegFlags); | |
3942 | |
3943 #ifdef _LP64 | |
3944 format %{ "xcc_P" %} | |
3945 #else | |
3946 format %{ "icc_P" %} | |
3947 #endif | |
3948 interface(REG_INTER); | |
3949 %} | |
3950 | |
3951 // Condition Code Register, long comparisons. | |
3952 operand flagsRegL() %{ | |
3953 constraint(ALLOC_IN_RC(int_flags)); | |
3954 match(RegFlags); | |
3955 | |
3956 format %{ "xcc_L" %} | |
3957 interface(REG_INTER); | |
3958 %} | |
3959 | |
3960 // Condition Code Register, floating comparisons, unordered same as "less". | |
3961 operand flagsRegF() %{ | |
3962 constraint(ALLOC_IN_RC(float_flags)); | |
3963 match(RegFlags); | |
3964 match(flagsRegF0); | |
3965 | |
3966 format %{ %} | |
3967 interface(REG_INTER); | |
3968 %} | |
3969 | |
3970 operand flagsRegF0() %{ | |
3971 constraint(ALLOC_IN_RC(float_flag0)); | |
3972 match(RegFlags); | |
3973 | |
3974 format %{ %} | |
3975 interface(REG_INTER); | |
3976 %} | |
3977 | |
3978 | |
3979 // Condition Code Flag Register used by long compare | |
3980 operand flagsReg_long_LTGE() %{ | |
3981 constraint(ALLOC_IN_RC(int_flags)); | |
3982 match(RegFlags); | |
3983 format %{ "icc_LTGE" %} | |
3984 interface(REG_INTER); | |
3985 %} | |
3986 operand flagsReg_long_EQNE() %{ | |
3987 constraint(ALLOC_IN_RC(int_flags)); | |
3988 match(RegFlags); | |
3989 format %{ "icc_EQNE" %} | |
3990 interface(REG_INTER); | |
3991 %} | |
3992 operand flagsReg_long_LEGT() %{ | |
3993 constraint(ALLOC_IN_RC(int_flags)); | |
3994 match(RegFlags); | |
3995 format %{ "icc_LEGT" %} | |
3996 interface(REG_INTER); | |
3997 %} | |
3998 | |
3999 | |
4000 operand regD() %{ | |
4001 constraint(ALLOC_IN_RC(dflt_reg)); | |
4002 match(RegD); | |
4003 | |
551 | 4004 match(regD_low); |
4005 | |
0 | 4006 format %{ %} |
4007 interface(REG_INTER); | |
4008 %} | |
4009 | |
4010 operand regF() %{ | |
4011 constraint(ALLOC_IN_RC(sflt_reg)); | |
4012 match(RegF); | |
4013 | |
4014 format %{ %} | |
4015 interface(REG_INTER); | |
4016 %} | |
4017 | |
4018 operand regD_low() %{ | |
4019 constraint(ALLOC_IN_RC(dflt_low_reg)); | |
551 | 4020 match(regD); |
0 | 4021 |
4022 format %{ %} | |
4023 interface(REG_INTER); | |
4024 %} | |
4025 | |
4026 // Special Registers | |
4027 | |
4028 // Method Register | |
4029 operand inline_cache_regP(iRegP reg) %{ | |
4030 constraint(ALLOC_IN_RC(g5_regP)); // G5=inline_cache_reg but uses 2 bits instead of 1 | |
4031 match(reg); | |
4032 format %{ %} | |
4033 interface(REG_INTER); | |
4034 %} | |
4035 | |
4036 operand interpreter_method_oop_regP(iRegP reg) %{ | |
4037 constraint(ALLOC_IN_RC(g5_regP)); // G5=interpreter_method_oop_reg but uses 2 bits instead of 1 | |
4038 match(reg); | |
4039 format %{ %} | |
4040 interface(REG_INTER); | |
4041 %} | |
4042 | |
4043 | |
4044 //----------Complex Operands--------------------------------------------------- | |
4045 // Indirect Memory Reference | |
4046 operand indirect(sp_ptr_RegP reg) %{ | |
4047 constraint(ALLOC_IN_RC(sp_ptr_reg)); | |
4048 match(reg); | |
4049 | |
4050 op_cost(100); | |
4051 format %{ "[$reg]" %} | |
4052 interface(MEMORY_INTER) %{ | |
4053 base($reg); | |
4054 index(0x0); | |
4055 scale(0x0); | |
4056 disp(0x0); | |
4057 %} | |
4058 %} | |
4059 | |
785 | 4060 // Indirect with simm13 Offset |
0 | 4061 operand indOffset13(sp_ptr_RegP reg, immX13 offset) %{ |
4062 constraint(ALLOC_IN_RC(sp_ptr_reg)); | |
4063 match(AddP reg offset); | |
4064 | |
4065 op_cost(100); | |
4066 format %{ "[$reg + $offset]" %} | |
4067 interface(MEMORY_INTER) %{ | |
4068 base($reg); | |
4069 index(0x0); | |
4070 scale(0x0); | |
4071 disp($offset); | |
4072 %} | |
4073 %} | |
4074 | |
785 | 4075 // Indirect with simm13 Offset minus 7 |
4076 operand indOffset13m7(sp_ptr_RegP reg, immX13m7 offset) %{ | |
4077 constraint(ALLOC_IN_RC(sp_ptr_reg)); | |
4078 match(AddP reg offset); | |
4079 | |
4080 op_cost(100); | |
4081 format %{ "[$reg + $offset]" %} | |
4082 interface(MEMORY_INTER) %{ | |
4083 base($reg); | |
4084 index(0x0); | |
4085 scale(0x0); | |
4086 disp($offset); | |
4087 %} | |
4088 %} | |
4089 | |
0 | 4090 // Note: Intel has a swapped version also, like this: |
4091 //operand indOffsetX(iRegI reg, immP offset) %{ | |
4092 // constraint(ALLOC_IN_RC(int_reg)); | |
4093 // match(AddP offset reg); | |
4094 // | |
4095 // op_cost(100); | |
4096 // format %{ "[$reg + $offset]" %} | |
4097 // interface(MEMORY_INTER) %{ | |
4098 // base($reg); | |
4099 // index(0x0); | |
4100 // scale(0x0); | |
4101 // disp($offset); | |
4102 // %} | |
4103 //%} | |
4104 //// However, it doesn't make sense for SPARC, since | |
4105 // we have no particularly good way to embed oops in | |
4106 // single instructions. | |
4107 | |
4108 // Indirect with Register Index | |
4109 operand indIndex(iRegP addr, iRegX index) %{ | |
4110 constraint(ALLOC_IN_RC(ptr_reg)); | |
4111 match(AddP addr index); | |
4112 | |
4113 op_cost(100); | |
4114 format %{ "[$addr + $index]" %} | |
4115 interface(MEMORY_INTER) %{ | |
4116 base($addr); | |
4117 index($index); | |
4118 scale(0x0); | |
4119 disp(0x0); | |
4120 %} | |
4121 %} | |
4122 | |
4123 //----------Special Memory Operands-------------------------------------------- | |
4124 // Stack Slot Operand - This operand is used for loading and storing temporary | |
4125 // values on the stack where a match requires a value to | |
4126 // flow through memory. | |
4127 operand stackSlotI(sRegI reg) %{ | |
4128 constraint(ALLOC_IN_RC(stack_slots)); | |
4129 op_cost(100); | |
4130 //match(RegI); | |
4131 format %{ "[$reg]" %} | |
4132 interface(MEMORY_INTER) %{ | |
4133 base(0xE); // R_SP | |
4134 index(0x0); | |
4135 scale(0x0); | |
4136 disp($reg); // Stack Offset | |
4137 %} | |
4138 %} | |
4139 | |
4140 operand stackSlotP(sRegP reg) %{ | |
4141 constraint(ALLOC_IN_RC(stack_slots)); | |
4142 op_cost(100); | |
4143 //match(RegP); | |
4144 format %{ "[$reg]" %} | |
4145 interface(MEMORY_INTER) %{ | |
4146 base(0xE); // R_SP | |
4147 index(0x0); | |
4148 scale(0x0); | |
4149 disp($reg); // Stack Offset | |
4150 %} | |
4151 %} | |
4152 | |
4153 operand stackSlotF(sRegF reg) %{ | |
4154 constraint(ALLOC_IN_RC(stack_slots)); | |
4155 op_cost(100); | |
4156 //match(RegF); | |
4157 format %{ "[$reg]" %} | |
4158 interface(MEMORY_INTER) %{ | |
4159 base(0xE); // R_SP | |
4160 index(0x0); | |
4161 scale(0x0); | |
4162 disp($reg); // Stack Offset | |
4163 %} | |
4164 %} | |
4165 operand stackSlotD(sRegD reg) %{ | |
4166 constraint(ALLOC_IN_RC(stack_slots)); | |
4167 op_cost(100); | |
4168 //match(RegD); | |
4169 format %{ "[$reg]" %} | |
4170 interface(MEMORY_INTER) %{ | |
4171 base(0xE); // R_SP | |
4172 index(0x0); | |
4173 scale(0x0); | |
4174 disp($reg); // Stack Offset | |
4175 %} | |
4176 %} | |
4177 operand stackSlotL(sRegL reg) %{ | |
4178 constraint(ALLOC_IN_RC(stack_slots)); | |
4179 op_cost(100); | |
4180 //match(RegL); | |
4181 format %{ "[$reg]" %} | |
4182 interface(MEMORY_INTER) %{ | |
4183 base(0xE); // R_SP | |
4184 index(0x0); | |
4185 scale(0x0); | |
4186 disp($reg); // Stack Offset | |
4187 %} | |
4188 %} | |
4189 | |
4190 // Operands for expressing Control Flow | |
4191 // NOTE: Label is a predefined operand which should not be redefined in | |
4192 // the AD file. It is generically handled within the ADLC. | |
4193 | |
4194 //----------Conditional Branch Operands---------------------------------------- | |
4195 // Comparison Op - This is the operation of the comparison, and is limited to | |
4196 // the following set of codes: | |
4197 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) | |
4198 // | |
4199 // Other attributes of the comparison, such as unsignedness, are specified | |
4200 // by the comparison instruction that sets a condition code flags register. | |
4201 // That result is represented by a flags operand whose subtype is appropriate | |
4202 // to the unsignedness (etc.) of the comparison. | |
4203 // | |
4204 // Later, the instruction which matches both the Comparison Op (a Bool) and | |
4205 // the flags (produced by the Cmp) specifies the coding of the comparison op | |
4206 // by matching a specific subtype of Bool operand below, such as cmpOpU. | |
4207 | |
4208 operand cmpOp() %{ | |
4209 match(Bool); | |
4210 | |
4211 format %{ "" %} | |
4212 interface(COND_INTER) %{ | |
4213 equal(0x1); | |
4214 not_equal(0x9); | |
4215 less(0x3); | |
4216 greater_equal(0xB); | |
4217 less_equal(0x2); | |
4218 greater(0xA); | |
4219 %} | |
4220 %} | |
4221 | |
4222 // Comparison Op, unsigned | |
4223 operand cmpOpU() %{ | |
4224 match(Bool); | |
4225 | |
4226 format %{ "u" %} | |
4227 interface(COND_INTER) %{ | |
4228 equal(0x1); | |
4229 not_equal(0x9); | |
4230 less(0x5); | |
4231 greater_equal(0xD); | |
4232 less_equal(0x4); | |
4233 greater(0xC); | |
4234 %} | |
4235 %} | |
4236 | |
4237 // Comparison Op, pointer (same as unsigned) | |
4238 operand cmpOpP() %{ | |
4239 match(Bool); | |
4240 | |
4241 format %{ "p" %} | |
4242 interface(COND_INTER) %{ | |
4243 equal(0x1); | |
4244 not_equal(0x9); | |
4245 less(0x5); | |
4246 greater_equal(0xD); | |
4247 less_equal(0x4); | |
4248 greater(0xC); | |
4249 %} | |
4250 %} | |
4251 | |
4252 // Comparison Op, branch-register encoding | |
4253 operand cmpOp_reg() %{ | |
4254 match(Bool); | |
4255 | |
4256 format %{ "" %} | |
4257 interface(COND_INTER) %{ | |
4258 equal (0x1); | |
4259 not_equal (0x5); | |
4260 less (0x3); | |
4261 greater_equal(0x7); | |
4262 less_equal (0x2); | |
4263 greater (0x6); | |
4264 %} | |
4265 %} | |
4266 | |
4267 // Comparison Code, floating, unordered same as less | |
4268 operand cmpOpF() %{ | |
4269 match(Bool); | |
4270 | |
4271 format %{ "fl" %} | |
4272 interface(COND_INTER) %{ | |
4273 equal(0x9); | |
4274 not_equal(0x1); | |
4275 less(0x3); | |
4276 greater_equal(0xB); | |
4277 less_equal(0xE); | |
4278 greater(0x6); | |
4279 %} | |
4280 %} | |
4281 | |
4282 // Used by long compare | |
4283 operand cmpOp_commute() %{ | |
4284 match(Bool); | |
4285 | |
4286 format %{ "" %} | |
4287 interface(COND_INTER) %{ | |
4288 equal(0x1); | |
4289 not_equal(0x9); | |
4290 less(0xA); | |
4291 greater_equal(0x2); | |
4292 less_equal(0xB); | |
4293 greater(0x3); | |
4294 %} | |
4295 %} | |
4296 | |
4297 //----------OPERAND CLASSES---------------------------------------------------- | |
4298 // Operand Classes are groups of operands that are used to simplify | |
605 | 4299 // instruction definitions by not requiring the AD writer to specify separate |
0 | 4300 // instructions for every form of operand when the instruction accepts |
4301 // multiple operand types with the same basic encoding and format. The classic | |
4302 // case of this is memory operands. | |
4303 opclass memory( indirect, indOffset13, indIndex ); | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
4304 opclass indIndexMemory( indIndex ); |
0 | 4305 |
4306 //----------PIPELINE----------------------------------------------------------- | |
4307 pipeline %{ | |
4308 | |
4309 //----------ATTRIBUTES--------------------------------------------------------- | |
4310 attributes %{ | |
4311 fixed_size_instructions; // Fixed size instructions | |
4312 branch_has_delay_slot; // Branch has delay slot following | |
4313 max_instructions_per_bundle = 4; // Up to 4 instructions per bundle | |
4314 instruction_unit_size = 4; // An instruction is 4 bytes long | |
4315 instruction_fetch_unit_size = 16; // The processor fetches one line | |
4316 instruction_fetch_units = 1; // of 16 bytes | |
4317 | |
4318 // List of nop instructions | |
4319 nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR ); | |
4320 %} | |
4321 | |
4322 //----------RESOURCES---------------------------------------------------------- | |
4323 // Resources are the functional units available to the machine | |
4324 resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1); | |
4325 | |
4326 //----------PIPELINE DESCRIPTION----------------------------------------------- | |
4327 // Pipeline Description specifies the stages in the machine's pipeline | |
4328 | |
4329 pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D); | |
4330 | |
4331 //----------PIPELINE CLASSES--------------------------------------------------- | |
4332 // Pipeline Classes describe the stages in which input and output are | |
4333 // referenced by the hardware pipeline. | |
4334 | |
4335 // Integer ALU reg-reg operation | |
4336 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
4337 single_instruction; | |
4338 dst : E(write); | |
4339 src1 : R(read); | |
4340 src2 : R(read); | |
4341 IALU : R; | |
4342 %} | |
4343 | |
4344 // Integer ALU reg-reg long operation | |
4345 pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{ | |
4346 instruction_count(2); | |
4347 dst : E(write); | |
4348 src1 : R(read); | |
4349 src2 : R(read); | |
4350 IALU : R; | |
4351 IALU : R; | |
4352 %} | |
4353 | |
4354 // Integer ALU reg-reg long dependent operation | |
4355 pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{ | |
4356 instruction_count(1); multiple_bundles; | |
4357 dst : E(write); | |
4358 src1 : R(read); | |
4359 src2 : R(read); | |
4360 cr : E(write); | |
4361 IALU : R(2); | |
4362 %} | |
4363 | |
4364 // Integer ALU reg-imm operaion | |
4365 pipe_class ialu_reg_imm(iRegI dst, iRegI src1, immI13 src2) %{ | |
4366 single_instruction; | |
4367 dst : E(write); | |
4368 src1 : R(read); | |
4369 IALU : R; | |
4370 %} | |
4371 | |
4372 // Integer ALU reg-reg operation with condition code | |
4373 pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{ | |
4374 single_instruction; | |
4375 dst : E(write); | |
4376 cr : E(write); | |
4377 src1 : R(read); | |
4378 src2 : R(read); | |
4379 IALU : R; | |
4380 %} | |
4381 | |
4382 // Integer ALU reg-imm operation with condition code | |
4383 pipe_class ialu_cc_reg_imm(iRegI dst, iRegI src1, immI13 src2, flagsReg cr) %{ | |
4384 single_instruction; | |
4385 dst : E(write); | |
4386 cr : E(write); | |
4387 src1 : R(read); | |
4388 IALU : R; | |
4389 %} | |
4390 | |
4391 // Integer ALU zero-reg operation | |
4392 pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{ | |
4393 single_instruction; | |
4394 dst : E(write); | |
4395 src2 : R(read); | |
4396 IALU : R; | |
4397 %} | |
4398 | |
4399 // Integer ALU zero-reg operation with condition code only | |
4400 pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{ | |
4401 single_instruction; | |
4402 cr : E(write); | |
4403 src : R(read); | |
4404 IALU : R; | |
4405 %} | |
4406 | |
4407 // Integer ALU reg-reg operation with condition code only | |
4408 pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{ | |
4409 single_instruction; | |
4410 cr : E(write); | |
4411 src1 : R(read); | |
4412 src2 : R(read); | |
4413 IALU : R; | |
4414 %} | |
4415 | |
4416 // Integer ALU reg-imm operation with condition code only | |
4417 pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1, immI13 src2) %{ | |
4418 single_instruction; | |
4419 cr : E(write); | |
4420 src1 : R(read); | |
4421 IALU : R; | |
4422 %} | |
4423 | |
4424 // Integer ALU reg-reg-zero operation with condition code only | |
4425 pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{ | |
4426 single_instruction; | |
4427 cr : E(write); | |
4428 src1 : R(read); | |
4429 src2 : R(read); | |
4430 IALU : R; | |
4431 %} | |
4432 | |
4433 // Integer ALU reg-imm-zero operation with condition code only | |
4434 pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI13 src2, immI0 zero) %{ | |
4435 single_instruction; | |
4436 cr : E(write); | |
4437 src1 : R(read); | |
4438 IALU : R; | |
4439 %} | |
4440 | |
4441 // Integer ALU reg-reg operation with condition code, src1 modified | |
4442 pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{ | |
4443 single_instruction; | |
4444 cr : E(write); | |
4445 src1 : E(write); | |
4446 src1 : R(read); | |
4447 src2 : R(read); | |
4448 IALU : R; | |
4449 %} | |
4450 | |
4451 // Integer ALU reg-imm operation with condition code, src1 modified | |
4452 pipe_class ialu_cc_rwreg_imm(flagsReg cr, iRegI src1, immI13 src2) %{ | |
4453 single_instruction; | |
4454 cr : E(write); | |
4455 src1 : E(write); | |
4456 src1 : R(read); | |
4457 IALU : R; | |
4458 %} | |
4459 | |
4460 pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{ | |
4461 multiple_bundles; | |
4462 dst : E(write)+4; | |
4463 cr : E(write); | |
4464 src1 : R(read); | |
4465 src2 : R(read); | |
4466 IALU : R(3); | |
4467 BR : R(2); | |
4468 %} | |
4469 | |
4470 // Integer ALU operation | |
4471 pipe_class ialu_none(iRegI dst) %{ | |
4472 single_instruction; | |
4473 dst : E(write); | |
4474 IALU : R; | |
4475 %} | |
4476 | |
4477 // Integer ALU reg operation | |
4478 pipe_class ialu_reg(iRegI dst, iRegI src) %{ | |
4479 single_instruction; may_have_no_code; | |
4480 dst : E(write); | |
4481 src : R(read); | |
4482 IALU : R; | |
4483 %} | |
4484 | |
4485 // Integer ALU reg conditional operation | |
4486 // This instruction has a 1 cycle stall, and cannot execute | |
4487 // in the same cycle as the instruction setting the condition | |
4488 // code. We kludge this by pretending to read the condition code | |
4489 // 1 cycle earlier, and by marking the functional units as busy | |
4490 // for 2 cycles with the result available 1 cycle later than | |
4491 // is really the case. | |
4492 pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{ | |
4493 single_instruction; | |
4494 op2_out : C(write); | |
4495 op1 : R(read); | |
4496 cr : R(read); // This is really E, with a 1 cycle stall | |
4497 BR : R(2); | |
4498 MS : R(2); | |
4499 %} | |
4500 | |
4501 #ifdef _LP64 | |
4502 pipe_class ialu_clr_and_mover( iRegI dst, iRegP src ) %{ | |
4503 instruction_count(1); multiple_bundles; | |
4504 dst : C(write)+1; | |
4505 src : R(read)+1; | |
4506 IALU : R(1); | |
4507 BR : E(2); | |
4508 MS : E(2); | |
4509 %} | |
4510 #endif | |
4511 | |
4512 // Integer ALU reg operation | |
4513 pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{ | |
4514 single_instruction; may_have_no_code; | |
4515 dst : E(write); | |
4516 src : R(read); | |
4517 IALU : R; | |
4518 %} | |
4519 pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{ | |
4520 single_instruction; may_have_no_code; | |
4521 dst : E(write); | |
4522 src : R(read); | |
4523 IALU : R; | |
4524 %} | |
4525 | |
4526 // Two integer ALU reg operations | |
4527 pipe_class ialu_reg_2(iRegL dst, iRegL src) %{ | |
4528 instruction_count(2); | |
4529 dst : E(write); | |
4530 src : R(read); | |
4531 A0 : R; | |
4532 A1 : R; | |
4533 %} | |
4534 | |
4535 // Two integer ALU reg operations | |
4536 pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{ | |
4537 instruction_count(2); may_have_no_code; | |
4538 dst : E(write); | |
4539 src : R(read); | |
4540 A0 : R; | |
4541 A1 : R; | |
4542 %} | |
4543 | |
4544 // Integer ALU imm operation | |
4545 pipe_class ialu_imm(iRegI dst, immI13 src) %{ | |
4546 single_instruction; | |
4547 dst : E(write); | |
4548 IALU : R; | |
4549 %} | |
4550 | |
4551 // Integer ALU reg-reg with carry operation | |
4552 pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{ | |
4553 single_instruction; | |
4554 dst : E(write); | |
4555 src1 : R(read); | |
4556 src2 : R(read); | |
4557 IALU : R; | |
4558 %} | |
4559 | |
4560 // Integer ALU cc operation | |
4561 pipe_class ialu_cc(iRegI dst, flagsReg cc) %{ | |
4562 single_instruction; | |
4563 dst : E(write); | |
4564 cc : R(read); | |
4565 IALU : R; | |
4566 %} | |
4567 | |
4568 // Integer ALU cc / second IALU operation | |
4569 pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{ | |
4570 instruction_count(1); multiple_bundles; | |
4571 dst : E(write)+1; | |
4572 src : R(read); | |
4573 IALU : R; | |
4574 %} | |
4575 | |
4576 // Integer ALU cc / second IALU operation | |
4577 pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{ | |
4578 instruction_count(1); multiple_bundles; | |
4579 dst : E(write)+1; | |
4580 p : R(read); | |
4581 q : R(read); | |
4582 IALU : R; | |
4583 %} | |
4584 | |
4585 // Integer ALU hi-lo-reg operation | |
4586 pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{ | |
4587 instruction_count(1); multiple_bundles; | |
4588 dst : E(write)+1; | |
4589 IALU : R(2); | |
4590 %} | |
4591 | |
4592 // Float ALU hi-lo-reg operation (with temp) | |
4593 pipe_class ialu_hi_lo_reg_temp(regF dst, immF src, g3RegP tmp) %{ | |
4594 instruction_count(1); multiple_bundles; | |
4595 dst : E(write)+1; | |
4596 IALU : R(2); | |
4597 %} | |
4598 | |
4599 // Long Constant | |
4600 pipe_class loadConL( iRegL dst, immL src ) %{ | |
4601 instruction_count(2); multiple_bundles; | |
4602 dst : E(write)+1; | |
4603 IALU : R(2); | |
4604 IALU : R(2); | |
4605 %} | |
4606 | |
4607 // Pointer Constant | |
4608 pipe_class loadConP( iRegP dst, immP src ) %{ | |
4609 instruction_count(0); multiple_bundles; | |
4610 fixed_latency(6); | |
4611 %} | |
4612 | |
4613 // Polling Address | |
4614 pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{ | |
4615 #ifdef _LP64 | |
4616 instruction_count(0); multiple_bundles; | |
4617 fixed_latency(6); | |
4618 #else | |
4619 dst : E(write); | |
4620 IALU : R; | |
4621 #endif | |
4622 %} | |
4623 | |
4624 // Long Constant small | |
4625 pipe_class loadConLlo( iRegL dst, immL src ) %{ | |
4626 instruction_count(2); | |
4627 dst : E(write); | |
4628 IALU : R; | |
4629 IALU : R; | |
4630 %} | |
4631 | |
4632 // [PHH] This is wrong for 64-bit. See LdImmF/D. | |
4633 pipe_class loadConFD(regF dst, immF src, g3RegP tmp) %{ | |
4634 instruction_count(1); multiple_bundles; | |
4635 src : R(read); | |
4636 dst : M(write)+1; | |
4637 IALU : R; | |
4638 MS : E; | |
4639 %} | |
4640 | |
4641 // Integer ALU nop operation | |
4642 pipe_class ialu_nop() %{ | |
4643 single_instruction; | |
4644 IALU : R; | |
4645 %} | |
4646 | |
4647 // Integer ALU nop operation | |
4648 pipe_class ialu_nop_A0() %{ | |
4649 single_instruction; | |
4650 A0 : R; | |
4651 %} | |
4652 | |
4653 // Integer ALU nop operation | |
4654 pipe_class ialu_nop_A1() %{ | |
4655 single_instruction; | |
4656 A1 : R; | |
4657 %} | |
4658 | |
4659 // Integer Multiply reg-reg operation | |
4660 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
4661 single_instruction; | |
4662 dst : E(write); | |
4663 src1 : R(read); | |
4664 src2 : R(read); | |
4665 MS : R(5); | |
4666 %} | |
4667 | |
4668 // Integer Multiply reg-imm operation | |
4669 pipe_class imul_reg_imm(iRegI dst, iRegI src1, immI13 src2) %{ | |
4670 single_instruction; | |
4671 dst : E(write); | |
4672 src1 : R(read); | |
4673 MS : R(5); | |
4674 %} | |
4675 | |
4676 pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
4677 single_instruction; | |
4678 dst : E(write)+4; | |
4679 src1 : R(read); | |
4680 src2 : R(read); | |
4681 MS : R(6); | |
4682 %} | |
4683 | |
4684 pipe_class mulL_reg_imm(iRegL dst, iRegL src1, immL13 src2) %{ | |
4685 single_instruction; | |
4686 dst : E(write)+4; | |
4687 src1 : R(read); | |
4688 MS : R(6); | |
4689 %} | |
4690 | |
4691 // Integer Divide reg-reg | |
4692 pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{ | |
4693 instruction_count(1); multiple_bundles; | |
4694 dst : E(write); | |
4695 temp : E(write); | |
4696 src1 : R(read); | |
4697 src2 : R(read); | |
4698 temp : R(read); | |
4699 MS : R(38); | |
4700 %} | |
4701 | |
4702 // Integer Divide reg-imm | |
4703 pipe_class sdiv_reg_imm(iRegI dst, iRegI src1, immI13 src2, iRegI temp, flagsReg cr) %{ | |
4704 instruction_count(1); multiple_bundles; | |
4705 dst : E(write); | |
4706 temp : E(write); | |
4707 src1 : R(read); | |
4708 temp : R(read); | |
4709 MS : R(38); | |
4710 %} | |
4711 | |
4712 // Long Divide | |
4713 pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
4714 dst : E(write)+71; | |
4715 src1 : R(read); | |
4716 src2 : R(read)+1; | |
4717 MS : R(70); | |
4718 %} | |
4719 | |
4720 pipe_class divL_reg_imm(iRegL dst, iRegL src1, immL13 src2) %{ | |
4721 dst : E(write)+71; | |
4722 src1 : R(read); | |
4723 MS : R(70); | |
4724 %} | |
4725 | |
4726 // Floating Point Add Float | |
4727 pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{ | |
4728 single_instruction; | |
4729 dst : X(write); | |
4730 src1 : E(read); | |
4731 src2 : E(read); | |
4732 FA : R; | |
4733 %} | |
4734 | |
4735 // Floating Point Add Double | |
4736 pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{ | |
4737 single_instruction; | |
4738 dst : X(write); | |
4739 src1 : E(read); | |
4740 src2 : E(read); | |
4741 FA : R; | |
4742 %} | |
4743 | |
4744 // Floating Point Conditional Move based on integer flags | |
4745 pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{ | |
4746 single_instruction; | |
4747 dst : X(write); | |
4748 src : E(read); | |
4749 cr : R(read); | |
4750 FA : R(2); | |
4751 BR : R(2); | |
4752 %} | |
4753 | |
4754 // Floating Point Conditional Move based on integer flags | |
4755 pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{ | |
4756 single_instruction; | |
4757 dst : X(write); | |
4758 src : E(read); | |
4759 cr : R(read); | |
4760 FA : R(2); | |
4761 BR : R(2); | |
4762 %} | |
4763 | |
4764 // Floating Point Multiply Float | |
4765 pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{ | |
4766 single_instruction; | |
4767 dst : X(write); | |
4768 src1 : E(read); | |
4769 src2 : E(read); | |
4770 FM : R; | |
4771 %} | |
4772 | |
4773 // Floating Point Multiply Double | |
4774 pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{ | |
4775 single_instruction; | |
4776 dst : X(write); | |
4777 src1 : E(read); | |
4778 src2 : E(read); | |
4779 FM : R; | |
4780 %} | |
4781 | |
4782 // Floating Point Divide Float | |
4783 pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{ | |
4784 single_instruction; | |
4785 dst : X(write); | |
4786 src1 : E(read); | |
4787 src2 : E(read); | |
4788 FM : R; | |
4789 FDIV : C(14); | |
4790 %} | |
4791 | |
4792 // Floating Point Divide Double | |
4793 pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{ | |
4794 single_instruction; | |
4795 dst : X(write); | |
4796 src1 : E(read); | |
4797 src2 : E(read); | |
4798 FM : R; | |
4799 FDIV : C(17); | |
4800 %} | |
4801 | |
4802 // Floating Point Move/Negate/Abs Float | |
4803 pipe_class faddF_reg(regF dst, regF src) %{ | |
4804 single_instruction; | |
4805 dst : W(write); | |
4806 src : E(read); | |
4807 FA : R(1); | |
4808 %} | |
4809 | |
4810 // Floating Point Move/Negate/Abs Double | |
4811 pipe_class faddD_reg(regD dst, regD src) %{ | |
4812 single_instruction; | |
4813 dst : W(write); | |
4814 src : E(read); | |
4815 FA : R; | |
4816 %} | |
4817 | |
4818 // Floating Point Convert F->D | |
4819 pipe_class fcvtF2D(regD dst, regF src) %{ | |
4820 single_instruction; | |
4821 dst : X(write); | |
4822 src : E(read); | |
4823 FA : R; | |
4824 %} | |
4825 | |
4826 // Floating Point Convert I->D | |
4827 pipe_class fcvtI2D(regD dst, regF src) %{ | |
4828 single_instruction; | |
4829 dst : X(write); | |
4830 src : E(read); | |
4831 FA : R; | |
4832 %} | |
4833 | |
4834 // Floating Point Convert LHi->D | |
4835 pipe_class fcvtLHi2D(regD dst, regD src) %{ | |
4836 single_instruction; | |
4837 dst : X(write); | |
4838 src : E(read); | |
4839 FA : R; | |
4840 %} | |
4841 | |
4842 // Floating Point Convert L->D | |
4843 pipe_class fcvtL2D(regD dst, regF src) %{ | |
4844 single_instruction; | |
4845 dst : X(write); | |
4846 src : E(read); | |
4847 FA : R; | |
4848 %} | |
4849 | |
4850 // Floating Point Convert L->F | |
4851 pipe_class fcvtL2F(regD dst, regF src) %{ | |
4852 single_instruction; | |
4853 dst : X(write); | |
4854 src : E(read); | |
4855 FA : R; | |
4856 %} | |
4857 | |
4858 // Floating Point Convert D->F | |
4859 pipe_class fcvtD2F(regD dst, regF src) %{ | |
4860 single_instruction; | |
4861 dst : X(write); | |
4862 src : E(read); | |
4863 FA : R; | |
4864 %} | |
4865 | |
4866 // Floating Point Convert I->L | |
4867 pipe_class fcvtI2L(regD dst, regF src) %{ | |
4868 single_instruction; | |
4869 dst : X(write); | |
4870 src : E(read); | |
4871 FA : R; | |
4872 %} | |
4873 | |
4874 // Floating Point Convert D->F | |
4875 pipe_class fcvtD2I(regF dst, regD src, flagsReg cr) %{ | |
4876 instruction_count(1); multiple_bundles; | |
4877 dst : X(write)+6; | |
4878 src : E(read); | |
4879 FA : R; | |
4880 %} | |
4881 | |
4882 // Floating Point Convert D->L | |
4883 pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{ | |
4884 instruction_count(1); multiple_bundles; | |
4885 dst : X(write)+6; | |
4886 src : E(read); | |
4887 FA : R; | |
4888 %} | |
4889 | |
4890 // Floating Point Convert F->I | |
4891 pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{ | |
4892 instruction_count(1); multiple_bundles; | |
4893 dst : X(write)+6; | |
4894 src : E(read); | |
4895 FA : R; | |
4896 %} | |
4897 | |
4898 // Floating Point Convert F->L | |
4899 pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{ | |
4900 instruction_count(1); multiple_bundles; | |
4901 dst : X(write)+6; | |
4902 src : E(read); | |
4903 FA : R; | |
4904 %} | |
4905 | |
4906 // Floating Point Convert I->F | |
4907 pipe_class fcvtI2F(regF dst, regF src) %{ | |
4908 single_instruction; | |
4909 dst : X(write); | |
4910 src : E(read); | |
4911 FA : R; | |
4912 %} | |
4913 | |
4914 // Floating Point Compare | |
4915 pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{ | |
4916 single_instruction; | |
4917 cr : X(write); | |
4918 src1 : E(read); | |
4919 src2 : E(read); | |
4920 FA : R; | |
4921 %} | |
4922 | |
4923 // Floating Point Compare | |
4924 pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{ | |
4925 single_instruction; | |
4926 cr : X(write); | |
4927 src1 : E(read); | |
4928 src2 : E(read); | |
4929 FA : R; | |
4930 %} | |
4931 | |
4932 // Floating Add Nop | |
4933 pipe_class fadd_nop() %{ | |
4934 single_instruction; | |
4935 FA : R; | |
4936 %} | |
4937 | |
4938 // Integer Store to Memory | |
4939 pipe_class istore_mem_reg(memory mem, iRegI src) %{ | |
4940 single_instruction; | |
4941 mem : R(read); | |
4942 src : C(read); | |
4943 MS : R; | |
4944 %} | |
4945 | |
4946 // Integer Store to Memory | |
4947 pipe_class istore_mem_spORreg(memory mem, sp_ptr_RegP src) %{ | |
4948 single_instruction; | |
4949 mem : R(read); | |
4950 src : C(read); | |
4951 MS : R; | |
4952 %} | |
4953 | |
4954 // Integer Store Zero to Memory | |
4955 pipe_class istore_mem_zero(memory mem, immI0 src) %{ | |
4956 single_instruction; | |
4957 mem : R(read); | |
4958 MS : R; | |
4959 %} | |
4960 | |
4961 // Special Stack Slot Store | |
4962 pipe_class istore_stk_reg(stackSlotI stkSlot, iRegI src) %{ | |
4963 single_instruction; | |
4964 stkSlot : R(read); | |
4965 src : C(read); | |
4966 MS : R; | |
4967 %} | |
4968 | |
4969 // Special Stack Slot Store | |
4970 pipe_class lstoreI_stk_reg(stackSlotL stkSlot, iRegI src) %{ | |
4971 instruction_count(2); multiple_bundles; | |
4972 stkSlot : R(read); | |
4973 src : C(read); | |
4974 MS : R(2); | |
4975 %} | |
4976 | |
4977 // Float Store | |
4978 pipe_class fstoreF_mem_reg(memory mem, RegF src) %{ | |
4979 single_instruction; | |
4980 mem : R(read); | |
4981 src : C(read); | |
4982 MS : R; | |
4983 %} | |
4984 | |
4985 // Float Store | |
4986 pipe_class fstoreF_mem_zero(memory mem, immF0 src) %{ | |
4987 single_instruction; | |
4988 mem : R(read); | |
4989 MS : R; | |
4990 %} | |
4991 | |
4992 // Double Store | |
4993 pipe_class fstoreD_mem_reg(memory mem, RegD src) %{ | |
4994 instruction_count(1); | |
4995 mem : R(read); | |
4996 src : C(read); | |
4997 MS : R; | |
4998 %} | |
4999 | |
5000 // Double Store | |
5001 pipe_class fstoreD_mem_zero(memory mem, immD0 src) %{ | |
5002 single_instruction; | |
5003 mem : R(read); | |
5004 MS : R; | |
5005 %} | |
5006 | |
5007 // Special Stack Slot Float Store | |
5008 pipe_class fstoreF_stk_reg(stackSlotI stkSlot, RegF src) %{ | |
5009 single_instruction; | |
5010 stkSlot : R(read); | |
5011 src : C(read); | |
5012 MS : R; | |
5013 %} | |
5014 | |
5015 // Special Stack Slot Double Store | |
5016 pipe_class fstoreD_stk_reg(stackSlotI stkSlot, RegD src) %{ | |
5017 single_instruction; | |
5018 stkSlot : R(read); | |
5019 src : C(read); | |
5020 MS : R; | |
5021 %} | |
5022 | |
5023 // Integer Load (when sign bit propagation not needed) | |
5024 pipe_class iload_mem(iRegI dst, memory mem) %{ | |
5025 single_instruction; | |
5026 mem : R(read); | |
5027 dst : C(write); | |
5028 MS : R; | |
5029 %} | |
5030 | |
5031 // Integer Load from stack operand | |
5032 pipe_class iload_stkD(iRegI dst, stackSlotD mem ) %{ | |
5033 single_instruction; | |
5034 mem : R(read); | |
5035 dst : C(write); | |
5036 MS : R; | |
5037 %} | |
5038 | |
5039 // Integer Load (when sign bit propagation or masking is needed) | |
5040 pipe_class iload_mask_mem(iRegI dst, memory mem) %{ | |
5041 single_instruction; | |
5042 mem : R(read); | |
5043 dst : M(write); | |
5044 MS : R; | |
5045 %} | |
5046 | |
5047 // Float Load | |
5048 pipe_class floadF_mem(regF dst, memory mem) %{ | |
5049 single_instruction; | |
5050 mem : R(read); | |
5051 dst : M(write); | |
5052 MS : R; | |
5053 %} | |
5054 | |
5055 // Float Load | |
5056 pipe_class floadD_mem(regD dst, memory mem) %{ | |
5057 instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case | |
5058 mem : R(read); | |
5059 dst : M(write); | |
5060 MS : R; | |
5061 %} | |
5062 | |
5063 // Float Load | |
5064 pipe_class floadF_stk(regF dst, stackSlotI stkSlot) %{ | |
5065 single_instruction; | |
5066 stkSlot : R(read); | |
5067 dst : M(write); | |
5068 MS : R; | |
5069 %} | |
5070 | |
5071 // Float Load | |
5072 pipe_class floadD_stk(regD dst, stackSlotI stkSlot) %{ | |
5073 single_instruction; | |
5074 stkSlot : R(read); | |
5075 dst : M(write); | |
5076 MS : R; | |
5077 %} | |
5078 | |
5079 // Memory Nop | |
5080 pipe_class mem_nop() %{ | |
5081 single_instruction; | |
5082 MS : R; | |
5083 %} | |
5084 | |
5085 pipe_class sethi(iRegP dst, immI src) %{ | |
5086 single_instruction; | |
5087 dst : E(write); | |
5088 IALU : R; | |
5089 %} | |
5090 | |
5091 pipe_class loadPollP(iRegP poll) %{ | |
5092 single_instruction; | |
5093 poll : R(read); | |
5094 MS : R; | |
5095 %} | |
5096 | |
5097 pipe_class br(Universe br, label labl) %{ | |
5098 single_instruction_with_delay_slot; | |
5099 BR : R; | |
5100 %} | |
5101 | |
5102 pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{ | |
5103 single_instruction_with_delay_slot; | |
5104 cr : E(read); | |
5105 BR : R; | |
5106 %} | |
5107 | |
5108 pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{ | |
5109 single_instruction_with_delay_slot; | |
5110 op1 : E(read); | |
5111 BR : R; | |
5112 MS : R; | |
5113 %} | |
5114 | |
5115 pipe_class br_fcc(Universe br, cmpOpF cc, flagsReg cr, label labl) %{ | |
5116 single_instruction_with_delay_slot; | |
5117 cr : E(read); | |
5118 BR : R; | |
5119 %} | |
5120 | |
5121 pipe_class br_nop() %{ | |
5122 single_instruction; | |
5123 BR : R; | |
5124 %} | |
5125 | |
5126 pipe_class simple_call(method meth) %{ | |
5127 instruction_count(2); multiple_bundles; force_serialization; | |
5128 fixed_latency(100); | |
5129 BR : R(1); | |
5130 MS : R(1); | |
5131 A0 : R(1); | |
5132 %} | |
5133 | |
5134 pipe_class compiled_call(method meth) %{ | |
5135 instruction_count(1); multiple_bundles; force_serialization; | |
5136 fixed_latency(100); | |
5137 MS : R(1); | |
5138 %} | |
5139 | |
5140 pipe_class call(method meth) %{ | |
5141 instruction_count(0); multiple_bundles; force_serialization; | |
5142 fixed_latency(100); | |
5143 %} | |
5144 | |
5145 pipe_class tail_call(Universe ignore, label labl) %{ | |
5146 single_instruction; has_delay_slot; | |
5147 fixed_latency(100); | |
5148 BR : R(1); | |
5149 MS : R(1); | |
5150 %} | |
5151 | |
5152 pipe_class ret(Universe ignore) %{ | |
5153 single_instruction; has_delay_slot; | |
5154 BR : R(1); | |
5155 MS : R(1); | |
5156 %} | |
5157 | |
5158 pipe_class ret_poll(g3RegP poll) %{ | |
5159 instruction_count(3); has_delay_slot; | |
5160 poll : E(read); | |
5161 MS : R; | |
5162 %} | |
5163 | |
5164 // The real do-nothing guy | |
5165 pipe_class empty( ) %{ | |
5166 instruction_count(0); | |
5167 %} | |
5168 | |
5169 pipe_class long_memory_op() %{ | |
5170 instruction_count(0); multiple_bundles; force_serialization; | |
5171 fixed_latency(25); | |
5172 MS : R(1); | |
5173 %} | |
5174 | |
5175 // Check-cast | |
5176 pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{ | |
5177 array : R(read); | |
5178 match : R(read); | |
5179 IALU : R(2); | |
5180 BR : R(2); | |
5181 MS : R; | |
5182 %} | |
5183 | |
5184 // Convert FPU flags into +1,0,-1 | |
5185 pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{ | |
5186 src1 : E(read); | |
5187 src2 : E(read); | |
5188 dst : E(write); | |
5189 FA : R; | |
5190 MS : R(2); | |
5191 BR : R(2); | |
5192 %} | |
5193 | |
5194 // Compare for p < q, and conditionally add y | |
5195 pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{ | |
5196 p : E(read); | |
5197 q : E(read); | |
5198 y : E(read); | |
5199 IALU : R(3) | |
5200 %} | |
5201 | |
5202 // Perform a compare, then move conditionally in a branch delay slot. | |
5203 pipe_class min_max( iRegI src2, iRegI srcdst ) %{ | |
5204 src2 : E(read); | |
5205 srcdst : E(read); | |
5206 IALU : R; | |
5207 BR : R; | |
5208 %} | |
5209 | |
5210 // Define the class for the Nop node | |
5211 define %{ | |
5212 MachNop = ialu_nop; | |
5213 %} | |
5214 | |
5215 %} | |
5216 | |
5217 //----------INSTRUCTIONS------------------------------------------------------- | |
5218 | |
5219 //------------Special Stack Slot instructions - no match rules----------------- | |
5220 instruct stkI_to_regF(regF dst, stackSlotI src) %{ | |
5221 // No match rule to avoid chain rule match. | |
5222 effect(DEF dst, USE src); | |
5223 ins_cost(MEMORY_REF_COST); | |
5224 size(4); | |
5225 format %{ "LDF $src,$dst\t! stkI to regF" %} | |
5226 opcode(Assembler::ldf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5227 ins_encode(simple_form3_mem_reg(src, dst)); |
0 | 5228 ins_pipe(floadF_stk); |
5229 %} | |
5230 | |
5231 instruct stkL_to_regD(regD dst, stackSlotL src) %{ | |
5232 // No match rule to avoid chain rule match. | |
5233 effect(DEF dst, USE src); | |
5234 ins_cost(MEMORY_REF_COST); | |
5235 size(4); | |
5236 format %{ "LDDF $src,$dst\t! stkL to regD" %} | |
5237 opcode(Assembler::lddf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5238 ins_encode(simple_form3_mem_reg(src, dst)); |
0 | 5239 ins_pipe(floadD_stk); |
5240 %} | |
5241 | |
5242 instruct regF_to_stkI(stackSlotI dst, regF src) %{ | |
5243 // No match rule to avoid chain rule match. | |
5244 effect(DEF dst, USE src); | |
5245 ins_cost(MEMORY_REF_COST); | |
5246 size(4); | |
5247 format %{ "STF $src,$dst\t! regF to stkI" %} | |
5248 opcode(Assembler::stf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5249 ins_encode(simple_form3_mem_reg(dst, src)); |
0 | 5250 ins_pipe(fstoreF_stk_reg); |
5251 %} | |
5252 | |
5253 instruct regD_to_stkL(stackSlotL dst, regD src) %{ | |
5254 // No match rule to avoid chain rule match. | |
5255 effect(DEF dst, USE src); | |
5256 ins_cost(MEMORY_REF_COST); | |
5257 size(4); | |
5258 format %{ "STDF $src,$dst\t! regD to stkL" %} | |
5259 opcode(Assembler::stdf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5260 ins_encode(simple_form3_mem_reg(dst, src)); |
0 | 5261 ins_pipe(fstoreD_stk_reg); |
5262 %} | |
5263 | |
5264 instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{ | |
5265 effect(DEF dst, USE src); | |
5266 ins_cost(MEMORY_REF_COST*2); | |
5267 size(8); | |
5268 format %{ "STW $src,$dst.hi\t! long\n\t" | |
5269 "STW R_G0,$dst.lo" %} | |
5270 opcode(Assembler::stw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5271 ins_encode(simple_form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0)); |
0 | 5272 ins_pipe(lstoreI_stk_reg); |
5273 %} | |
5274 | |
5275 instruct regL_to_stkD(stackSlotD dst, iRegL src) %{ | |
5276 // No match rule to avoid chain rule match. | |
5277 effect(DEF dst, USE src); | |
5278 ins_cost(MEMORY_REF_COST); | |
5279 size(4); | |
5280 format %{ "STX $src,$dst\t! regL to stkD" %} | |
5281 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5282 ins_encode(simple_form3_mem_reg( dst, src ) ); |
0 | 5283 ins_pipe(istore_stk_reg); |
5284 %} | |
5285 | |
5286 //---------- Chain stack slots between similar types -------- | |
5287 | |
5288 // Load integer from stack slot | |
5289 instruct stkI_to_regI( iRegI dst, stackSlotI src ) %{ | |
5290 match(Set dst src); | |
5291 ins_cost(MEMORY_REF_COST); | |
5292 | |
5293 size(4); | |
5294 format %{ "LDUW $src,$dst\t!stk" %} | |
5295 opcode(Assembler::lduw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5296 ins_encode(simple_form3_mem_reg( src, dst ) ); |
0 | 5297 ins_pipe(iload_mem); |
5298 %} | |
5299 | |
5300 // Store integer to stack slot | |
5301 instruct regI_to_stkI( stackSlotI dst, iRegI src ) %{ | |
5302 match(Set dst src); | |
5303 ins_cost(MEMORY_REF_COST); | |
5304 | |
5305 size(4); | |
5306 format %{ "STW $src,$dst\t!stk" %} | |
5307 opcode(Assembler::stw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5308 ins_encode(simple_form3_mem_reg( dst, src ) ); |
0 | 5309 ins_pipe(istore_mem_reg); |
5310 %} | |
5311 | |
5312 // Load long from stack slot | |
5313 instruct stkL_to_regL( iRegL dst, stackSlotL src ) %{ | |
5314 match(Set dst src); | |
5315 | |
5316 ins_cost(MEMORY_REF_COST); | |
5317 size(4); | |
5318 format %{ "LDX $src,$dst\t! long" %} | |
5319 opcode(Assembler::ldx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5320 ins_encode(simple_form3_mem_reg( src, dst ) ); |
0 | 5321 ins_pipe(iload_mem); |
5322 %} | |
5323 | |
5324 // Store long to stack slot | |
5325 instruct regL_to_stkL(stackSlotL dst, iRegL src) %{ | |
5326 match(Set dst src); | |
5327 | |
5328 ins_cost(MEMORY_REF_COST); | |
5329 size(4); | |
5330 format %{ "STX $src,$dst\t! long" %} | |
5331 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5332 ins_encode(simple_form3_mem_reg( dst, src ) ); |
0 | 5333 ins_pipe(istore_mem_reg); |
5334 %} | |
5335 | |
5336 #ifdef _LP64 | |
5337 // Load pointer from stack slot, 64-bit encoding | |
5338 instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{ | |
5339 match(Set dst src); | |
5340 ins_cost(MEMORY_REF_COST); | |
5341 size(4); | |
5342 format %{ "LDX $src,$dst\t!ptr" %} | |
5343 opcode(Assembler::ldx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5344 ins_encode(simple_form3_mem_reg( src, dst ) ); |
0 | 5345 ins_pipe(iload_mem); |
5346 %} | |
5347 | |
5348 // Store pointer to stack slot | |
5349 instruct regP_to_stkP(stackSlotP dst, iRegP src) %{ | |
5350 match(Set dst src); | |
5351 ins_cost(MEMORY_REF_COST); | |
5352 size(4); | |
5353 format %{ "STX $src,$dst\t!ptr" %} | |
5354 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5355 ins_encode(simple_form3_mem_reg( dst, src ) ); |
0 | 5356 ins_pipe(istore_mem_reg); |
5357 %} | |
5358 #else // _LP64 | |
5359 // Load pointer from stack slot, 32-bit encoding | |
5360 instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{ | |
5361 match(Set dst src); | |
5362 ins_cost(MEMORY_REF_COST); | |
5363 format %{ "LDUW $src,$dst\t!ptr" %} | |
5364 opcode(Assembler::lduw_op3, Assembler::ldst_op); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5365 ins_encode(simple_form3_mem_reg( src, dst ) ); |
0 | 5366 ins_pipe(iload_mem); |
5367 %} | |
5368 | |
5369 // Store pointer to stack slot | |
5370 instruct regP_to_stkP(stackSlotP dst, iRegP src) %{ | |
5371 match(Set dst src); | |
5372 ins_cost(MEMORY_REF_COST); | |
5373 format %{ "STW $src,$dst\t!ptr" %} | |
5374 opcode(Assembler::stw_op3, Assembler::ldst_op); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5375 ins_encode(simple_form3_mem_reg( dst, src ) ); |
0 | 5376 ins_pipe(istore_mem_reg); |
5377 %} | |
5378 #endif // _LP64 | |
5379 | |
5380 //------------Special Nop instructions for bundling - no match rules----------- | |
5381 // Nop using the A0 functional unit | |
5382 instruct Nop_A0() %{ | |
5383 ins_cost(0); | |
5384 | |
5385 format %{ "NOP ! Alu Pipeline" %} | |
5386 opcode(Assembler::or_op3, Assembler::arith_op); | |
5387 ins_encode( form2_nop() ); | |
5388 ins_pipe(ialu_nop_A0); | |
5389 %} | |
5390 | |
5391 // Nop using the A1 functional unit | |
5392 instruct Nop_A1( ) %{ | |
5393 ins_cost(0); | |
5394 | |
5395 format %{ "NOP ! Alu Pipeline" %} | |
5396 opcode(Assembler::or_op3, Assembler::arith_op); | |
5397 ins_encode( form2_nop() ); | |
5398 ins_pipe(ialu_nop_A1); | |
5399 %} | |
5400 | |
5401 // Nop using the memory functional unit | |
5402 instruct Nop_MS( ) %{ | |
5403 ins_cost(0); | |
5404 | |
5405 format %{ "NOP ! Memory Pipeline" %} | |
5406 ins_encode( emit_mem_nop ); | |
5407 ins_pipe(mem_nop); | |
5408 %} | |
5409 | |
5410 // Nop using the floating add functional unit | |
5411 instruct Nop_FA( ) %{ | |
5412 ins_cost(0); | |
5413 | |
5414 format %{ "NOP ! Floating Add Pipeline" %} | |
5415 ins_encode( emit_fadd_nop ); | |
5416 ins_pipe(fadd_nop); | |
5417 %} | |
5418 | |
5419 // Nop using the branch functional unit | |
5420 instruct Nop_BR( ) %{ | |
5421 ins_cost(0); | |
5422 | |
5423 format %{ "NOP ! Branch Pipeline" %} | |
5424 ins_encode( emit_br_nop ); | |
5425 ins_pipe(br_nop); | |
5426 %} | |
5427 | |
5428 //----------Load/Store/Move Instructions--------------------------------------- | |
5429 //----------Load Instructions-------------------------------------------------- | |
5430 // Load Byte (8bit signed) | |
5431 instruct loadB(iRegI dst, memory mem) %{ | |
5432 match(Set dst (LoadB mem)); | |
5433 ins_cost(MEMORY_REF_COST); | |
5434 | |
5435 size(4); | |
624 | 5436 format %{ "LDSB $mem,$dst\t! byte" %} |
727 | 5437 ins_encode %{ |
5438 __ ldsb($mem$$Address, $dst$$Register); | |
5439 %} | |
624 | 5440 ins_pipe(iload_mask_mem); |
5441 %} | |
5442 | |
5443 // Load Byte (8bit signed) into a Long Register | |
5444 instruct loadB2L(iRegL dst, memory mem) %{ | |
5445 match(Set dst (ConvI2L (LoadB mem))); | |
5446 ins_cost(MEMORY_REF_COST); | |
5447 | |
5448 size(4); | |
5449 format %{ "LDSB $mem,$dst\t! byte -> long" %} | |
727 | 5450 ins_encode %{ |
5451 __ ldsb($mem$$Address, $dst$$Register); | |
5452 %} | |
0 | 5453 ins_pipe(iload_mask_mem); |
5454 %} | |
5455 | |
624 | 5456 // Load Unsigned Byte (8bit UNsigned) into an int reg |
5457 instruct loadUB(iRegI dst, memory mem) %{ | |
5458 match(Set dst (LoadUB mem)); | |
0 | 5459 ins_cost(MEMORY_REF_COST); |
5460 | |
5461 size(4); | |
624 | 5462 format %{ "LDUB $mem,$dst\t! ubyte" %} |
727 | 5463 ins_encode %{ |
5464 __ ldub($mem$$Address, $dst$$Register); | |
5465 %} | |
824 | 5466 ins_pipe(iload_mem); |
624 | 5467 %} |
5468 | |
5469 // Load Unsigned Byte (8bit UNsigned) into a Long Register | |
5470 instruct loadUB2L(iRegL dst, memory mem) %{ | |
5471 match(Set dst (ConvI2L (LoadUB mem))); | |
5472 ins_cost(MEMORY_REF_COST); | |
5473 | |
5474 size(4); | |
5475 format %{ "LDUB $mem,$dst\t! ubyte -> long" %} | |
727 | 5476 ins_encode %{ |
5477 __ ldub($mem$$Address, $dst$$Register); | |
5478 %} | |
824 | 5479 ins_pipe(iload_mem); |
5480 %} | |
5481 | |
5482 // Load Unsigned Byte (8 bit UNsigned) with 8-bit mask into Long Register | |
5483 instruct loadUB2L_immI8(iRegL dst, memory mem, immI8 mask) %{ | |
5484 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); | |
5485 ins_cost(MEMORY_REF_COST + DEFAULT_COST); | |
5486 | |
5487 size(2*4); | |
5488 format %{ "LDUB $mem,$dst\t# ubyte & 8-bit mask -> long\n\t" | |
5489 "AND $dst,$mask,$dst" %} | |
5490 ins_encode %{ | |
5491 __ ldub($mem$$Address, $dst$$Register); | |
5492 __ and3($dst$$Register, $mask$$constant, $dst$$Register); | |
5493 %} | |
5494 ins_pipe(iload_mem); | |
0 | 5495 %} |
5496 | |
624 | 5497 // Load Short (16bit signed) |
5498 instruct loadS(iRegI dst, memory mem) %{ | |
5499 match(Set dst (LoadS mem)); | |
5500 ins_cost(MEMORY_REF_COST); | |
5501 | |
5502 size(4); | |
5503 format %{ "LDSH $mem,$dst\t! short" %} | |
727 | 5504 ins_encode %{ |
5505 __ ldsh($mem$$Address, $dst$$Register); | |
5506 %} | |
624 | 5507 ins_pipe(iload_mask_mem); |
5508 %} | |
5509 | |
785 | 5510 // Load Short (16 bit signed) to Byte (8 bit signed) |
5511 instruct loadS2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{ | |
5512 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); | |
5513 ins_cost(MEMORY_REF_COST); | |
5514 | |
5515 size(4); | |
5516 | |
5517 format %{ "LDSB $mem+1,$dst\t! short -> byte" %} | |
5518 ins_encode %{ | |
5519 __ ldsb($mem$$Address, $dst$$Register, 1); | |
5520 %} | |
5521 ins_pipe(iload_mask_mem); | |
5522 %} | |
5523 | |
624 | 5524 // Load Short (16bit signed) into a Long Register |
5525 instruct loadS2L(iRegL dst, memory mem) %{ | |
5526 match(Set dst (ConvI2L (LoadS mem))); | |
0 | 5527 ins_cost(MEMORY_REF_COST); |
5528 | |
5529 size(4); | |
624 | 5530 format %{ "LDSH $mem,$dst\t! short -> long" %} |
727 | 5531 ins_encode %{ |
5532 __ ldsh($mem$$Address, $dst$$Register); | |
5533 %} | |
624 | 5534 ins_pipe(iload_mask_mem); |
5535 %} | |
5536 | |
5537 // Load Unsigned Short/Char (16bit UNsigned) | |
5538 instruct loadUS(iRegI dst, memory mem) %{ | |
5539 match(Set dst (LoadUS mem)); | |
5540 ins_cost(MEMORY_REF_COST); | |
5541 | |
5542 size(4); | |
5543 format %{ "LDUH $mem,$dst\t! ushort/char" %} | |
727 | 5544 ins_encode %{ |
5545 __ lduh($mem$$Address, $dst$$Register); | |
5546 %} | |
824 | 5547 ins_pipe(iload_mem); |
0 | 5548 %} |
5549 | |
785 | 5550 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) |
5551 instruct loadUS2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{ | |
5552 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); | |
5553 ins_cost(MEMORY_REF_COST); | |
5554 | |
5555 size(4); | |
5556 format %{ "LDSB $mem+1,$dst\t! ushort -> byte" %} | |
5557 ins_encode %{ | |
5558 __ ldsb($mem$$Address, $dst$$Register, 1); | |
5559 %} | |
5560 ins_pipe(iload_mask_mem); | |
5561 %} | |
5562 | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
551
diff
changeset
|
5563 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register |
624 | 5564 instruct loadUS2L(iRegL dst, memory mem) %{ |
5565 match(Set dst (ConvI2L (LoadUS mem))); | |
0 | 5566 ins_cost(MEMORY_REF_COST); |
5567 | |
5568 size(4); | |
624 | 5569 format %{ "LDUH $mem,$dst\t! ushort/char -> long" %} |
727 | 5570 ins_encode %{ |
5571 __ lduh($mem$$Address, $dst$$Register); | |
5572 %} | |
824 | 5573 ins_pipe(iload_mem); |
5574 %} | |
5575 | |
5576 // Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register | |
5577 instruct loadUS2L_immI_255(iRegL dst, indOffset13m7 mem, immI_255 mask) %{ | |
5578 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); | |
5579 ins_cost(MEMORY_REF_COST); | |
5580 | |
5581 size(4); | |
5582 format %{ "LDUB $mem+1,$dst\t! ushort/char & 0xFF -> long" %} | |
5583 ins_encode %{ | |
5584 __ ldub($mem$$Address, $dst$$Register, 1); // LSB is index+1 on BE | |
5585 %} | |
5586 ins_pipe(iload_mem); | |
5587 %} | |
5588 | |
5589 // Load Unsigned Short/Char (16bit UNsigned) with a 13-bit mask into a Long Register | |
5590 instruct loadUS2L_immI13(iRegL dst, memory mem, immI13 mask) %{ | |
5591 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); | |
5592 ins_cost(MEMORY_REF_COST + DEFAULT_COST); | |
5593 | |
5594 size(2*4); | |
5595 format %{ "LDUH $mem,$dst\t! ushort/char & 13-bit mask -> long\n\t" | |
5596 "AND $dst,$mask,$dst" %} | |
5597 ins_encode %{ | |
5598 Register Rdst = $dst$$Register; | |
5599 __ lduh($mem$$Address, Rdst); | |
5600 __ and3(Rdst, $mask$$constant, Rdst); | |
5601 %} | |
5602 ins_pipe(iload_mem); | |
5603 %} | |
5604 | |
5605 // Load Unsigned Short/Char (16bit UNsigned) with a 16-bit mask into a Long Register | |
5606 instruct loadUS2L_immI16(iRegL dst, memory mem, immI16 mask, iRegL tmp) %{ | |
5607 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); | |
5608 effect(TEMP dst, TEMP tmp); | |
5609 ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST); | |
5610 | |
951
1fbd5d696bf4
6875967: CTW fails with./generated/adfiles/ad_sparc.cpp:6711
twisti
parents:
824
diff
changeset
|
5611 size((3+1)*4); // set may use two instructions. |
824 | 5612 format %{ "LDUH $mem,$dst\t! ushort/char & 16-bit mask -> long\n\t" |
5613 "SET $mask,$tmp\n\t" | |
5614 "AND $dst,$tmp,$dst" %} | |
5615 ins_encode %{ | |
5616 Register Rdst = $dst$$Register; | |
5617 Register Rtmp = $tmp$$Register; | |
5618 __ lduh($mem$$Address, Rdst); | |
5619 __ set($mask$$constant, Rtmp); | |
5620 __ and3(Rdst, Rtmp, Rdst); | |
5621 %} | |
5622 ins_pipe(iload_mem); | |
0 | 5623 %} |
5624 | |
5625 // Load Integer | |
5626 instruct loadI(iRegI dst, memory mem) %{ | |
5627 match(Set dst (LoadI mem)); | |
5628 ins_cost(MEMORY_REF_COST); | |
624 | 5629 |
5630 size(4); | |
5631 format %{ "LDUW $mem,$dst\t! int" %} | |
727 | 5632 ins_encode %{ |
5633 __ lduw($mem$$Address, $dst$$Register); | |
5634 %} | |
624 | 5635 ins_pipe(iload_mem); |
5636 %} | |
5637 | |
785 | 5638 // Load Integer to Byte (8 bit signed) |
5639 instruct loadI2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{ | |
5640 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); | |
5641 ins_cost(MEMORY_REF_COST); | |
5642 | |
5643 size(4); | |
5644 | |
5645 format %{ "LDSB $mem+3,$dst\t! int -> byte" %} | |
5646 ins_encode %{ | |
5647 __ ldsb($mem$$Address, $dst$$Register, 3); | |
5648 %} | |
5649 ins_pipe(iload_mask_mem); | |
5650 %} | |
5651 | |
5652 // Load Integer to Unsigned Byte (8 bit UNsigned) | |
5653 instruct loadI2UB(iRegI dst, indOffset13m7 mem, immI_255 mask) %{ | |
5654 match(Set dst (AndI (LoadI mem) mask)); | |
5655 ins_cost(MEMORY_REF_COST); | |
5656 | |
5657 size(4); | |
5658 | |
5659 format %{ "LDUB $mem+3,$dst\t! int -> ubyte" %} | |
5660 ins_encode %{ | |
5661 __ ldub($mem$$Address, $dst$$Register, 3); | |
5662 %} | |
5663 ins_pipe(iload_mask_mem); | |
5664 %} | |
5665 | |
5666 // Load Integer to Short (16 bit signed) | |
5667 instruct loadI2S(iRegI dst, indOffset13m7 mem, immI_16 sixteen) %{ | |
5668 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); | |
5669 ins_cost(MEMORY_REF_COST); | |
5670 | |
5671 size(4); | |
5672 | |
5673 format %{ "LDSH $mem+2,$dst\t! int -> short" %} | |
5674 ins_encode %{ | |
5675 __ ldsh($mem$$Address, $dst$$Register, 2); | |
5676 %} | |
5677 ins_pipe(iload_mask_mem); | |
5678 %} | |
5679 | |
5680 // Load Integer to Unsigned Short (16 bit UNsigned) | |
5681 instruct loadI2US(iRegI dst, indOffset13m7 mem, immI_65535 mask) %{ | |
5682 match(Set dst (AndI (LoadI mem) mask)); | |
5683 ins_cost(MEMORY_REF_COST); | |
5684 | |
5685 size(4); | |
5686 | |
5687 format %{ "LDUH $mem+2,$dst\t! int -> ushort/char" %} | |
5688 ins_encode %{ | |
5689 __ lduh($mem$$Address, $dst$$Register, 2); | |
5690 %} | |
5691 ins_pipe(iload_mask_mem); | |
5692 %} | |
5693 | |
624 | 5694 // Load Integer into a Long Register |
5695 instruct loadI2L(iRegL dst, memory mem) %{ | |
5696 match(Set dst (ConvI2L (LoadI mem))); | |
5697 ins_cost(MEMORY_REF_COST); | |
5698 | |
5699 size(4); | |
5700 format %{ "LDSW $mem,$dst\t! int -> long" %} | |
727 | 5701 ins_encode %{ |
5702 __ ldsw($mem$$Address, $dst$$Register); | |
5703 %} | |
824 | 5704 ins_pipe(iload_mask_mem); |
5705 %} | |
5706 | |
5707 // Load Integer with mask 0xFF into a Long Register | |
5708 instruct loadI2L_immI_255(iRegL dst, indOffset13m7 mem, immI_255 mask) %{ | |
5709 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); | |
5710 ins_cost(MEMORY_REF_COST); | |
5711 | |
5712 size(4); | |
5713 format %{ "LDUB $mem+3,$dst\t! int & 0xFF -> long" %} | |
5714 ins_encode %{ | |
5715 __ ldub($mem$$Address, $dst$$Register, 3); // LSB is index+3 on BE | |
5716 %} | |
5717 ins_pipe(iload_mem); | |
5718 %} | |
5719 | |
5720 // Load Integer with mask 0xFFFF into a Long Register | |
5721 instruct loadI2L_immI_65535(iRegL dst, indOffset13m7 mem, immI_65535 mask) %{ | |
5722 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); | |
5723 ins_cost(MEMORY_REF_COST); | |
5724 | |
5725 size(4); | |
5726 format %{ "LDUH $mem+2,$dst\t! int & 0xFFFF -> long" %} | |
5727 ins_encode %{ | |
5728 __ lduh($mem$$Address, $dst$$Register, 2); // LSW is index+2 on BE | |
5729 %} | |
5730 ins_pipe(iload_mem); | |
5731 %} | |
5732 | |
5733 // Load Integer with a 13-bit mask into a Long Register | |
5734 instruct loadI2L_immI13(iRegL dst, memory mem, immI13 mask) %{ | |
5735 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); | |
5736 ins_cost(MEMORY_REF_COST + DEFAULT_COST); | |
5737 | |
5738 size(2*4); | |
5739 format %{ "LDUW $mem,$dst\t! int & 13-bit mask -> long\n\t" | |
5740 "AND $dst,$mask,$dst" %} | |
5741 ins_encode %{ | |
5742 Register Rdst = $dst$$Register; | |
5743 __ lduw($mem$$Address, Rdst); | |
5744 __ and3(Rdst, $mask$$constant, Rdst); | |
5745 %} | |
5746 ins_pipe(iload_mem); | |
5747 %} | |
5748 | |
5749 // Load Integer with a 32-bit mask into a Long Register | |
5750 instruct loadI2L_immI(iRegL dst, memory mem, immI mask, iRegL tmp) %{ | |
5751 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); | |
5752 effect(TEMP dst, TEMP tmp); | |
5753 ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST); | |
5754 | |
951
1fbd5d696bf4
6875967: CTW fails with./generated/adfiles/ad_sparc.cpp:6711
twisti
parents:
824
diff
changeset
|
5755 size((3+1)*4); // set may use two instructions. |
824 | 5756 format %{ "LDUW $mem,$dst\t! int & 32-bit mask -> long\n\t" |
5757 "SET $mask,$tmp\n\t" | |
5758 "AND $dst,$tmp,$dst" %} | |
5759 ins_encode %{ | |
5760 Register Rdst = $dst$$Register; | |
5761 Register Rtmp = $tmp$$Register; | |
5762 __ lduw($mem$$Address, Rdst); | |
5763 __ set($mask$$constant, Rtmp); | |
5764 __ and3(Rdst, Rtmp, Rdst); | |
5765 %} | |
624 | 5766 ins_pipe(iload_mem); |
5767 %} | |
5768 | |
5769 // Load Unsigned Integer into a Long Register | |
5770 instruct loadUI2L(iRegL dst, memory mem) %{ | |
5771 match(Set dst (LoadUI2L mem)); | |
5772 ins_cost(MEMORY_REF_COST); | |
5773 | |
5774 size(4); | |
5775 format %{ "LDUW $mem,$dst\t! uint -> long" %} | |
727 | 5776 ins_encode %{ |
5777 __ lduw($mem$$Address, $dst$$Register); | |
5778 %} | |
0 | 5779 ins_pipe(iload_mem); |
5780 %} | |
5781 | |
5782 // Load Long - aligned | |
5783 instruct loadL(iRegL dst, memory mem ) %{ | |
5784 match(Set dst (LoadL mem)); | |
5785 ins_cost(MEMORY_REF_COST); | |
624 | 5786 |
0 | 5787 size(4); |
5788 format %{ "LDX $mem,$dst\t! long" %} | |
727 | 5789 ins_encode %{ |
5790 __ ldx($mem$$Address, $dst$$Register); | |
5791 %} | |
0 | 5792 ins_pipe(iload_mem); |
5793 %} | |
5794 | |
5795 // Load Long - UNaligned | |
5796 instruct loadL_unaligned(iRegL dst, memory mem, o7RegI tmp) %{ | |
5797 match(Set dst (LoadL_unaligned mem)); | |
5798 effect(KILL tmp); | |
5799 ins_cost(MEMORY_REF_COST*2+DEFAULT_COST); | |
5800 size(16); | |
5801 format %{ "LDUW $mem+4,R_O7\t! misaligned long\n" | |
5802 "\tLDUW $mem ,$dst\n" | |
5803 "\tSLLX #32, $dst, $dst\n" | |
5804 "\tOR $dst, R_O7, $dst" %} | |
5805 opcode(Assembler::lduw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5806 ins_encode(form3_mem_reg_long_unaligned_marshal( mem, dst )); |
0 | 5807 ins_pipe(iload_mem); |
5808 %} | |
5809 | |
5810 // Load Aligned Packed Byte into a Double Register | |
5811 instruct loadA8B(regD dst, memory mem) %{ | |
5812 match(Set dst (Load8B mem)); | |
5813 ins_cost(MEMORY_REF_COST); | |
5814 size(4); | |
5815 format %{ "LDDF $mem,$dst\t! packed8B" %} | |
5816 opcode(Assembler::lddf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5817 ins_encode(simple_form3_mem_reg( mem, dst ) ); |
0 | 5818 ins_pipe(floadD_mem); |
5819 %} | |
5820 | |
5821 // Load Aligned Packed Char into a Double Register | |
5822 instruct loadA4C(regD dst, memory mem) %{ | |
5823 match(Set dst (Load4C mem)); | |
5824 ins_cost(MEMORY_REF_COST); | |
5825 size(4); | |
5826 format %{ "LDDF $mem,$dst\t! packed4C" %} | |
5827 opcode(Assembler::lddf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5828 ins_encode(simple_form3_mem_reg( mem, dst ) ); |
0 | 5829 ins_pipe(floadD_mem); |
5830 %} | |
5831 | |
5832 // Load Aligned Packed Short into a Double Register | |
5833 instruct loadA4S(regD dst, memory mem) %{ | |
5834 match(Set dst (Load4S mem)); | |
5835 ins_cost(MEMORY_REF_COST); | |
5836 size(4); | |
5837 format %{ "LDDF $mem,$dst\t! packed4S" %} | |
5838 opcode(Assembler::lddf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5839 ins_encode(simple_form3_mem_reg( mem, dst ) ); |
0 | 5840 ins_pipe(floadD_mem); |
5841 %} | |
5842 | |
5843 // Load Aligned Packed Int into a Double Register | |
5844 instruct loadA2I(regD dst, memory mem) %{ | |
5845 match(Set dst (Load2I mem)); | |
5846 ins_cost(MEMORY_REF_COST); | |
5847 size(4); | |
5848 format %{ "LDDF $mem,$dst\t! packed2I" %} | |
5849 opcode(Assembler::lddf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5850 ins_encode(simple_form3_mem_reg( mem, dst ) ); |
0 | 5851 ins_pipe(floadD_mem); |
5852 %} | |
5853 | |
5854 // Load Range | |
5855 instruct loadRange(iRegI dst, memory mem) %{ | |
5856 match(Set dst (LoadRange mem)); | |
5857 ins_cost(MEMORY_REF_COST); | |
5858 | |
5859 size(4); | |
5860 format %{ "LDUW $mem,$dst\t! range" %} | |
5861 opcode(Assembler::lduw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5862 ins_encode(simple_form3_mem_reg( mem, dst ) ); |
0 | 5863 ins_pipe(iload_mem); |
5864 %} | |
5865 | |
5866 // Load Integer into %f register (for fitos/fitod) | |
5867 instruct loadI_freg(regF dst, memory mem) %{ | |
5868 match(Set dst (LoadI mem)); | |
5869 ins_cost(MEMORY_REF_COST); | |
5870 size(4); | |
5871 | |
5872 format %{ "LDF $mem,$dst\t! for fitos/fitod" %} | |
5873 opcode(Assembler::ldf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5874 ins_encode(simple_form3_mem_reg( mem, dst ) ); |
0 | 5875 ins_pipe(floadF_mem); |
5876 %} | |
5877 | |
5878 // Load Pointer | |
5879 instruct loadP(iRegP dst, memory mem) %{ | |
5880 match(Set dst (LoadP mem)); | |
5881 ins_cost(MEMORY_REF_COST); | |
5882 size(4); | |
5883 | |
5884 #ifndef _LP64 | |
5885 format %{ "LDUW $mem,$dst\t! ptr" %} | |
727 | 5886 ins_encode %{ |
5887 __ lduw($mem$$Address, $dst$$Register); | |
5888 %} | |
0 | 5889 #else |
5890 format %{ "LDX $mem,$dst\t! ptr" %} | |
727 | 5891 ins_encode %{ |
5892 __ ldx($mem$$Address, $dst$$Register); | |
5893 %} | |
0 | 5894 #endif |
5895 ins_pipe(iload_mem); | |
5896 %} | |
5897 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5898 // Load Compressed Pointer |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5899 instruct loadN(iRegN dst, memory mem) %{ |
727 | 5900 match(Set dst (LoadN mem)); |
5901 ins_cost(MEMORY_REF_COST); | |
5902 size(4); | |
5903 | |
5904 format %{ "LDUW $mem,$dst\t! compressed ptr" %} | |
5905 ins_encode %{ | |
5906 __ lduw($mem$$Address, $dst$$Register); | |
5907 %} | |
5908 ins_pipe(iload_mem); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5909 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5910 |
0 | 5911 // Load Klass Pointer |
5912 instruct loadKlass(iRegP dst, memory mem) %{ | |
5913 match(Set dst (LoadKlass mem)); | |
5914 ins_cost(MEMORY_REF_COST); | |
5915 size(4); | |
5916 | |
5917 #ifndef _LP64 | |
5918 format %{ "LDUW $mem,$dst\t! klass ptr" %} | |
727 | 5919 ins_encode %{ |
5920 __ lduw($mem$$Address, $dst$$Register); | |
5921 %} | |
0 | 5922 #else |
5923 format %{ "LDX $mem,$dst\t! klass ptr" %} | |
727 | 5924 ins_encode %{ |
5925 __ ldx($mem$$Address, $dst$$Register); | |
5926 %} | |
0 | 5927 #endif |
5928 ins_pipe(iload_mem); | |
5929 %} | |
5930 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5931 // Load narrow Klass Pointer |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5932 instruct loadNKlass(iRegN dst, memory mem) %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
5933 match(Set dst (LoadNKlass mem)); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5934 ins_cost(MEMORY_REF_COST); |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
164
diff
changeset
|
5935 size(4); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5936 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5937 format %{ "LDUW $mem,$dst\t! compressed klass ptr" %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5938 ins_encode %{ |
727 | 5939 __ lduw($mem$$Address, $dst$$Register); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5940 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5941 ins_pipe(iload_mem); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5942 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
5943 |
0 | 5944 // Load Double |
5945 instruct loadD(regD dst, memory mem) %{ | |
5946 match(Set dst (LoadD mem)); | |
5947 ins_cost(MEMORY_REF_COST); | |
5948 | |
5949 size(4); | |
5950 format %{ "LDDF $mem,$dst" %} | |
5951 opcode(Assembler::lddf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5952 ins_encode(simple_form3_mem_reg( mem, dst ) ); |
0 | 5953 ins_pipe(floadD_mem); |
5954 %} | |
5955 | |
5956 // Load Double - UNaligned | |
5957 instruct loadD_unaligned(regD_low dst, memory mem ) %{ | |
5958 match(Set dst (LoadD_unaligned mem)); | |
5959 ins_cost(MEMORY_REF_COST*2+DEFAULT_COST); | |
5960 size(8); | |
5961 format %{ "LDF $mem ,$dst.hi\t! misaligned double\n" | |
5962 "\tLDF $mem+4,$dst.lo\t!" %} | |
5963 opcode(Assembler::ldf_op3); | |
5964 ins_encode( form3_mem_reg_double_unaligned( mem, dst )); | |
5965 ins_pipe(iload_mem); | |
5966 %} | |
5967 | |
5968 // Load Float | |
5969 instruct loadF(regF dst, memory mem) %{ | |
5970 match(Set dst (LoadF mem)); | |
5971 ins_cost(MEMORY_REF_COST); | |
5972 | |
5973 size(4); | |
5974 format %{ "LDF $mem,$dst" %} | |
5975 opcode(Assembler::ldf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
5976 ins_encode(simple_form3_mem_reg( mem, dst ) ); |
0 | 5977 ins_pipe(floadF_mem); |
5978 %} | |
5979 | |
5980 // Load Constant | |
5981 instruct loadConI( iRegI dst, immI src ) %{ | |
5982 match(Set dst src); | |
5983 ins_cost(DEFAULT_COST * 3/2); | |
5984 format %{ "SET $src,$dst" %} | |
5985 ins_encode( Set32(src, dst) ); | |
5986 ins_pipe(ialu_hi_lo_reg); | |
5987 %} | |
5988 | |
5989 instruct loadConI13( iRegI dst, immI13 src ) %{ | |
5990 match(Set dst src); | |
5991 | |
5992 size(4); | |
5993 format %{ "MOV $src,$dst" %} | |
5994 ins_encode( Set13( src, dst ) ); | |
5995 ins_pipe(ialu_imm); | |
5996 %} | |
5997 | |
5998 instruct loadConP(iRegP dst, immP src) %{ | |
5999 match(Set dst src); | |
6000 ins_cost(DEFAULT_COST * 3/2); | |
6001 format %{ "SET $src,$dst\t!ptr" %} | |
6002 // This rule does not use "expand" unlike loadConI because then | |
6003 // the result type is not known to be an Oop. An ADLC | |
6004 // enhancement will be needed to make that work - not worth it! | |
6005 | |
6006 ins_encode( SetPtr( src, dst ) ); | |
6007 ins_pipe(loadConP); | |
6008 | |
6009 %} | |
6010 | |
6011 instruct loadConP0(iRegP dst, immP0 src) %{ | |
6012 match(Set dst src); | |
6013 | |
6014 size(4); | |
6015 format %{ "CLR $dst\t!ptr" %} | |
6016 ins_encode( SetNull( dst ) ); | |
6017 ins_pipe(ialu_imm); | |
6018 %} | |
6019 | |
6020 instruct loadConP_poll(iRegP dst, immP_poll src) %{ | |
6021 match(Set dst src); | |
6022 ins_cost(DEFAULT_COST); | |
6023 format %{ "SET $src,$dst\t!ptr" %} | |
6024 ins_encode %{ | |
727 | 6025 AddressLiteral polling_page(os::get_polling_page()); |
6026 __ sethi(polling_page, reg_to_register_object($dst$$reg)); | |
0 | 6027 %} |
6028 ins_pipe(loadConP_poll); | |
6029 %} | |
6030 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6031 instruct loadConN0(iRegN dst, immN0 src) %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6032 match(Set dst src); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6033 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6034 size(4); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6035 format %{ "CLR $dst\t! compressed NULL ptr" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6036 ins_encode( SetNull( dst ) ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6037 ins_pipe(ialu_imm); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6038 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6039 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6040 instruct loadConN(iRegN dst, immN src) %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6041 match(Set dst src); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6042 ins_cost(DEFAULT_COST * 3/2); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6043 format %{ "SET $src,$dst\t! compressed ptr" %} |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6044 ins_encode %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6045 Register dst = $dst$$Register; |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6046 __ set_narrow_oop((jobject)$src$$constant, dst); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6047 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6048 ins_pipe(ialu_hi_lo_reg); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6049 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6050 |
0 | 6051 instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{ |
6052 // %%% maybe this should work like loadConD | |
6053 match(Set dst src); | |
6054 effect(KILL tmp); | |
6055 ins_cost(DEFAULT_COST * 4); | |
6056 format %{ "SET64 $src,$dst KILL $tmp\t! long" %} | |
6057 ins_encode( LdImmL(src, dst, tmp) ); | |
6058 ins_pipe(loadConL); | |
6059 %} | |
6060 | |
6061 instruct loadConL0( iRegL dst, immL0 src ) %{ | |
6062 match(Set dst src); | |
6063 ins_cost(DEFAULT_COST); | |
6064 size(4); | |
6065 format %{ "CLR $dst\t! long" %} | |
6066 ins_encode( Set13( src, dst ) ); | |
6067 ins_pipe(ialu_imm); | |
6068 %} | |
6069 | |
6070 instruct loadConL13( iRegL dst, immL13 src ) %{ | |
6071 match(Set dst src); | |
6072 ins_cost(DEFAULT_COST * 2); | |
6073 | |
6074 size(4); | |
6075 format %{ "MOV $src,$dst\t! long" %} | |
6076 ins_encode( Set13( src, dst ) ); | |
6077 ins_pipe(ialu_imm); | |
6078 %} | |
6079 | |
6080 instruct loadConF(regF dst, immF src, o7RegP tmp) %{ | |
6081 match(Set dst src); | |
6082 effect(KILL tmp); | |
6083 | |
6084 #ifdef _LP64 | |
727 | 6085 size(8*4); |
0 | 6086 #else |
727 | 6087 size(2*4); |
0 | 6088 #endif |
6089 | |
6090 format %{ "SETHI hi(&$src),$tmp\t!get float $src from table\n\t" | |
6091 "LDF [$tmp+lo(&$src)],$dst" %} | |
727 | 6092 ins_encode %{ |
6093 address float_address = __ float_constant($src$$constant); | |
6094 RelocationHolder rspec = internal_word_Relocation::spec(float_address); | |
6095 AddressLiteral addrlit(float_address, rspec); | |
6096 | |
6097 __ sethi(addrlit, $tmp$$Register); | |
6098 __ ldf(FloatRegisterImpl::S, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); | |
6099 %} | |
0 | 6100 ins_pipe(loadConFD); |
6101 %} | |
6102 | |
6103 instruct loadConD(regD dst, immD src, o7RegP tmp) %{ | |
6104 match(Set dst src); | |
6105 effect(KILL tmp); | |
6106 | |
6107 #ifdef _LP64 | |
727 | 6108 size(8*4); |
0 | 6109 #else |
727 | 6110 size(2*4); |
0 | 6111 #endif |
6112 | |
6113 format %{ "SETHI hi(&$src),$tmp\t!get double $src from table\n\t" | |
6114 "LDDF [$tmp+lo(&$src)],$dst" %} | |
727 | 6115 ins_encode %{ |
6116 address double_address = __ double_constant($src$$constant); | |
6117 RelocationHolder rspec = internal_word_Relocation::spec(double_address); | |
6118 AddressLiteral addrlit(double_address, rspec); | |
6119 | |
6120 __ sethi(addrlit, $tmp$$Register); | |
732
fb4c18a2ec66
6833573: C2 sparc: assert(c < 64 && (c & 1) == 0,"bad double float register")
never
parents:
727
diff
changeset
|
6121 // XXX This is a quick fix for 6833573. |
fb4c18a2ec66
6833573: C2 sparc: assert(c < 64 && (c & 1) == 0,"bad double float register")
never
parents:
727
diff
changeset
|
6122 //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); |
fb4c18a2ec66
6833573: C2 sparc: assert(c < 64 && (c & 1) == 0,"bad double float register")
never
parents:
727
diff
changeset
|
6123 __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec); |
727 | 6124 %} |
0 | 6125 ins_pipe(loadConFD); |
6126 %} | |
6127 | |
6128 // Prefetch instructions. | |
6129 // Must be safe to execute with invalid address (cannot fault). | |
6130 | |
6131 instruct prefetchr( memory mem ) %{ | |
6132 match( PrefetchRead mem ); | |
6133 ins_cost(MEMORY_REF_COST); | |
6134 | |
6135 format %{ "PREFETCH $mem,0\t! Prefetch read-many" %} | |
6136 opcode(Assembler::prefetch_op3); | |
6137 ins_encode( form3_mem_prefetch_read( mem ) ); | |
6138 ins_pipe(iload_mem); | |
6139 %} | |
6140 | |
6141 instruct prefetchw( memory mem ) %{ | |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6142 predicate(AllocatePrefetchStyle != 3 ); |
0 | 6143 match( PrefetchWrite mem ); |
6144 ins_cost(MEMORY_REF_COST); | |
6145 | |
6146 format %{ "PREFETCH $mem,2\t! Prefetch write-many (and read)" %} | |
6147 opcode(Assembler::prefetch_op3); | |
6148 ins_encode( form3_mem_prefetch_write( mem ) ); | |
6149 ins_pipe(iload_mem); | |
6150 %} | |
6151 | |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6152 // Use BIS instruction to prefetch. |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6153 instruct prefetchw_bis( memory mem ) %{ |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6154 predicate(AllocatePrefetchStyle == 3); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6155 match( PrefetchWrite mem ); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6156 ins_cost(MEMORY_REF_COST); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6157 |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6158 format %{ "STXA G0,$mem\t! // Block initializing store" %} |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6159 ins_encode %{ |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6160 Register base = as_Register($mem$$base); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6161 int disp = $mem$$disp; |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6162 if (disp != 0) { |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6163 __ add(base, AllocatePrefetchStepSize, base); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6164 } |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6165 __ stxa(G0, base, G0, ASI_BLK_INIT_QUAD_LDD_P); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6166 %} |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6167 ins_pipe(istore_mem_reg); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1274
diff
changeset
|
6168 %} |
0 | 6169 |
6170 //----------Store Instructions------------------------------------------------- | |
6171 // Store Byte | |
6172 instruct storeB(memory mem, iRegI src) %{ | |
6173 match(Set mem (StoreB mem src)); | |
6174 ins_cost(MEMORY_REF_COST); | |
6175 | |
6176 size(4); | |
6177 format %{ "STB $src,$mem\t! byte" %} | |
6178 opcode(Assembler::stb_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6179 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6180 ins_pipe(istore_mem_reg); |
6181 %} | |
6182 | |
6183 instruct storeB0(memory mem, immI0 src) %{ | |
6184 match(Set mem (StoreB mem src)); | |
6185 ins_cost(MEMORY_REF_COST); | |
6186 | |
6187 size(4); | |
6188 format %{ "STB $src,$mem\t! byte" %} | |
6189 opcode(Assembler::stb_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6190 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6191 ins_pipe(istore_mem_zero); |
6192 %} | |
6193 | |
6194 instruct storeCM0(memory mem, immI0 src) %{ | |
6195 match(Set mem (StoreCM mem src)); | |
6196 ins_cost(MEMORY_REF_COST); | |
6197 | |
6198 size(4); | |
6199 format %{ "STB $src,$mem\t! CMS card-mark byte 0" %} | |
6200 opcode(Assembler::stb_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6201 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6202 ins_pipe(istore_mem_zero); |
6203 %} | |
6204 | |
6205 // Store Char/Short | |
6206 instruct storeC(memory mem, iRegI src) %{ | |
6207 match(Set mem (StoreC mem src)); | |
6208 ins_cost(MEMORY_REF_COST); | |
6209 | |
6210 size(4); | |
6211 format %{ "STH $src,$mem\t! short" %} | |
6212 opcode(Assembler::sth_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6213 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6214 ins_pipe(istore_mem_reg); |
6215 %} | |
6216 | |
6217 instruct storeC0(memory mem, immI0 src) %{ | |
6218 match(Set mem (StoreC mem src)); | |
6219 ins_cost(MEMORY_REF_COST); | |
6220 | |
6221 size(4); | |
6222 format %{ "STH $src,$mem\t! short" %} | |
6223 opcode(Assembler::sth_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6224 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6225 ins_pipe(istore_mem_zero); |
6226 %} | |
6227 | |
6228 // Store Integer | |
6229 instruct storeI(memory mem, iRegI src) %{ | |
6230 match(Set mem (StoreI mem src)); | |
6231 ins_cost(MEMORY_REF_COST); | |
6232 | |
6233 size(4); | |
6234 format %{ "STW $src,$mem" %} | |
6235 opcode(Assembler::stw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6236 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6237 ins_pipe(istore_mem_reg); |
6238 %} | |
6239 | |
6240 // Store Long | |
6241 instruct storeL(memory mem, iRegL src) %{ | |
6242 match(Set mem (StoreL mem src)); | |
6243 ins_cost(MEMORY_REF_COST); | |
6244 size(4); | |
6245 format %{ "STX $src,$mem\t! long" %} | |
6246 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6247 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6248 ins_pipe(istore_mem_reg); |
6249 %} | |
6250 | |
6251 instruct storeI0(memory mem, immI0 src) %{ | |
6252 match(Set mem (StoreI mem src)); | |
6253 ins_cost(MEMORY_REF_COST); | |
6254 | |
6255 size(4); | |
6256 format %{ "STW $src,$mem" %} | |
6257 opcode(Assembler::stw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6258 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6259 ins_pipe(istore_mem_zero); |
6260 %} | |
6261 | |
6262 instruct storeL0(memory mem, immL0 src) %{ | |
6263 match(Set mem (StoreL mem src)); | |
6264 ins_cost(MEMORY_REF_COST); | |
6265 | |
6266 size(4); | |
6267 format %{ "STX $src,$mem" %} | |
6268 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6269 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6270 ins_pipe(istore_mem_zero); |
6271 %} | |
6272 | |
6273 // Store Integer from float register (used after fstoi) | |
6274 instruct storeI_Freg(memory mem, regF src) %{ | |
6275 match(Set mem (StoreI mem src)); | |
6276 ins_cost(MEMORY_REF_COST); | |
6277 | |
6278 size(4); | |
6279 format %{ "STF $src,$mem\t! after fstoi/fdtoi" %} | |
6280 opcode(Assembler::stf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6281 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6282 ins_pipe(fstoreF_mem_reg); |
6283 %} | |
6284 | |
6285 // Store Pointer | |
6286 instruct storeP(memory dst, sp_ptr_RegP src) %{ | |
6287 match(Set dst (StoreP dst src)); | |
6288 ins_cost(MEMORY_REF_COST); | |
6289 size(4); | |
6290 | |
6291 #ifndef _LP64 | |
6292 format %{ "STW $src,$dst\t! ptr" %} | |
6293 opcode(Assembler::stw_op3, 0, REGP_OP); | |
6294 #else | |
6295 format %{ "STX $src,$dst\t! ptr" %} | |
6296 opcode(Assembler::stx_op3, 0, REGP_OP); | |
6297 #endif | |
6298 ins_encode( form3_mem_reg( dst, src ) ); | |
6299 ins_pipe(istore_mem_spORreg); | |
6300 %} | |
6301 | |
6302 instruct storeP0(memory dst, immP0 src) %{ | |
6303 match(Set dst (StoreP dst src)); | |
6304 ins_cost(MEMORY_REF_COST); | |
6305 size(4); | |
6306 | |
6307 #ifndef _LP64 | |
6308 format %{ "STW $src,$dst\t! ptr" %} | |
6309 opcode(Assembler::stw_op3, 0, REGP_OP); | |
6310 #else | |
6311 format %{ "STX $src,$dst\t! ptr" %} | |
6312 opcode(Assembler::stx_op3, 0, REGP_OP); | |
6313 #endif | |
6314 ins_encode( form3_mem_reg( dst, R_G0 ) ); | |
6315 ins_pipe(istore_mem_zero); | |
6316 %} | |
6317 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6318 // Store Compressed Pointer |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6319 instruct storeN(memory dst, iRegN src) %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6320 match(Set dst (StoreN dst src)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6321 ins_cost(MEMORY_REF_COST); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6322 size(4); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6323 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6324 format %{ "STW $src,$dst\t! compressed ptr" %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6325 ins_encode %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6326 Register base = as_Register($dst$$base); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6327 Register index = as_Register($dst$$index); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6328 Register src = $src$$Register; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6329 if (index != G0) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6330 __ stw(src, base, index); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6331 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6332 __ stw(src, base, $dst$$disp); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6333 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6334 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6335 ins_pipe(istore_mem_spORreg); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6336 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6337 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6338 instruct storeN0(memory dst, immN0 src) %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6339 match(Set dst (StoreN dst src)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6340 ins_cost(MEMORY_REF_COST); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6341 size(4); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6342 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6343 format %{ "STW $src,$dst\t! compressed ptr" %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6344 ins_encode %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6345 Register base = as_Register($dst$$base); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6346 Register index = as_Register($dst$$index); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6347 if (index != G0) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6348 __ stw(0, base, index); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6349 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6350 __ stw(0, base, $dst$$disp); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6351 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6352 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6353 ins_pipe(istore_mem_zero); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6354 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6355 |
0 | 6356 // Store Double |
6357 instruct storeD( memory mem, regD src) %{ | |
6358 match(Set mem (StoreD mem src)); | |
6359 ins_cost(MEMORY_REF_COST); | |
6360 | |
6361 size(4); | |
6362 format %{ "STDF $src,$mem" %} | |
6363 opcode(Assembler::stdf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6364 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6365 ins_pipe(fstoreD_mem_reg); |
6366 %} | |
6367 | |
6368 instruct storeD0( memory mem, immD0 src) %{ | |
6369 match(Set mem (StoreD mem src)); | |
6370 ins_cost(MEMORY_REF_COST); | |
6371 | |
6372 size(4); | |
6373 format %{ "STX $src,$mem" %} | |
6374 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6375 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6376 ins_pipe(fstoreD_mem_zero); |
6377 %} | |
6378 | |
6379 // Store Float | |
6380 instruct storeF( memory mem, regF src) %{ | |
6381 match(Set mem (StoreF mem src)); | |
6382 ins_cost(MEMORY_REF_COST); | |
6383 | |
6384 size(4); | |
6385 format %{ "STF $src,$mem" %} | |
6386 opcode(Assembler::stf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6387 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6388 ins_pipe(fstoreF_mem_reg); |
6389 %} | |
6390 | |
6391 instruct storeF0( memory mem, immF0 src) %{ | |
6392 match(Set mem (StoreF mem src)); | |
6393 ins_cost(MEMORY_REF_COST); | |
6394 | |
6395 size(4); | |
6396 format %{ "STW $src,$mem\t! storeF0" %} | |
6397 opcode(Assembler::stw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6398 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6399 ins_pipe(fstoreF_mem_zero); |
6400 %} | |
6401 | |
6402 // Store Aligned Packed Bytes in Double register to memory | |
6403 instruct storeA8B(memory mem, regD src) %{ | |
6404 match(Set mem (Store8B mem src)); | |
6405 ins_cost(MEMORY_REF_COST); | |
6406 size(4); | |
6407 format %{ "STDF $src,$mem\t! packed8B" %} | |
6408 opcode(Assembler::stdf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6409 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6410 ins_pipe(fstoreD_mem_reg); |
6411 %} | |
6412 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6413 // Convert oop pointer into compressed form |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6414 instruct encodeHeapOop(iRegN dst, iRegP src) %{ |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
182
diff
changeset
|
6415 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6416 match(Set dst (EncodeP src)); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6417 format %{ "encode_heap_oop $src, $dst" %} |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6418 ins_encode %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6419 __ encode_heap_oop($src$$Register, $dst$$Register); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6420 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6421 ins_pipe(ialu_reg); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6422 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6423 |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6424 instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{ |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
182
diff
changeset
|
6425 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6426 match(Set dst (EncodeP src)); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6427 format %{ "encode_heap_oop_not_null $src, $dst" %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6428 ins_encode %{ |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6429 __ encode_heap_oop_not_null($src$$Register, $dst$$Register); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6430 %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6431 ins_pipe(ialu_reg); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6432 %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6433 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6434 instruct decodeHeapOop(iRegP dst, iRegN src) %{ |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
181
diff
changeset
|
6435 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
181
diff
changeset
|
6436 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6437 match(Set dst (DecodeN src)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6438 format %{ "decode_heap_oop $src, $dst" %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6439 ins_encode %{ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6440 __ decode_heap_oop($src$$Register, $dst$$Register); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6441 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6442 ins_pipe(ialu_reg); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6443 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6444 |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6445 instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{ |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
181
diff
changeset
|
6446 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
181
diff
changeset
|
6447 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6448 match(Set dst (DecodeN src)); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6449 format %{ "decode_heap_oop_not_null $src, $dst" %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6450 ins_encode %{ |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6451 __ decode_heap_oop_not_null($src$$Register, $dst$$Register); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6452 %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6453 ins_pipe(ialu_reg); |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6454 %} |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
6455 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
6456 |
0 | 6457 // Store Zero into Aligned Packed Bytes |
6458 instruct storeA8B0(memory mem, immI0 zero) %{ | |
6459 match(Set mem (Store8B mem zero)); | |
6460 ins_cost(MEMORY_REF_COST); | |
6461 size(4); | |
6462 format %{ "STX $zero,$mem\t! packed8B" %} | |
6463 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6464 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6465 ins_pipe(fstoreD_mem_zero); |
6466 %} | |
6467 | |
6468 // Store Aligned Packed Chars/Shorts in Double register to memory | |
6469 instruct storeA4C(memory mem, regD src) %{ | |
6470 match(Set mem (Store4C mem src)); | |
6471 ins_cost(MEMORY_REF_COST); | |
6472 size(4); | |
6473 format %{ "STDF $src,$mem\t! packed4C" %} | |
6474 opcode(Assembler::stdf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6475 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6476 ins_pipe(fstoreD_mem_reg); |
6477 %} | |
6478 | |
6479 // Store Zero into Aligned Packed Chars/Shorts | |
6480 instruct storeA4C0(memory mem, immI0 zero) %{ | |
6481 match(Set mem (Store4C mem (Replicate4C zero))); | |
6482 ins_cost(MEMORY_REF_COST); | |
6483 size(4); | |
6484 format %{ "STX $zero,$mem\t! packed4C" %} | |
6485 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6486 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6487 ins_pipe(fstoreD_mem_zero); |
6488 %} | |
6489 | |
6490 // Store Aligned Packed Ints in Double register to memory | |
6491 instruct storeA2I(memory mem, regD src) %{ | |
6492 match(Set mem (Store2I mem src)); | |
6493 ins_cost(MEMORY_REF_COST); | |
6494 size(4); | |
6495 format %{ "STDF $src,$mem\t! packed2I" %} | |
6496 opcode(Assembler::stdf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6497 ins_encode(simple_form3_mem_reg( mem, src ) ); |
0 | 6498 ins_pipe(fstoreD_mem_reg); |
6499 %} | |
6500 | |
6501 // Store Zero into Aligned Packed Ints | |
6502 instruct storeA2I0(memory mem, immI0 zero) %{ | |
6503 match(Set mem (Store2I mem zero)); | |
6504 ins_cost(MEMORY_REF_COST); | |
6505 size(4); | |
6506 format %{ "STX $zero,$mem\t! packed2I" %} | |
6507 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6508 ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); |
0 | 6509 ins_pipe(fstoreD_mem_zero); |
6510 %} | |
6511 | |
6512 | |
6513 //----------MemBar Instructions----------------------------------------------- | |
6514 // Memory barrier flavors | |
6515 | |
6516 instruct membar_acquire() %{ | |
6517 match(MemBarAcquire); | |
6518 ins_cost(4*MEMORY_REF_COST); | |
6519 | |
6520 size(0); | |
6521 format %{ "MEMBAR-acquire" %} | |
6522 ins_encode( enc_membar_acquire ); | |
6523 ins_pipe(long_memory_op); | |
6524 %} | |
6525 | |
6526 instruct membar_acquire_lock() %{ | |
6527 match(MemBarAcquire); | |
6528 predicate(Matcher::prior_fast_lock(n)); | |
6529 ins_cost(0); | |
6530 | |
6531 size(0); | |
6532 format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %} | |
6533 ins_encode( ); | |
6534 ins_pipe(empty); | |
6535 %} | |
6536 | |
6537 instruct membar_release() %{ | |
6538 match(MemBarRelease); | |
6539 ins_cost(4*MEMORY_REF_COST); | |
6540 | |
6541 size(0); | |
6542 format %{ "MEMBAR-release" %} | |
6543 ins_encode( enc_membar_release ); | |
6544 ins_pipe(long_memory_op); | |
6545 %} | |
6546 | |
6547 instruct membar_release_lock() %{ | |
6548 match(MemBarRelease); | |
6549 predicate(Matcher::post_fast_unlock(n)); | |
6550 ins_cost(0); | |
6551 | |
6552 size(0); | |
6553 format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %} | |
6554 ins_encode( ); | |
6555 ins_pipe(empty); | |
6556 %} | |
6557 | |
6558 instruct membar_volatile() %{ | |
6559 match(MemBarVolatile); | |
6560 ins_cost(4*MEMORY_REF_COST); | |
6561 | |
6562 size(4); | |
6563 format %{ "MEMBAR-volatile" %} | |
6564 ins_encode( enc_membar_volatile ); | |
6565 ins_pipe(long_memory_op); | |
6566 %} | |
6567 | |
6568 instruct unnecessary_membar_volatile() %{ | |
6569 match(MemBarVolatile); | |
6570 predicate(Matcher::post_store_load_barrier(n)); | |
6571 ins_cost(0); | |
6572 | |
6573 size(0); | |
6574 format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %} | |
6575 ins_encode( ); | |
6576 ins_pipe(empty); | |
6577 %} | |
6578 | |
6579 //----------Register Move Instructions----------------------------------------- | |
6580 instruct roundDouble_nop(regD dst) %{ | |
6581 match(Set dst (RoundDouble dst)); | |
6582 ins_cost(0); | |
6583 // SPARC results are already "rounded" (i.e., normal-format IEEE) | |
6584 ins_encode( ); | |
6585 ins_pipe(empty); | |
6586 %} | |
6587 | |
6588 | |
6589 instruct roundFloat_nop(regF dst) %{ | |
6590 match(Set dst (RoundFloat dst)); | |
6591 ins_cost(0); | |
6592 // SPARC results are already "rounded" (i.e., normal-format IEEE) | |
6593 ins_encode( ); | |
6594 ins_pipe(empty); | |
6595 %} | |
6596 | |
6597 | |
6598 // Cast Index to Pointer for unsafe natives | |
6599 instruct castX2P(iRegX src, iRegP dst) %{ | |
6600 match(Set dst (CastX2P src)); | |
6601 | |
6602 format %{ "MOV $src,$dst\t! IntX->Ptr" %} | |
6603 ins_encode( form3_g0_rs2_rd_move( src, dst ) ); | |
6604 ins_pipe(ialu_reg); | |
6605 %} | |
6606 | |
6607 // Cast Pointer to Index for unsafe natives | |
6608 instruct castP2X(iRegP src, iRegX dst) %{ | |
6609 match(Set dst (CastP2X src)); | |
6610 | |
6611 format %{ "MOV $src,$dst\t! Ptr->IntX" %} | |
6612 ins_encode( form3_g0_rs2_rd_move( src, dst ) ); | |
6613 ins_pipe(ialu_reg); | |
6614 %} | |
6615 | |
6616 instruct stfSSD(stackSlotD stkSlot, regD src) %{ | |
6617 // %%%% TO DO: Tell the coalescer that this kind of node is a copy! | |
6618 match(Set stkSlot src); // chain rule | |
6619 ins_cost(MEMORY_REF_COST); | |
6620 format %{ "STDF $src,$stkSlot\t!stk" %} | |
6621 opcode(Assembler::stdf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6622 ins_encode(simple_form3_mem_reg(stkSlot, src)); |
0 | 6623 ins_pipe(fstoreD_stk_reg); |
6624 %} | |
6625 | |
6626 instruct ldfSSD(regD dst, stackSlotD stkSlot) %{ | |
6627 // %%%% TO DO: Tell the coalescer that this kind of node is a copy! | |
6628 match(Set dst stkSlot); // chain rule | |
6629 ins_cost(MEMORY_REF_COST); | |
6630 format %{ "LDDF $stkSlot,$dst\t!stk" %} | |
6631 opcode(Assembler::lddf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6632 ins_encode(simple_form3_mem_reg(stkSlot, dst)); |
0 | 6633 ins_pipe(floadD_stk); |
6634 %} | |
6635 | |
6636 instruct stfSSF(stackSlotF stkSlot, regF src) %{ | |
6637 // %%%% TO DO: Tell the coalescer that this kind of node is a copy! | |
6638 match(Set stkSlot src); // chain rule | |
6639 ins_cost(MEMORY_REF_COST); | |
6640 format %{ "STF $src,$stkSlot\t!stk" %} | |
6641 opcode(Assembler::stf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
6642 ins_encode(simple_form3_mem_reg(stkSlot, src)); |
0 | 6643 ins_pipe(fstoreF_stk_reg); |
6644 %} | |
6645 | |
6646 //----------Conditional Move--------------------------------------------------- | |
6647 // Conditional move | |
6648 instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{ | |
6649 match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src))); | |
6650 ins_cost(150); | |
6651 format %{ "MOV$cmp $pcc,$src,$dst" %} | |
6652 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) ); | |
6653 ins_pipe(ialu_reg); | |
6654 %} | |
6655 | |
6656 instruct cmovIP_imm(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI11 src) %{ | |
6657 match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src))); | |
6658 ins_cost(140); | |
6659 format %{ "MOV$cmp $pcc,$src,$dst" %} | |
6660 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::ptr_cc)) ); | |
6661 ins_pipe(ialu_imm); | |
6662 %} | |
6663 | |
6664 instruct cmovII_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{ | |
6665 match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); | |
6666 ins_cost(150); | |
6667 size(4); | |
6668 format %{ "MOV$cmp $icc,$src,$dst" %} | |
6669 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); | |
6670 ins_pipe(ialu_reg); | |
6671 %} | |
6672 | |
6673 instruct cmovII_imm(cmpOp cmp, flagsReg icc, iRegI dst, immI11 src) %{ | |
6674 match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); | |
6675 ins_cost(140); | |
6676 size(4); | |
6677 format %{ "MOV$cmp $icc,$src,$dst" %} | |
6678 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) ); | |
6679 ins_pipe(ialu_imm); | |
6680 %} | |
6681 | |
1160
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6682 instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{ |
0 | 6683 match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); |
6684 ins_cost(150); | |
6685 size(4); | |
6686 format %{ "MOV$cmp $icc,$src,$dst" %} | |
6687 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); | |
6688 ins_pipe(ialu_reg); | |
6689 %} | |
6690 | |
1160
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6691 instruct cmovIIu_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{ |
0 | 6692 match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); |
6693 ins_cost(140); | |
6694 size(4); | |
6695 format %{ "MOV$cmp $icc,$src,$dst" %} | |
6696 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) ); | |
6697 ins_pipe(ialu_imm); | |
6698 %} | |
6699 | |
6700 instruct cmovIF_reg(cmpOpF cmp, flagsRegF fcc, iRegI dst, iRegI src) %{ | |
6701 match(Set dst (CMoveI (Binary cmp fcc) (Binary dst src))); | |
6702 ins_cost(150); | |
6703 size(4); | |
6704 format %{ "MOV$cmp $fcc,$src,$dst" %} | |
6705 ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) ); | |
6706 ins_pipe(ialu_reg); | |
6707 %} | |
6708 | |
6709 instruct cmovIF_imm(cmpOpF cmp, flagsRegF fcc, iRegI dst, immI11 src) %{ | |
6710 match(Set dst (CMoveI (Binary cmp fcc) (Binary dst src))); | |
6711 ins_cost(140); | |
6712 size(4); | |
6713 format %{ "MOV$cmp $fcc,$src,$dst" %} | |
6714 ins_encode( enc_cmov_imm_f(cmp,dst,src, fcc) ); | |
6715 ins_pipe(ialu_imm); | |
6716 %} | |
6717 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6718 // Conditional move for RegN. Only cmov(reg,reg). |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6719 instruct cmovNP_reg(cmpOpP cmp, flagsRegP pcc, iRegN dst, iRegN src) %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6720 match(Set dst (CMoveN (Binary cmp pcc) (Binary dst src))); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6721 ins_cost(150); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6722 format %{ "MOV$cmp $pcc,$src,$dst" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6723 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6724 ins_pipe(ialu_reg); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6725 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6726 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6727 // This instruction also works with CmpN so we don't need cmovNN_reg. |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6728 instruct cmovNI_reg(cmpOp cmp, flagsReg icc, iRegN dst, iRegN src) %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6729 match(Set dst (CMoveN (Binary cmp icc) (Binary dst src))); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6730 ins_cost(150); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6731 size(4); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6732 format %{ "MOV$cmp $icc,$src,$dst" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6733 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6734 ins_pipe(ialu_reg); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6735 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6736 |
1160
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6737 // This instruction also works with CmpN so we don't need cmovNN_reg. |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6738 instruct cmovNIu_reg(cmpOpU cmp, flagsRegU icc, iRegN dst, iRegN src) %{ |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6739 match(Set dst (CMoveN (Binary cmp icc) (Binary dst src))); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6740 ins_cost(150); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6741 size(4); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6742 format %{ "MOV$cmp $icc,$src,$dst" %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6743 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6744 ins_pipe(ialu_reg); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6745 %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6746 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6747 instruct cmovNF_reg(cmpOpF cmp, flagsRegF fcc, iRegN dst, iRegN src) %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6748 match(Set dst (CMoveN (Binary cmp fcc) (Binary dst src))); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6749 ins_cost(150); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6750 size(4); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6751 format %{ "MOV$cmp $fcc,$src,$dst" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6752 ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6753 ins_pipe(ialu_reg); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6754 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6755 |
0 | 6756 // Conditional move |
6757 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{ | |
6758 match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src))); | |
6759 ins_cost(150); | |
6760 format %{ "MOV$cmp $pcc,$src,$dst\t! ptr" %} | |
6761 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) ); | |
6762 ins_pipe(ialu_reg); | |
6763 %} | |
6764 | |
6765 instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{ | |
6766 match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src))); | |
6767 ins_cost(140); | |
6768 format %{ "MOV$cmp $pcc,$src,$dst\t! ptr" %} | |
6769 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::ptr_cc)) ); | |
6770 ins_pipe(ialu_imm); | |
6771 %} | |
6772 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
6773 // This instruction also works with CmpN so we don't need cmovPN_reg. |
0 | 6774 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{ |
6775 match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); | |
6776 ins_cost(150); | |
6777 | |
6778 size(4); | |
6779 format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %} | |
6780 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); | |
6781 ins_pipe(ialu_reg); | |
6782 %} | |
6783 | |
1160
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6784 instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{ |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6785 match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6786 ins_cost(150); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6787 |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6788 size(4); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6789 format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6790 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6791 ins_pipe(ialu_reg); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6792 %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6793 |
0 | 6794 instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{ |
6795 match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); | |
6796 ins_cost(140); | |
6797 | |
6798 size(4); | |
6799 format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %} | |
6800 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) ); | |
6801 ins_pipe(ialu_imm); | |
6802 %} | |
6803 | |
1160
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6804 instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{ |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6805 match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6806 ins_cost(140); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6807 |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6808 size(4); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6809 format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6810 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) ); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6811 ins_pipe(ialu_imm); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6812 %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6813 |
0 | 6814 instruct cmovPF_reg(cmpOpF cmp, flagsRegF fcc, iRegP dst, iRegP src) %{ |
6815 match(Set dst (CMoveP (Binary cmp fcc) (Binary dst src))); | |
6816 ins_cost(150); | |
6817 size(4); | |
6818 format %{ "MOV$cmp $fcc,$src,$dst" %} | |
6819 ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) ); | |
6820 ins_pipe(ialu_imm); | |
6821 %} | |
6822 | |
6823 instruct cmovPF_imm(cmpOpF cmp, flagsRegF fcc, iRegP dst, immP0 src) %{ | |
6824 match(Set dst (CMoveP (Binary cmp fcc) (Binary dst src))); | |
6825 ins_cost(140); | |
6826 size(4); | |
6827 format %{ "MOV$cmp $fcc,$src,$dst" %} | |
6828 ins_encode( enc_cmov_imm_f(cmp,dst,src, fcc) ); | |
6829 ins_pipe(ialu_imm); | |
6830 %} | |
6831 | |
6832 // Conditional move | |
6833 instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{ | |
6834 match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src))); | |
6835 ins_cost(150); | |
6836 opcode(0x101); | |
6837 format %{ "FMOVD$cmp $pcc,$src,$dst" %} | |
6838 ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::ptr_cc)) ); | |
6839 ins_pipe(int_conditional_float_move); | |
6840 %} | |
6841 | |
6842 instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{ | |
6843 match(Set dst (CMoveF (Binary cmp icc) (Binary dst src))); | |
6844 ins_cost(150); | |
6845 | |
6846 size(4); | |
6847 format %{ "FMOVS$cmp $icc,$src,$dst" %} | |
6848 opcode(0x101); | |
6849 ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) ); | |
6850 ins_pipe(int_conditional_float_move); | |
6851 %} | |
6852 | |
1160
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6853 instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{ |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6854 match(Set dst (CMoveF (Binary cmp icc) (Binary dst src))); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6855 ins_cost(150); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6856 |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6857 size(4); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6858 format %{ "FMOVS$cmp $icc,$src,$dst" %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6859 opcode(0x101); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6860 ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) ); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6861 ins_pipe(int_conditional_float_move); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6862 %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6863 |
0 | 6864 // Conditional move, |
6865 instruct cmovFF_reg(cmpOpF cmp, flagsRegF fcc, regF dst, regF src) %{ | |
6866 match(Set dst (CMoveF (Binary cmp fcc) (Binary dst src))); | |
6867 ins_cost(150); | |
6868 size(4); | |
6869 format %{ "FMOVF$cmp $fcc,$src,$dst" %} | |
6870 opcode(0x1); | |
6871 ins_encode( enc_cmovff_reg(cmp,fcc,dst,src) ); | |
6872 ins_pipe(int_conditional_double_move); | |
6873 %} | |
6874 | |
6875 // Conditional move | |
6876 instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{ | |
6877 match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src))); | |
6878 ins_cost(150); | |
6879 size(4); | |
6880 opcode(0x102); | |
6881 format %{ "FMOVD$cmp $pcc,$src,$dst" %} | |
6882 ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::ptr_cc)) ); | |
6883 ins_pipe(int_conditional_double_move); | |
6884 %} | |
6885 | |
6886 instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{ | |
6887 match(Set dst (CMoveD (Binary cmp icc) (Binary dst src))); | |
6888 ins_cost(150); | |
6889 | |
6890 size(4); | |
6891 format %{ "FMOVD$cmp $icc,$src,$dst" %} | |
6892 opcode(0x102); | |
6893 ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) ); | |
6894 ins_pipe(int_conditional_double_move); | |
6895 %} | |
6896 | |
1160
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6897 instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{ |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6898 match(Set dst (CMoveD (Binary cmp icc) (Binary dst src))); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6899 ins_cost(150); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6900 |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6901 size(4); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6902 format %{ "FMOVD$cmp $icc,$src,$dst" %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6903 opcode(0x102); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6904 ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) ); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6905 ins_pipe(int_conditional_double_move); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6906 %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6907 |
0 | 6908 // Conditional move, |
6909 instruct cmovDF_reg(cmpOpF cmp, flagsRegF fcc, regD dst, regD src) %{ | |
6910 match(Set dst (CMoveD (Binary cmp fcc) (Binary dst src))); | |
6911 ins_cost(150); | |
6912 size(4); | |
6913 format %{ "FMOVD$cmp $fcc,$src,$dst" %} | |
6914 opcode(0x2); | |
6915 ins_encode( enc_cmovff_reg(cmp,fcc,dst,src) ); | |
6916 ins_pipe(int_conditional_double_move); | |
6917 %} | |
6918 | |
6919 // Conditional move | |
6920 instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{ | |
6921 match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src))); | |
6922 ins_cost(150); | |
6923 format %{ "MOV$cmp $pcc,$src,$dst\t! long" %} | |
6924 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) ); | |
6925 ins_pipe(ialu_reg); | |
6926 %} | |
6927 | |
6928 instruct cmovLP_imm(cmpOpP cmp, flagsRegP pcc, iRegL dst, immI11 src) %{ | |
6929 match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src))); | |
6930 ins_cost(140); | |
6931 format %{ "MOV$cmp $pcc,$src,$dst\t! long" %} | |
6932 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::ptr_cc)) ); | |
6933 ins_pipe(ialu_imm); | |
6934 %} | |
6935 | |
6936 instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{ | |
6937 match(Set dst (CMoveL (Binary cmp icc) (Binary dst src))); | |
6938 ins_cost(150); | |
6939 | |
6940 size(4); | |
6941 format %{ "MOV$cmp $icc,$src,$dst\t! long" %} | |
6942 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); | |
6943 ins_pipe(ialu_reg); | |
6944 %} | |
6945 | |
6946 | |
1160
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6947 instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{ |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6948 match(Set dst (CMoveL (Binary cmp icc) (Binary dst src))); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6949 ins_cost(150); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6950 |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6951 size(4); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6952 format %{ "MOV$cmp $icc,$src,$dst\t! long" %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6953 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6954 ins_pipe(ialu_reg); |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6955 %} |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6956 |
f24201449cac
6909839: missing unsigned compare cases for some cmoves in sparc.ad
never
parents:
1137
diff
changeset
|
6957 |
0 | 6958 instruct cmovLF_reg(cmpOpF cmp, flagsRegF fcc, iRegL dst, iRegL src) %{ |
6959 match(Set dst (CMoveL (Binary cmp fcc) (Binary dst src))); | |
6960 ins_cost(150); | |
6961 | |
6962 size(4); | |
6963 format %{ "MOV$cmp $fcc,$src,$dst\t! long" %} | |
6964 ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) ); | |
6965 ins_pipe(ialu_reg); | |
6966 %} | |
6967 | |
6968 | |
6969 | |
6970 //----------OS and Locking Instructions---------------------------------------- | |
6971 | |
6972 // This name is KNOWN by the ADLC and cannot be changed. | |
6973 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type | |
6974 // for this guy. | |
6975 instruct tlsLoadP(g2RegP dst) %{ | |
6976 match(Set dst (ThreadLocal)); | |
6977 | |
6978 size(0); | |
6979 ins_cost(0); | |
6980 format %{ "# TLS is in G2" %} | |
6981 ins_encode( /*empty encoding*/ ); | |
6982 ins_pipe(ialu_none); | |
6983 %} | |
6984 | |
6985 instruct checkCastPP( iRegP dst ) %{ | |
6986 match(Set dst (CheckCastPP dst)); | |
6987 | |
6988 size(0); | |
6989 format %{ "# checkcastPP of $dst" %} | |
6990 ins_encode( /*empty encoding*/ ); | |
6991 ins_pipe(empty); | |
6992 %} | |
6993 | |
6994 | |
6995 instruct castPP( iRegP dst ) %{ | |
6996 match(Set dst (CastPP dst)); | |
6997 format %{ "# castPP of $dst" %} | |
6998 ins_encode( /*empty encoding*/ ); | |
6999 ins_pipe(empty); | |
7000 %} | |
7001 | |
7002 instruct castII( iRegI dst ) %{ | |
7003 match(Set dst (CastII dst)); | |
7004 format %{ "# castII of $dst" %} | |
7005 ins_encode( /*empty encoding*/ ); | |
7006 ins_cost(0); | |
7007 ins_pipe(empty); | |
7008 %} | |
7009 | |
7010 //----------Arithmetic Instructions-------------------------------------------- | |
7011 // Addition Instructions | |
7012 // Register Addition | |
7013 instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
7014 match(Set dst (AddI src1 src2)); | |
7015 | |
7016 size(4); | |
7017 format %{ "ADD $src1,$src2,$dst" %} | |
7018 ins_encode %{ | |
7019 __ add($src1$$Register, $src2$$Register, $dst$$Register); | |
7020 %} | |
7021 ins_pipe(ialu_reg_reg); | |
7022 %} | |
7023 | |
7024 // Immediate Addition | |
7025 instruct addI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ | |
7026 match(Set dst (AddI src1 src2)); | |
7027 | |
7028 size(4); | |
7029 format %{ "ADD $src1,$src2,$dst" %} | |
7030 opcode(Assembler::add_op3, Assembler::arith_op); | |
7031 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7032 ins_pipe(ialu_reg_imm); | |
7033 %} | |
7034 | |
7035 // Pointer Register Addition | |
7036 instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{ | |
7037 match(Set dst (AddP src1 src2)); | |
7038 | |
7039 size(4); | |
7040 format %{ "ADD $src1,$src2,$dst" %} | |
7041 opcode(Assembler::add_op3, Assembler::arith_op); | |
7042 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7043 ins_pipe(ialu_reg_reg); | |
7044 %} | |
7045 | |
7046 // Pointer Immediate Addition | |
7047 instruct addP_reg_imm13(iRegP dst, iRegP src1, immX13 src2) %{ | |
7048 match(Set dst (AddP src1 src2)); | |
7049 | |
7050 size(4); | |
7051 format %{ "ADD $src1,$src2,$dst" %} | |
7052 opcode(Assembler::add_op3, Assembler::arith_op); | |
7053 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7054 ins_pipe(ialu_reg_imm); | |
7055 %} | |
7056 | |
7057 // Long Addition | |
7058 instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
7059 match(Set dst (AddL src1 src2)); | |
7060 | |
7061 size(4); | |
7062 format %{ "ADD $src1,$src2,$dst\t! long" %} | |
7063 opcode(Assembler::add_op3, Assembler::arith_op); | |
7064 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7065 ins_pipe(ialu_reg_reg); | |
7066 %} | |
7067 | |
7068 instruct addL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ | |
7069 match(Set dst (AddL src1 con)); | |
7070 | |
7071 size(4); | |
7072 format %{ "ADD $src1,$con,$dst" %} | |
7073 opcode(Assembler::add_op3, Assembler::arith_op); | |
7074 ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); | |
7075 ins_pipe(ialu_reg_imm); | |
7076 %} | |
7077 | |
7078 //----------Conditional_store-------------------------------------------------- | |
7079 // Conditional-store of the updated heap-top. | |
7080 // Used during allocation of the shared heap. | |
7081 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. | |
7082 | |
7083 // LoadP-locked. Same as a regular pointer load when used with a compare-swap | |
7084 instruct loadPLocked(iRegP dst, memory mem) %{ | |
7085 match(Set dst (LoadPLocked mem)); | |
7086 ins_cost(MEMORY_REF_COST); | |
7087 | |
7088 #ifndef _LP64 | |
7089 size(4); | |
7090 format %{ "LDUW $mem,$dst\t! ptr" %} | |
7091 opcode(Assembler::lduw_op3, 0, REGP_OP); | |
7092 #else | |
7093 format %{ "LDX $mem,$dst\t! ptr" %} | |
7094 opcode(Assembler::ldx_op3, 0, REGP_OP); | |
7095 #endif | |
7096 ins_encode( form3_mem_reg( mem, dst ) ); | |
7097 ins_pipe(iload_mem); | |
7098 %} | |
7099 | |
7100 // LoadL-locked. Same as a regular long load when used with a compare-swap | |
7101 instruct loadLLocked(iRegL dst, memory mem) %{ | |
7102 match(Set dst (LoadLLocked mem)); | |
7103 ins_cost(MEMORY_REF_COST); | |
7104 size(4); | |
7105 format %{ "LDX $mem,$dst\t! long" %} | |
7106 opcode(Assembler::ldx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
7107 ins_encode(simple_form3_mem_reg( mem, dst ) ); |
0 | 7108 ins_pipe(iload_mem); |
7109 %} | |
7110 | |
7111 instruct storePConditional( iRegP heap_top_ptr, iRegP oldval, g3RegP newval, flagsRegP pcc ) %{ | |
7112 match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval))); | |
7113 effect( KILL newval ); | |
7114 format %{ "CASA [$heap_top_ptr],$oldval,R_G3\t! If $oldval==[$heap_top_ptr] Then store R_G3 into [$heap_top_ptr], set R_G3=[$heap_top_ptr] in any case\n\t" | |
7115 "CMP R_G3,$oldval\t\t! See if we made progress" %} | |
7116 ins_encode( enc_cas(heap_top_ptr,oldval,newval) ); | |
7117 ins_pipe( long_memory_op ); | |
7118 %} | |
7119 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7120 // Conditional-store of an int value. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7121 instruct storeIConditional( iRegP mem_ptr, iRegI oldval, g3RegI newval, flagsReg icc ) %{ |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7122 match(Set icc (StoreIConditional mem_ptr (Binary oldval newval))); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7123 effect( KILL newval ); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7124 format %{ "CASA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t" |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7125 "CMP $oldval,$newval\t\t! See if we made progress" %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7126 ins_encode( enc_cas(mem_ptr,oldval,newval) ); |
0 | 7127 ins_pipe( long_memory_op ); |
7128 %} | |
7129 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7130 // Conditional-store of a long value. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7131 instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsRegL xcc ) %{ |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7132 match(Set xcc (StoreLConditional mem_ptr (Binary oldval newval))); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7133 effect( KILL newval ); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7134 format %{ "CASXA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t" |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7135 "CMP $oldval,$newval\t\t! See if we made progress" %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7136 ins_encode( enc_cas(mem_ptr,oldval,newval) ); |
0 | 7137 ins_pipe( long_memory_op ); |
7138 %} | |
7139 | |
7140 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them | |
7141 | |
7142 instruct compareAndSwapL_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ | |
7143 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); | |
7144 effect( USE mem_ptr, KILL ccr, KILL tmp1); | |
7145 format %{ | |
7146 "MOV $newval,O7\n\t" | |
7147 "CASXA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" | |
7148 "CMP $oldval,O7\t\t! See if we made progress\n\t" | |
7149 "MOV 1,$res\n\t" | |
7150 "MOVne xcc,R_G0,$res" | |
7151 %} | |
7152 ins_encode( enc_casx(mem_ptr, oldval, newval), | |
7153 enc_lflags_ne_to_boolean(res) ); | |
7154 ins_pipe( long_memory_op ); | |
7155 %} | |
7156 | |
7157 | |
7158 instruct compareAndSwapI_bool(iRegP mem_ptr, iRegI oldval, iRegI newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ | |
7159 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); | |
7160 effect( USE mem_ptr, KILL ccr, KILL tmp1); | |
7161 format %{ | |
7162 "MOV $newval,O7\n\t" | |
7163 "CASA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" | |
7164 "CMP $oldval,O7\t\t! See if we made progress\n\t" | |
7165 "MOV 1,$res\n\t" | |
7166 "MOVne icc,R_G0,$res" | |
7167 %} | |
7168 ins_encode( enc_casi(mem_ptr, oldval, newval), | |
7169 enc_iflags_ne_to_boolean(res) ); | |
7170 ins_pipe( long_memory_op ); | |
7171 %} | |
7172 | |
7173 instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ | |
7174 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); | |
7175 effect( USE mem_ptr, KILL ccr, KILL tmp1); | |
7176 format %{ | |
7177 "MOV $newval,O7\n\t" | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
7178 "CASA_PTR [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" |
0 | 7179 "CMP $oldval,O7\t\t! See if we made progress\n\t" |
7180 "MOV 1,$res\n\t" | |
7181 "MOVne xcc,R_G0,$res" | |
7182 %} | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
7183 #ifdef _LP64 |
0 | 7184 ins_encode( enc_casx(mem_ptr, oldval, newval), |
7185 enc_lflags_ne_to_boolean(res) ); | |
7186 #else | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
7187 ins_encode( enc_casi(mem_ptr, oldval, newval), |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
7188 enc_iflags_ne_to_boolean(res) ); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
7189 #endif |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
7190 ins_pipe( long_memory_op ); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
7191 %} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
7192 |
181
823298b11afc
6709165: Tests hang or misbahve with HS 13.0-b01 on solaris-sparcv9
never
parents:
165
diff
changeset
|
7193 instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
7194 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); |
181
823298b11afc
6709165: Tests hang or misbahve with HS 13.0-b01 on solaris-sparcv9
never
parents:
165
diff
changeset
|
7195 effect( USE mem_ptr, KILL ccr, KILL tmp1); |
0 | 7196 format %{ |
7197 "MOV $newval,O7\n\t" | |
7198 "CASA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" | |
7199 "CMP $oldval,O7\t\t! See if we made progress\n\t" | |
7200 "MOV 1,$res\n\t" | |
7201 "MOVne icc,R_G0,$res" | |
7202 %} | |
181
823298b11afc
6709165: Tests hang or misbahve with HS 13.0-b01 on solaris-sparcv9
never
parents:
165
diff
changeset
|
7203 ins_encode( enc_casi(mem_ptr, oldval, newval), |
823298b11afc
6709165: Tests hang or misbahve with HS 13.0-b01 on solaris-sparcv9
never
parents:
165
diff
changeset
|
7204 enc_iflags_ne_to_boolean(res) ); |
0 | 7205 ins_pipe( long_memory_op ); |
7206 %} | |
7207 | |
7208 //--------------------- | |
7209 // Subtraction Instructions | |
7210 // Register Subtraction | |
7211 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
7212 match(Set dst (SubI src1 src2)); | |
7213 | |
7214 size(4); | |
7215 format %{ "SUB $src1,$src2,$dst" %} | |
7216 opcode(Assembler::sub_op3, Assembler::arith_op); | |
7217 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7218 ins_pipe(ialu_reg_reg); | |
7219 %} | |
7220 | |
7221 // Immediate Subtraction | |
7222 instruct subI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ | |
7223 match(Set dst (SubI src1 src2)); | |
7224 | |
7225 size(4); | |
7226 format %{ "SUB $src1,$src2,$dst" %} | |
7227 opcode(Assembler::sub_op3, Assembler::arith_op); | |
7228 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7229 ins_pipe(ialu_reg_imm); | |
7230 %} | |
7231 | |
7232 instruct subI_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{ | |
7233 match(Set dst (SubI zero src2)); | |
7234 | |
7235 size(4); | |
7236 format %{ "NEG $src2,$dst" %} | |
7237 opcode(Assembler::sub_op3, Assembler::arith_op); | |
7238 ins_encode( form3_rs1_rs2_rd( R_G0, src2, dst ) ); | |
7239 ins_pipe(ialu_zero_reg); | |
7240 %} | |
7241 | |
7242 // Long subtraction | |
7243 instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
7244 match(Set dst (SubL src1 src2)); | |
7245 | |
7246 size(4); | |
7247 format %{ "SUB $src1,$src2,$dst\t! long" %} | |
7248 opcode(Assembler::sub_op3, Assembler::arith_op); | |
7249 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7250 ins_pipe(ialu_reg_reg); | |
7251 %} | |
7252 | |
7253 // Immediate Subtraction | |
7254 instruct subL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ | |
7255 match(Set dst (SubL src1 con)); | |
7256 | |
7257 size(4); | |
7258 format %{ "SUB $src1,$con,$dst\t! long" %} | |
7259 opcode(Assembler::sub_op3, Assembler::arith_op); | |
7260 ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); | |
7261 ins_pipe(ialu_reg_imm); | |
7262 %} | |
7263 | |
7264 // Long negation | |
7265 instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2) %{ | |
7266 match(Set dst (SubL zero src2)); | |
7267 | |
7268 size(4); | |
7269 format %{ "NEG $src2,$dst\t! long" %} | |
7270 opcode(Assembler::sub_op3, Assembler::arith_op); | |
7271 ins_encode( form3_rs1_rs2_rd( R_G0, src2, dst ) ); | |
7272 ins_pipe(ialu_zero_reg); | |
7273 %} | |
7274 | |
7275 // Multiplication Instructions | |
7276 // Integer Multiplication | |
7277 // Register Multiplication | |
7278 instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
7279 match(Set dst (MulI src1 src2)); | |
7280 | |
7281 size(4); | |
7282 format %{ "MULX $src1,$src2,$dst" %} | |
7283 opcode(Assembler::mulx_op3, Assembler::arith_op); | |
7284 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7285 ins_pipe(imul_reg_reg); | |
7286 %} | |
7287 | |
7288 // Immediate Multiplication | |
7289 instruct mulI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ | |
7290 match(Set dst (MulI src1 src2)); | |
7291 | |
7292 size(4); | |
7293 format %{ "MULX $src1,$src2,$dst" %} | |
7294 opcode(Assembler::mulx_op3, Assembler::arith_op); | |
7295 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7296 ins_pipe(imul_reg_imm); | |
7297 %} | |
7298 | |
7299 instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
7300 match(Set dst (MulL src1 src2)); | |
7301 ins_cost(DEFAULT_COST * 5); | |
7302 size(4); | |
7303 format %{ "MULX $src1,$src2,$dst\t! long" %} | |
7304 opcode(Assembler::mulx_op3, Assembler::arith_op); | |
7305 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7306 ins_pipe(mulL_reg_reg); | |
7307 %} | |
7308 | |
7309 // Immediate Multiplication | |
7310 instruct mulL_reg_imm13(iRegL dst, iRegL src1, immL13 src2) %{ | |
7311 match(Set dst (MulL src1 src2)); | |
7312 ins_cost(DEFAULT_COST * 5); | |
7313 size(4); | |
7314 format %{ "MULX $src1,$src2,$dst" %} | |
7315 opcode(Assembler::mulx_op3, Assembler::arith_op); | |
7316 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7317 ins_pipe(mulL_reg_imm); | |
7318 %} | |
7319 | |
7320 // Integer Division | |
7321 // Register Division | |
7322 instruct divI_reg_reg(iRegI dst, iRegIsafe src1, iRegIsafe src2) %{ | |
7323 match(Set dst (DivI src1 src2)); | |
7324 ins_cost((2+71)*DEFAULT_COST); | |
7325 | |
7326 format %{ "SRA $src2,0,$src2\n\t" | |
7327 "SRA $src1,0,$src1\n\t" | |
7328 "SDIVX $src1,$src2,$dst" %} | |
7329 ins_encode( idiv_reg( src1, src2, dst ) ); | |
7330 ins_pipe(sdiv_reg_reg); | |
7331 %} | |
7332 | |
7333 // Immediate Division | |
7334 instruct divI_reg_imm13(iRegI dst, iRegIsafe src1, immI13 src2) %{ | |
7335 match(Set dst (DivI src1 src2)); | |
7336 ins_cost((2+71)*DEFAULT_COST); | |
7337 | |
7338 format %{ "SRA $src1,0,$src1\n\t" | |
7339 "SDIVX $src1,$src2,$dst" %} | |
7340 ins_encode( idiv_imm( src1, src2, dst ) ); | |
7341 ins_pipe(sdiv_reg_imm); | |
7342 %} | |
7343 | |
7344 //----------Div-By-10-Expansion------------------------------------------------ | |
7345 // Extract hi bits of a 32x32->64 bit multiply. | |
7346 // Expand rule only, not matched | |
7347 instruct mul_hi(iRegIsafe dst, iRegIsafe src1, iRegIsafe src2 ) %{ | |
7348 effect( DEF dst, USE src1, USE src2 ); | |
7349 format %{ "MULX $src1,$src2,$dst\t! Used in div-by-10\n\t" | |
7350 "SRLX $dst,#32,$dst\t\t! Extract only hi word of result" %} | |
7351 ins_encode( enc_mul_hi(dst,src1,src2)); | |
7352 ins_pipe(sdiv_reg_reg); | |
7353 %} | |
7354 | |
605 | 7355 // Magic constant, reciprocal of 10 |
0 | 7356 instruct loadConI_x66666667(iRegIsafe dst) %{ |
7357 effect( DEF dst ); | |
7358 | |
7359 size(8); | |
7360 format %{ "SET 0x66666667,$dst\t! Used in div-by-10" %} | |
7361 ins_encode( Set32(0x66666667, dst) ); | |
7362 ins_pipe(ialu_hi_lo_reg); | |
7363 %} | |
7364 | |
605 | 7365 // Register Shift Right Arithmetic Long by 32-63 |
0 | 7366 instruct sra_31( iRegI dst, iRegI src ) %{ |
7367 effect( DEF dst, USE src ); | |
7368 format %{ "SRA $src,31,$dst\t! Used in div-by-10" %} | |
7369 ins_encode( form3_rs1_rd_copysign_hi(src,dst) ); | |
7370 ins_pipe(ialu_reg_reg); | |
7371 %} | |
7372 | |
7373 // Arithmetic Shift Right by 8-bit immediate | |
7374 instruct sra_reg_2( iRegI dst, iRegI src ) %{ | |
7375 effect( DEF dst, USE src ); | |
7376 format %{ "SRA $src,2,$dst\t! Used in div-by-10" %} | |
7377 opcode(Assembler::sra_op3, Assembler::arith_op); | |
7378 ins_encode( form3_rs1_simm13_rd( src, 0x2, dst ) ); | |
7379 ins_pipe(ialu_reg_imm); | |
7380 %} | |
7381 | |
7382 // Integer DIV with 10 | |
7383 instruct divI_10( iRegI dst, iRegIsafe src, immI10 div ) %{ | |
7384 match(Set dst (DivI src div)); | |
7385 ins_cost((6+6)*DEFAULT_COST); | |
7386 expand %{ | |
7387 iRegIsafe tmp1; // Killed temps; | |
7388 iRegIsafe tmp2; // Killed temps; | |
7389 iRegI tmp3; // Killed temps; | |
7390 iRegI tmp4; // Killed temps; | |
7391 loadConI_x66666667( tmp1 ); // SET 0x66666667 -> tmp1 | |
7392 mul_hi( tmp2, src, tmp1 ); // MUL hibits(src * tmp1) -> tmp2 | |
7393 sra_31( tmp3, src ); // SRA src,31 -> tmp3 | |
7394 sra_reg_2( tmp4, tmp2 ); // SRA tmp2,2 -> tmp4 | |
7395 subI_reg_reg( dst,tmp4,tmp3); // SUB tmp4 - tmp3 -> dst | |
7396 %} | |
7397 %} | |
7398 | |
7399 // Register Long Division | |
7400 instruct divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
7401 match(Set dst (DivL src1 src2)); | |
7402 ins_cost(DEFAULT_COST*71); | |
7403 size(4); | |
7404 format %{ "SDIVX $src1,$src2,$dst\t! long" %} | |
7405 opcode(Assembler::sdivx_op3, Assembler::arith_op); | |
7406 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7407 ins_pipe(divL_reg_reg); | |
7408 %} | |
7409 | |
7410 // Register Long Division | |
7411 instruct divL_reg_imm13(iRegL dst, iRegL src1, immL13 src2) %{ | |
7412 match(Set dst (DivL src1 src2)); | |
7413 ins_cost(DEFAULT_COST*71); | |
7414 size(4); | |
7415 format %{ "SDIVX $src1,$src2,$dst\t! long" %} | |
7416 opcode(Assembler::sdivx_op3, Assembler::arith_op); | |
7417 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7418 ins_pipe(divL_reg_imm); | |
7419 %} | |
7420 | |
7421 // Integer Remainder | |
7422 // Register Remainder | |
7423 instruct modI_reg_reg(iRegI dst, iRegIsafe src1, iRegIsafe src2, o7RegP temp, flagsReg ccr ) %{ | |
7424 match(Set dst (ModI src1 src2)); | |
7425 effect( KILL ccr, KILL temp); | |
7426 | |
7427 format %{ "SREM $src1,$src2,$dst" %} | |
7428 ins_encode( irem_reg(src1, src2, dst, temp) ); | |
7429 ins_pipe(sdiv_reg_reg); | |
7430 %} | |
7431 | |
7432 // Immediate Remainder | |
7433 instruct modI_reg_imm13(iRegI dst, iRegIsafe src1, immI13 src2, o7RegP temp, flagsReg ccr ) %{ | |
7434 match(Set dst (ModI src1 src2)); | |
7435 effect( KILL ccr, KILL temp); | |
7436 | |
7437 format %{ "SREM $src1,$src2,$dst" %} | |
7438 ins_encode( irem_imm(src1, src2, dst, temp) ); | |
7439 ins_pipe(sdiv_reg_imm); | |
7440 %} | |
7441 | |
7442 // Register Long Remainder | |
7443 instruct divL_reg_reg_1(iRegL dst, iRegL src1, iRegL src2) %{ | |
7444 effect(DEF dst, USE src1, USE src2); | |
7445 size(4); | |
7446 format %{ "SDIVX $src1,$src2,$dst\t! long" %} | |
7447 opcode(Assembler::sdivx_op3, Assembler::arith_op); | |
7448 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7449 ins_pipe(divL_reg_reg); | |
7450 %} | |
7451 | |
7452 // Register Long Division | |
7453 instruct divL_reg_imm13_1(iRegL dst, iRegL src1, immL13 src2) %{ | |
7454 effect(DEF dst, USE src1, USE src2); | |
7455 size(4); | |
7456 format %{ "SDIVX $src1,$src2,$dst\t! long" %} | |
7457 opcode(Assembler::sdivx_op3, Assembler::arith_op); | |
7458 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7459 ins_pipe(divL_reg_imm); | |
7460 %} | |
7461 | |
7462 instruct mulL_reg_reg_1(iRegL dst, iRegL src1, iRegL src2) %{ | |
7463 effect(DEF dst, USE src1, USE src2); | |
7464 size(4); | |
7465 format %{ "MULX $src1,$src2,$dst\t! long" %} | |
7466 opcode(Assembler::mulx_op3, Assembler::arith_op); | |
7467 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7468 ins_pipe(mulL_reg_reg); | |
7469 %} | |
7470 | |
7471 // Immediate Multiplication | |
7472 instruct mulL_reg_imm13_1(iRegL dst, iRegL src1, immL13 src2) %{ | |
7473 effect(DEF dst, USE src1, USE src2); | |
7474 size(4); | |
7475 format %{ "MULX $src1,$src2,$dst" %} | |
7476 opcode(Assembler::mulx_op3, Assembler::arith_op); | |
7477 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7478 ins_pipe(mulL_reg_imm); | |
7479 %} | |
7480 | |
7481 instruct subL_reg_reg_1(iRegL dst, iRegL src1, iRegL src2) %{ | |
7482 effect(DEF dst, USE src1, USE src2); | |
7483 size(4); | |
7484 format %{ "SUB $src1,$src2,$dst\t! long" %} | |
7485 opcode(Assembler::sub_op3, Assembler::arith_op); | |
7486 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7487 ins_pipe(ialu_reg_reg); | |
7488 %} | |
7489 | |
7490 instruct subL_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{ | |
7491 effect(DEF dst, USE src1, USE src2); | |
7492 size(4); | |
7493 format %{ "SUB $src1,$src2,$dst\t! long" %} | |
7494 opcode(Assembler::sub_op3, Assembler::arith_op); | |
7495 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7496 ins_pipe(ialu_reg_reg); | |
7497 %} | |
7498 | |
7499 // Register Long Remainder | |
7500 instruct modL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
7501 match(Set dst (ModL src1 src2)); | |
7502 ins_cost(DEFAULT_COST*(71 + 6 + 1)); | |
7503 expand %{ | |
7504 iRegL tmp1; | |
7505 iRegL tmp2; | |
7506 divL_reg_reg_1(tmp1, src1, src2); | |
7507 mulL_reg_reg_1(tmp2, tmp1, src2); | |
7508 subL_reg_reg_1(dst, src1, tmp2); | |
7509 %} | |
7510 %} | |
7511 | |
7512 // Register Long Remainder | |
7513 instruct modL_reg_imm13(iRegL dst, iRegL src1, immL13 src2) %{ | |
7514 match(Set dst (ModL src1 src2)); | |
7515 ins_cost(DEFAULT_COST*(71 + 6 + 1)); | |
7516 expand %{ | |
7517 iRegL tmp1; | |
7518 iRegL tmp2; | |
7519 divL_reg_imm13_1(tmp1, src1, src2); | |
7520 mulL_reg_imm13_1(tmp2, tmp1, src2); | |
7521 subL_reg_reg_2 (dst, src1, tmp2); | |
7522 %} | |
7523 %} | |
7524 | |
7525 // Integer Shift Instructions | |
7526 // Register Shift Left | |
7527 instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
7528 match(Set dst (LShiftI src1 src2)); | |
7529 | |
7530 size(4); | |
7531 format %{ "SLL $src1,$src2,$dst" %} | |
7532 opcode(Assembler::sll_op3, Assembler::arith_op); | |
7533 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7534 ins_pipe(ialu_reg_reg); | |
7535 %} | |
7536 | |
7537 // Register Shift Left Immediate | |
7538 instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{ | |
7539 match(Set dst (LShiftI src1 src2)); | |
7540 | |
7541 size(4); | |
7542 format %{ "SLL $src1,$src2,$dst" %} | |
7543 opcode(Assembler::sll_op3, Assembler::arith_op); | |
7544 ins_encode( form3_rs1_imm5_rd( src1, src2, dst ) ); | |
7545 ins_pipe(ialu_reg_imm); | |
7546 %} | |
7547 | |
7548 // Register Shift Left | |
7549 instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{ | |
7550 match(Set dst (LShiftL src1 src2)); | |
7551 | |
7552 size(4); | |
7553 format %{ "SLLX $src1,$src2,$dst" %} | |
7554 opcode(Assembler::sllx_op3, Assembler::arith_op); | |
7555 ins_encode( form3_sd_rs1_rs2_rd( src1, src2, dst ) ); | |
7556 ins_pipe(ialu_reg_reg); | |
7557 %} | |
7558 | |
7559 // Register Shift Left Immediate | |
7560 instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{ | |
7561 match(Set dst (LShiftL src1 src2)); | |
7562 | |
7563 size(4); | |
7564 format %{ "SLLX $src1,$src2,$dst" %} | |
7565 opcode(Assembler::sllx_op3, Assembler::arith_op); | |
7566 ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) ); | |
7567 ins_pipe(ialu_reg_imm); | |
7568 %} | |
7569 | |
7570 // Register Arithmetic Shift Right | |
7571 instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
7572 match(Set dst (RShiftI src1 src2)); | |
7573 size(4); | |
7574 format %{ "SRA $src1,$src2,$dst" %} | |
7575 opcode(Assembler::sra_op3, Assembler::arith_op); | |
7576 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7577 ins_pipe(ialu_reg_reg); | |
7578 %} | |
7579 | |
7580 // Register Arithmetic Shift Right Immediate | |
7581 instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{ | |
7582 match(Set dst (RShiftI src1 src2)); | |
7583 | |
7584 size(4); | |
7585 format %{ "SRA $src1,$src2,$dst" %} | |
7586 opcode(Assembler::sra_op3, Assembler::arith_op); | |
7587 ins_encode( form3_rs1_imm5_rd( src1, src2, dst ) ); | |
7588 ins_pipe(ialu_reg_imm); | |
7589 %} | |
7590 | |
7591 // Register Shift Right Arithmatic Long | |
7592 instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{ | |
7593 match(Set dst (RShiftL src1 src2)); | |
7594 | |
7595 size(4); | |
7596 format %{ "SRAX $src1,$src2,$dst" %} | |
7597 opcode(Assembler::srax_op3, Assembler::arith_op); | |
7598 ins_encode( form3_sd_rs1_rs2_rd( src1, src2, dst ) ); | |
7599 ins_pipe(ialu_reg_reg); | |
7600 %} | |
7601 | |
7602 // Register Shift Left Immediate | |
7603 instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{ | |
7604 match(Set dst (RShiftL src1 src2)); | |
7605 | |
7606 size(4); | |
7607 format %{ "SRAX $src1,$src2,$dst" %} | |
7608 opcode(Assembler::srax_op3, Assembler::arith_op); | |
7609 ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) ); | |
7610 ins_pipe(ialu_reg_imm); | |
7611 %} | |
7612 | |
7613 // Register Shift Right | |
7614 instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
7615 match(Set dst (URShiftI src1 src2)); | |
7616 | |
7617 size(4); | |
7618 format %{ "SRL $src1,$src2,$dst" %} | |
7619 opcode(Assembler::srl_op3, Assembler::arith_op); | |
7620 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7621 ins_pipe(ialu_reg_reg); | |
7622 %} | |
7623 | |
7624 // Register Shift Right Immediate | |
7625 instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{ | |
7626 match(Set dst (URShiftI src1 src2)); | |
7627 | |
7628 size(4); | |
7629 format %{ "SRL $src1,$src2,$dst" %} | |
7630 opcode(Assembler::srl_op3, Assembler::arith_op); | |
7631 ins_encode( form3_rs1_imm5_rd( src1, src2, dst ) ); | |
7632 ins_pipe(ialu_reg_imm); | |
7633 %} | |
7634 | |
7635 // Register Shift Right | |
7636 instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{ | |
7637 match(Set dst (URShiftL src1 src2)); | |
7638 | |
7639 size(4); | |
7640 format %{ "SRLX $src1,$src2,$dst" %} | |
7641 opcode(Assembler::srlx_op3, Assembler::arith_op); | |
7642 ins_encode( form3_sd_rs1_rs2_rd( src1, src2, dst ) ); | |
7643 ins_pipe(ialu_reg_reg); | |
7644 %} | |
7645 | |
7646 // Register Shift Right Immediate | |
7647 instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{ | |
7648 match(Set dst (URShiftL src1 src2)); | |
7649 | |
7650 size(4); | |
7651 format %{ "SRLX $src1,$src2,$dst" %} | |
7652 opcode(Assembler::srlx_op3, Assembler::arith_op); | |
7653 ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) ); | |
7654 ins_pipe(ialu_reg_imm); | |
7655 %} | |
7656 | |
7657 // Register Shift Right Immediate with a CastP2X | |
7658 #ifdef _LP64 | |
7659 instruct shrP_reg_imm6(iRegL dst, iRegP src1, immU6 src2) %{ | |
7660 match(Set dst (URShiftL (CastP2X src1) src2)); | |
7661 size(4); | |
7662 format %{ "SRLX $src1,$src2,$dst\t! Cast ptr $src1 to long and shift" %} | |
7663 opcode(Assembler::srlx_op3, Assembler::arith_op); | |
7664 ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) ); | |
7665 ins_pipe(ialu_reg_imm); | |
7666 %} | |
7667 #else | |
7668 instruct shrP_reg_imm5(iRegI dst, iRegP src1, immU5 src2) %{ | |
7669 match(Set dst (URShiftI (CastP2X src1) src2)); | |
7670 size(4); | |
7671 format %{ "SRL $src1,$src2,$dst\t! Cast ptr $src1 to int and shift" %} | |
7672 opcode(Assembler::srl_op3, Assembler::arith_op); | |
7673 ins_encode( form3_rs1_imm5_rd( src1, src2, dst ) ); | |
7674 ins_pipe(ialu_reg_imm); | |
7675 %} | |
7676 #endif | |
7677 | |
7678 | |
7679 //----------Floating Point Arithmetic Instructions----------------------------- | |
7680 | |
7681 // Add float single precision | |
7682 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ | |
7683 match(Set dst (AddF src1 src2)); | |
7684 | |
7685 size(4); | |
7686 format %{ "FADDS $src1,$src2,$dst" %} | |
7687 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fadds_opf); | |
7688 ins_encode(form3_opf_rs1F_rs2F_rdF(src1, src2, dst)); | |
7689 ins_pipe(faddF_reg_reg); | |
7690 %} | |
7691 | |
7692 // Add float double precision | |
7693 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ | |
7694 match(Set dst (AddD src1 src2)); | |
7695 | |
7696 size(4); | |
7697 format %{ "FADDD $src1,$src2,$dst" %} | |
7698 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::faddd_opf); | |
7699 ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); | |
7700 ins_pipe(faddD_reg_reg); | |
7701 %} | |
7702 | |
7703 // Sub float single precision | |
7704 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ | |
7705 match(Set dst (SubF src1 src2)); | |
7706 | |
7707 size(4); | |
7708 format %{ "FSUBS $src1,$src2,$dst" %} | |
7709 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fsubs_opf); | |
7710 ins_encode(form3_opf_rs1F_rs2F_rdF(src1, src2, dst)); | |
7711 ins_pipe(faddF_reg_reg); | |
7712 %} | |
7713 | |
7714 // Sub float double precision | |
7715 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ | |
7716 match(Set dst (SubD src1 src2)); | |
7717 | |
7718 size(4); | |
7719 format %{ "FSUBD $src1,$src2,$dst" %} | |
7720 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fsubd_opf); | |
7721 ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); | |
7722 ins_pipe(faddD_reg_reg); | |
7723 %} | |
7724 | |
7725 // Mul float single precision | |
7726 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ | |
7727 match(Set dst (MulF src1 src2)); | |
7728 | |
7729 size(4); | |
7730 format %{ "FMULS $src1,$src2,$dst" %} | |
7731 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fmuls_opf); | |
7732 ins_encode(form3_opf_rs1F_rs2F_rdF(src1, src2, dst)); | |
7733 ins_pipe(fmulF_reg_reg); | |
7734 %} | |
7735 | |
7736 // Mul float double precision | |
7737 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ | |
7738 match(Set dst (MulD src1 src2)); | |
7739 | |
7740 size(4); | |
7741 format %{ "FMULD $src1,$src2,$dst" %} | |
7742 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fmuld_opf); | |
7743 ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); | |
7744 ins_pipe(fmulD_reg_reg); | |
7745 %} | |
7746 | |
7747 // Div float single precision | |
7748 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ | |
7749 match(Set dst (DivF src1 src2)); | |
7750 | |
7751 size(4); | |
7752 format %{ "FDIVS $src1,$src2,$dst" %} | |
7753 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fdivs_opf); | |
7754 ins_encode(form3_opf_rs1F_rs2F_rdF(src1, src2, dst)); | |
7755 ins_pipe(fdivF_reg_reg); | |
7756 %} | |
7757 | |
7758 // Div float double precision | |
7759 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ | |
7760 match(Set dst (DivD src1 src2)); | |
7761 | |
7762 size(4); | |
7763 format %{ "FDIVD $src1,$src2,$dst" %} | |
7764 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fdivd_opf); | |
7765 ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); | |
7766 ins_pipe(fdivD_reg_reg); | |
7767 %} | |
7768 | |
7769 // Absolute float double precision | |
7770 instruct absD_reg(regD dst, regD src) %{ | |
7771 match(Set dst (AbsD src)); | |
7772 | |
7773 format %{ "FABSd $src,$dst" %} | |
7774 ins_encode(fabsd(dst, src)); | |
7775 ins_pipe(faddD_reg); | |
7776 %} | |
7777 | |
7778 // Absolute float single precision | |
7779 instruct absF_reg(regF dst, regF src) %{ | |
7780 match(Set dst (AbsF src)); | |
7781 | |
7782 format %{ "FABSs $src,$dst" %} | |
7783 ins_encode(fabss(dst, src)); | |
7784 ins_pipe(faddF_reg); | |
7785 %} | |
7786 | |
7787 instruct negF_reg(regF dst, regF src) %{ | |
7788 match(Set dst (NegF src)); | |
7789 | |
7790 size(4); | |
7791 format %{ "FNEGs $src,$dst" %} | |
7792 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fnegs_opf); | |
7793 ins_encode(form3_opf_rs2F_rdF(src, dst)); | |
7794 ins_pipe(faddF_reg); | |
7795 %} | |
7796 | |
7797 instruct negD_reg(regD dst, regD src) %{ | |
7798 match(Set dst (NegD src)); | |
7799 | |
7800 format %{ "FNEGd $src,$dst" %} | |
7801 ins_encode(fnegd(dst, src)); | |
7802 ins_pipe(faddD_reg); | |
7803 %} | |
7804 | |
7805 // Sqrt float double precision | |
7806 instruct sqrtF_reg_reg(regF dst, regF src) %{ | |
7807 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); | |
7808 | |
7809 size(4); | |
7810 format %{ "FSQRTS $src,$dst" %} | |
7811 ins_encode(fsqrts(dst, src)); | |
7812 ins_pipe(fdivF_reg_reg); | |
7813 %} | |
7814 | |
7815 // Sqrt float double precision | |
7816 instruct sqrtD_reg_reg(regD dst, regD src) %{ | |
7817 match(Set dst (SqrtD src)); | |
7818 | |
7819 size(4); | |
7820 format %{ "FSQRTD $src,$dst" %} | |
7821 ins_encode(fsqrtd(dst, src)); | |
7822 ins_pipe(fdivD_reg_reg); | |
7823 %} | |
7824 | |
7825 //----------Logical Instructions----------------------------------------------- | |
7826 // And Instructions | |
7827 // Register And | |
7828 instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
7829 match(Set dst (AndI src1 src2)); | |
7830 | |
7831 size(4); | |
7832 format %{ "AND $src1,$src2,$dst" %} | |
7833 opcode(Assembler::and_op3, Assembler::arith_op); | |
7834 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7835 ins_pipe(ialu_reg_reg); | |
7836 %} | |
7837 | |
7838 // Immediate And | |
7839 instruct andI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ | |
7840 match(Set dst (AndI src1 src2)); | |
7841 | |
7842 size(4); | |
7843 format %{ "AND $src1,$src2,$dst" %} | |
7844 opcode(Assembler::and_op3, Assembler::arith_op); | |
7845 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7846 ins_pipe(ialu_reg_imm); | |
7847 %} | |
7848 | |
7849 // Register And Long | |
7850 instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
7851 match(Set dst (AndL src1 src2)); | |
7852 | |
7853 ins_cost(DEFAULT_COST); | |
7854 size(4); | |
7855 format %{ "AND $src1,$src2,$dst\t! long" %} | |
7856 opcode(Assembler::and_op3, Assembler::arith_op); | |
7857 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7858 ins_pipe(ialu_reg_reg); | |
7859 %} | |
7860 | |
7861 instruct andL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ | |
7862 match(Set dst (AndL src1 con)); | |
7863 | |
7864 ins_cost(DEFAULT_COST); | |
7865 size(4); | |
7866 format %{ "AND $src1,$con,$dst\t! long" %} | |
7867 opcode(Assembler::and_op3, Assembler::arith_op); | |
7868 ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); | |
7869 ins_pipe(ialu_reg_imm); | |
7870 %} | |
7871 | |
7872 // Or Instructions | |
7873 // Register Or | |
7874 instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
7875 match(Set dst (OrI src1 src2)); | |
7876 | |
7877 size(4); | |
7878 format %{ "OR $src1,$src2,$dst" %} | |
7879 opcode(Assembler::or_op3, Assembler::arith_op); | |
7880 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7881 ins_pipe(ialu_reg_reg); | |
7882 %} | |
7883 | |
7884 // Immediate Or | |
7885 instruct orI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ | |
7886 match(Set dst (OrI src1 src2)); | |
7887 | |
7888 size(4); | |
7889 format %{ "OR $src1,$src2,$dst" %} | |
7890 opcode(Assembler::or_op3, Assembler::arith_op); | |
7891 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7892 ins_pipe(ialu_reg_imm); | |
7893 %} | |
7894 | |
7895 // Register Or Long | |
7896 instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
7897 match(Set dst (OrL src1 src2)); | |
7898 | |
7899 ins_cost(DEFAULT_COST); | |
7900 size(4); | |
7901 format %{ "OR $src1,$src2,$dst\t! long" %} | |
7902 opcode(Assembler::or_op3, Assembler::arith_op); | |
7903 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7904 ins_pipe(ialu_reg_reg); | |
7905 %} | |
7906 | |
7907 instruct orL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ | |
7908 match(Set dst (OrL src1 con)); | |
7909 ins_cost(DEFAULT_COST*2); | |
7910 | |
7911 ins_cost(DEFAULT_COST); | |
7912 size(4); | |
7913 format %{ "OR $src1,$con,$dst\t! long" %} | |
7914 opcode(Assembler::or_op3, Assembler::arith_op); | |
7915 ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); | |
7916 ins_pipe(ialu_reg_imm); | |
7917 %} | |
7918 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7919 #ifndef _LP64 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7920 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7921 // Use sp_ptr_RegP to match G2 (TLS register) without spilling. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7922 instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{ |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7923 match(Set dst (OrI src1 (CastP2X src2))); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7924 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7925 size(4); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7926 format %{ "OR $src1,$src2,$dst" %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7927 opcode(Assembler::or_op3, Assembler::arith_op); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7928 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7929 ins_pipe(ialu_reg_reg); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7930 %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7931 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7932 #else |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7933 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7934 instruct orL_reg_castP2X(iRegL dst, iRegL src1, sp_ptr_RegP src2) %{ |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7935 match(Set dst (OrL src1 (CastP2X src2))); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7936 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7937 ins_cost(DEFAULT_COST); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7938 size(4); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7939 format %{ "OR $src1,$src2,$dst\t! long" %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7940 opcode(Assembler::or_op3, Assembler::arith_op); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7941 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7942 ins_pipe(ialu_reg_reg); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7943 %} |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7944 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7945 #endif |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
415
diff
changeset
|
7946 |
0 | 7947 // Xor Instructions |
7948 // Register Xor | |
7949 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ | |
7950 match(Set dst (XorI src1 src2)); | |
7951 | |
7952 size(4); | |
7953 format %{ "XOR $src1,$src2,$dst" %} | |
7954 opcode(Assembler::xor_op3, Assembler::arith_op); | |
7955 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7956 ins_pipe(ialu_reg_reg); | |
7957 %} | |
7958 | |
7959 // Immediate Xor | |
7960 instruct xorI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ | |
7961 match(Set dst (XorI src1 src2)); | |
7962 | |
7963 size(4); | |
7964 format %{ "XOR $src1,$src2,$dst" %} | |
7965 opcode(Assembler::xor_op3, Assembler::arith_op); | |
7966 ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); | |
7967 ins_pipe(ialu_reg_imm); | |
7968 %} | |
7969 | |
7970 // Register Xor Long | |
7971 instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ | |
7972 match(Set dst (XorL src1 src2)); | |
7973 | |
7974 ins_cost(DEFAULT_COST); | |
7975 size(4); | |
7976 format %{ "XOR $src1,$src2,$dst\t! long" %} | |
7977 opcode(Assembler::xor_op3, Assembler::arith_op); | |
7978 ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); | |
7979 ins_pipe(ialu_reg_reg); | |
7980 %} | |
7981 | |
7982 instruct xorL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ | |
7983 match(Set dst (XorL src1 con)); | |
7984 | |
7985 ins_cost(DEFAULT_COST); | |
7986 size(4); | |
7987 format %{ "XOR $src1,$con,$dst\t! long" %} | |
7988 opcode(Assembler::xor_op3, Assembler::arith_op); | |
7989 ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); | |
7990 ins_pipe(ialu_reg_imm); | |
7991 %} | |
7992 | |
7993 //----------Convert to Boolean------------------------------------------------- | |
7994 // Nice hack for 32-bit tests but doesn't work for | |
7995 // 64-bit pointers. | |
7996 instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{ | |
7997 match(Set dst (Conv2B src)); | |
7998 effect( KILL ccr ); | |
7999 ins_cost(DEFAULT_COST*2); | |
8000 format %{ "CMP R_G0,$src\n\t" | |
8001 "ADDX R_G0,0,$dst" %} | |
8002 ins_encode( enc_to_bool( src, dst ) ); | |
8003 ins_pipe(ialu_reg_ialu); | |
8004 %} | |
8005 | |
8006 #ifndef _LP64 | |
8007 instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{ | |
8008 match(Set dst (Conv2B src)); | |
8009 effect( KILL ccr ); | |
8010 ins_cost(DEFAULT_COST*2); | |
8011 format %{ "CMP R_G0,$src\n\t" | |
8012 "ADDX R_G0,0,$dst" %} | |
8013 ins_encode( enc_to_bool( src, dst ) ); | |
8014 ins_pipe(ialu_reg_ialu); | |
8015 %} | |
8016 #else | |
8017 instruct convP2B( iRegI dst, iRegP src ) %{ | |
8018 match(Set dst (Conv2B src)); | |
8019 ins_cost(DEFAULT_COST*2); | |
8020 format %{ "MOV $src,$dst\n\t" | |
8021 "MOVRNZ $src,1,$dst" %} | |
8022 ins_encode( form3_g0_rs2_rd_move( src, dst ), enc_convP2B( dst, src ) ); | |
8023 ins_pipe(ialu_clr_and_mover); | |
8024 %} | |
8025 #endif | |
8026 | |
8027 instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{ | |
8028 match(Set dst (CmpLTMask p q)); | |
8029 effect( KILL ccr ); | |
8030 ins_cost(DEFAULT_COST*4); | |
8031 format %{ "CMP $p,$q\n\t" | |
8032 "MOV #0,$dst\n\t" | |
8033 "BLT,a .+8\n\t" | |
8034 "MOV #-1,$dst" %} | |
8035 ins_encode( enc_ltmask(p,q,dst) ); | |
8036 ins_pipe(ialu_reg_reg_ialu); | |
8037 %} | |
8038 | |
8039 instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, iRegI tmp, flagsReg ccr ) %{ | |
8040 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); | |
8041 effect(KILL ccr, TEMP tmp); | |
8042 ins_cost(DEFAULT_COST*3); | |
8043 | |
8044 format %{ "SUBcc $p,$q,$p\t! p' = p-q\n\t" | |
8045 "ADD $p,$y,$tmp\t! g3=p-q+y\n\t" | |
8046 "MOVl $tmp,$p\t! p' < 0 ? p'+y : p'" %} | |
8047 ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) ); | |
8048 ins_pipe( cadd_cmpltmask ); | |
8049 %} | |
8050 | |
8051 instruct cadd_cmpLTMask2( iRegI p, iRegI q, iRegI y, iRegI tmp, flagsReg ccr ) %{ | |
8052 match(Set p (AddI (SubI p q) (AndI (CmpLTMask p q) y))); | |
8053 effect( KILL ccr, TEMP tmp); | |
8054 ins_cost(DEFAULT_COST*3); | |
8055 | |
8056 format %{ "SUBcc $p,$q,$p\t! p' = p-q\n\t" | |
8057 "ADD $p,$y,$tmp\t! g3=p-q+y\n\t" | |
8058 "MOVl $tmp,$p\t! p' < 0 ? p'+y : p'" %} | |
8059 ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) ); | |
8060 ins_pipe( cadd_cmpltmask ); | |
8061 %} | |
8062 | |
8063 //----------Arithmetic Conversion Instructions--------------------------------- | |
8064 // The conversions operations are all Alpha sorted. Please keep it that way! | |
8065 | |
8066 instruct convD2F_reg(regF dst, regD src) %{ | |
8067 match(Set dst (ConvD2F src)); | |
8068 size(4); | |
8069 format %{ "FDTOS $src,$dst" %} | |
8070 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fdtos_opf); | |
8071 ins_encode(form3_opf_rs2D_rdF(src, dst)); | |
8072 ins_pipe(fcvtD2F); | |
8073 %} | |
8074 | |
8075 | |
8076 // Convert a double to an int in a float register. | |
8077 // If the double is a NAN, stuff a zero in instead. | |
8078 instruct convD2I_helper(regF dst, regD src, flagsRegF0 fcc0) %{ | |
8079 effect(DEF dst, USE src, KILL fcc0); | |
8080 format %{ "FCMPd fcc0,$src,$src\t! check for NAN\n\t" | |
8081 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" | |
8082 "FDTOI $src,$dst\t! convert in delay slot\n\t" | |
8083 "FITOS $dst,$dst\t! change NaN/max-int to valid float\n\t" | |
8084 "FSUBs $dst,$dst,$dst\t! cleared only if nan\n" | |
8085 "skip:" %} | |
8086 ins_encode(form_d2i_helper(src,dst)); | |
8087 ins_pipe(fcvtD2I); | |
8088 %} | |
8089 | |
8090 instruct convD2I_reg(stackSlotI dst, regD src) %{ | |
8091 match(Set dst (ConvD2I src)); | |
8092 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); | |
8093 expand %{ | |
8094 regF tmp; | |
8095 convD2I_helper(tmp, src); | |
8096 regF_to_stkI(dst, tmp); | |
8097 %} | |
8098 %} | |
8099 | |
8100 // Convert a double to a long in a double register. | |
8101 // If the double is a NAN, stuff a zero in instead. | |
8102 instruct convD2L_helper(regD dst, regD src, flagsRegF0 fcc0) %{ | |
8103 effect(DEF dst, USE src, KILL fcc0); | |
8104 format %{ "FCMPd fcc0,$src,$src\t! check for NAN\n\t" | |
8105 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" | |
8106 "FDTOX $src,$dst\t! convert in delay slot\n\t" | |
8107 "FXTOD $dst,$dst\t! change NaN/max-long to valid double\n\t" | |
8108 "FSUBd $dst,$dst,$dst\t! cleared only if nan\n" | |
8109 "skip:" %} | |
8110 ins_encode(form_d2l_helper(src,dst)); | |
8111 ins_pipe(fcvtD2L); | |
8112 %} | |
8113 | |
8114 | |
8115 // Double to Long conversion | |
8116 instruct convD2L_reg(stackSlotL dst, regD src) %{ | |
8117 match(Set dst (ConvD2L src)); | |
8118 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); | |
8119 expand %{ | |
8120 regD tmp; | |
8121 convD2L_helper(tmp, src); | |
8122 regD_to_stkL(dst, tmp); | |
8123 %} | |
8124 %} | |
8125 | |
8126 | |
8127 instruct convF2D_reg(regD dst, regF src) %{ | |
8128 match(Set dst (ConvF2D src)); | |
8129 format %{ "FSTOD $src,$dst" %} | |
8130 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fstod_opf); | |
8131 ins_encode(form3_opf_rs2F_rdD(src, dst)); | |
8132 ins_pipe(fcvtF2D); | |
8133 %} | |
8134 | |
8135 | |
8136 instruct convF2I_helper(regF dst, regF src, flagsRegF0 fcc0) %{ | |
8137 effect(DEF dst, USE src, KILL fcc0); | |
8138 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" | |
8139 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" | |
8140 "FSTOI $src,$dst\t! convert in delay slot\n\t" | |
8141 "FITOS $dst,$dst\t! change NaN/max-int to valid float\n\t" | |
8142 "FSUBs $dst,$dst,$dst\t! cleared only if nan\n" | |
8143 "skip:" %} | |
8144 ins_encode(form_f2i_helper(src,dst)); | |
8145 ins_pipe(fcvtF2I); | |
8146 %} | |
8147 | |
8148 instruct convF2I_reg(stackSlotI dst, regF src) %{ | |
8149 match(Set dst (ConvF2I src)); | |
8150 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); | |
8151 expand %{ | |
8152 regF tmp; | |
8153 convF2I_helper(tmp, src); | |
8154 regF_to_stkI(dst, tmp); | |
8155 %} | |
8156 %} | |
8157 | |
8158 | |
8159 instruct convF2L_helper(regD dst, regF src, flagsRegF0 fcc0) %{ | |
8160 effect(DEF dst, USE src, KILL fcc0); | |
8161 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" | |
8162 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" | |
8163 "FSTOX $src,$dst\t! convert in delay slot\n\t" | |
8164 "FXTOD $dst,$dst\t! change NaN/max-long to valid double\n\t" | |
8165 "FSUBd $dst,$dst,$dst\t! cleared only if nan\n" | |
8166 "skip:" %} | |
8167 ins_encode(form_f2l_helper(src,dst)); | |
8168 ins_pipe(fcvtF2L); | |
8169 %} | |
8170 | |
8171 // Float to Long conversion | |
8172 instruct convF2L_reg(stackSlotL dst, regF src) %{ | |
8173 match(Set dst (ConvF2L src)); | |
8174 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); | |
8175 expand %{ | |
8176 regD tmp; | |
8177 convF2L_helper(tmp, src); | |
8178 regD_to_stkL(dst, tmp); | |
8179 %} | |
8180 %} | |
8181 | |
8182 | |
8183 instruct convI2D_helper(regD dst, regF tmp) %{ | |
8184 effect(USE tmp, DEF dst); | |
8185 format %{ "FITOD $tmp,$dst" %} | |
8186 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf); | |
8187 ins_encode(form3_opf_rs2F_rdD(tmp, dst)); | |
8188 ins_pipe(fcvtI2D); | |
8189 %} | |
8190 | |
8191 instruct convI2D_reg(stackSlotI src, regD dst) %{ | |
8192 match(Set dst (ConvI2D src)); | |
8193 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | |
8194 expand %{ | |
8195 regF tmp; | |
8196 stkI_to_regF( tmp, src); | |
8197 convI2D_helper( dst, tmp); | |
8198 %} | |
8199 %} | |
8200 | |
8201 instruct convI2D_mem( regD_low dst, memory mem ) %{ | |
8202 match(Set dst (ConvI2D (LoadI mem))); | |
8203 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | |
8204 size(8); | |
8205 format %{ "LDF $mem,$dst\n\t" | |
8206 "FITOD $dst,$dst" %} | |
8207 opcode(Assembler::ldf_op3, Assembler::fitod_opf); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8208 ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst)); |
0 | 8209 ins_pipe(floadF_mem); |
8210 %} | |
8211 | |
8212 | |
8213 instruct convI2F_helper(regF dst, regF tmp) %{ | |
8214 effect(DEF dst, USE tmp); | |
8215 format %{ "FITOS $tmp,$dst" %} | |
8216 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitos_opf); | |
8217 ins_encode(form3_opf_rs2F_rdF(tmp, dst)); | |
8218 ins_pipe(fcvtI2F); | |
8219 %} | |
8220 | |
8221 instruct convI2F_reg( regF dst, stackSlotI src ) %{ | |
8222 match(Set dst (ConvI2F src)); | |
8223 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | |
8224 expand %{ | |
8225 regF tmp; | |
8226 stkI_to_regF(tmp,src); | |
8227 convI2F_helper(dst, tmp); | |
8228 %} | |
8229 %} | |
8230 | |
8231 instruct convI2F_mem( regF dst, memory mem ) %{ | |
8232 match(Set dst (ConvI2F (LoadI mem))); | |
8233 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | |
8234 size(8); | |
8235 format %{ "LDF $mem,$dst\n\t" | |
8236 "FITOS $dst,$dst" %} | |
8237 opcode(Assembler::ldf_op3, Assembler::fitos_opf); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8238 ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst)); |
0 | 8239 ins_pipe(floadF_mem); |
8240 %} | |
8241 | |
8242 | |
8243 instruct convI2L_reg(iRegL dst, iRegI src) %{ | |
8244 match(Set dst (ConvI2L src)); | |
8245 size(4); | |
8246 format %{ "SRA $src,0,$dst\t! int->long" %} | |
8247 opcode(Assembler::sra_op3, Assembler::arith_op); | |
8248 ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) ); | |
8249 ins_pipe(ialu_reg_reg); | |
8250 %} | |
8251 | |
8252 // Zero-extend convert int to long | |
8253 instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{ | |
8254 match(Set dst (AndL (ConvI2L src) mask) ); | |
8255 size(4); | |
8256 format %{ "SRL $src,0,$dst\t! zero-extend int to long" %} | |
8257 opcode(Assembler::srl_op3, Assembler::arith_op); | |
8258 ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) ); | |
8259 ins_pipe(ialu_reg_reg); | |
8260 %} | |
8261 | |
8262 // Zero-extend long | |
8263 instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{ | |
8264 match(Set dst (AndL src mask) ); | |
8265 size(4); | |
8266 format %{ "SRL $src,0,$dst\t! zero-extend long" %} | |
8267 opcode(Assembler::srl_op3, Assembler::arith_op); | |
8268 ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) ); | |
8269 ins_pipe(ialu_reg_reg); | |
8270 %} | |
8271 | |
8272 instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{ | |
8273 match(Set dst (MoveF2I src)); | |
8274 effect(DEF dst, USE src); | |
8275 ins_cost(MEMORY_REF_COST); | |
8276 | |
8277 size(4); | |
8278 format %{ "LDUW $src,$dst\t! MoveF2I" %} | |
8279 opcode(Assembler::lduw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8280 ins_encode(simple_form3_mem_reg( src, dst ) ); |
0 | 8281 ins_pipe(iload_mem); |
8282 %} | |
8283 | |
8284 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ | |
8285 match(Set dst (MoveI2F src)); | |
8286 effect(DEF dst, USE src); | |
8287 ins_cost(MEMORY_REF_COST); | |
8288 | |
8289 size(4); | |
8290 format %{ "LDF $src,$dst\t! MoveI2F" %} | |
8291 opcode(Assembler::ldf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8292 ins_encode(simple_form3_mem_reg(src, dst)); |
0 | 8293 ins_pipe(floadF_stk); |
8294 %} | |
8295 | |
8296 instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{ | |
8297 match(Set dst (MoveD2L src)); | |
8298 effect(DEF dst, USE src); | |
8299 ins_cost(MEMORY_REF_COST); | |
8300 | |
8301 size(4); | |
8302 format %{ "LDX $src,$dst\t! MoveD2L" %} | |
8303 opcode(Assembler::ldx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8304 ins_encode(simple_form3_mem_reg( src, dst ) ); |
0 | 8305 ins_pipe(iload_mem); |
8306 %} | |
8307 | |
8308 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ | |
8309 match(Set dst (MoveL2D src)); | |
8310 effect(DEF dst, USE src); | |
8311 ins_cost(MEMORY_REF_COST); | |
8312 | |
8313 size(4); | |
8314 format %{ "LDDF $src,$dst\t! MoveL2D" %} | |
8315 opcode(Assembler::lddf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8316 ins_encode(simple_form3_mem_reg(src, dst)); |
0 | 8317 ins_pipe(floadD_stk); |
8318 %} | |
8319 | |
8320 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ | |
8321 match(Set dst (MoveF2I src)); | |
8322 effect(DEF dst, USE src); | |
8323 ins_cost(MEMORY_REF_COST); | |
8324 | |
8325 size(4); | |
8326 format %{ "STF $src,$dst\t!MoveF2I" %} | |
8327 opcode(Assembler::stf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8328 ins_encode(simple_form3_mem_reg(dst, src)); |
0 | 8329 ins_pipe(fstoreF_stk_reg); |
8330 %} | |
8331 | |
8332 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ | |
8333 match(Set dst (MoveI2F src)); | |
8334 effect(DEF dst, USE src); | |
8335 ins_cost(MEMORY_REF_COST); | |
8336 | |
8337 size(4); | |
8338 format %{ "STW $src,$dst\t!MoveI2F" %} | |
8339 opcode(Assembler::stw_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8340 ins_encode(simple_form3_mem_reg( dst, src ) ); |
0 | 8341 ins_pipe(istore_mem_reg); |
8342 %} | |
8343 | |
8344 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ | |
8345 match(Set dst (MoveD2L src)); | |
8346 effect(DEF dst, USE src); | |
8347 ins_cost(MEMORY_REF_COST); | |
8348 | |
8349 size(4); | |
8350 format %{ "STDF $src,$dst\t!MoveD2L" %} | |
8351 opcode(Assembler::stdf_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8352 ins_encode(simple_form3_mem_reg(dst, src)); |
0 | 8353 ins_pipe(fstoreD_stk_reg); |
8354 %} | |
8355 | |
8356 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ | |
8357 match(Set dst (MoveL2D src)); | |
8358 effect(DEF dst, USE src); | |
8359 ins_cost(MEMORY_REF_COST); | |
8360 | |
8361 size(4); | |
8362 format %{ "STX $src,$dst\t!MoveL2D" %} | |
8363 opcode(Assembler::stx_op3); | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
235
diff
changeset
|
8364 ins_encode(simple_form3_mem_reg( dst, src ) ); |
0 | 8365 ins_pipe(istore_mem_reg); |
8366 %} | |
8367 | |
8368 | |
8369 //----------- | |
8370 // Long to Double conversion using V8 opcodes. | |
8371 // Still useful because cheetah traps and becomes | |
8372 // amazingly slow for some common numbers. | |
8373 | |
8374 // Magic constant, 0x43300000 | |
8375 instruct loadConI_x43300000(iRegI dst) %{ | |
8376 effect(DEF dst); | |
8377 size(4); | |
8378 format %{ "SETHI HI(0x43300000),$dst\t! 2^52" %} | |
8379 ins_encode(SetHi22(0x43300000, dst)); | |
8380 ins_pipe(ialu_none); | |
8381 %} | |
8382 | |
8383 // Magic constant, 0x41f00000 | |
8384 instruct loadConI_x41f00000(iRegI dst) %{ | |
8385 effect(DEF dst); | |
8386 size(4); | |
8387 format %{ "SETHI HI(0x41f00000),$dst\t! 2^32" %} | |
8388 ins_encode(SetHi22(0x41f00000, dst)); | |
8389 ins_pipe(ialu_none); | |
8390 %} | |
8391 | |
8392 // Construct a double from two float halves | |
8393 instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{ | |
8394 effect(DEF dst, USE src1, USE src2); | |
8395 size(8); | |
8396 format %{ "FMOVS $src1.hi,$dst.hi\n\t" | |
8397 "FMOVS $src2.lo,$dst.lo" %} | |
8398 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fmovs_opf); | |
8399 ins_encode(form3_opf_rs2D_hi_rdD_hi(src1, dst), form3_opf_rs2D_lo_rdD_lo(src2, dst)); | |
8400 ins_pipe(faddD_reg_reg); | |
8401 %} | |
8402 | |
8403 // Convert integer in high half of a double register (in the lower half of | |
8404 // the double register file) to double | |
8405 instruct convI2D_regDHi_regD(regD dst, regD_low src) %{ | |
8406 effect(DEF dst, USE src); | |
8407 size(4); | |
8408 format %{ "FITOD $src,$dst" %} | |
8409 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf); | |
8410 ins_encode(form3_opf_rs2D_rdD(src, dst)); | |
8411 ins_pipe(fcvtLHi2D); | |
8412 %} | |
8413 | |
8414 // Add float double precision | |
8415 instruct addD_regD_regD(regD dst, regD src1, regD src2) %{ | |
8416 effect(DEF dst, USE src1, USE src2); | |
8417 size(4); | |
8418 format %{ "FADDD $src1,$src2,$dst" %} | |
8419 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::faddd_opf); | |
8420 ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); | |
8421 ins_pipe(faddD_reg_reg); | |
8422 %} | |
8423 | |
8424 // Sub float double precision | |
8425 instruct subD_regD_regD(regD dst, regD src1, regD src2) %{ | |
8426 effect(DEF dst, USE src1, USE src2); | |
8427 size(4); | |
8428 format %{ "FSUBD $src1,$src2,$dst" %} | |
8429 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fsubd_opf); | |
8430 ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); | |
8431 ins_pipe(faddD_reg_reg); | |
8432 %} | |
8433 | |
8434 // Mul float double precision | |
8435 instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{ | |
8436 effect(DEF dst, USE src1, USE src2); | |
8437 size(4); | |
8438 format %{ "FMULD $src1,$src2,$dst" %} | |
8439 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fmuld_opf); | |
8440 ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); | |
8441 ins_pipe(fmulD_reg_reg); | |
8442 %} | |
8443 | |
8444 instruct convL2D_reg_slow_fxtof(regD dst, stackSlotL src) %{ | |
8445 match(Set dst (ConvL2D src)); | |
8446 ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); | |
8447 | |
8448 expand %{ | |
8449 regD_low tmpsrc; | |
8450 iRegI ix43300000; | |
8451 iRegI ix41f00000; | |
8452 stackSlotL lx43300000; | |
8453 stackSlotL lx41f00000; | |
8454 regD_low dx43300000; | |
8455 regD dx41f00000; | |
8456 regD tmp1; | |
8457 regD_low tmp2; | |
8458 regD tmp3; | |
8459 regD tmp4; | |
8460 | |
8461 stkL_to_regD(tmpsrc, src); | |
8462 | |
8463 loadConI_x43300000(ix43300000); | |
8464 loadConI_x41f00000(ix41f00000); | |
8465 regI_to_stkLHi(lx43300000, ix43300000); | |
8466 regI_to_stkLHi(lx41f00000, ix41f00000); | |
8467 stkL_to_regD(dx43300000, lx43300000); | |
8468 stkL_to_regD(dx41f00000, lx41f00000); | |
8469 | |
8470 convI2D_regDHi_regD(tmp1, tmpsrc); | |
8471 regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc); | |
8472 subD_regD_regD(tmp3, tmp2, dx43300000); | |
8473 mulD_regD_regD(tmp4, tmp1, dx41f00000); | |
8474 addD_regD_regD(dst, tmp3, tmp4); | |
8475 %} | |
8476 %} | |
8477 | |
8478 // Long to Double conversion using fast fxtof | |
8479 instruct convL2D_helper(regD dst, regD tmp) %{ | |
8480 effect(DEF dst, USE tmp); | |
8481 size(4); | |
8482 format %{ "FXTOD $tmp,$dst" %} | |
8483 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtod_opf); | |
8484 ins_encode(form3_opf_rs2D_rdD(tmp, dst)); | |
8485 ins_pipe(fcvtL2D); | |
8486 %} | |
8487 | |
8488 instruct convL2D_reg_fast_fxtof(regD dst, stackSlotL src) %{ | |
8489 predicate(VM_Version::has_fast_fxtof()); | |
8490 match(Set dst (ConvL2D src)); | |
8491 ins_cost(DEFAULT_COST + 3 * MEMORY_REF_COST); | |
8492 expand %{ | |
8493 regD tmp; | |
8494 stkL_to_regD(tmp, src); | |
8495 convL2D_helper(dst, tmp); | |
8496 %} | |
8497 %} | |
8498 | |
8499 //----------- | |
8500 // Long to Float conversion using V8 opcodes. | |
8501 // Still useful because cheetah traps and becomes | |
8502 // amazingly slow for some common numbers. | |
8503 | |
8504 // Long to Float conversion using fast fxtof | |
8505 instruct convL2F_helper(regF dst, regD tmp) %{ | |
8506 effect(DEF dst, USE tmp); | |
8507 size(4); | |
8508 format %{ "FXTOS $tmp,$dst" %} | |
8509 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtos_opf); | |
8510 ins_encode(form3_opf_rs2D_rdF(tmp, dst)); | |
8511 ins_pipe(fcvtL2F); | |
8512 %} | |
8513 | |
8514 instruct convL2F_reg_fast_fxtof(regF dst, stackSlotL src) %{ | |
8515 match(Set dst (ConvL2F src)); | |
8516 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | |
8517 expand %{ | |
8518 regD tmp; | |
8519 stkL_to_regD(tmp, src); | |
8520 convL2F_helper(dst, tmp); | |
8521 %} | |
8522 %} | |
8523 //----------- | |
8524 | |
8525 instruct convL2I_reg(iRegI dst, iRegL src) %{ | |
8526 match(Set dst (ConvL2I src)); | |
8527 #ifndef _LP64 | |
8528 format %{ "MOV $src.lo,$dst\t! long->int" %} | |
8529 ins_encode( form3_g0_rs2_rd_move_lo2( src, dst ) ); | |
8530 ins_pipe(ialu_move_reg_I_to_L); | |
8531 #else | |
8532 size(4); | |
8533 format %{ "SRA $src,R_G0,$dst\t! long->int" %} | |
8534 ins_encode( form3_rs1_rd_signextend_lo1( src, dst ) ); | |
8535 ins_pipe(ialu_reg); | |
8536 #endif | |
8537 %} | |
8538 | |
8539 // Register Shift Right Immediate | |
8540 instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{ | |
8541 match(Set dst (ConvL2I (RShiftL src cnt))); | |
8542 | |
8543 size(4); | |
8544 format %{ "SRAX $src,$cnt,$dst" %} | |
8545 opcode(Assembler::srax_op3, Assembler::arith_op); | |
8546 ins_encode( form3_sd_rs1_imm6_rd( src, cnt, dst ) ); | |
8547 ins_pipe(ialu_reg_imm); | |
8548 %} | |
8549 | |
8550 // Replicate scalar to packed byte values in Double register | |
8551 instruct Repl8B_reg_helper(iRegL dst, iRegI src) %{ | |
8552 effect(DEF dst, USE src); | |
8553 format %{ "SLLX $src,56,$dst\n\t" | |
8554 "SRLX $dst, 8,O7\n\t" | |
8555 "OR $dst,O7,$dst\n\t" | |
8556 "SRLX $dst,16,O7\n\t" | |
8557 "OR $dst,O7,$dst\n\t" | |
8558 "SRLX $dst,32,O7\n\t" | |
8559 "OR $dst,O7,$dst\t! replicate8B" %} | |
8560 ins_encode( enc_repl8b(src, dst)); | |
8561 ins_pipe(ialu_reg); | |
8562 %} | |
8563 | |
8564 // Replicate scalar to packed byte values in Double register | |
8565 instruct Repl8B_reg(stackSlotD dst, iRegI src) %{ | |
8566 match(Set dst (Replicate8B src)); | |
8567 expand %{ | |
8568 iRegL tmp; | |
8569 Repl8B_reg_helper(tmp, src); | |
8570 regL_to_stkD(dst, tmp); | |
8571 %} | |
8572 %} | |
8573 | |
8574 // Replicate scalar constant to packed byte values in Double register | |
8575 instruct Repl8B_immI(regD dst, immI13 src, o7RegP tmp) %{ | |
8576 match(Set dst (Replicate8B src)); | |
8577 #ifdef _LP64 | |
8578 size(36); | |
8579 #else | |
8580 size(8); | |
8581 #endif | |
8582 format %{ "SETHI hi(&Repl8($src)),$tmp\t!get Repl8B($src) from table\n\t" | |
8583 "LDDF [$tmp+lo(&Repl8($src))],$dst" %} | |
8584 ins_encode( LdReplImmI(src, dst, tmp, (8), (1)) ); | |
8585 ins_pipe(loadConFD); | |
8586 %} | |
8587 | |
8588 // Replicate scalar to packed char values into stack slot | |
8589 instruct Repl4C_reg_helper(iRegL dst, iRegI src) %{ | |
8590 effect(DEF dst, USE src); | |
8591 format %{ "SLLX $src,48,$dst\n\t" | |
8592 "SRLX $dst,16,O7\n\t" | |
8593 "OR $dst,O7,$dst\n\t" | |
8594 "SRLX $dst,32,O7\n\t" | |
8595 "OR $dst,O7,$dst\t! replicate4C" %} | |
8596 ins_encode( enc_repl4s(src, dst) ); | |
8597 ins_pipe(ialu_reg); | |
8598 %} | |
8599 | |
8600 // Replicate scalar to packed char values into stack slot | |
8601 instruct Repl4C_reg(stackSlotD dst, iRegI src) %{ | |
8602 match(Set dst (Replicate4C src)); | |
8603 expand %{ | |
8604 iRegL tmp; | |
8605 Repl4C_reg_helper(tmp, src); | |
8606 regL_to_stkD(dst, tmp); | |
8607 %} | |
8608 %} | |
8609 | |
8610 // Replicate scalar constant to packed char values in Double register | |
8611 instruct Repl4C_immI(regD dst, immI src, o7RegP tmp) %{ | |
8612 match(Set dst (Replicate4C src)); | |
8613 #ifdef _LP64 | |
8614 size(36); | |
8615 #else | |
8616 size(8); | |
8617 #endif | |
8618 format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4C($src) from table\n\t" | |
8619 "LDDF [$tmp+lo(&Repl4($src))],$dst" %} | |
8620 ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); | |
8621 ins_pipe(loadConFD); | |
8622 %} | |
8623 | |
8624 // Replicate scalar to packed short values into stack slot | |
8625 instruct Repl4S_reg_helper(iRegL dst, iRegI src) %{ | |
8626 effect(DEF dst, USE src); | |
8627 format %{ "SLLX $src,48,$dst\n\t" | |
8628 "SRLX $dst,16,O7\n\t" | |
8629 "OR $dst,O7,$dst\n\t" | |
8630 "SRLX $dst,32,O7\n\t" | |
8631 "OR $dst,O7,$dst\t! replicate4S" %} | |
8632 ins_encode( enc_repl4s(src, dst) ); | |
8633 ins_pipe(ialu_reg); | |
8634 %} | |
8635 | |
8636 // Replicate scalar to packed short values into stack slot | |
8637 instruct Repl4S_reg(stackSlotD dst, iRegI src) %{ | |
8638 match(Set dst (Replicate4S src)); | |
8639 expand %{ | |
8640 iRegL tmp; | |
8641 Repl4S_reg_helper(tmp, src); | |
8642 regL_to_stkD(dst, tmp); | |
8643 %} | |
8644 %} | |
8645 | |
8646 // Replicate scalar constant to packed short values in Double register | |
8647 instruct Repl4S_immI(regD dst, immI src, o7RegP tmp) %{ | |
8648 match(Set dst (Replicate4S src)); | |
8649 #ifdef _LP64 | |
8650 size(36); | |
8651 #else | |
8652 size(8); | |
8653 #endif | |
8654 format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4S($src) from table\n\t" | |
8655 "LDDF [$tmp+lo(&Repl4($src))],$dst" %} | |
8656 ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); | |
8657 ins_pipe(loadConFD); | |
8658 %} | |
8659 | |
8660 // Replicate scalar to packed int values in Double register | |
8661 instruct Repl2I_reg_helper(iRegL dst, iRegI src) %{ | |
8662 effect(DEF dst, USE src); | |
8663 format %{ "SLLX $src,32,$dst\n\t" | |
8664 "SRLX $dst,32,O7\n\t" | |
8665 "OR $dst,O7,$dst\t! replicate2I" %} | |
8666 ins_encode( enc_repl2i(src, dst)); | |
8667 ins_pipe(ialu_reg); | |
8668 %} | |
8669 | |
8670 // Replicate scalar to packed int values in Double register | |
8671 instruct Repl2I_reg(stackSlotD dst, iRegI src) %{ | |
8672 match(Set dst (Replicate2I src)); | |
8673 expand %{ | |
8674 iRegL tmp; | |
8675 Repl2I_reg_helper(tmp, src); | |
8676 regL_to_stkD(dst, tmp); | |
8677 %} | |
8678 %} | |
8679 | |
8680 // Replicate scalar zero constant to packed int values in Double register | |
8681 instruct Repl2I_immI(regD dst, immI src, o7RegP tmp) %{ | |
8682 match(Set dst (Replicate2I src)); | |
8683 #ifdef _LP64 | |
8684 size(36); | |
8685 #else | |
8686 size(8); | |
8687 #endif | |
8688 format %{ "SETHI hi(&Repl2($src)),$tmp\t!get Repl2I($src) from table\n\t" | |
8689 "LDDF [$tmp+lo(&Repl2($src))],$dst" %} | |
8690 ins_encode( LdReplImmI(src, dst, tmp, (2), (4)) ); | |
8691 ins_pipe(loadConFD); | |
8692 %} | |
8693 | |
8694 //----------Control Flow Instructions------------------------------------------ | |
8695 // Compare Instructions | |
8696 // Compare Integers | |
8697 instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{ | |
8698 match(Set icc (CmpI op1 op2)); | |
8699 effect( DEF icc, USE op1, USE op2 ); | |
8700 | |
8701 size(4); | |
8702 format %{ "CMP $op1,$op2" %} | |
8703 opcode(Assembler::subcc_op3, Assembler::arith_op); | |
8704 ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); | |
8705 ins_pipe(ialu_cconly_reg_reg); | |
8706 %} | |
8707 | |
8708 instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{ | |
8709 match(Set icc (CmpU op1 op2)); | |
8710 | |
8711 size(4); | |
8712 format %{ "CMP $op1,$op2\t! unsigned" %} | |
8713 opcode(Assembler::subcc_op3, Assembler::arith_op); | |
8714 ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); | |
8715 ins_pipe(ialu_cconly_reg_reg); | |
8716 %} | |
8717 | |
8718 instruct compI_iReg_imm13(flagsReg icc, iRegI op1, immI13 op2) %{ | |
8719 match(Set icc (CmpI op1 op2)); | |
8720 effect( DEF icc, USE op1 ); | |
8721 | |
8722 size(4); | |
8723 format %{ "CMP $op1,$op2" %} | |
8724 opcode(Assembler::subcc_op3, Assembler::arith_op); | |
8725 ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); | |
8726 ins_pipe(ialu_cconly_reg_imm); | |
8727 %} | |
8728 | |
8729 instruct testI_reg_reg( flagsReg icc, iRegI op1, iRegI op2, immI0 zero ) %{ | |
8730 match(Set icc (CmpI (AndI op1 op2) zero)); | |
8731 | |
8732 size(4); | |
8733 format %{ "BTST $op2,$op1" %} | |
8734 opcode(Assembler::andcc_op3, Assembler::arith_op); | |
8735 ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); | |
8736 ins_pipe(ialu_cconly_reg_reg_zero); | |
8737 %} | |
8738 | |
8739 instruct testI_reg_imm( flagsReg icc, iRegI op1, immI13 op2, immI0 zero ) %{ | |
8740 match(Set icc (CmpI (AndI op1 op2) zero)); | |
8741 | |
8742 size(4); | |
8743 format %{ "BTST $op2,$op1" %} | |
8744 opcode(Assembler::andcc_op3, Assembler::arith_op); | |
8745 ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); | |
8746 ins_pipe(ialu_cconly_reg_imm_zero); | |
8747 %} | |
8748 | |
8749 instruct compL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2 ) %{ | |
8750 match(Set xcc (CmpL op1 op2)); | |
8751 effect( DEF xcc, USE op1, USE op2 ); | |
8752 | |
8753 size(4); | |
8754 format %{ "CMP $op1,$op2\t\t! long" %} | |
8755 opcode(Assembler::subcc_op3, Assembler::arith_op); | |
8756 ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); | |
8757 ins_pipe(ialu_cconly_reg_reg); | |
8758 %} | |
8759 | |
8760 instruct compL_reg_con(flagsRegL xcc, iRegL op1, immL13 con) %{ | |
8761 match(Set xcc (CmpL op1 con)); | |
8762 effect( DEF xcc, USE op1, USE con ); | |
8763 | |
8764 size(4); | |
8765 format %{ "CMP $op1,$con\t\t! long" %} | |
8766 opcode(Assembler::subcc_op3, Assembler::arith_op); | |
8767 ins_encode( form3_rs1_simm13_rd( op1, con, R_G0 ) ); | |
8768 ins_pipe(ialu_cconly_reg_reg); | |
8769 %} | |
8770 | |
8771 instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ | |
8772 match(Set xcc (CmpL (AndL op1 op2) zero)); | |
8773 effect( DEF xcc, USE op1, USE op2 ); | |
8774 | |
8775 size(4); | |
8776 format %{ "BTST $op1,$op2\t\t! long" %} | |
8777 opcode(Assembler::andcc_op3, Assembler::arith_op); | |
8778 ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); | |
8779 ins_pipe(ialu_cconly_reg_reg); | |
8780 %} | |
8781 | |
8782 // useful for checking the alignment of a pointer: | |
8783 instruct testL_reg_con(flagsRegL xcc, iRegL op1, immL13 con, immL0 zero) %{ | |
8784 match(Set xcc (CmpL (AndL op1 con) zero)); | |
8785 effect( DEF xcc, USE op1, USE con ); | |
8786 | |
8787 size(4); | |
8788 format %{ "BTST $op1,$con\t\t! long" %} | |
8789 opcode(Assembler::andcc_op3, Assembler::arith_op); | |
8790 ins_encode( form3_rs1_simm13_rd( op1, con, R_G0 ) ); | |
8791 ins_pipe(ialu_cconly_reg_reg); | |
8792 %} | |
8793 | |
8794 instruct compU_iReg_imm13(flagsRegU icc, iRegI op1, immU13 op2 ) %{ | |
8795 match(Set icc (CmpU op1 op2)); | |
8796 | |
8797 size(4); | |
8798 format %{ "CMP $op1,$op2\t! unsigned" %} | |
8799 opcode(Assembler::subcc_op3, Assembler::arith_op); | |
8800 ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); | |
8801 ins_pipe(ialu_cconly_reg_imm); | |
8802 %} | |
8803 | |
8804 // Compare Pointers | |
8805 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{ | |
8806 match(Set pcc (CmpP op1 op2)); | |
8807 | |
8808 size(4); | |
8809 format %{ "CMP $op1,$op2\t! ptr" %} | |
8810 opcode(Assembler::subcc_op3, Assembler::arith_op); | |
8811 ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); | |
8812 ins_pipe(ialu_cconly_reg_reg); | |
8813 %} | |
8814 | |
8815 instruct compP_iRegP_imm13(flagsRegP pcc, iRegP op1, immP13 op2 ) %{ | |
8816 match(Set pcc (CmpP op1 op2)); | |
8817 | |
8818 size(4); | |
8819 format %{ "CMP $op1,$op2\t! ptr" %} | |
8820 opcode(Assembler::subcc_op3, Assembler::arith_op); | |
8821 ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); | |
8822 ins_pipe(ialu_cconly_reg_imm); | |
8823 %} | |
8824 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8825 // Compare Narrow oops |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8826 instruct compN_iRegN(flagsReg icc, iRegN op1, iRegN op2 ) %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8827 match(Set icc (CmpN op1 op2)); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8828 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8829 size(4); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8830 format %{ "CMP $op1,$op2\t! compressed ptr" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8831 opcode(Assembler::subcc_op3, Assembler::arith_op); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8832 ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8833 ins_pipe(ialu_cconly_reg_reg); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8834 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8835 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8836 instruct compN_iRegN_immN0(flagsReg icc, iRegN op1, immN0 op2 ) %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8837 match(Set icc (CmpN op1 op2)); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8838 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8839 size(4); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8840 format %{ "CMP $op1,$op2\t! compressed ptr" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8841 opcode(Assembler::subcc_op3, Assembler::arith_op); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8842 ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8843 ins_pipe(ialu_cconly_reg_imm); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8844 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
8845 |
0 | 8846 //----------Max and Min-------------------------------------------------------- |
8847 // Min Instructions | |
8848 // Conditional move for min | |
8849 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{ | |
8850 effect( USE_DEF op2, USE op1, USE icc ); | |
8851 | |
8852 size(4); | |
8853 format %{ "MOVlt icc,$op1,$op2\t! min" %} | |
8854 opcode(Assembler::less); | |
8855 ins_encode( enc_cmov_reg_minmax(op2,op1) ); | |
8856 ins_pipe(ialu_reg_flags); | |
8857 %} | |
8858 | |
8859 // Min Register with Register. | |
8860 instruct minI_eReg(iRegI op1, iRegI op2) %{ | |
8861 match(Set op2 (MinI op1 op2)); | |
8862 ins_cost(DEFAULT_COST*2); | |
8863 expand %{ | |
8864 flagsReg icc; | |
8865 compI_iReg(icc,op1,op2); | |
8866 cmovI_reg_lt(op2,op1,icc); | |
8867 %} | |
8868 %} | |
8869 | |
8870 // Max Instructions | |
8871 // Conditional move for max | |
8872 instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{ | |
8873 effect( USE_DEF op2, USE op1, USE icc ); | |
8874 format %{ "MOVgt icc,$op1,$op2\t! max" %} | |
8875 opcode(Assembler::greater); | |
8876 ins_encode( enc_cmov_reg_minmax(op2,op1) ); | |
8877 ins_pipe(ialu_reg_flags); | |
8878 %} | |
8879 | |
8880 // Max Register with Register | |
8881 instruct maxI_eReg(iRegI op1, iRegI op2) %{ | |
8882 match(Set op2 (MaxI op1 op2)); | |
8883 ins_cost(DEFAULT_COST*2); | |
8884 expand %{ | |
8885 flagsReg icc; | |
8886 compI_iReg(icc,op1,op2); | |
8887 cmovI_reg_gt(op2,op1,icc); | |
8888 %} | |
8889 %} | |
8890 | |
8891 | |
8892 //----------Float Compares---------------------------------------------------- | |
8893 // Compare floating, generate condition code | |
8894 instruct cmpF_cc(flagsRegF fcc, regF src1, regF src2) %{ | |
8895 match(Set fcc (CmpF src1 src2)); | |
8896 | |
8897 size(4); | |
8898 format %{ "FCMPs $fcc,$src1,$src2" %} | |
8899 opcode(Assembler::fpop2_op3, Assembler::arith_op, Assembler::fcmps_opf); | |
8900 ins_encode( form3_opf_rs1F_rs2F_fcc( src1, src2, fcc ) ); | |
8901 ins_pipe(faddF_fcc_reg_reg_zero); | |
8902 %} | |
8903 | |
8904 instruct cmpD_cc(flagsRegF fcc, regD src1, regD src2) %{ | |
8905 match(Set fcc (CmpD src1 src2)); | |
8906 | |
8907 size(4); | |
8908 format %{ "FCMPd $fcc,$src1,$src2" %} | |
8909 opcode(Assembler::fpop2_op3, Assembler::arith_op, Assembler::fcmpd_opf); | |
8910 ins_encode( form3_opf_rs1D_rs2D_fcc( src1, src2, fcc ) ); | |
8911 ins_pipe(faddD_fcc_reg_reg_zero); | |
8912 %} | |
8913 | |
8914 | |
8915 // Compare floating, generate -1,0,1 | |
8916 instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF0 fcc0) %{ | |
8917 match(Set dst (CmpF3 src1 src2)); | |
8918 effect(KILL fcc0); | |
8919 ins_cost(DEFAULT_COST*3+BRANCH_COST*3); | |
8920 format %{ "fcmpl $dst,$src1,$src2" %} | |
8921 // Primary = float | |
8922 opcode( true ); | |
8923 ins_encode( floating_cmp( dst, src1, src2 ) ); | |
8924 ins_pipe( floating_cmp ); | |
8925 %} | |
8926 | |
8927 instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF0 fcc0) %{ | |
8928 match(Set dst (CmpD3 src1 src2)); | |
8929 effect(KILL fcc0); | |
8930 ins_cost(DEFAULT_COST*3+BRANCH_COST*3); | |
8931 format %{ "dcmpl $dst,$src1,$src2" %} | |
8932 // Primary = double (not float) | |
8933 opcode( false ); | |
8934 ins_encode( floating_cmp( dst, src1, src2 ) ); | |
8935 ins_pipe( floating_cmp ); | |
8936 %} | |
8937 | |
8938 //----------Branches--------------------------------------------------------- | |
8939 // Jump | |
8940 // (compare 'operand indIndex' and 'instruct addP_reg_reg' above) | |
8941 instruct jumpXtnd(iRegX switch_val, o7RegI table) %{ | |
8942 match(Jump switch_val); | |
8943 | |
8944 ins_cost(350); | |
8945 | |
8946 format %{ "SETHI [hi(table_base)],O7\n\t" | |
8947 "ADD O7, lo(table_base), O7\n\t" | |
8948 "LD [O7+$switch_val], O7\n\t" | |
8949 "JUMP O7" | |
8950 %} | |
8951 ins_encode( jump_enc( switch_val, table) ); | |
8952 ins_pc_relative(1); | |
8953 ins_pipe(ialu_reg_reg); | |
8954 %} | |
8955 | |
8956 // Direct Branch. Use V8 version with longer range. | |
8957 instruct branch(label labl) %{ | |
8958 match(Goto); | |
8959 effect(USE labl); | |
8960 | |
8961 size(8); | |
8962 ins_cost(BRANCH_COST); | |
8963 format %{ "BA $labl" %} | |
8964 // Prim = bits 24-22, Secnd = bits 31-30, Tert = cond | |
8965 opcode(Assembler::br_op2, Assembler::branch_op, Assembler::always); | |
8966 ins_encode( enc_ba( labl ) ); | |
8967 ins_pc_relative(1); | |
8968 ins_pipe(br); | |
8969 %} | |
8970 | |
8971 // Conditional Direct Branch | |
8972 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{ | |
8973 match(If cmp icc); | |
8974 effect(USE labl); | |
8975 | |
8976 size(8); | |
8977 ins_cost(BRANCH_COST); | |
8978 format %{ "BP$cmp $icc,$labl" %} | |
8979 // Prim = bits 24-22, Secnd = bits 31-30 | |
8980 ins_encode( enc_bp( labl, cmp, icc ) ); | |
8981 ins_pc_relative(1); | |
8982 ins_pipe(br_cc); | |
8983 %} | |
8984 | |
8985 // Branch-on-register tests all 64 bits. We assume that values | |
8986 // in 64-bit registers always remains zero or sign extended | |
8987 // unless our code munges the high bits. Interrupts can chop | |
8988 // the high order bits to zero or sign at any time. | |
8989 instruct branchCon_regI(cmpOp_reg cmp, iRegI op1, immI0 zero, label labl) %{ | |
8990 match(If cmp (CmpI op1 zero)); | |
8991 predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf)); | |
8992 effect(USE labl); | |
8993 | |
8994 size(8); | |
8995 ins_cost(BRANCH_COST); | |
8996 format %{ "BR$cmp $op1,$labl" %} | |
8997 ins_encode( enc_bpr( labl, cmp, op1 ) ); | |
8998 ins_pc_relative(1); | |
8999 ins_pipe(br_reg); | |
9000 %} | |
9001 | |
9002 instruct branchCon_regP(cmpOp_reg cmp, iRegP op1, immP0 null, label labl) %{ | |
9003 match(If cmp (CmpP op1 null)); | |
9004 predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf)); | |
9005 effect(USE labl); | |
9006 | |
9007 size(8); | |
9008 ins_cost(BRANCH_COST); | |
9009 format %{ "BR$cmp $op1,$labl" %} | |
9010 ins_encode( enc_bpr( labl, cmp, op1 ) ); | |
9011 ins_pc_relative(1); | |
9012 ins_pipe(br_reg); | |
9013 %} | |
9014 | |
9015 instruct branchCon_regL(cmpOp_reg cmp, iRegL op1, immL0 zero, label labl) %{ | |
9016 match(If cmp (CmpL op1 zero)); | |
9017 predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf)); | |
9018 effect(USE labl); | |
9019 | |
9020 size(8); | |
9021 ins_cost(BRANCH_COST); | |
9022 format %{ "BR$cmp $op1,$labl" %} | |
9023 ins_encode( enc_bpr( labl, cmp, op1 ) ); | |
9024 ins_pc_relative(1); | |
9025 ins_pipe(br_reg); | |
9026 %} | |
9027 | |
9028 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{ | |
9029 match(If cmp icc); | |
9030 effect(USE labl); | |
9031 | |
9032 format %{ "BP$cmp $icc,$labl" %} | |
9033 // Prim = bits 24-22, Secnd = bits 31-30 | |
9034 ins_encode( enc_bp( labl, cmp, icc ) ); | |
9035 ins_pc_relative(1); | |
9036 ins_pipe(br_cc); | |
9037 %} | |
9038 | |
9039 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{ | |
9040 match(If cmp pcc); | |
9041 effect(USE labl); | |
9042 | |
9043 size(8); | |
9044 ins_cost(BRANCH_COST); | |
9045 format %{ "BP$cmp $pcc,$labl" %} | |
9046 // Prim = bits 24-22, Secnd = bits 31-30 | |
9047 ins_encode( enc_bpx( labl, cmp, pcc ) ); | |
9048 ins_pc_relative(1); | |
9049 ins_pipe(br_cc); | |
9050 %} | |
9051 | |
9052 instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{ | |
9053 match(If cmp fcc); | |
9054 effect(USE labl); | |
9055 | |
9056 size(8); | |
9057 ins_cost(BRANCH_COST); | |
9058 format %{ "FBP$cmp $fcc,$labl" %} | |
9059 // Prim = bits 24-22, Secnd = bits 31-30 | |
9060 ins_encode( enc_fbp( labl, cmp, fcc ) ); | |
9061 ins_pc_relative(1); | |
9062 ins_pipe(br_fcc); | |
9063 %} | |
9064 | |
9065 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ | |
9066 match(CountedLoopEnd cmp icc); | |
9067 effect(USE labl); | |
9068 | |
9069 size(8); | |
9070 ins_cost(BRANCH_COST); | |
9071 format %{ "BP$cmp $icc,$labl\t! Loop end" %} | |
9072 // Prim = bits 24-22, Secnd = bits 31-30 | |
9073 ins_encode( enc_bp( labl, cmp, icc ) ); | |
9074 ins_pc_relative(1); | |
9075 ins_pipe(br_cc); | |
9076 %} | |
9077 | |
9078 instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{ | |
9079 match(CountedLoopEnd cmp icc); | |
9080 effect(USE labl); | |
9081 | |
9082 size(8); | |
9083 ins_cost(BRANCH_COST); | |
9084 format %{ "BP$cmp $icc,$labl\t! Loop end" %} | |
9085 // Prim = bits 24-22, Secnd = bits 31-30 | |
9086 ins_encode( enc_bp( labl, cmp, icc ) ); | |
9087 ins_pc_relative(1); | |
9088 ins_pipe(br_cc); | |
9089 %} | |
9090 | |
9091 // ============================================================================ | |
9092 // Long Compare | |
9093 // | |
9094 // Currently we hold longs in 2 registers. Comparing such values efficiently | |
9095 // is tricky. The flavor of compare used depends on whether we are testing | |
9096 // for LT, LE, or EQ. For a simple LT test we can check just the sign bit. | |
9097 // The GE test is the negated LT test. The LE test can be had by commuting | |
9098 // the operands (yielding a GE test) and then negating; negate again for the | |
9099 // GT test. The EQ test is done by ORcc'ing the high and low halves, and the | |
9100 // NE test is negated from that. | |
9101 | |
9102 // Due to a shortcoming in the ADLC, it mixes up expressions like: | |
9103 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)). Note the | |
9104 // difference between 'Y' and '0L'. The tree-matches for the CmpI sections | |
9105 // are collapsed internally in the ADLC's dfa-gen code. The match for | |
9106 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the | |
9107 // foo match ends up with the wrong leaf. One fix is to not match both | |
9108 // reg-reg and reg-zero forms of long-compare. This is unfortunate because | |
9109 // both forms beat the trinary form of long-compare and both are very useful | |
9110 // on Intel which has so few registers. | |
9111 | |
9112 instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{ | |
9113 match(If cmp xcc); | |
9114 effect(USE labl); | |
9115 | |
9116 size(8); | |
9117 ins_cost(BRANCH_COST); | |
9118 format %{ "BP$cmp $xcc,$labl" %} | |
9119 // Prim = bits 24-22, Secnd = bits 31-30 | |
9120 ins_encode( enc_bpl( labl, cmp, xcc ) ); | |
9121 ins_pc_relative(1); | |
9122 ins_pipe(br_cc); | |
9123 %} | |
9124 | |
9125 // Manifest a CmpL3 result in an integer register. Very painful. | |
9126 // This is the test to avoid. | |
9127 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{ | |
9128 match(Set dst (CmpL3 src1 src2) ); | |
9129 effect( KILL ccr ); | |
9130 ins_cost(6*DEFAULT_COST); | |
9131 size(24); | |
9132 format %{ "CMP $src1,$src2\t\t! long\n" | |
9133 "\tBLT,a,pn done\n" | |
9134 "\tMOV -1,$dst\t! delay slot\n" | |
9135 "\tBGT,a,pn done\n" | |
9136 "\tMOV 1,$dst\t! delay slot\n" | |
9137 "\tCLR $dst\n" | |
9138 "done:" %} | |
9139 ins_encode( cmpl_flag(src1,src2,dst) ); | |
9140 ins_pipe(cmpL_reg); | |
9141 %} | |
9142 | |
9143 // Conditional move | |
9144 instruct cmovLL_reg(cmpOp cmp, flagsRegL xcc, iRegL dst, iRegL src) %{ | |
9145 match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); | |
9146 ins_cost(150); | |
9147 format %{ "MOV$cmp $xcc,$src,$dst\t! long" %} | |
9148 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) ); | |
9149 ins_pipe(ialu_reg); | |
9150 %} | |
9151 | |
9152 instruct cmovLL_imm(cmpOp cmp, flagsRegL xcc, iRegL dst, immL0 src) %{ | |
9153 match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); | |
9154 ins_cost(140); | |
9155 format %{ "MOV$cmp $xcc,$src,$dst\t! long" %} | |
9156 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::xcc)) ); | |
9157 ins_pipe(ialu_imm); | |
9158 %} | |
9159 | |
9160 instruct cmovIL_reg(cmpOp cmp, flagsRegL xcc, iRegI dst, iRegI src) %{ | |
9161 match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); | |
9162 ins_cost(150); | |
9163 format %{ "MOV$cmp $xcc,$src,$dst" %} | |
9164 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) ); | |
9165 ins_pipe(ialu_reg); | |
9166 %} | |
9167 | |
9168 instruct cmovIL_imm(cmpOp cmp, flagsRegL xcc, iRegI dst, immI11 src) %{ | |
9169 match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); | |
9170 ins_cost(140); | |
9171 format %{ "MOV$cmp $xcc,$src,$dst" %} | |
9172 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::xcc)) ); | |
9173 ins_pipe(ialu_imm); | |
9174 %} | |
9175 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
9176 instruct cmovNL_reg(cmpOp cmp, flagsRegL xcc, iRegN dst, iRegN src) %{ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
9177 match(Set dst (CMoveN (Binary cmp xcc) (Binary dst src))); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
9178 ins_cost(150); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
9179 format %{ "MOV$cmp $xcc,$src,$dst" %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
9180 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
9181 ins_pipe(ialu_reg); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
9182 %} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
9183 |
0 | 9184 instruct cmovPL_reg(cmpOp cmp, flagsRegL xcc, iRegP dst, iRegP src) %{ |
9185 match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); | |
9186 ins_cost(150); | |
9187 format %{ "MOV$cmp $xcc,$src,$dst" %} | |
9188 ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) ); | |
9189 ins_pipe(ialu_reg); | |
9190 %} | |
9191 | |
9192 instruct cmovPL_imm(cmpOp cmp, flagsRegL xcc, iRegP dst, immP0 src) %{ | |
9193 match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); | |
9194 ins_cost(140); | |
9195 format %{ "MOV$cmp $xcc,$src,$dst" %} | |
9196 ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::xcc)) ); | |
9197 ins_pipe(ialu_imm); | |
9198 %} | |
9199 | |
9200 instruct cmovFL_reg(cmpOp cmp, flagsRegL xcc, regF dst, regF src) %{ | |
9201 match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src))); | |
9202 ins_cost(150); | |
9203 opcode(0x101); | |
9204 format %{ "FMOVS$cmp $xcc,$src,$dst" %} | |
9205 ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::xcc)) ); | |
9206 ins_pipe(int_conditional_float_move); | |
9207 %} | |
9208 | |
9209 instruct cmovDL_reg(cmpOp cmp, flagsRegL xcc, regD dst, regD src) %{ | |
9210 match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src))); | |
9211 ins_cost(150); | |
9212 opcode(0x102); | |
9213 format %{ "FMOVD$cmp $xcc,$src,$dst" %} | |
9214 ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::xcc)) ); | |
9215 ins_pipe(int_conditional_float_move); | |
9216 %} | |
9217 | |
9218 // ============================================================================ | |
9219 // Safepoint Instruction | |
9220 instruct safePoint_poll(iRegP poll) %{ | |
9221 match(SafePoint poll); | |
9222 effect(USE poll); | |
9223 | |
9224 size(4); | |
9225 #ifdef _LP64 | |
9226 format %{ "LDX [$poll],R_G0\t! Safepoint: poll for GC" %} | |
9227 #else | |
9228 format %{ "LDUW [$poll],R_G0\t! Safepoint: poll for GC" %} | |
9229 #endif | |
9230 ins_encode %{ | |
9231 __ relocate(relocInfo::poll_type); | |
9232 __ ld_ptr($poll$$Register, 0, G0); | |
9233 %} | |
9234 ins_pipe(loadPollP); | |
9235 %} | |
9236 | |
9237 // ============================================================================ | |
9238 // Call Instructions | |
9239 // Call Java Static Instruction | |
9240 instruct CallStaticJavaDirect( method meth ) %{ | |
9241 match(CallStaticJava); | |
1567 | 9242 predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke()); |
0 | 9243 effect(USE meth); |
9244 | |
9245 size(8); | |
9246 ins_cost(CALL_COST); | |
9247 format %{ "CALL,static ; NOP ==> " %} | |
9248 ins_encode( Java_Static_Call( meth ), call_epilog ); | |
9249 ins_pc_relative(1); | |
9250 ins_pipe(simple_call); | |
9251 %} | |
9252 | |
1567 | 9253 // Call Java Static Instruction (method handle version) |
9254 instruct CallStaticJavaHandle(method meth, l7RegP l7_mh_SP_save) %{ | |
9255 match(CallStaticJava); | |
9256 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); | |
9257 effect(USE meth, KILL l7_mh_SP_save); | |
9258 | |
9259 size(8); | |
9260 ins_cost(CALL_COST); | |
9261 format %{ "CALL,static/MethodHandle" %} | |
9262 ins_encode(preserve_SP, Java_Static_Call(meth), restore_SP, call_epilog); | |
9263 ins_pc_relative(1); | |
9264 ins_pipe(simple_call); | |
9265 %} | |
9266 | |
0 | 9267 // Call Java Dynamic Instruction |
9268 instruct CallDynamicJavaDirect( method meth ) %{ | |
9269 match(CallDynamicJava); | |
9270 effect(USE meth); | |
9271 | |
9272 ins_cost(CALL_COST); | |
9273 format %{ "SET (empty),R_G5\n\t" | |
9274 "CALL,dynamic ; NOP ==> " %} | |
9275 ins_encode( Java_Dynamic_Call( meth ), call_epilog ); | |
9276 ins_pc_relative(1); | |
9277 ins_pipe(call); | |
9278 %} | |
9279 | |
9280 // Call Runtime Instruction | |
9281 instruct CallRuntimeDirect(method meth, l7RegP l7) %{ | |
9282 match(CallRuntime); | |
9283 effect(USE meth, KILL l7); | |
9284 ins_cost(CALL_COST); | |
9285 format %{ "CALL,runtime" %} | |
9286 ins_encode( Java_To_Runtime( meth ), | |
9287 call_epilog, adjust_long_from_native_call ); | |
9288 ins_pc_relative(1); | |
9289 ins_pipe(simple_call); | |
9290 %} | |
9291 | |
9292 // Call runtime without safepoint - same as CallRuntime | |
9293 instruct CallLeafDirect(method meth, l7RegP l7) %{ | |
9294 match(CallLeaf); | |
9295 effect(USE meth, KILL l7); | |
9296 ins_cost(CALL_COST); | |
9297 format %{ "CALL,runtime leaf" %} | |
9298 ins_encode( Java_To_Runtime( meth ), | |
9299 call_epilog, | |
9300 adjust_long_from_native_call ); | |
9301 ins_pc_relative(1); | |
9302 ins_pipe(simple_call); | |
9303 %} | |
9304 | |
9305 // Call runtime without safepoint - same as CallLeaf | |
9306 instruct CallLeafNoFPDirect(method meth, l7RegP l7) %{ | |
9307 match(CallLeafNoFP); | |
9308 effect(USE meth, KILL l7); | |
9309 ins_cost(CALL_COST); | |
9310 format %{ "CALL,runtime leaf nofp" %} | |
9311 ins_encode( Java_To_Runtime( meth ), | |
9312 call_epilog, | |
9313 adjust_long_from_native_call ); | |
9314 ins_pc_relative(1); | |
9315 ins_pipe(simple_call); | |
9316 %} | |
9317 | |
9318 // Tail Call; Jump from runtime stub to Java code. | |
9319 // Also known as an 'interprocedural jump'. | |
9320 // Target of jump will eventually return to caller. | |
9321 // TailJump below removes the return address. | |
9322 instruct TailCalljmpInd(g3RegP jump_target, inline_cache_regP method_oop) %{ | |
9323 match(TailCall jump_target method_oop ); | |
9324 | |
9325 ins_cost(CALL_COST); | |
9326 format %{ "Jmp $jump_target ; NOP \t! $method_oop holds method oop" %} | |
9327 ins_encode(form_jmpl(jump_target)); | |
9328 ins_pipe(tail_call); | |
9329 %} | |
9330 | |
9331 | |
9332 // Return Instruction | |
9333 instruct Ret() %{ | |
9334 match(Return); | |
9335 | |
9336 // The epilogue node did the ret already. | |
9337 size(0); | |
9338 format %{ "! return" %} | |
9339 ins_encode(); | |
9340 ins_pipe(empty); | |
9341 %} | |
9342 | |
9343 | |
9344 // Tail Jump; remove the return address; jump to target. | |
9345 // TailCall above leaves the return address around. | |
9346 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). | |
9347 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a | |
9348 // "restore" before this instruction (in Epilogue), we need to materialize it | |
9349 // in %i0. | |
9350 instruct tailjmpInd(g1RegP jump_target, i0RegP ex_oop) %{ | |
9351 match( TailJump jump_target ex_oop ); | |
9352 ins_cost(CALL_COST); | |
9353 format %{ "! discard R_O7\n\t" | |
9354 "Jmp $jump_target ; ADD O7,8,O1 \t! $ex_oop holds exc. oop" %} | |
9355 ins_encode(form_jmpl_set_exception_pc(jump_target)); | |
9356 // opcode(Assembler::jmpl_op3, Assembler::arith_op); | |
9357 // The hack duplicates the exception oop into G3, so that CreateEx can use it there. | |
9358 // ins_encode( form3_rs1_simm13_rd( jump_target, 0x00, R_G0 ), move_return_pc_to_o1() ); | |
9359 ins_pipe(tail_call); | |
9360 %} | |
9361 | |
9362 // Create exception oop: created by stack-crawling runtime code. | |
9363 // Created exception is now available to this handler, and is setup | |
9364 // just prior to jumping to this handler. No code emitted. | |
9365 instruct CreateException( o0RegP ex_oop ) | |
9366 %{ | |
9367 match(Set ex_oop (CreateEx)); | |
9368 ins_cost(0); | |
9369 | |
9370 size(0); | |
9371 // use the following format syntax | |
9372 format %{ "! exception oop is in R_O0; no code emitted" %} | |
9373 ins_encode(); | |
9374 ins_pipe(empty); | |
9375 %} | |
9376 | |
9377 | |
9378 // Rethrow exception: | |
9379 // The exception oop will come in the first argument position. | |
9380 // Then JUMP (not call) to the rethrow stub code. | |
9381 instruct RethrowException() | |
9382 %{ | |
9383 match(Rethrow); | |
9384 ins_cost(CALL_COST); | |
9385 | |
9386 // use the following format syntax | |
9387 format %{ "Jmp rethrow_stub" %} | |
9388 ins_encode(enc_rethrow); | |
9389 ins_pipe(tail_call); | |
9390 %} | |
9391 | |
9392 | |
9393 // Die now | |
9394 instruct ShouldNotReachHere( ) | |
9395 %{ | |
9396 match(Halt); | |
9397 ins_cost(CALL_COST); | |
9398 | |
9399 size(4); | |
9400 // Use the following format syntax | |
9401 format %{ "ILLTRAP ; ShouldNotReachHere" %} | |
9402 ins_encode( form2_illtrap() ); | |
9403 ins_pipe(tail_call); | |
9404 %} | |
9405 | |
9406 // ============================================================================ | |
9407 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass | |
9408 // array for an instance of the superklass. Set a hidden internal cache on a | |
9409 // hit (cache is checked with exposed code in gen_subtype_check()). Return | |
9410 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. | |
9411 instruct partialSubtypeCheck( o0RegP index, o1RegP sub, o2RegP super, flagsRegP pcc, o7RegP o7 ) %{ | |
9412 match(Set index (PartialSubtypeCheck sub super)); | |
9413 effect( KILL pcc, KILL o7 ); | |
9414 ins_cost(DEFAULT_COST*10); | |
9415 format %{ "CALL PartialSubtypeCheck\n\tNOP" %} | |
9416 ins_encode( enc_PartialSubtypeCheck() ); | |
9417 ins_pipe(partial_subtype_check_pipe); | |
9418 %} | |
9419 | |
9420 instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ | |
9421 match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); | |
9422 effect( KILL idx, KILL o7 ); | |
9423 ins_cost(DEFAULT_COST*10); | |
9424 format %{ "CALL PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %} | |
9425 ins_encode( enc_PartialSubtypeCheck() ); | |
9426 ins_pipe(partial_subtype_check_pipe); | |
9427 %} | |
9428 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
81
diff
changeset
|
9429 |
0 | 9430 // ============================================================================ |
9431 // inlined locking and unlocking | |
9432 | |
9433 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ | |
9434 match(Set pcc (FastLock object box)); | |
9435 | |
9436 effect(KILL scratch, TEMP scratch2); | |
9437 ins_cost(100); | |
9438 | |
9439 size(4*112); // conservative overestimation ... | |
9440 format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2, $box" %} | |
9441 ins_encode( Fast_Lock(object, box, scratch, scratch2) ); | |
9442 ins_pipe(long_memory_op); | |
9443 %} | |
9444 | |
9445 | |
9446 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ | |
9447 match(Set pcc (FastUnlock object box)); | |
9448 effect(KILL scratch, TEMP scratch2); | |
9449 ins_cost(100); | |
9450 | |
9451 size(4*120); // conservative overestimation ... | |
9452 format %{ "FASTUNLOCK $object, $box; KILL $scratch, $scratch2, $box" %} | |
9453 ins_encode( Fast_Unlock(object, box, scratch, scratch2) ); | |
9454 ins_pipe(long_memory_op); | |
9455 %} | |
9456 | |
9457 // Count and Base registers are fixed because the allocator cannot | |
9458 // kill unknown registers. The encodings are generic. | |
9459 instruct clear_array(iRegX cnt, iRegP base, iRegX temp, Universe dummy, flagsReg ccr) %{ | |
9460 match(Set dummy (ClearArray cnt base)); | |
9461 effect(TEMP temp, KILL ccr); | |
9462 ins_cost(300); | |
9463 format %{ "MOV $cnt,$temp\n" | |
9464 "loop: SUBcc $temp,8,$temp\t! Count down a dword of bytes\n" | |
9465 " BRge loop\t\t! Clearing loop\n" | |
9466 " STX G0,[$base+$temp]\t! delay slot" %} | |
9467 ins_encode( enc_Clear_Array(cnt, base, temp) ); | |
9468 ins_pipe(long_memory_op); | |
9469 %} | |
9470 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9471 instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9472 o7RegI tmp, flagsReg ccr) %{ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9473 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9474 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp); |
0 | 9475 ins_cost(300); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9476 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp" %} |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9477 ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result) ); |
0 | 9478 ins_pipe(long_memory_op); |
9479 %} | |
9480 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9481 instruct string_equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9482 o7RegI tmp, flagsReg ccr) %{ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9483 match(Set result (StrEquals (Binary str1 str2) cnt)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9484 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr); |
681 | 9485 ins_cost(300); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9486 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %} |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9487 ins_encode( enc_String_Equals(str1, str2, cnt, result) ); |
681 | 9488 ins_pipe(long_memory_op); |
9489 %} | |
9490 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9491 instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9492 o7RegI tmp2, flagsReg ccr) %{ |
681 | 9493 match(Set result (AryEq ary1 ary2)); |
9494 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr); | |
9495 ins_cost(300); | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9496 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1,$tmp2" %} |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
951
diff
changeset
|
9497 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, result)); |
681 | 9498 ins_pipe(long_memory_op); |
9499 %} | |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9500 |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9501 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9502 //---------- Zeros Count Instructions ------------------------------------------ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9503 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9504 instruct countLeadingZerosI(iRegI dst, iRegI src, iRegI tmp, flagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9505 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9506 match(Set dst (CountLeadingZerosI src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9507 effect(TEMP dst, TEMP tmp, KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9508 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9509 // x |= (x >> 1); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9510 // x |= (x >> 2); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9511 // x |= (x >> 4); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9512 // x |= (x >> 8); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9513 // x |= (x >> 16); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9514 // return (WORDBITS - popc(x)); |
1041
f875b4f472f7
6893554: SPECjvm2008 mpegaudio fails with SecurityException
twisti
parents:
1016
diff
changeset
|
9515 format %{ "SRL $src,1,$tmp\t! count leading zeros (int)\n\t" |
f875b4f472f7
6893554: SPECjvm2008 mpegaudio fails with SecurityException
twisti
parents:
1016
diff
changeset
|
9516 "SRL $src,0,$dst\t! 32-bit zero extend\n\t" |
f875b4f472f7
6893554: SPECjvm2008 mpegaudio fails with SecurityException
twisti
parents:
1016
diff
changeset
|
9517 "OR $dst,$tmp,$dst\n\t" |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9518 "SRL $dst,2,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9519 "OR $dst,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9520 "SRL $dst,4,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9521 "OR $dst,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9522 "SRL $dst,8,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9523 "OR $dst,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9524 "SRL $dst,16,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9525 "OR $dst,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9526 "POPC $dst,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9527 "MOV 32,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9528 "SUB $tmp,$dst,$dst" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9529 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9530 Register Rdst = $dst$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9531 Register Rsrc = $src$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9532 Register Rtmp = $tmp$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9533 __ srl(Rsrc, 1, Rtmp); |
1041
f875b4f472f7
6893554: SPECjvm2008 mpegaudio fails with SecurityException
twisti
parents:
1016
diff
changeset
|
9534 __ srl(Rsrc, 0, Rdst); |
f875b4f472f7
6893554: SPECjvm2008 mpegaudio fails with SecurityException
twisti
parents:
1016
diff
changeset
|
9535 __ or3(Rdst, Rtmp, Rdst); |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9536 __ srl(Rdst, 2, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9537 __ or3(Rdst, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9538 __ srl(Rdst, 4, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9539 __ or3(Rdst, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9540 __ srl(Rdst, 8, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9541 __ or3(Rdst, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9542 __ srl(Rdst, 16, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9543 __ or3(Rdst, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9544 __ popc(Rdst, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9545 __ mov(BitsPerInt, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9546 __ sub(Rtmp, Rdst, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9547 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9548 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9549 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9550 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9551 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegL tmp, flagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9552 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9553 match(Set dst (CountLeadingZerosL src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9554 effect(TEMP dst, TEMP tmp, KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9555 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9556 // x |= (x >> 1); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9557 // x |= (x >> 2); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9558 // x |= (x >> 4); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9559 // x |= (x >> 8); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9560 // x |= (x >> 16); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9561 // x |= (x >> 32); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9562 // return (WORDBITS - popc(x)); |
1041
f875b4f472f7
6893554: SPECjvm2008 mpegaudio fails with SecurityException
twisti
parents:
1016
diff
changeset
|
9563 format %{ "SRLX $src,1,$tmp\t! count leading zeros (long)\n\t" |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9564 "OR $src,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9565 "SRLX $dst,2,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9566 "OR $dst,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9567 "SRLX $dst,4,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9568 "OR $dst,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9569 "SRLX $dst,8,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9570 "OR $dst,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9571 "SRLX $dst,16,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9572 "OR $dst,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9573 "SRLX $dst,32,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9574 "OR $dst,$tmp,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9575 "POPC $dst,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9576 "MOV 64,$tmp\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9577 "SUB $tmp,$dst,$dst" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9578 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9579 Register Rdst = $dst$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9580 Register Rsrc = $src$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9581 Register Rtmp = $tmp$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9582 __ srlx(Rsrc, 1, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9583 __ or3(Rsrc, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9584 __ srlx(Rdst, 2, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9585 __ or3(Rdst, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9586 __ srlx(Rdst, 4, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9587 __ or3(Rdst, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9588 __ srlx(Rdst, 8, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9589 __ or3(Rdst, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9590 __ srlx(Rdst, 16, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9591 __ or3(Rdst, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9592 __ srlx(Rdst, 32, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9593 __ or3(Rdst, Rtmp, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9594 __ popc(Rdst, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9595 __ mov(BitsPerLong, Rtmp); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9596 __ sub(Rtmp, Rdst, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9597 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9598 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9599 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9600 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9601 instruct countTrailingZerosI(iRegI dst, iRegI src, flagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9602 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9603 match(Set dst (CountTrailingZerosI src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9604 effect(TEMP dst, KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9605 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9606 // return popc(~x & (x - 1)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9607 format %{ "SUB $src,1,$dst\t! count trailing zeros (int)\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9608 "ANDN $dst,$src,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9609 "SRL $dst,R_G0,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9610 "POPC $dst,$dst" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9611 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9612 Register Rdst = $dst$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9613 Register Rsrc = $src$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9614 __ sub(Rsrc, 1, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9615 __ andn(Rdst, Rsrc, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9616 __ srl(Rdst, G0, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9617 __ popc(Rdst, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9618 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9619 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9620 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9621 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9622 instruct countTrailingZerosL(iRegI dst, iRegL src, flagsReg cr) %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9623 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9624 match(Set dst (CountTrailingZerosL src)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9625 effect(TEMP dst, KILL cr); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9626 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9627 // return popc(~x & (x - 1)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9628 format %{ "SUB $src,1,$dst\t! count trailing zeros (long)\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9629 "ANDN $dst,$src,$dst\n\t" |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9630 "POPC $dst,$dst" %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9631 ins_encode %{ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9632 Register Rdst = $dst$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9633 Register Rsrc = $src$$Register; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9634 __ sub(Rsrc, 1, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9635 __ andn(Rdst, Rsrc, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9636 __ popc(Rdst, Rdst); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9637 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9638 ins_pipe(ialu_reg); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9639 %} |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9640 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
732
diff
changeset
|
9641 |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9642 //---------- Population Count Instructions ------------------------------------- |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9643 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9644 instruct popCountI(iRegI dst, iRegI src) %{ |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9645 predicate(UsePopCountInstruction); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9646 match(Set dst (PopCountI src)); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9647 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9648 format %{ "POPC $src, $dst" %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9649 ins_encode %{ |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9650 __ popc($src$$Register, $dst$$Register); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9651 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9652 ins_pipe(ialu_reg); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9653 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9654 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9655 // Note: Long.bitCount(long) returns an int. |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9656 instruct popCountL(iRegI dst, iRegL src) %{ |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9657 predicate(UsePopCountInstruction); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9658 match(Set dst (PopCountL src)); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9659 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9660 format %{ "POPC $src, $dst" %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9661 ins_encode %{ |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9662 __ popc($src$$Register, $dst$$Register); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9663 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9664 ins_pipe(ialu_reg); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9665 %} |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9666 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
9667 |
0 | 9668 // ============================================================================ |
9669 //------------Bytes reverse-------------------------------------------------- | |
9670 | |
9671 instruct bytes_reverse_int(iRegI dst, stackSlotI src) %{ | |
9672 match(Set dst (ReverseBytesI src)); | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9673 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9674 // Op cost is artificially doubled to make sure that load or store |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9675 // instructions are preferred over this one which requires a spill |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9676 // onto a stack slot. |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9677 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9678 format %{ "LDUWA $src, $dst\t!asi=primary_little" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9679 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9680 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9681 __ set($src$$disp + STACK_BIAS, O7); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9682 __ lduwa($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9683 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9684 ins_pipe( iload_mem ); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9685 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9686 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9687 instruct bytes_reverse_long(iRegL dst, stackSlotL src) %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9688 match(Set dst (ReverseBytesL src)); |
0 | 9689 |
9690 // Op cost is artificially doubled to make sure that load or store | |
9691 // instructions are preferred over this one which requires a spill | |
9692 // onto a stack slot. | |
9693 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9694 format %{ "LDXA $src, $dst\t!asi=primary_little" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9695 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9696 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9697 __ set($src$$disp + STACK_BIAS, O7); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9698 __ ldxa($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9699 %} |
0 | 9700 ins_pipe( iload_mem ); |
9701 %} | |
9702 | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9703 instruct bytes_reverse_unsigned_short(iRegI dst, stackSlotI src) %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9704 match(Set dst (ReverseBytesUS src)); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9705 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9706 // Op cost is artificially doubled to make sure that load or store |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9707 // instructions are preferred over this one which requires a spill |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9708 // onto a stack slot. |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9709 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9710 format %{ "LDUHA $src, $dst\t!asi=primary_little\n\t" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9711 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9712 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9713 // the value was spilled as an int so bias the load |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9714 __ set($src$$disp + STACK_BIAS + 2, O7); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9715 __ lduha($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9716 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9717 ins_pipe( iload_mem ); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9718 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9719 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9720 instruct bytes_reverse_short(iRegI dst, stackSlotI src) %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9721 match(Set dst (ReverseBytesS src)); |
0 | 9722 |
9723 // Op cost is artificially doubled to make sure that load or store | |
9724 // instructions are preferred over this one which requires a spill | |
9725 // onto a stack slot. | |
9726 ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9727 format %{ "LDSHA $src, $dst\t!asi=primary_little\n\t" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9728 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9729 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9730 // the value was spilled as an int so bias the load |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9731 __ set($src$$disp + STACK_BIAS + 2, O7); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9732 __ ldsha($src$$base$$Register, O7, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9733 %} |
0 | 9734 ins_pipe( iload_mem ); |
9735 %} | |
9736 | |
9737 // Load Integer reversed byte order | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9738 instruct loadI_reversed(iRegI dst, indIndexMemory src) %{ |
0 | 9739 match(Set dst (ReverseBytesI (LoadI src))); |
9740 | |
9741 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9742 size(4); |
0 | 9743 format %{ "LDUWA $src, $dst\t!asi=primary_little" %} |
9744 | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9745 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9746 __ lduwa($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9747 %} |
0 | 9748 ins_pipe(iload_mem); |
9749 %} | |
9750 | |
9751 // Load Long - aligned and reversed | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9752 instruct loadL_reversed(iRegL dst, indIndexMemory src) %{ |
0 | 9753 match(Set dst (ReverseBytesL (LoadL src))); |
9754 | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9755 ins_cost(MEMORY_REF_COST); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9756 size(4); |
0 | 9757 format %{ "LDXA $src, $dst\t!asi=primary_little" %} |
9758 | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9759 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9760 __ ldxa($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9761 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9762 ins_pipe(iload_mem); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9763 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9764 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9765 // Load unsigned short / char reversed byte order |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9766 instruct loadUS_reversed(iRegI dst, indIndexMemory src) %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9767 match(Set dst (ReverseBytesUS (LoadUS src))); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9768 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9769 ins_cost(MEMORY_REF_COST); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9770 size(4); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9771 format %{ "LDUHA $src, $dst\t!asi=primary_little" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9772 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9773 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9774 __ lduha($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9775 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9776 ins_pipe(iload_mem); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9777 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9778 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9779 // Load short reversed byte order |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9780 instruct loadS_reversed(iRegI dst, indIndexMemory src) %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9781 match(Set dst (ReverseBytesS (LoadS src))); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9782 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9783 ins_cost(MEMORY_REF_COST); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9784 size(4); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9785 format %{ "LDSHA $src, $dst\t!asi=primary_little" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9786 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9787 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9788 __ ldsha($src$$base$$Register, $src$$index$$Register, Assembler::ASI_PRIMARY_LITTLE, $dst$$Register); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9789 %} |
0 | 9790 ins_pipe(iload_mem); |
9791 %} | |
9792 | |
9793 // Store Integer reversed byte order | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9794 instruct storeI_reversed(indIndexMemory dst, iRegI src) %{ |
0 | 9795 match(Set dst (StoreI dst (ReverseBytesI src))); |
9796 | |
9797 ins_cost(MEMORY_REF_COST); | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9798 size(4); |
0 | 9799 format %{ "STWA $src, $dst\t!asi=primary_little" %} |
9800 | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9801 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9802 __ stwa($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9803 %} |
0 | 9804 ins_pipe(istore_mem_reg); |
9805 %} | |
9806 | |
9807 // Store Long reversed byte order | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9808 instruct storeL_reversed(indIndexMemory dst, iRegL src) %{ |
0 | 9809 match(Set dst (StoreL dst (ReverseBytesL src))); |
9810 | |
9811 ins_cost(MEMORY_REF_COST); | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9812 size(4); |
0 | 9813 format %{ "STXA $src, $dst\t!asi=primary_little" %} |
9814 | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9815 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9816 __ stxa($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9817 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9818 ins_pipe(istore_mem_reg); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9819 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9820 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9821 // Store unsighed short/char reversed byte order |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9822 instruct storeUS_reversed(indIndexMemory dst, iRegI src) %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9823 match(Set dst (StoreC dst (ReverseBytesUS src))); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9824 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9825 ins_cost(MEMORY_REF_COST); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9826 size(4); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9827 format %{ "STHA $src, $dst\t!asi=primary_little" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9828 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9829 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9830 __ stha($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9831 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9832 ins_pipe(istore_mem_reg); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9833 %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9834 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9835 // Store short reversed byte order |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9836 instruct storeS_reversed(indIndexMemory dst, iRegI src) %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9837 match(Set dst (StoreC dst (ReverseBytesS src))); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9838 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9839 ins_cost(MEMORY_REF_COST); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9840 size(4); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9841 format %{ "STHA $src, $dst\t!asi=primary_little" %} |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9842 |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9843 ins_encode %{ |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9844 __ stha($src$$Register, $dst$$base$$Register, $dst$$index$$Register, Assembler::ASI_PRIMARY_LITTLE); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1367
diff
changeset
|
9845 %} |
0 | 9846 ins_pipe(istore_mem_reg); |
9847 %} | |
9848 | |
9849 //----------PEEPHOLE RULES----------------------------------------------------- | |
9850 // These must follow all instruction definitions as they use the names | |
9851 // defined in the instructions definitions. | |
9852 // | |
605 | 9853 // peepmatch ( root_instr_name [preceding_instruction]* ); |
0 | 9854 // |
9855 // peepconstraint %{ | |
9856 // (instruction_number.operand_name relational_op instruction_number.operand_name | |
9857 // [, ...] ); | |
9858 // // instruction numbers are zero-based using left to right order in peepmatch | |
9859 // | |
9860 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); | |
9861 // // provide an instruction_number.operand_name for each operand that appears | |
9862 // // in the replacement instruction's match rule | |
9863 // | |
9864 // ---------VM FLAGS--------------------------------------------------------- | |
9865 // | |
9866 // All peephole optimizations can be turned off using -XX:-OptoPeephole | |
9867 // | |
9868 // Each peephole rule is given an identifying number starting with zero and | |
9869 // increasing by one in the order seen by the parser. An individual peephole | |
9870 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# | |
9871 // on the command-line. | |
9872 // | |
9873 // ---------CURRENT LIMITATIONS---------------------------------------------- | |
9874 // | |
9875 // Only match adjacent instructions in same basic block | |
9876 // Only equality constraints | |
9877 // Only constraints between operands, not (0.dest_reg == EAX_enc) | |
9878 // Only one replacement instruction | |
9879 // | |
9880 // ---------EXAMPLE---------------------------------------------------------- | |
9881 // | |
9882 // // pertinent parts of existing instructions in architecture description | |
9883 // instruct movI(eRegI dst, eRegI src) %{ | |
9884 // match(Set dst (CopyI src)); | |
9885 // %} | |
9886 // | |
9887 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ | |
9888 // match(Set dst (AddI dst src)); | |
9889 // effect(KILL cr); | |
9890 // %} | |
9891 // | |
9892 // // Change (inc mov) to lea | |
9893 // peephole %{ | |
9894 // // increment preceeded by register-register move | |
9895 // peepmatch ( incI_eReg movI ); | |
9896 // // require that the destination register of the increment | |
9897 // // match the destination register of the move | |
9898 // peepconstraint ( 0.dst == 1.dst ); | |
9899 // // construct a replacement instruction that sets | |
9900 // // the destination to ( move's source register + one ) | |
9901 // peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) ); | |
9902 // %} | |
9903 // | |
9904 | |
9905 // // Change load of spilled value to only a spill | |
9906 // instruct storeI(memory mem, eRegI src) %{ | |
9907 // match(Set mem (StoreI mem src)); | |
9908 // %} | |
9909 // | |
9910 // instruct loadI(eRegI dst, memory mem) %{ | |
9911 // match(Set dst (LoadI mem)); | |
9912 // %} | |
9913 // | |
9914 // peephole %{ | |
9915 // peepmatch ( loadI storeI ); | |
9916 // peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); | |
9917 // peepreplace ( storeI( 1.mem 1.mem 1.src ) ); | |
9918 // %} | |
9919 | |
9920 //----------SMARTSPILL RULES--------------------------------------------------- | |
9921 // These must follow all instruction definitions as they use the names | |
9922 // defined in the instructions definitions. | |
9923 // | |
9924 // SPARC will probably not have any of these rules due to RISC instruction set. | |
9925 | |
9926 //----------PIPELINE----------------------------------------------------------- | |
9927 // Rules which define the behavior of the target architectures pipeline. |