annotate src/cpu/x86/vm/x86_32.ad @ 3096:8073f5ad1d87

IdealGraphVisualizer: Rename predecessors to "Nodes Above" and successors to "Nodes Below" and actions "Expand Predecessors" and "Expand Successors" to "Expand Above" and "Expand Below" to avoid ambiguity with the Graal concept of successors and predecessors
author Peter Hofer <peter.hofer@jku.at>
date Wed, 29 Jun 2011 18:27:14 +0200
parents 15c9a0e16269
children bad7ecd0b6ed
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 //
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
2 // Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5 // This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 // under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 // published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 //
a61af66fc99e Initial load
duke
parents:
diff changeset
9 // This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 // version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 // accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 //
a61af66fc99e Initial load
duke
parents:
diff changeset
15 // You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 // 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
22 //
a61af66fc99e Initial load
duke
parents:
diff changeset
23 //
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // X86 Architecture Description File
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 //----------REGISTER DEFINITION BLOCK------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // This information is used by the matcher and the register allocator to
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // describe individual registers and classes of registers within the target
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // archtecture.
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 register %{
a61af66fc99e Initial load
duke
parents:
diff changeset
33 //----------Architecture Description Register Definitions----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // General Registers
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // "reg_def" name ( register save type, C convention save type,
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // ideal register type, encoding );
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // Register Save Types:
a61af66fc99e Initial load
duke
parents:
diff changeset
38 //
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // NS = No-Save: The register allocator assumes that these registers
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // can be used without saving upon entry to the method, &
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // that they do not need to be saved at call sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
42 //
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // SOC = Save-On-Call: The register allocator assumes that these registers
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // can be used without saving upon entry to the method,
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // but that they must be saved at call sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
46 //
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // SOE = Save-On-Entry: The register allocator assumes that these registers
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // must be saved before using them upon entry to the
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // method, but they do not need to be saved at call
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
51 //
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // AS = Always-Save: The register allocator assumes that these registers
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // must be saved before using them upon entry to the
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // method, & that they must be saved at call sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
55 //
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // Ideal Register Type is used to determine how to save & restore a
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
a61af66fc99e Initial load
duke
parents:
diff changeset
59 //
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // The encoding number is the actual bit-pattern placed into the opcodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // General Registers
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // Previously set EBX, ESI, and EDI as save-on-entry for java code
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // Turn off SOE in java-code due to frequent use of uncommon-traps.
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // Now that allocator is better, turn on ESI and EDI as SOE registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 reg_def EBX(SOC, SOE, Op_RegI, 3, rbx->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
68 reg_def ECX(SOC, SOC, Op_RegI, 1, rcx->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
69 reg_def ESI(SOC, SOE, Op_RegI, 6, rsi->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
70 reg_def EDI(SOC, SOE, Op_RegI, 7, rdi->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // now that adapter frames are gone EBP is always saved and restored by the prolog/epilog code
a61af66fc99e Initial load
duke
parents:
diff changeset
72 reg_def EBP(NS, SOE, Op_RegI, 5, rbp->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
73 reg_def EDX(SOC, SOC, Op_RegI, 2, rdx->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
74 reg_def EAX(SOC, SOC, Op_RegI, 0, rax->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
75 reg_def ESP( NS, NS, Op_RegI, 4, rsp->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // Special Registers
a61af66fc99e Initial load
duke
parents:
diff changeset
78 reg_def EFLAGS(SOC, SOC, 0, 8, VMRegImpl::Bad());
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // Float registers. We treat TOS/FPR0 special. It is invisible to the
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // allocator, and only shows up in the encodings.
a61af66fc99e Initial load
duke
parents:
diff changeset
82 reg_def FPR0L( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad());
a61af66fc99e Initial load
duke
parents:
diff changeset
83 reg_def FPR0H( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad());
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // Ok so here's the trick FPR1 is really st(0) except in the midst
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // of emission of assembly for a machnode. During the emission the fpu stack
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // is pushed making FPR1 == st(1) temporarily. However at any safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // the stack will not have this element so FPR1 == st(0) from the
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // oopMap viewpoint. This same weirdness with numbering causes
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // instruction encoding to have to play games with the register
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // encode to correct for this 0/1 issue. See MachSpillCopyNode::implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // where it does flt->flt moves to see an example
a61af66fc99e Initial load
duke
parents:
diff changeset
92 //
a61af66fc99e Initial load
duke
parents:
diff changeset
93 reg_def FPR1L( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
94 reg_def FPR1H( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
95 reg_def FPR2L( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
96 reg_def FPR2H( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
97 reg_def FPR3L( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
98 reg_def FPR3H( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
99 reg_def FPR4L( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
100 reg_def FPR4H( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
101 reg_def FPR5L( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
102 reg_def FPR5H( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
103 reg_def FPR6L( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
104 reg_def FPR6H( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
105 reg_def FPR7L( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
106 reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // XMM registers. 128-bit registers or 4 words each, labeled a-d.
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // Word a in each register holds a Float, words ab hold a Double.
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // We currently do not use the SIMD capabilities, so registers cd
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // are unused at the moment.
a61af66fc99e Initial load
duke
parents:
diff changeset
112 reg_def XMM0a( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
113 reg_def XMM0b( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
114 reg_def XMM1a( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
115 reg_def XMM1b( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
116 reg_def XMM2a( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
117 reg_def XMM2b( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
118 reg_def XMM3a( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
119 reg_def XMM3b( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
120 reg_def XMM4a( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
121 reg_def XMM4b( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
122 reg_def XMM5a( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
123 reg_def XMM5b( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
124 reg_def XMM6a( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
125 reg_def XMM6b( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
126 reg_def XMM7a( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
127 reg_def XMM7b( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // Specify priority of register selection within phases of register
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // allocation. Highest priority is first. A useful heuristic is to
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // give registers a low priority when they are required by machine
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // instructions, like EAX and EDX. Registers which are used as
605
98cb887364d3 6810672: Comment typos
twisti
parents: 570
diff changeset
133 // pairs must fall on an even boundary (witness the FPR#L's in this list).
0
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // For the Intel integer registers, the equivalent Long pairs are
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // EDX:EAX, EBX:ECX, and EDI:EBP.
a61af66fc99e Initial load
duke
parents:
diff changeset
136 alloc_class chunk0( ECX, EBX, EBP, EDI, EAX, EDX, ESI, ESP,
a61af66fc99e Initial load
duke
parents:
diff changeset
137 FPR0L, FPR0H, FPR1L, FPR1H, FPR2L, FPR2H,
a61af66fc99e Initial load
duke
parents:
diff changeset
138 FPR3L, FPR3H, FPR4L, FPR4H, FPR5L, FPR5H,
a61af66fc99e Initial load
duke
parents:
diff changeset
139 FPR6L, FPR6H, FPR7L, FPR7H );
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 alloc_class chunk1( XMM0a, XMM0b,
a61af66fc99e Initial load
duke
parents:
diff changeset
142 XMM1a, XMM1b,
a61af66fc99e Initial load
duke
parents:
diff changeset
143 XMM2a, XMM2b,
a61af66fc99e Initial load
duke
parents:
diff changeset
144 XMM3a, XMM3b,
a61af66fc99e Initial load
duke
parents:
diff changeset
145 XMM4a, XMM4b,
a61af66fc99e Initial load
duke
parents:
diff changeset
146 XMM5a, XMM5b,
a61af66fc99e Initial load
duke
parents:
diff changeset
147 XMM6a, XMM6b,
a61af66fc99e Initial load
duke
parents:
diff changeset
148 XMM7a, XMM7b, EFLAGS);
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 //----------Architecture Description Register Classes--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // Several register classes are automatically defined based upon information in
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // this architecture description.
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ )
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ )
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
a61af66fc99e Initial load
duke
parents:
diff changeset
158 //
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // Class for all registers
a61af66fc99e Initial load
duke
parents:
diff changeset
160 reg_class any_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX, ESP);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // Class for general registers
a61af66fc99e Initial load
duke
parents:
diff changeset
162 reg_class e_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX);
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // Class for general registers which may be used for implicit null checks on win95
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // Also safe for use by tailjump. We don't want to allocate in rbp,
a61af66fc99e Initial load
duke
parents:
diff changeset
165 reg_class e_reg_no_rbp(EAX, EDX, EDI, ESI, ECX, EBX);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Class of "X" registers
a61af66fc99e Initial load
duke
parents:
diff changeset
167 reg_class x_reg(EBX, ECX, EDX, EAX);
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // Class of registers that can appear in an address with no offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // EBP and ESP require an extra instruction byte for zero offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // Used in fast-unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
171 reg_class p_reg(EDX, EDI, ESI, EBX);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Class for general registers not including ECX
a61af66fc99e Initial load
duke
parents:
diff changeset
173 reg_class ncx_reg(EAX, EDX, EBP, EDI, ESI, EBX);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // Class for general registers not including EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
175 reg_class nax_reg(EDX, EDI, ESI, ECX, EBX);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // Class for general registers not including EAX or EBX.
a61af66fc99e Initial load
duke
parents:
diff changeset
177 reg_class nabx_reg(EDX, EDI, ESI, ECX, EBP);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // Class of EAX (for multiply and divide operations)
a61af66fc99e Initial load
duke
parents:
diff changeset
179 reg_class eax_reg(EAX);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // Class of EBX (for atomic add)
a61af66fc99e Initial load
duke
parents:
diff changeset
181 reg_class ebx_reg(EBX);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // Class of ECX (for shift and JCXZ operations and cmpLTMask)
a61af66fc99e Initial load
duke
parents:
diff changeset
183 reg_class ecx_reg(ECX);
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Class of EDX (for multiply and divide operations)
a61af66fc99e Initial load
duke
parents:
diff changeset
185 reg_class edx_reg(EDX);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // Class of EDI (for synchronization)
a61af66fc99e Initial load
duke
parents:
diff changeset
187 reg_class edi_reg(EDI);
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // Class of ESI (for synchronization)
a61af66fc99e Initial load
duke
parents:
diff changeset
189 reg_class esi_reg(ESI);
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // Singleton class for interpreter's stack pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
191 reg_class ebp_reg(EBP);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // Singleton class for stack pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
193 reg_class sp_reg(ESP);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // Singleton class for instruction pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // reg_class ip_reg(EIP);
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // Singleton class for condition codes
a61af66fc99e Initial load
duke
parents:
diff changeset
197 reg_class int_flags(EFLAGS);
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // Class of integer register pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
199 reg_class long_reg( EAX,EDX, ECX,EBX, EBP,EDI );
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // Class of integer register pairs that aligns with calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
201 reg_class eadx_reg( EAX,EDX );
a61af66fc99e Initial load
duke
parents:
diff changeset
202 reg_class ebcx_reg( ECX,EBX );
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // Not AX or DX, used in divides
a61af66fc99e Initial load
duke
parents:
diff changeset
204 reg_class nadx_reg( EBX,ECX,ESI,EDI,EBP );
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // Floating point registers. Notice FPR0 is not a choice.
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // FPR0 is not ever allocated; we use clever encodings to fake
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // a 2-address instructions out of Intels FP stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
209 reg_class flt_reg( FPR1L,FPR2L,FPR3L,FPR4L,FPR5L,FPR6L,FPR7L );
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // make a register class for SSE registers
a61af66fc99e Initial load
duke
parents:
diff changeset
212 reg_class xmm_reg(XMM0a, XMM1a, XMM2a, XMM3a, XMM4a, XMM5a, XMM6a, XMM7a);
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // make a double register class for SSE2 registers
a61af66fc99e Initial load
duke
parents:
diff changeset
215 reg_class xdb_reg(XMM0a,XMM0b, XMM1a,XMM1b, XMM2a,XMM2b, XMM3a,XMM3b,
a61af66fc99e Initial load
duke
parents:
diff changeset
216 XMM4a,XMM4b, XMM5a,XMM5b, XMM6a,XMM6b, XMM7a,XMM7b );
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 reg_class dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H,
a61af66fc99e Initial load
duke
parents:
diff changeset
219 FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H,
a61af66fc99e Initial load
duke
parents:
diff changeset
220 FPR7L,FPR7H );
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 reg_class flt_reg0( FPR1L );
a61af66fc99e Initial load
duke
parents:
diff changeset
223 reg_class dbl_reg0( FPR1L,FPR1H );
a61af66fc99e Initial load
duke
parents:
diff changeset
224 reg_class dbl_reg1( FPR2L,FPR2H );
a61af66fc99e Initial load
duke
parents:
diff changeset
225 reg_class dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H,
a61af66fc99e Initial load
duke
parents:
diff changeset
226 FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H );
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // XMM6 and XMM7 could be used as temporary registers for long, float and
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // double values for SSE2.
a61af66fc99e Initial load
duke
parents:
diff changeset
230 reg_class xdb_reg6( XMM6a,XMM6b );
a61af66fc99e Initial load
duke
parents:
diff changeset
231 reg_class xdb_reg7( XMM7a,XMM7b );
a61af66fc99e Initial load
duke
parents:
diff changeset
232 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 //----------SOURCE BLOCK-------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // This is a block of C++ code which provides values, functions, and
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // definitions necessary in the rest of the architecture description
1209
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
238 source_hpp %{
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
239 // Must be visible to the DFA in dfa_x86_32.cpp
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
240 extern bool is_operand_hi32_zero(Node* n);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
241 %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
242
0
a61af66fc99e Initial load
duke
parents:
diff changeset
243 source %{
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
244 #define RELOC_IMM32 Assembler::imm_operand
0
a61af66fc99e Initial load
duke
parents:
diff changeset
245 #define RELOC_DISP32 Assembler::disp32_operand
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 #define __ _masm.
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // How to find the high register of a Long pair, given the low register
a61af66fc99e Initial load
duke
parents:
diff changeset
250 #define HIGH_FROM_LOW(x) ((x)+2)
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // These masks are used to provide 128-bit aligned bitmasks to the XMM
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // instructions, to allow sign-masking or sign-bit flipping. They allow
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // fast versions of NegF/NegD and AbsF/AbsD.
a61af66fc99e Initial load
duke
parents:
diff changeset
255
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // Note: 'double' and 'long long' have 32-bits alignment on x86.
a61af66fc99e Initial load
duke
parents:
diff changeset
257 static jlong* double_quadword(jlong *adr, jlong lo, jlong hi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // Use the expression (adr)&(~0xF) to provide 128-bits aligned address
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // of 128-bits operands for SSE instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
260 jlong *operand = (jlong*)(((uintptr_t)adr)&((uintptr_t)(~0xF)));
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // Store the value to a 128-bits operand.
a61af66fc99e Initial load
duke
parents:
diff changeset
262 operand[0] = lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 operand[1] = hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 return operand;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Buffer for 128-bits masks used by SSE instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
268 static jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment)
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Static initialization during VM startup.
a61af66fc99e Initial load
duke
parents:
diff changeset
271 static jlong *float_signmask_pool = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF));
a61af66fc99e Initial load
duke
parents:
diff changeset
272 static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF));
a61af66fc99e Initial load
duke
parents:
diff changeset
273 static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000));
a61af66fc99e Initial load
duke
parents:
diff changeset
274 static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
a61af66fc99e Initial load
duke
parents:
diff changeset
275
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
276 // Offset hacking within calls.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
277 static int pre_call_FPU_size() {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
278 if (Compile::current()->in_24_bit_fp_mode())
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
279 return 6; // fldcw
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
280 return 0;
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
281 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
282
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
283 static int preserve_SP_size() {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
284 return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg)
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
285 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
286
0
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // !!!!! Special hack to get all type of calls to specify the byte offset
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // from the start of the call to the point where the return address
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // will point.
a61af66fc99e Initial load
duke
parents:
diff changeset
290 int MachCallStaticJavaNode::ret_addr_offset() {
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
291 int offset = 5 + pre_call_FPU_size(); // 5 bytes from start of call to where return address points
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
292 if (_method_handle_invoke)
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
293 offset += preserve_SP_size();
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
294 return offset;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 int MachCallDynamicJavaNode::ret_addr_offset() {
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
298 return 10 + pre_call_FPU_size(); // 10 bytes from start of call to where return address points
0
a61af66fc99e Initial load
duke
parents:
diff changeset
299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 static int sizeof_FFree_Float_Stack_All = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 int MachCallRuntimeNode::ret_addr_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 assert(sizeof_FFree_Float_Stack_All != -1, "must have been emitted already");
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
305 return sizeof_FFree_Float_Stack_All + 5 + pre_call_FPU_size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // Indicate if the safepoint node needs the polling page as an input.
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // Since x86 does have absolute addressing, it doesn't.
a61af66fc99e Initial load
duke
parents:
diff changeset
310 bool SafePointNode::needs_polling_address_input() {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 //
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // Compute padding required for nodes which need alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
316 //
a61af66fc99e Initial load
duke
parents:
diff changeset
317
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // The address of the call instruction needs to be 4-byte aligned to
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // ensure that it does not span a cache line so that it can be patched.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 int CallStaticJavaDirectNode::compute_padding(int current_offset) const {
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
321 current_offset += pre_call_FPU_size(); // skip fldcw, if any
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
322 current_offset += 1; // skip call opcode byte
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
323 return round_to(current_offset, alignment_required()) - current_offset;
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
324 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
325
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
326 // The address of the call instruction needs to be 4-byte aligned to
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
327 // ensure that it does not span a cache line so that it can be patched.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
328 int CallStaticJavaHandleNode::compute_padding(int current_offset) const {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
329 current_offset += pre_call_FPU_size(); // skip fldcw, if any
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
330 current_offset += preserve_SP_size(); // skip mov rbp, rsp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
331 current_offset += 1; // skip call opcode byte
a61af66fc99e Initial load
duke
parents:
diff changeset
332 return round_to(current_offset, alignment_required()) - current_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // The address of the call instruction needs to be 4-byte aligned to
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // ensure that it does not span a cache line so that it can be patched.
a61af66fc99e Initial load
duke
parents:
diff changeset
337 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const {
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
338 current_offset += pre_call_FPU_size(); // skip fldcw, if any
0
a61af66fc99e Initial load
duke
parents:
diff changeset
339 current_offset += 5; // skip MOV instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
340 current_offset += 1; // skip call opcode byte
a61af66fc99e Initial load
duke
parents:
diff changeset
341 return round_to(current_offset, alignment_required()) - current_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
345 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
346 st->print("INT3");
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // EMIT_RM()
a61af66fc99e Initial load
duke
parents:
diff changeset
351 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 unsigned char c = (unsigned char)((f1 << 6) | (f2 << 3) | f3);
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
353 cbuf.insts()->emit_int8(c);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // EMIT_CC()
a61af66fc99e Initial load
duke
parents:
diff changeset
357 void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 unsigned char c = (unsigned char)( f1 | f2 );
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
359 cbuf.insts()->emit_int8(c);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // EMIT_OPCODE()
a61af66fc99e Initial load
duke
parents:
diff changeset
363 void emit_opcode(CodeBuffer &cbuf, int code) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
364 cbuf.insts()->emit_int8((unsigned char) code);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // EMIT_OPCODE() w/ relocation information
a61af66fc99e Initial load
duke
parents:
diff changeset
368 void emit_opcode(CodeBuffer &cbuf, int code, relocInfo::relocType reloc, int offset = 0) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
369 cbuf.relocate(cbuf.insts_mark() + offset, reloc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
370 emit_opcode(cbuf, code);
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // EMIT_D8()
a61af66fc99e Initial load
duke
parents:
diff changeset
374 void emit_d8(CodeBuffer &cbuf, int d8) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
375 cbuf.insts()->emit_int8((unsigned char) d8);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // EMIT_D16()
a61af66fc99e Initial load
duke
parents:
diff changeset
379 void emit_d16(CodeBuffer &cbuf, int d16) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
380 cbuf.insts()->emit_int16(d16);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
382
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // EMIT_D32()
a61af66fc99e Initial load
duke
parents:
diff changeset
384 void emit_d32(CodeBuffer &cbuf, int d32) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
385 cbuf.insts()->emit_int32(d32);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // emit 32 bit value and construct relocation entry from relocInfo::relocType
a61af66fc99e Initial load
duke
parents:
diff changeset
389 void emit_d32_reloc(CodeBuffer &cbuf, int d32, relocInfo::relocType reloc,
a61af66fc99e Initial load
duke
parents:
diff changeset
390 int format) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
391 cbuf.relocate(cbuf.insts_mark(), reloc, format);
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
392 cbuf.insts()->emit_int32(d32);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
394
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // emit 32 bit value and construct relocation entry from RelocationHolder
a61af66fc99e Initial load
duke
parents:
diff changeset
396 void emit_d32_reloc(CodeBuffer &cbuf, int d32, RelocationHolder const& rspec,
a61af66fc99e Initial load
duke
parents:
diff changeset
397 int format) {
a61af66fc99e Initial load
duke
parents:
diff changeset
398 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
399 if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 986
diff changeset
400 assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
402 #endif
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
403 cbuf.relocate(cbuf.insts_mark(), rspec, format);
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
404 cbuf.insts()->emit_int32(d32);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 // Access stack slot for load or store
a61af66fc99e Initial load
duke
parents:
diff changeset
408 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
409 emit_opcode( cbuf, opcode ); // (e.g., FILD [ESP+src])
a61af66fc99e Initial load
duke
parents:
diff changeset
410 if( -128 <= disp && disp <= 127 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 emit_rm( cbuf, 0x01, rm_field, ESP_enc ); // R/M byte
a61af66fc99e Initial load
duke
parents:
diff changeset
412 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte
a61af66fc99e Initial load
duke
parents:
diff changeset
413 emit_d8 (cbuf, disp); // Displacement // R/M byte
a61af66fc99e Initial load
duke
parents:
diff changeset
414 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 emit_rm( cbuf, 0x02, rm_field, ESP_enc ); // R/M byte
a61af66fc99e Initial load
duke
parents:
diff changeset
416 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte
a61af66fc99e Initial load
duke
parents:
diff changeset
417 emit_d32(cbuf, disp); // Displacement // R/M byte
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // eRegI ereg, memory mem) %{ // emit_reg_mem
a61af66fc99e Initial load
duke
parents:
diff changeset
422 void encode_RegMem( CodeBuffer &cbuf, int reg_encoding, int base, int index, int scale, int displace, bool displace_is_oop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // There is no index & no scale, use form without SIB byte
a61af66fc99e Initial load
duke
parents:
diff changeset
424 if ((index == 0x4) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
425 (scale == 0) && (base != ESP_enc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // If no displacement, mode is 0x0; unless base is [EBP]
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if ( (displace == 0) && (base != EBP_enc) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 emit_rm(cbuf, 0x0, reg_encoding, base);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430 else { // If 8-bit displacement, mode 0x1
a61af66fc99e Initial load
duke
parents:
diff changeset
431 if ((displace >= -128) && (displace <= 127)
a61af66fc99e Initial load
duke
parents:
diff changeset
432 && !(displace_is_oop) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
433 emit_rm(cbuf, 0x1, reg_encoding, base);
a61af66fc99e Initial load
duke
parents:
diff changeset
434 emit_d8(cbuf, displace);
a61af66fc99e Initial load
duke
parents:
diff changeset
435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
436 else { // If 32-bit displacement
a61af66fc99e Initial load
duke
parents:
diff changeset
437 if (base == -1) { // Special flag for absolute address
a61af66fc99e Initial load
duke
parents:
diff changeset
438 emit_rm(cbuf, 0x0, reg_encoding, 0x5);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // (manual lies; no SIB needed here)
a61af66fc99e Initial load
duke
parents:
diff changeset
440 if ( displace_is_oop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 emit_d32_reloc(cbuf, displace, relocInfo::oop_type, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
442 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 emit_d32 (cbuf, displace);
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
446 else { // Normal base + offset
a61af66fc99e Initial load
duke
parents:
diff changeset
447 emit_rm(cbuf, 0x2, reg_encoding, base);
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if ( displace_is_oop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 emit_d32_reloc(cbuf, displace, relocInfo::oop_type, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
450 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
451 emit_d32 (cbuf, displace);
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457 else { // Else, encode with the SIB byte
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // If no displacement, mode is 0x0; unless base is [EBP]
a61af66fc99e Initial load
duke
parents:
diff changeset
459 if (displace == 0 && (base != EBP_enc)) { // If no displacement
a61af66fc99e Initial load
duke
parents:
diff changeset
460 emit_rm(cbuf, 0x0, reg_encoding, 0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
461 emit_rm(cbuf, scale, index, base);
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463 else { // If 8-bit displacement, mode 0x1
a61af66fc99e Initial load
duke
parents:
diff changeset
464 if ((displace >= -128) && (displace <= 127)
a61af66fc99e Initial load
duke
parents:
diff changeset
465 && !(displace_is_oop) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
466 emit_rm(cbuf, 0x1, reg_encoding, 0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
467 emit_rm(cbuf, scale, index, base);
a61af66fc99e Initial load
duke
parents:
diff changeset
468 emit_d8(cbuf, displace);
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
470 else { // If 32-bit displacement
a61af66fc99e Initial load
duke
parents:
diff changeset
471 if (base == 0x04 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 emit_rm(cbuf, 0x2, reg_encoding, 0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 emit_rm(cbuf, scale, index, 0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 emit_rm(cbuf, 0x2, reg_encoding, 0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
476 emit_rm(cbuf, scale, index, base);
a61af66fc99e Initial load
duke
parents:
diff changeset
477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
478 if ( displace_is_oop ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 emit_d32_reloc(cbuf, displace, relocInfo::oop_type, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
480 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
481 emit_d32 (cbuf, displace);
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488
a61af66fc99e Initial load
duke
parents:
diff changeset
489 void encode_Copy( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
490 if( dst_encoding == src_encoding ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // reg-reg copy, use an empty encoding
a61af66fc99e Initial load
duke
parents:
diff changeset
492 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
493 emit_opcode( cbuf, 0x8B );
a61af66fc99e Initial load
duke
parents:
diff changeset
494 emit_rm(cbuf, 0x3, dst_encoding, src_encoding );
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 if( dst_encoding == src_encoding ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // reg-reg copy, use an empty encoding
a61af66fc99e Initial load
duke
parents:
diff changeset
501 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
502 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509 //=============================================================================
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
510 const bool Matcher::constant_table_absolute_addressing = true;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
511 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
512
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
513 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
514 // Empty encoding
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
515 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
516
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
517 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
518 return 0;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
519 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
520
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
521 #ifndef PRODUCT
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
522 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
523 st->print("# MachConstantBaseNode (empty encoding)");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
524 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
525 #endif
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
526
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
527
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
528 //=============================================================================
0
a61af66fc99e Initial load
duke
parents:
diff changeset
529 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
530 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 Compile* C = ra_->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
532 if( C->in_24_bit_fp_mode() ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
533 st->print("FLDCW 24 bit fpu control word");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
534 st->print_cr(""); st->print("\t");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536
a61af66fc99e Initial load
duke
parents:
diff changeset
537 int framesize = C->frame_slots() << LogBytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // Remove two words for return addr and rbp,
a61af66fc99e Initial load
duke
parents:
diff changeset
540 framesize -= 2*wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // Calls to C2R adapters often do not accept exceptional returns.
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // We require that their callers must bang for them. But be careful, because
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // some VM calls (such as call site linkage) can use several kilobytes of
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // stack. But the stack safety zone should account for that.
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // See bugs 4446381, 4468289, 4497237.
a61af66fc99e Initial load
duke
parents:
diff changeset
547 if (C->need_stack_bang(framesize)) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
548 st->print_cr("# stack bang"); st->print("\t");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
550 st->print_cr("PUSHL EBP"); st->print("\t");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
553 st->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
554 st->print_cr(""); st->print("\t");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
555 framesize -= wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
559 if (framesize) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
560 st->print("SUB ESP,%d\t# Create frame",framesize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
561 }
a61af66fc99e Initial load
duke
parents:
diff changeset
562 } else {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
563 st->print("SUB ESP,%d\t# Create frame",framesize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
565 }
a61af66fc99e Initial load
duke
parents:
diff changeset
566 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 Compile* C = ra_->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
571
a61af66fc99e Initial load
duke
parents:
diff changeset
572 if (UseSSE >= 2 && VerifyFPU) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
574 masm.verify_FPU(0, "FPU stack must be clean on entry");
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // WARNING: Initial instruction MUST be 5 bytes or longer so that
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // NativeJump::patch_verified_entry will be able to patch out the entry
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // code safely. The fldcw is ok at 6 bytes, the push to verify stack
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // depth is ok at 5 bytes, the frame allocation can be either 3 or
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // 6 bytes. So if we don't do the fldcw or the push then we must
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // use the 6 byte frame allocation even if we have no frame. :-(
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // If method sets FPU control word do it now
a61af66fc99e Initial load
duke
parents:
diff changeset
584 if( C->in_24_bit_fp_mode() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
585 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
586 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24()));
a61af66fc99e Initial load
duke
parents:
diff changeset
587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 int framesize = C->frame_slots() << LogBytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // Remove two words for return addr and rbp,
a61af66fc99e Initial load
duke
parents:
diff changeset
592 framesize -= 2*wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // Calls to C2R adapters often do not accept exceptional returns.
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // We require that their callers must bang for them. But be careful, because
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // some VM calls (such as call site linkage) can use several kilobytes of
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // stack. But the stack safety zone should account for that.
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // See bugs 4446381, 4468289, 4497237.
a61af66fc99e Initial load
duke
parents:
diff changeset
599 if (C->need_stack_bang(framesize)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
600 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 masm.generate_stack_overflow_check(framesize);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // We always push rbp, so that on return to interpreter rbp, will be
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // restored correctly and we can correct the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
606 emit_opcode(cbuf, 0x50 | EBP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
a61af66fc99e Initial load
duke
parents:
diff changeset
609 emit_opcode(cbuf, 0x68); // push 0xbadb100d
a61af66fc99e Initial load
duke
parents:
diff changeset
610 emit_d32(cbuf, 0xbadb100d);
a61af66fc99e Initial load
duke
parents:
diff changeset
611 framesize -= wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
615 if (framesize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
616 emit_opcode(cbuf, 0x83); // sub SP,#framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
617 emit_rm(cbuf, 0x3, 0x05, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 emit_d8(cbuf, framesize);
a61af66fc99e Initial load
duke
parents:
diff changeset
619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
620 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
621 emit_opcode(cbuf, 0x81); // sub SP,#framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
622 emit_rm(cbuf, 0x3, 0x05, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 emit_d32(cbuf, framesize);
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
625 C->set_frame_complete(cbuf.insts_size());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
628 if (VerifyStackAtCalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
629 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
630 MacroAssembler masm(&cbuf);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
631 masm.push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
632 masm.mov(rax, rsp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
633 masm.andptr(rax, StackAlignmentInBytes-1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
634 masm.cmpptr(rax, StackAlignmentInBytes-wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
635 masm.pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
636 masm.jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
637 masm.stop("Stack is not properly aligned!");
a61af66fc99e Initial load
duke
parents:
diff changeset
638 masm.bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
640 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
641
a61af66fc99e Initial load
duke
parents:
diff changeset
642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
643
a61af66fc99e Initial load
duke
parents:
diff changeset
644 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
645 return MachNode::size(ra_); // too many variables; just compute it the hard way
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 int MachPrologNode::reloc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
649 return 0; // a large enough number
a61af66fc99e Initial load
duke
parents:
diff changeset
650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
653 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
654 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
655 Compile *C = ra_->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 int framesize = C->frame_slots() << LogBytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // Remove two words for return addr and rbp,
a61af66fc99e Initial load
duke
parents:
diff changeset
659 framesize -= 2*wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
660
a61af66fc99e Initial load
duke
parents:
diff changeset
661 if( C->in_24_bit_fp_mode() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
662 st->print("FLDCW standard control word");
a61af66fc99e Initial load
duke
parents:
diff changeset
663 st->cr(); st->print("\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665 if( framesize ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
666 st->print("ADD ESP,%d\t# Destroy frame",framesize);
a61af66fc99e Initial load
duke
parents:
diff changeset
667 st->cr(); st->print("\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
669 st->print_cr("POPL EBP"); st->print("\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
670 if( do_polling() && C->is_method_compilation() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
671 st->print("TEST PollPage,EAX\t! Poll Safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
672 st->cr(); st->print("\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
675 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
678 Compile *C = ra_->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
679
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // If method set FPU control word, restore to standard control word
a61af66fc99e Initial load
duke
parents:
diff changeset
681 if( C->in_24_bit_fp_mode() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
683 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685
a61af66fc99e Initial load
duke
parents:
diff changeset
686 int framesize = C->frame_slots() << LogBytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
687 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
688 // Remove two words for return addr and rbp,
a61af66fc99e Initial load
duke
parents:
diff changeset
689 framesize -= 2*wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
a61af66fc99e Initial load
duke
parents:
diff changeset
692
a61af66fc99e Initial load
duke
parents:
diff changeset
693 if( framesize >= 128 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 emit_opcode(cbuf, 0x81); // add SP, #framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
695 emit_rm(cbuf, 0x3, 0x00, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
696 emit_d32(cbuf, framesize);
a61af66fc99e Initial load
duke
parents:
diff changeset
697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
698 else if( framesize ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
699 emit_opcode(cbuf, 0x83); // add SP, #framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
700 emit_rm(cbuf, 0x3, 0x00, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
701 emit_d8(cbuf, framesize);
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 emit_opcode(cbuf, 0x58 | EBP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 if( do_polling() && C->is_method_compilation() ) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
707 cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
708 emit_opcode(cbuf,0x85);
a61af66fc99e Initial load
duke
parents:
diff changeset
709 emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
710 emit_d32(cbuf, (intptr_t)os::get_polling_page());
a61af66fc99e Initial load
duke
parents:
diff changeset
711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
715 Compile *C = ra_->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // If method set FPU control word, restore to standard control word
a61af66fc99e Initial load
duke
parents:
diff changeset
717 int size = C->in_24_bit_fp_mode() ? 6 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if( do_polling() && C->is_method_compilation() ) size += 6;
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 int framesize = C->frame_slots() << LogBytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
721 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // Remove two words for return addr and rbp,
a61af66fc99e Initial load
duke
parents:
diff changeset
723 framesize -= 2*wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
724
a61af66fc99e Initial load
duke
parents:
diff changeset
725 size++; // popl rbp,
a61af66fc99e Initial load
duke
parents:
diff changeset
726
a61af66fc99e Initial load
duke
parents:
diff changeset
727 if( framesize >= 128 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 size += 6;
a61af66fc99e Initial load
duke
parents:
diff changeset
729 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 size += framesize ? 3 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
732 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735 int MachEpilogNode::reloc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 return 0; // a large enough number
a61af66fc99e Initial load
duke
parents:
diff changeset
737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
738
a61af66fc99e Initial load
duke
parents:
diff changeset
739 const Pipeline * MachEpilogNode::pipeline() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
740 return MachNode::pipeline_class();
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 int MachEpilogNode::safepoint_offset() const { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
744
a61af66fc99e Initial load
duke
parents:
diff changeset
745 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
746
a61af66fc99e Initial load
duke
parents:
diff changeset
747 enum RC { rc_bad, rc_int, rc_float, rc_xmm, rc_stack };
a61af66fc99e Initial load
duke
parents:
diff changeset
748 static enum RC rc_class( OptoReg::Name reg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 if( !OptoReg::is_valid(reg) ) return rc_bad;
a61af66fc99e Initial load
duke
parents:
diff changeset
751 if (OptoReg::is_stack(reg)) return rc_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 VMReg r = OptoReg::as_VMReg(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 if (r->is_Register()) return rc_int;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 if (r->is_FloatRegister()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
756 assert(UseSSE < 2, "shouldn't be used in SSE2+ mode");
a61af66fc99e Initial load
duke
parents:
diff changeset
757 return rc_float;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
759 assert(r->is_XMMRegister(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
760 return rc_xmm;
a61af66fc99e Initial load
duke
parents:
diff changeset
761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
762
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
763 static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
764 int opcode, const char *op_str, int size, outputStream* st ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
765 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
766 emit_opcode (*cbuf, opcode );
a61af66fc99e Initial load
duke
parents:
diff changeset
767 encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
768 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
769 } else if( !do_size ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
770 if( size != 0 ) st->print("\n\t");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
771 if( opcode == 0x8B || opcode == 0x89 ) { // MOV
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
772 if( is_load ) st->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
773 else st->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
774 } else { // FLD, FST, PUSH, POP
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
775 st->print("%s [ESP + #%d]",op_str,offset);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
777 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
780 return size+3+offset_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
782
a61af66fc99e Initial load
duke
parents:
diff changeset
783 // Helper for XMM registers. Extra opcode bits, limited syntax.
a61af66fc99e Initial load
duke
parents:
diff changeset
784 static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
785 int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
786 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
787 if( reg_lo+1 == reg_hi ) { // double move?
a61af66fc99e Initial load
duke
parents:
diff changeset
788 if( is_load && !UseXmmLoadAndClearUpper )
a61af66fc99e Initial load
duke
parents:
diff changeset
789 emit_opcode(*cbuf, 0x66 ); // use 'movlpd' for load
a61af66fc99e Initial load
duke
parents:
diff changeset
790 else
a61af66fc99e Initial load
duke
parents:
diff changeset
791 emit_opcode(*cbuf, 0xF2 ); // use 'movsd' otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
792 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
793 emit_opcode(*cbuf, 0xF3 );
a61af66fc99e Initial load
duke
parents:
diff changeset
794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
795 emit_opcode(*cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
796 if( reg_lo+1 == reg_hi && is_load && !UseXmmLoadAndClearUpper )
a61af66fc99e Initial load
duke
parents:
diff changeset
797 emit_opcode(*cbuf, 0x12 ); // use 'movlpd' for load
a61af66fc99e Initial load
duke
parents:
diff changeset
798 else
a61af66fc99e Initial load
duke
parents:
diff changeset
799 emit_opcode(*cbuf, is_load ? 0x10 : 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
800 encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
801 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
802 } else if( !do_size ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
803 if( size != 0 ) st->print("\n\t");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
804 if( reg_lo+1 == reg_hi ) { // double move?
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
805 if( is_load ) st->print("%s %s,[ESP + #%d]",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
806 UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
a61af66fc99e Initial load
duke
parents:
diff changeset
807 Matcher::regName[reg_lo], offset);
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
808 else st->print("MOVSD [ESP + #%d],%s",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
809 offset, Matcher::regName[reg_lo]);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 } else {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
811 if( is_load ) st->print("MOVSS %s,[ESP + #%d]",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
812 Matcher::regName[reg_lo], offset);
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
813 else st->print("MOVSS [ESP + #%d],%s",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
814 offset, Matcher::regName[reg_lo]);
a61af66fc99e Initial load
duke
parents:
diff changeset
815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
816 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
819 return size+5+offset_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
821
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
824 int src_hi, int dst_hi, int size, outputStream* st ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
825 if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
a61af66fc99e Initial load
duke
parents:
diff changeset
826 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
827 if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
828 emit_opcode(*cbuf, 0x66 );
a61af66fc99e Initial load
duke
parents:
diff changeset
829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
830 emit_opcode(*cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
831 emit_opcode(*cbuf, 0x28 );
a61af66fc99e Initial load
duke
parents:
diff changeset
832 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
a61af66fc99e Initial load
duke
parents:
diff changeset
833 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
834 } else if( !do_size ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
835 if( size != 0 ) st->print("\n\t");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
836 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
837 st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
838 } else {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
839 st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
841 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
843 return size + ((src_lo+1 == src_hi && dst_lo+1 == dst_hi) ? 4 : 3);
a61af66fc99e Initial load
duke
parents:
diff changeset
844 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
845 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
846 emit_opcode(*cbuf, (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ? 0xF2 : 0xF3 );
a61af66fc99e Initial load
duke
parents:
diff changeset
847 emit_opcode(*cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
848 emit_opcode(*cbuf, 0x10 );
a61af66fc99e Initial load
duke
parents:
diff changeset
849 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
a61af66fc99e Initial load
duke
parents:
diff changeset
850 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
851 } else if( !do_size ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
852 if( size != 0 ) st->print("\n\t");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
853 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
854 st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
855 } else {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
856 st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
858 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
860 return size+4;
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863
1730
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
864 static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
865 int src_hi, int dst_hi, int size, outputStream* st ) {
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
866 // 32-bit
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
867 if (cbuf) {
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
868 emit_opcode(*cbuf, 0x66);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
869 emit_opcode(*cbuf, 0x0F);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
870 emit_opcode(*cbuf, 0x6E);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
871 emit_rm(*cbuf, 0x3, Matcher::_regEncode[dst_lo] & 7, Matcher::_regEncode[src_lo] & 7);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
872 #ifndef PRODUCT
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
873 } else if (!do_size) {
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
874 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
875 #endif
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
876 }
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
877 return 4;
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
878 }
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
879
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
880
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
881 static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
882 int src_hi, int dst_hi, int size, outputStream* st ) {
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
883 // 32-bit
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
884 if (cbuf) {
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
885 emit_opcode(*cbuf, 0x66);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
886 emit_opcode(*cbuf, 0x0F);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
887 emit_opcode(*cbuf, 0x7E);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
888 emit_rm(*cbuf, 0x3, Matcher::_regEncode[src_lo] & 7, Matcher::_regEncode[dst_lo] & 7);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
889 #ifndef PRODUCT
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
890 } else if (!do_size) {
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
891 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
892 #endif
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
893 }
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
894 return 4;
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
895 }
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
896
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
897 static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
898 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
899 emit_opcode(*cbuf, 0x8B );
a61af66fc99e Initial load
duke
parents:
diff changeset
900 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
a61af66fc99e Initial load
duke
parents:
diff changeset
901 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
902 } else if( !do_size ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
903 if( size != 0 ) st->print("\n\t");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
904 st->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
905 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
907 return size+2;
a61af66fc99e Initial load
duke
parents:
diff changeset
908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
909
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
910 static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
911 int offset, int size, outputStream* st ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
912 if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there
a61af66fc99e Initial load
duke
parents:
diff changeset
913 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
914 emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it)
a61af66fc99e Initial load
duke
parents:
diff changeset
915 emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] );
a61af66fc99e Initial load
duke
parents:
diff changeset
916 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
917 } else if( !do_size ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
918 if( size != 0 ) st->print("\n\t");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
919 st->print("FLD %s",Matcher::regName[src_lo]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
920 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
922 size += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 int st_op = (src_lo != FPR1L_num) ? EBX_num /*store & pop*/ : EDX_num /*store no pop*/;
a61af66fc99e Initial load
duke
parents:
diff changeset
926 const char *op_str;
a61af66fc99e Initial load
duke
parents:
diff changeset
927 int op;
a61af66fc99e Initial load
duke
parents:
diff changeset
928 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double store?
a61af66fc99e Initial load
duke
parents:
diff changeset
929 op_str = (src_lo != FPR1L_num) ? "FSTP_D" : "FST_D ";
a61af66fc99e Initial load
duke
parents:
diff changeset
930 op = 0xDD;
a61af66fc99e Initial load
duke
parents:
diff changeset
931 } else { // 32-bit store
a61af66fc99e Initial load
duke
parents:
diff changeset
932 op_str = (src_lo != FPR1L_num) ? "FSTP_S" : "FST_S ";
a61af66fc99e Initial load
duke
parents:
diff changeset
933 op = 0xD9;
a61af66fc99e Initial load
duke
parents:
diff changeset
934 assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
a61af66fc99e Initial load
duke
parents:
diff changeset
935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
936
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
937 return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939
a61af66fc99e Initial load
duke
parents:
diff changeset
940 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
941 // Get registers to move
a61af66fc99e Initial load
duke
parents:
diff changeset
942 OptoReg::Name src_second = ra_->get_reg_second(in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
943 OptoReg::Name src_first = ra_->get_reg_first(in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
944 OptoReg::Name dst_second = ra_->get_reg_second(this );
a61af66fc99e Initial load
duke
parents:
diff changeset
945 OptoReg::Name dst_first = ra_->get_reg_first(this );
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 enum RC src_second_rc = rc_class(src_second);
a61af66fc99e Initial load
duke
parents:
diff changeset
948 enum RC src_first_rc = rc_class(src_first);
a61af66fc99e Initial load
duke
parents:
diff changeset
949 enum RC dst_second_rc = rc_class(dst_second);
a61af66fc99e Initial load
duke
parents:
diff changeset
950 enum RC dst_first_rc = rc_class(dst_first);
a61af66fc99e Initial load
duke
parents:
diff changeset
951
a61af66fc99e Initial load
duke
parents:
diff changeset
952 assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // Generate spill code!
a61af66fc99e Initial load
duke
parents:
diff changeset
955 int size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
956
a61af66fc99e Initial load
duke
parents:
diff changeset
957 if( src_first == dst_first && src_second == dst_second )
a61af66fc99e Initial load
duke
parents:
diff changeset
958 return size; // Self copy, no move
a61af66fc99e Initial load
duke
parents:
diff changeset
959
a61af66fc99e Initial load
duke
parents:
diff changeset
960 // --------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // Check for mem-mem move. push/pop to move.
a61af66fc99e Initial load
duke
parents:
diff changeset
962 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
963 if( src_second == dst_first ) { // overlapping stack copy ranges
a61af66fc99e Initial load
duke
parents:
diff changeset
964 assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
965 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
966 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
967 src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits
a61af66fc99e Initial load
duke
parents:
diff changeset
968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // move low bits
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
970 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size, st);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
971 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
972 if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
973 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
974 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
976 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // --------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // Check for integer reg-reg copy
a61af66fc99e Initial load
duke
parents:
diff changeset
981 if( src_first_rc == rc_int && dst_first_rc == rc_int )
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
982 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
983
a61af66fc99e Initial load
duke
parents:
diff changeset
984 // Check for integer store
a61af66fc99e Initial load
duke
parents:
diff changeset
985 if( src_first_rc == rc_int && dst_first_rc == rc_stack )
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
986 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // Check for integer load
a61af66fc99e Initial load
duke
parents:
diff changeset
989 if( dst_first_rc == rc_int && src_first_rc == rc_stack )
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
990 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
991
1730
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
992 // Check for integer reg-xmm reg copy
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
993 if( src_first_rc == rc_int && dst_first_rc == rc_xmm ) {
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
994 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad),
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
995 "no 64 bit integer-float reg moves" );
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
996 return impl_movgpr2x_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
997 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
998 // --------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // Check for float reg-reg copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 if( src_first_rc == rc_float && dst_first_rc == rc_float ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 (src_first+1 == src_second && dst_first+1 == dst_second), "no non-adjacent float-moves" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1004
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // Note the mucking with the register encode to compensate for the 0/1
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 // indexing issue mentioned in a comment in the reg_def sections
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 // for FPR registers many lines above here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 if( src_first != FPR1L_num ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 emit_opcode (*cbuf, 0xD9 ); // FLD ST(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 emit_d8 (*cbuf, 0xC0+Matcher::_regEncode[src_first]-1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 emit_opcode (*cbuf, 0xDD ); // FSTP ST(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 emit_d8 (*cbuf, 0xD8+Matcher::_regEncode[dst_first] );
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 emit_opcode (*cbuf, 0xDD ); // FST ST(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 emit_d8 (*cbuf, 0xD0+Matcher::_regEncode[dst_first]-1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 } else if( !do_size ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 if( size != 0 ) st->print("\n\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 if( src_first != FPR1L_num ) st->print("FLD %s\n\tFSTP %s",Matcher::regName[src_first],Matcher::regName[dst_first]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 else st->print( "FST %s", Matcher::regName[dst_first]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 return size + ((src_first != FPR1L_num) ? 2+2 : 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 // Check for float store
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1030 return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1032
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // Check for float load
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 if( dst_first_rc == rc_float && src_first_rc == rc_stack ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 int offset = ra_->reg2offset(src_first);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 const char *op_str;
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 int op;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 if( src_first+1 == src_second && dst_first+1 == dst_second ) { // double load?
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 op_str = "FLD_D";
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 op = 0xDD;
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 } else { // 32-bit load
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 op_str = "FLD_S";
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 op = 0xD9;
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 assert( src_second_rc == rc_bad && dst_second_rc == rc_bad, "no non-adjacent float-loads" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 emit_opcode (*cbuf, op );
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 encode_RegMem(*cbuf, 0x0, ESP_enc, 0x4, 0, offset, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 emit_opcode (*cbuf, 0xDD ); // FSTP ST(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 emit_d8 (*cbuf, 0xD8+Matcher::_regEncode[dst_first] );
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 } else if( !do_size ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 if( size != 0 ) st->print("\n\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 st->print("%s ST,[ESP + #%d]\n\tFSTP %s",op_str, offset,Matcher::regName[dst_first]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 return size + 3+offset_size+2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1060
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // Check for xmm reg-reg copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 if( src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 (src_first+1 == src_second && dst_first+1 == dst_second),
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 "no non-adjacent float-moves" );
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1066 return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
1730
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
1069 // Check for xmm reg-integer reg copy
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
1070 if( src_first_rc == rc_xmm && dst_first_rc == rc_int ) {
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
1071 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad),
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
1072 "no 64 bit float-integer reg moves" );
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
1073 return impl_movx2gpr_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
1074 }
f55c4f82ab9d 6978249: spill between cpu and fpu registers when those moves are fast
never
parents: 1579
diff changeset
1075
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 // Check for xmm store
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1078 return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 // Check for float xmm load
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1083 return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1085
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 // Copy from float reg to xmm reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 if( dst_first_rc == rc_xmm && src_first_rc == rc_float ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // copy to the top of stack from floating point reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // and use LEA to preserve flags
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP-8]
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 emit_rm(*cbuf, 0x1, ESP_enc, 0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 emit_rm(*cbuf, 0x0, 0x04, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 emit_d8(*cbuf,0xF8);
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 } else if( !do_size ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 if( size != 0 ) st->print("\n\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 st->print("LEA ESP,[ESP-8]");
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 size += 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
1102
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1103 size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1104
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // Copy from the temp memory to the xmm reg.
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1106 size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1107
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 if( cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8]
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 emit_rm(*cbuf, 0x1, ESP_enc, 0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 emit_rm(*cbuf, 0x0, 0x04, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 emit_d8(*cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 } else if( !do_size ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 if( size != 0 ) st->print("\n\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 st->print("LEA ESP,[ESP+8]");
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 size += 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1122
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 assert( size > 0, "missed a case" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1124
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // --------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // Check for second bits still needing moving.
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 if( src_second == dst_second )
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 return size; // Self copy; no move
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // Check for second word int-int move
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 if( src_second_rc == rc_int && dst_second_rc == rc_int )
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1133 return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1134
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // Check for second word integer store
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 if( src_second_rc == rc_int && dst_second_rc == rc_stack )
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1137 return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // Check for second word integer load
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 if( dst_second_rc == rc_int && src_second_rc == rc_stack )
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1141 return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1142
a61af66fc99e Initial load
duke
parents:
diff changeset
1143
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 implementation( NULL, ra_, false, st );
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1152
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 implementation( &cbuf, ra_, false, NULL );
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 return implementation( NULL, ra_, true, NULL );
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 st->print("NOP \t# %d bytes pad for loops and calls", _count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1167
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 __ nop(_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 uint MachNopNode::size(PhaseRegAlloc *) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 return _count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1176
a61af66fc99e Initial load
duke
parents:
diff changeset
1177
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 int reg = ra_->get_reg_first(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 st->print("LEA %s,[ESP + #%d]",Matcher::regName[reg],offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1186
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 int reg = ra_->get_encode(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 if( offset >= 128 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 emit_rm(cbuf, 0x2, reg, 0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 emit_rm(cbuf, 0x0, 0x04, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 emit_d32(cbuf, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 emit_rm(cbuf, 0x1, reg, 0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 emit_rm(cbuf, 0x0, 0x04, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 emit_d8(cbuf, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1203
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 if( offset >= 128 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 return 7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 return 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1213
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 // emit call stub, compiled java to interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 void emit_java_to_interp(CodeBuffer &cbuf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 // Stub is fixed up when the corresponding call is converted from calling
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // compiled code to calling interpreted code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // mov rbx,0
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 // jmp -1
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1223 address mark = cbuf.insts_mark(); // get mark within main instrs section
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1224
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1225 // Note that the code buffer's insts_mark is always relative to insts.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // That's why we must use the macroassembler to generate a stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1228
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 address base =
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 __ start_a_stub(Compile::MAX_stubs_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 if (base == NULL) return; // CodeBuffer::expand failed
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // static stub relocation stores the instruction address of the call
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM32);
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // static stub relocation also tags the methodOop in the code-stream.
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 __ movoop(rbx, (jobject)NULL); // method is zapped till fixup time
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
1236 // This is recognized as unresolved by relocs/nativeInst/ic code
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
1237 __ jump(RuntimeAddress(__ pc()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1238
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 __ end_a_stub();
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1240 // Update current stubs pointer and restore insts_end.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // size of call stub, compiled java to interpretor
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 uint size_java_to_interp() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 return 10; // movl; jmp
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 // relocation entries for call stub, compiled java to interpretor
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 uint reloc_java_to_interp() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1250
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 st->print_cr( "CMP EAX,[ECX+4]\t# Inline cache check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 st->print_cr("\tJNE SharedRuntime::handle_ic_miss_stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 st->print_cr("\tNOP");
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 st->print_cr("\tNOP");
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 if( !OptoBreakpoint )
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 st->print_cr("\tNOP");
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 #ifdef ASSERT
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1266 uint insts_size = cbuf.insts_size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
1268 masm.cmpptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 masm.jump_cc(Assembler::notEqual,
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 /* WARNING these NOPs are critical so that verified entry point is properly
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 aligned for patching by NativeJump::patch_verified_entry() */
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 int nops_cnt = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 if( !OptoBreakpoint ) // Leave space for int3
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 nops_cnt += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 masm.nop(nops_cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1277
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1278 assert(cbuf.insts_size() - insts_size == size(ra_), "checking code size of inline cache node");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1280
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 return OptoBreakpoint ? 11 : 12;
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1284
a61af66fc99e Initial load
duke
parents:
diff changeset
1285
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 uint size_exception_handler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // NativeCall instruction size is the same as NativeJump.
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // exception handler starts out as jump and can be patched to
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // a call be deoptimization. (4932387)
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // Note that this value is also credited (in output.cpp) to
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 // the size of the code section.
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 return NativeJump::instruction_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1295
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // Emit exception handler code. Stuff framesize into a register
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // and call a VM stub routine.
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 int emit_exception_handler(CodeBuffer& cbuf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1299
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1300 // Note that the code buffer's insts_mark is always relative to insts.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // That's why we must use the macroassembler to generate a handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 address base =
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 __ start_a_stub(size_exception_handler());
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 if (base == NULL) return 0; // CodeBuffer::expand failed
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 int offset = __ offset();
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1307 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 __ end_a_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 return offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1312
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 uint size_deopt_handler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // NativeCall instruction size is the same as NativeJump.
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 // exception handler starts out as jump and can be patched to
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // a call be deoptimization. (4932387)
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // Note that this value is also credited (in output.cpp) to
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // the size of the code section.
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 return 5 + NativeJump::instruction_size; // pushl(); jmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1321
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 // Emit deopt handler code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 int emit_deopt_handler(CodeBuffer& cbuf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1324
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1325 // Note that the code buffer's insts_mark is always relative to insts.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 // That's why we must use the macroassembler to generate a handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 address base =
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 __ start_a_stub(size_exception_handler());
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 if (base == NULL) return 0; // CodeBuffer::expand failed
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 int offset = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 InternalAddress here(__ pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 __ pushptr(here.addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1334
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 __ end_a_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 return offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1340
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
775
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
1342 const bool Matcher::match_rule_supported(int opcode) {
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
1343 if (!has_match_rule(opcode))
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
1344 return false;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
1345
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
1346 return true; // Per default match rules are supported.
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
1347 }
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
1348
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 int Matcher::regnum_to_fpu_offset(int regnum) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 return regnum - 32; // The FP registers are in the second chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1352
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // This is UltraSparc specific, true just means we have fast l2f conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 const bool Matcher::convL2FSupported(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1357
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 // Vector width in bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 const uint Matcher::vector_width_in_bytes(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 return UseSSE >= 2 ? 8 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1362
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 // Vector ideal reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 const uint Matcher::vector_ideal_reg(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 return Op_RegD;
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1367
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 // Is this branch offset short enough that a short branch can be used?
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 // NOTE: If the platform does not provide any short branch variants, then
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // 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: 403
diff changeset
1372 bool Matcher::is_short_branch_offset(int rule, int offset) {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1373 // the short version of jmpConUCF2 contains multiple branches,
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1374 // making the reach slightly less
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1375 if (rule == jmpConUCF2_rule)
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
1376 return (-126 <= offset && offset <= 125);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 return (-128 <= offset && offset <= 127);
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1379
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 const bool Matcher::isSimpleConstant64(jlong value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1384
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // The ecx parameter to rep stos for the ClearArray node is in dwords.
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 const bool Matcher::init_array_count_is_in_bytes = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1387
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // Threshold size for cleararray.
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 const int Matcher::init_array_short_size = 8 * BytesPerLong;
a61af66fc99e Initial load
duke
parents:
diff changeset
1390
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 // Should the Matcher clone shifts on addressing modes, expecting them to
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 // be subsumed into complex addressing expressions or compute them into
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 // registers? True for Intel but false for most RISCs
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 const bool Matcher::clone_shift_expressions = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1395
2401
7e88bdae86ec 7029017: Additional architecture support for c2 compiler
roland
parents: 2320
diff changeset
1396 // Do we need to mask the count passed to shift instructions or does
7e88bdae86ec 7029017: Additional architecture support for c2 compiler
roland
parents: 2320
diff changeset
1397 // the cpu only look at the lower 5/6 bits anyway?
7e88bdae86ec 7029017: Additional architecture support for c2 compiler
roland
parents: 2320
diff changeset
1398 const bool Matcher::need_masked_shift_count = false;
7e88bdae86ec 7029017: Additional architecture support for c2 compiler
roland
parents: 2320
diff changeset
1399
1575
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1567
diff changeset
1400 bool Matcher::narrow_oop_use_complex_address() {
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1567
diff changeset
1401 ShouldNotCallThis();
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1567
diff changeset
1402 return true;
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1567
diff changeset
1403 }
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1567
diff changeset
1404
3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops
kvn
parents: 1567
diff changeset
1405
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 // Is it better to copy float constants, or load them directly from memory?
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 // Intel can load a float constant from a direct address, requiring no
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 // extra registers. Most RISCs will have to materialize an address into a
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // register first, so they would do better to copy the constant from stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 const bool Matcher::rematerialize_float_constants = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1411
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // If CPU can load and store mis-aligned doubles directly then no fixup is
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // needed. Else we split the double into 2 integer pieces and move it
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 // piece-by-piece. Only happens when passing doubles into C code as the
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // Java calling convention forces doubles to be aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 const bool Matcher::misaligned_doubles_ok = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1417
a61af66fc99e Initial load
duke
parents:
diff changeset
1418
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 // Get the memory operand from the node
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 uint numopnds = node->num_opnds(); // Virtual call for number of operands
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 uint skipped = node->oper_input_base(); // Sum of leaves skipped so far
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 assert( idx >= skipped, "idx too low in pd_implicit_null_fixup" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 uint opcnt = 1; // First operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 uint num_edges = node->_opnds[1]->num_edges(); // leaves for first operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 while( idx >= skipped+num_edges ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 skipped += num_edges;
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 opcnt++; // Bump operand count
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 assert( opcnt < numopnds, "Accessing non-existent operand" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 num_edges = node->_opnds[opcnt]->num_edges(); // leaves for next operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1432
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 MachOper *memory = node->_opnds[opcnt];
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 MachOper *new_memory = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 switch (memory->opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 case DIRECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 case INDOFFSET32X:
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 // No transformation necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 case INDIRECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 new_memory = new (C) indirect_win95_safeOper( );
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 case INDOFFSET8:
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 new_memory = new (C) indOffset8_win95_safeOper(memory->disp(NULL, NULL, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 case INDOFFSET32:
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 new_memory = new (C) indOffset32_win95_safeOper(memory->disp(NULL, NULL, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 case INDINDEXOFFSET:
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 new_memory = new (C) indIndexOffset_win95_safeOper(memory->disp(NULL, NULL, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 case INDINDEXSCALE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 new_memory = new (C) indIndexScale_win95_safeOper(memory->scale());
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 case INDINDEXSCALEOFFSET:
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 new_memory = new (C) indIndexScaleOffset_win95_safeOper(memory->scale(), memory->disp(NULL, NULL, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 case LOAD_LONG_INDIRECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 case LOAD_LONG_INDOFFSET32:
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 // Does not use EBP as address register, use { EDX, EBX, EDI, ESI}
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 assert(false, "unexpected memory operand in pd_implicit_null_fixup()");
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 node->_opnds[opcnt] = new_memory;
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1468
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // Advertise here if the CPU requires explicit rounding operations
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // to implement the UseStrictFP mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 const bool Matcher::strict_fp_requires_explicit_rounding = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1472
1274
2883969d09e7 6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents: 1209
diff changeset
1473 // 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: 1209
diff changeset
1474 // On x32 it is stored with convertion only when FPU is used for floats.
2883969d09e7 6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents: 1209
diff changeset
1475 bool Matcher::float_in_double() { return (UseSSE == 0); }
2883969d09e7 6910664: C2: java/util/Arrays/Sorting.java fails with DeoptimizeALot flag
kvn
parents: 1209
diff changeset
1476
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 // Do ints take an entire long register or just half?
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 const bool Matcher::int_in_long = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1479
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // Return whether or not this register is ever used as an argument. This
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // function is used on startup to build the trampoline stubs in generateOptoStub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 // Registers not mentioned will be killed by the VM call in the trampoline, and
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 // arguments in those registers not be available to the callee.
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 bool Matcher::can_be_java_arg( int reg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 if( reg == ECX_num || reg == EDX_num ) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 if( (reg == XMM0a_num || reg == XMM1a_num) && UseSSE>=1 ) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 if( (reg == XMM0b_num || reg == XMM1b_num) && UseSSE>=2 ) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1490
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 bool Matcher::is_spillable_arg( int reg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 return can_be_java_arg(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1494
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1495 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1496 // Use hardware integer DIV instruction when
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1497 // it is faster than a code which use multiply.
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1498 // Only when constant divisor fits into 32 bit
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1499 // (min_jint is excluded to get only correct
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1500 // positive 32 bit values from negative).
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1501 return VM_Version::has_fast_idiv() &&
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1502 (divisor == (int)divisor && divisor != min_jint);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1503 }
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1504
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // Register for DIVI projection of divmodI
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 RegMask Matcher::divI_proj_mask() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 return EAX_REG_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1509
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 // Register for MODI projection of divmodI
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 RegMask Matcher::modI_proj_mask() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 return EDX_REG_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1514
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 // Register for DIVL projection of divmodL
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 RegMask Matcher::divL_proj_mask() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 return RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1520
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 // Register for MODL projection of divmodL
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 RegMask Matcher::modL_proj_mask() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 return RegMask();
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1526
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1527 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1528 return EBP_REG_mask;
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1529 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1530
1209
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1531 // Returns true if the high 32 bits of the value is known to be zero.
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1532 bool is_operand_hi32_zero(Node* n) {
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1533 int opc = n->Opcode();
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1534 if (opc == Op_LoadUI2L) {
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1535 return true;
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1536 }
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1537 if (opc == Op_AndL) {
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1538 Node* o2 = n->in(2);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1539 if (o2->is_Con() && (o2->get_long() & 0xFFFFFFFF00000000LL) == 0LL) {
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1540 return true;
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1541 }
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1542 }
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1543 if (opc == Op_ConL && (n->get_long() & 0xFFFFFFFF00000000LL) == 0LL) {
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1544 return true;
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
1545 }
1209
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1546 return false;
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1547 }
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
1548
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1550
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 //----------ENCODING BLOCK-----------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 // This block specifies the encoding classes used by the compiler to output
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 // byte streams. Encoding classes generate functions which are called by
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 // Machine Instruction Nodes in order to generate the bit encoding of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 // instruction. Operands specify their base encoding interface with the
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // interface keyword. There are currently supported four interfaces,
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 // operand to generate a function which returns its register number when
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 // queried. CONST_INTER causes an operand to generate a function which
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 // returns the value of the constant when queried. MEMORY_INTER causes an
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // operand to generate four functions which return the Base Register, the
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 // Index Register, the Scale Value, and the Offset Value of the operand when
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 // queried. COND_INTER causes an operand to generate six functions which
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 // return the encoding code (ie - encoding bits for the instruction)
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 // associated with each basic boolean condition for a conditional instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 // Instructions specify two basic values for encoding. They use the
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 // ins_encode keyword to specify their encoding class (which must be one of
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 // the class names specified in the encoding block), and they use the
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 // opcode keyword to specify, in order, their primary, secondary, and
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 // tertiary opcode. Only the opcode sections which a particular instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 // needs for encoding need to be specified.
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 encode %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 // Build emit functions for each basic byte or larger field in the intel
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 // encoding scheme (opcode, rm, sib, immediate), and call them from C++
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 // code in the enc_class source block. Emit functions will live in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 // main source block for now. In future, we can generalize this by
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 // adding a syntax that specifies the sizes of fields in an order,
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 // so that the adlc can build the emit functions automagically
643
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1579
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1580 // Emit primary opcode
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1581 enc_class OpcP %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1582 emit_opcode(cbuf, $primary);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1583 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1584
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1585 // Emit secondary opcode
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1586 enc_class OpcS %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1587 emit_opcode(cbuf, $secondary);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1588 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1589
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1590 // Emit opcode directly
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1591 enc_class Opcode(immI d8) %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
1592 emit_opcode(cbuf, $d8$$constant);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1594
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 enc_class SizePrefix %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1598
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 enc_class RegReg (eRegI dst, eRegI src) %{ // RegReg(Many)
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1602
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 enc_class OpcRegReg (immI opcode, eRegI dst, eRegI src) %{ // OpcRegReg(Many)
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 emit_opcode(cbuf,$opcode$$constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1607
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 enc_class mov_r32_imm0( eRegI dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 emit_opcode( cbuf, 0xB8 + $dst$$reg ); // 0xB8+ rd -- MOV r32 ,imm32
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 emit_d32 ( cbuf, 0x0 ); // imm32==0x0
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1612
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 enc_class cdq_enc %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 // Full implementation of Java idiv and irem; checks for
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 // special case as described in JVM spec., p.243 & p.271.
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 // normal case special case
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 // input : rax,: dividend min_int
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 // reg: divisor -1
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // output: rax,: quotient (= rax, idiv reg) min_int
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 // rdx: remainder (= rax, irem reg) 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 // Code sequnce:
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 // 81 F8 00 00 00 80 cmp rax,80000000h
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 // 0F 85 0B 00 00 00 jne normal_case
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 // 33 D2 xor rdx,edx
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 // 83 F9 FF cmp rcx,0FFh
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 // 0F 84 03 00 00 00 je done
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 // normal_case:
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // 99 cdq
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // F7 F9 idiv rax,ecx
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // done:
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 emit_opcode(cbuf,0x81); emit_d8(cbuf,0xF8);
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00);
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x80); // cmp rax,80000000h
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x85);
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 emit_opcode(cbuf,0x0B); emit_d8(cbuf,0x00);
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // jne normal_case
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 emit_opcode(cbuf,0x33); emit_d8(cbuf,0xD2); // xor rdx,edx
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 emit_opcode(cbuf,0x83); emit_d8(cbuf,0xF9); emit_d8(cbuf,0xFF); // cmp rcx,0FFh
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x84);
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 emit_opcode(cbuf,0x03); emit_d8(cbuf,0x00);
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // je done
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // normal_case:
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 emit_opcode(cbuf,0x99); // cdq
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 // idiv (note: must be emitted by the user of this rule)
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 // normal:
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1653
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // Dense encoding for older common ops
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 enc_class Opc_plus(immI opcode, eRegI reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 emit_opcode(cbuf, $opcode$$constant + $reg$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1658
a61af66fc99e Initial load
duke
parents:
diff changeset
1659
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 enc_class OpcSE (immI imm) %{ // Emit primary opcode and set sign-extend bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 // Check for 8-bit immediate, and set sign extend bit in opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 emit_opcode(cbuf, $primary | 0x02);
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 else { // If 32-bit immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 emit_opcode(cbuf, $primary);
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1670
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 enc_class OpcSErm (eRegI dst, immI imm) %{ // OpcSEr/m
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 // Emit primary opcode and set sign-extend bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 // Check for 8-bit immediate, and set sign extend bit in opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 emit_opcode(cbuf, $primary | 0x02); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 else { // If 32-bit immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 emit_opcode(cbuf, $primary);
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 // Emit r/m byte with secondary opcode, after primary opcode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1682
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 enc_class Con8or32 (immI imm) %{ // Con8or32(storeImmI), 8 or 32 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 // Check for 8-bit immediate, and set sign extend bit in opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 $$$emit8$imm$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 else { // If 32-bit immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 // Output immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 $$$emit32$imm$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1693
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 enc_class Long_OpcSErm_Lo(eRegL dst, immL imm) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // Emit primary opcode and set sign-extend bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // Check for 8-bit immediate, and set sign extend bit in opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 int con = (int)$imm$$constant; // Throw away top bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary);
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // Emit r/m byte with secondary opcode, after primary opcode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 else emit_d32(cbuf,con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1704
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 enc_class Long_OpcSErm_Hi(eRegL dst, immL imm) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // Emit primary opcode and set sign-extend bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 // Check for 8-bit immediate, and set sign extend bit in opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 int con = (int)($imm$$constant >> 32); // Throw away bottom bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary);
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 // Emit r/m byte with tertiary opcode, after primary opcode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 emit_rm(cbuf, 0x3, $tertiary, HIGH_FROM_LOW($dst$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 else emit_d32(cbuf,con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1715
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 enc_class Lbl (label labl) %{ // JMP, CALL
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 Label *l = $labl$$label;
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1718 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1720
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 enc_class LblShort (label labl) %{ // JMP, CALL
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 Label *l = $labl$$label;
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1723 int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 emit_d8(cbuf, disp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1727
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 enc_class OpcSReg (eRegI dst) %{ // BSWAP
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 emit_cc(cbuf, $secondary, $dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1731
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 enc_class bswap_long_bytes(eRegL dst) %{ // BSWAP
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 int destlo = $dst$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 int desthi = HIGH_FROM_LOW(destlo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 // bswap lo
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 emit_opcode(cbuf, 0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 emit_cc(cbuf, 0xC8, destlo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // bswap hi
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 emit_opcode(cbuf, 0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 emit_cc(cbuf, 0xC8, desthi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 // xchg lo and hi
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 emit_opcode(cbuf, 0x87);
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 emit_rm(cbuf, 0x3, destlo, desthi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1745
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 enc_class RegOpc (eRegI div) %{ // IDIV, IMOD, JMP indirect, ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 emit_rm(cbuf, 0x3, $secondary, $div$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 enc_class Jcc (cmpOp cop, label labl) %{ // JCC
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 Label *l = $labl$$label;
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 $$$emit8$primary;
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 emit_cc(cbuf, $secondary, $cop$$cmpcode);
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1754 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1756
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 enc_class JccShort (cmpOp cop, label labl) %{ // JCC
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 Label *l = $labl$$label;
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 emit_cc(cbuf, $primary, $cop$$cmpcode);
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1760 int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 emit_d8(cbuf, disp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1764
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 enc_class enc_cmov(cmpOp cop ) %{ // CMOV
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 $$$emit8$primary;
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 emit_cc(cbuf, $secondary, $cop$$cmpcode);
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1769
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 enc_class enc_cmov_d(cmpOp cop, regD src ) %{ // CMOV
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 int op = 0xDA00 + $cop$$cmpcode + ($src$$reg-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 emit_d8(cbuf, op >> 8 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 emit_d8(cbuf, op & 255);
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1775
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 // emulate a CMOV with a conditional branch around a MOV
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 enc_class enc_cmov_branch( cmpOp cop, immI brOffs ) %{ // CMOV
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 // Invert sense of branch from sense of CMOV
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 emit_cc( cbuf, 0x70, ($cop$$cmpcode^1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 emit_d8( cbuf, $brOffs$$constant );
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1782
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 enc_class enc_PartialSubtypeCheck( ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 Register Redi = as_Register(EDI_enc); // result register
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 Register Reax = as_Register(EAX_enc); // super class
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 Register Recx = as_Register(ECX_enc); // killed
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 Register Resi = as_Register(ESI_enc); // sub class
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 643
diff changeset
1788 Label miss;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1789
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 MacroAssembler _masm(&cbuf);
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 643
diff changeset
1791 __ check_klass_subtype_slow_path(Resi, Reax, Recx, Redi,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 643
diff changeset
1792 NULL, &miss,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 643
diff changeset
1793 /*set_cond_codes:*/ true);
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 643
diff changeset
1794 if ($primary) {
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 643
diff changeset
1795 __ xorptr(Redi, Redi);
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 643
diff changeset
1796 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 __ bind(miss);
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1799
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 enc_class FFree_Float_Stack_All %{ // Free_Float_Stack_All
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 int start = masm.offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 if (UseSSE >= 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 if (VerifyFPU) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 masm.verify_FPU(0, "must be empty in SSE2+ mode");
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 // External c_calling_convention expects the FPU stack to be 'clean'.
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 // Compiled code leaves it dirty. Do cleanup now.
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 masm.empty_FPU_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 if (sizeof_FFree_Float_Stack_All == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 sizeof_FFree_Float_Stack_All = masm.offset() - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 assert(masm.offset() - start == sizeof_FFree_Float_Stack_All, "wrong size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1818
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 enc_class Verify_FPU_For_Leaf %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 if( VerifyFPU ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 masm.verify_FPU( -3, "Returning from Runtime Leaf call");
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1825
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 // This is the instruction starting address for relocation info.
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1828 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 $$$emit8$primary;
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 // CALL directly to the runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1831 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 runtime_call_Relocation::spec(), RELOC_IMM32 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1833
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 if (UseSSE >= 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 BasicType rt = tf()->return_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1837
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 if ((rt == T_FLOAT || rt == T_DOUBLE) && !return_value_is_used()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 // A C runtime call where the return value is unused. In SSE2+
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 // mode the result needs to be removed from the FPU stack. It's
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 // likely that this function call could be removed by the
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 // optimizer if the C function is a pure function.
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 __ ffree(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 } else if (rt == T_FLOAT) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
1845 __ lea(rsp, Address(rsp, -4));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 __ fstp_s(Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 __ movflt(xmm0, Address(rsp, 0));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
1848 __ lea(rsp, Address(rsp, 4));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 } else if (rt == T_DOUBLE) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
1850 __ lea(rsp, Address(rsp, -8));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 __ fstp_d(Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 __ movdbl(xmm0, Address(rsp, 0));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
1853 __ lea(rsp, Address(rsp, 8));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1857
a61af66fc99e Initial load
duke
parents:
diff changeset
1858
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 enc_class pre_call_FPU %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // If method sets FPU control word restore it here
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1861 debug_only(int off0 = cbuf.insts_size());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 if( Compile::current()->in_24_bit_fp_mode() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 }
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1866 debug_only(int off1 = cbuf.insts_size());
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1867 assert(off1 - off0 == pre_call_FPU_size(), "correct size prediction");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1869
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 enc_class post_call_FPU %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 // If method sets FPU control word do it here also
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 if( Compile::current()->in_24_bit_fp_mode() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1877
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1878 enc_class preserve_SP %{
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1879 debug_only(int off0 = cbuf.insts_size());
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1880 MacroAssembler _masm(&cbuf);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1881 // RBP is preserved across all calls, even compiled calls.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1882 // Use it to preserve RSP in places where the callee might change the SP.
1567
110501f54a99 6934104: JSR 292 needs to support SPARC C2
twisti
parents: 1396
diff changeset
1883 __ movptr(rbp_mh_SP_save, rsp);
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1884 debug_only(int off1 = cbuf.insts_size());
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1885 assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1886 %}
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1887
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1888 enc_class restore_SP %{
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1889 MacroAssembler _masm(&cbuf);
1567
110501f54a99 6934104: JSR 292 needs to support SPARC C2
twisti
parents: 1396
diff changeset
1890 __ movptr(rsp, rbp_mh_SP_save);
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1891 %}
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
1892
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 // who we intended to call.
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1896 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 $$$emit8$primary;
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 if ( !_method ) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1899 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 runtime_call_Relocation::spec(), RELOC_IMM32 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 } else if(_optimized_virtual) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1902 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 opt_virtual_call_Relocation::spec(), RELOC_IMM32 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 } else {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1905 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 static_call_Relocation::spec(), RELOC_IMM32 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 if( _method ) { // Emit stub for static call
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 emit_java_to_interp(cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1912
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 // !!!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 // Generate "Mov EAX,0x00", placeholder instruction to load oop-info
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 // emit_call_dynamic_prologue( cbuf );
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1917 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 emit_opcode(cbuf, 0xB8 + EAX_enc); // mov EAX,-1
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 emit_d32_reloc(cbuf, (int)Universe::non_oop_word(), oop_Relocation::spec_for_immediate(), RELOC_IMM32);
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1920 address virtual_call_oop_addr = cbuf.insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 // who we intended to call.
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1923 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 $$$emit8$primary;
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1925 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 virtual_call_Relocation::spec(virtual_call_oop_addr), RELOC_IMM32 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1928
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 enc_class Java_Compiled_Call (method meth) %{ // JAVA COMPILED CALL
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 int disp = in_bytes(methodOopDesc::from_compiled_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 assert( -128 <= disp && disp <= 127, "compiled_code_offset isn't small");
a61af66fc99e Initial load
duke
parents:
diff changeset
1932
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // CALL *[EAX+in_bytes(methodOopDesc::from_compiled_code_entry_point_offset())]
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1934 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 $$$emit8$primary;
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 emit_rm(cbuf, 0x01, $secondary, EAX_enc ); // R/M byte
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 emit_d8(cbuf, disp); // Displacement
a61af66fc99e Initial load
duke
parents:
diff changeset
1938
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1940
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 enc_class Xor_Reg (eRegI dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 emit_opcode(cbuf, 0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 emit_rm(cbuf, 0x3, $dst$$reg, $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1945
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 // Following encoding is no longer used, but may be restored if calling
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 // convention changes significantly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 // Became: Xor_Reg(EBP), Java_To_Runtime( labl )
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // enc_class Java_Interpreter_Call (label labl) %{ // JAVA INTERPRETER CALL
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 // // int ic_reg = Matcher::inline_cache_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 // // int ic_encode = Matcher::_regEncode[ic_reg];
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 // // int imo_reg = Matcher::interpreter_method_oop_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 // // int imo_encode = Matcher::_regEncode[imo_reg];
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 // // // Interpreter expects method_oop in EBX, currently a callee-saved register,
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // // // so we load it immediately before the call
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // // emit_opcode(cbuf, 0x8B); // MOV imo_reg,ic_reg # method_oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 // // emit_rm(cbuf, 0x03, imo_encode, ic_encode ); // R/M byte
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 // // xor rbp,ebp
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 // emit_opcode(cbuf, 0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 // emit_rm(cbuf, 0x3, EBP_enc, EBP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 // // CALL to interpreter.
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1966 // cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 // $$$emit8$primary;
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
1968 // emit_d32_reloc(cbuf, ($labl$$label - (int)(cbuf.insts_end()) - 4),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 // runtime_call_Relocation::spec(), RELOC_IMM32 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1971
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 enc_class RegOpcImm (eRegI dst, immI8 shift) %{ // SHL, SAR, SHR
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 $$$emit8$primary;
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 $$$emit8$shift$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1977
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 enc_class LdImmI (eRegI dst, immI src) %{ // Load Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 // Load immediate does not have a zero or sign extended version
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 // for 8-bit immediates
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 emit_opcode(cbuf, 0xB8 + $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 $$$emit32$src$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1984
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 enc_class LdImmP (eRegI dst, immI src) %{ // Load Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 // Load immediate does not have a zero or sign extended version
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 // for 8-bit immediates
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 emit_opcode(cbuf, $primary + $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 $$$emit32$src$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
1991
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 enc_class LdImmL_Lo( eRegL dst, immL src) %{ // Load Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 // Load immediate does not have a zero or sign extended version
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 // for 8-bit immediates
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 int dst_enc = $dst$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 int src_con = $src$$constant & 0x0FFFFFFFFL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 if (src_con == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 // xor dst, dst
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 emit_opcode(cbuf, 0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 emit_rm(cbuf, 0x3, dst_enc, dst_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 emit_opcode(cbuf, $primary + dst_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 emit_d32(cbuf, src_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2006
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 enc_class LdImmL_Hi( eRegL dst, immL src) %{ // Load Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 // Load immediate does not have a zero or sign extended version
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // for 8-bit immediates
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 int dst_enc = $dst$$reg + 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 int src_con = ((julong)($src$$constant)) >> 32;
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 if (src_con == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 // xor dst, dst
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 emit_opcode(cbuf, 0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 emit_rm(cbuf, 0x3, dst_enc, dst_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 emit_opcode(cbuf, $primary + dst_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 emit_d32(cbuf, src_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2021
a61af66fc99e Initial load
duke
parents:
diff changeset
2022
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 enc_class MovI2X_reg(regX dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 emit_opcode(cbuf, 0x66 ); // MOVD dst,src
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 emit_opcode(cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 emit_opcode(cbuf, 0x6E );
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2029
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 enc_class MovX2I_reg(eRegI dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 emit_opcode(cbuf, 0x66 ); // MOVD dst,src
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 emit_opcode(cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 emit_opcode(cbuf, 0x7E );
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 emit_rm(cbuf, 0x3, $src$$reg, $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2036
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 enc_class MovL2XD_reg(regXD dst, eRegL src, regXD tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 { // MOVD $dst,$src.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 emit_opcode(cbuf,0x6E);
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 { // MOVD $tmp,$src.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 emit_opcode(cbuf,0x6E);
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 { // PUNPCKLDQ $dst,$tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 emit_opcode(cbuf,0x62);
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 emit_rm(cbuf, 0x3, $dst$$reg, $tmp$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2057
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 enc_class MovXD2L_reg(eRegL dst, regXD src, regXD tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 { // MOVD $dst.lo,$src
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 emit_opcode(cbuf,0x7E);
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 emit_rm(cbuf, 0x3, $src$$reg, $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 { // PSHUFLW $tmp,$src,0x4E (01001110b)
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 emit_opcode(cbuf,0xF2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 emit_opcode(cbuf,0x70);
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 emit_d8(cbuf, 0x4E);
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 { // MOVD $dst.hi,$tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 emit_opcode(cbuf,0x7E);
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2079
a61af66fc99e Initial load
duke
parents:
diff changeset
2080
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 // Encode a reg-reg copy. If it is useless, then empty encoding.
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 enc_class enc_Copy( eRegI dst, eRegI src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 encode_Copy( cbuf, $dst$$reg, $src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2085
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 enc_class enc_CopyL_Lo( eRegI dst, eRegL src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 encode_Copy( cbuf, $dst$$reg, $src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2089
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 // Encode xmm reg-reg copy. If it is useless, then empty encoding.
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 enc_class enc_CopyXD( RegXD dst, RegXD src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 encode_CopyXD( cbuf, $dst$$reg, $src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2094
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 enc_class RegReg (eRegI dst, eRegI src) %{ // RegReg(Many)
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2098
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 enc_class RegReg_Lo(eRegL dst, eRegL src) %{ // RegReg(Many)
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 $$$emit8$primary;
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2103
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 enc_class RegReg_Hi(eRegL dst, eRegL src) %{ // RegReg(Many)
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 $$$emit8$secondary;
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2108
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 enc_class RegReg_Lo2(eRegL dst, eRegL src) %{ // RegReg(Many)
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2112
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 enc_class RegReg_Hi2(eRegL dst, eRegL src) %{ // RegReg(Many)
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2116
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 enc_class RegReg_HiLo( eRegL src, eRegI dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($src$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2120
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 enc_class Con32 (immI src) %{ // Con32(storeImmI)
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 // Output immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 $$$emit32$src$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2125
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 enc_class Con32F_as_bits(immF src) %{ // storeF_imm
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 // Output Float immediate bits
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 jfloat jf = $src$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 int jf_as_bits = jint_cast( jf );
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 emit_d32(cbuf, jf_as_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 enc_class Con32XF_as_bits(immXF src) %{ // storeX_imm
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 // Output Float immediate bits
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 jfloat jf = $src$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 int jf_as_bits = jint_cast( jf );
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 emit_d32(cbuf, jf_as_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2139
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 enc_class Con16 (immI src) %{ // Con16(storeImmI)
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 // Output immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 $$$emit16$src$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2144
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 enc_class Con_d32(immI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 emit_d32(cbuf,$src$$constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2148
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 enc_class conmemref (eRegP t1) %{ // Con32(storeImmI)
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 // Output immediate memory reference
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 emit_d32(cbuf, 0x00);
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2154
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 enc_class lock_prefix( ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 if( os::is_MP() )
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 emit_opcode(cbuf,0xF0); // [Lock]
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2159
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 // Cmp-xchg long value.
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 // Note: we need to swap rbx, and rcx before and after the
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 // cmpxchg8 instruction because the instruction uses
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 // rcx as the high order word of the new value to store but
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 // our register encoding uses rbx,.
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 enc_class enc_cmpxchg8(eSIRegP mem_ptr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2166
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // XCHG rbx,ecx
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 emit_opcode(cbuf,0x87);
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 emit_opcode(cbuf,0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 // [Lock]
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 if( os::is_MP() )
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 emit_opcode(cbuf,0xF0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // CMPXCHG8 [Eptr]
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 emit_opcode(cbuf,0xC7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 // XCHG rbx,ecx
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 emit_opcode(cbuf,0x87);
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 emit_opcode(cbuf,0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2181
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 enc_class enc_cmpxchg(eSIRegP mem_ptr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 // [Lock]
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 if( os::is_MP() )
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 emit_opcode(cbuf,0xF0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2186
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 // CMPXCHG [Eptr]
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 emit_opcode(cbuf,0xB1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2192
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 enc_class enc_flags_ne_to_boolean( iRegI res ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 int res_encoding = $res$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2195
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 // MOV res,0
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 emit_opcode( cbuf, 0xB8 + res_encoding);
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 emit_d32( cbuf, 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 // JNE,s fail
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 emit_opcode(cbuf,0x75);
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 emit_d8(cbuf, 5 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 // MOV res,1
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 emit_opcode( cbuf, 0xB8 + res_encoding);
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 emit_d32( cbuf, 1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 // fail:
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2207
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 enc_class set_instruction_start( ) %{
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
2209 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2211
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 enc_class RegMem (eRegI ereg, memory mem) %{ // emit_reg_mem
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 int reg_encoding = $ereg$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 bool disp_is_oop = $mem->disp_is_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2221
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 enc_class RegMem_Hi(eRegL ereg, memory mem) %{ // emit_reg_mem
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 int reg_encoding = HIGH_FROM_LOW($ereg$$reg); // Hi register of pair, computed from lo
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 int displace = $mem$$disp + 4; // Offset is 4 further in memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 assert( !$mem->disp_is_oop(), "Cannot add 4 to oop" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, false/*disp_is_oop*/);
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2231
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 enc_class move_long_small_shift( eRegL dst, immI_1_31 cnt ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 int r1, r2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 if( $tertiary == 0xA4 ) { r1 = $dst$$reg; r2 = HIGH_FROM_LOW($dst$$reg); }
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 else { r2 = $dst$$reg; r1 = HIGH_FROM_LOW($dst$$reg); }
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 emit_opcode(cbuf,$tertiary);
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 emit_rm(cbuf, 0x3, r1, r2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 emit_d8(cbuf,$cnt$$constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 emit_d8(cbuf,$primary);
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 emit_rm(cbuf, 0x3, $secondary, r1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 emit_d8(cbuf,$cnt$$constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2244
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 enc_class move_long_big_shift_sign( eRegL dst, immI_32_63 cnt ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 emit_opcode( cbuf, 0x8B ); // Move
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg));
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
2248 if( $cnt$$constant > 32 ) { // Shift, if not by zero
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
2249 emit_d8(cbuf,$primary);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
2250 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
2251 emit_d8(cbuf,$cnt$$constant-32);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
2252 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 emit_d8(cbuf,$primary);
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 emit_rm(cbuf, 0x3, $secondary, HIGH_FROM_LOW($dst$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 emit_d8(cbuf,31);
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2257
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 enc_class move_long_big_shift_clr( eRegL dst, immI_32_63 cnt ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 int r1, r2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 if( $secondary == 0x5 ) { r1 = $dst$$reg; r2 = HIGH_FROM_LOW($dst$$reg); }
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 else { r2 = $dst$$reg; r1 = HIGH_FROM_LOW($dst$$reg); }
a61af66fc99e Initial load
duke
parents:
diff changeset
2262
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 emit_opcode( cbuf, 0x8B ); // Move r1,r2
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 emit_rm(cbuf, 0x3, r1, r2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 if( $cnt$$constant > 32 ) { // Shift, if not by zero
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 emit_opcode(cbuf,$primary);
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 emit_rm(cbuf, 0x3, $secondary, r1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 emit_d8(cbuf,$cnt$$constant-32);
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 emit_opcode(cbuf,0x33); // XOR r2,r2
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 emit_rm(cbuf, 0x3, r2, r2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2273
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 // Clone of RegMem but accepts an extra parameter to access each
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 // half of a double in memory; it never needs relocation info.
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 enc_class Mov_MemD_half_to_Reg (immI opcode, memory mem, immI disp_for_half, eRegI rm_reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 emit_opcode(cbuf,$opcode$$constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 int reg_encoding = $rm_reg$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 int displace = $mem$$disp + $disp_for_half$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 bool disp_is_oop = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2286
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 // !!!!! Special Custom Code used by MemMove, and stack access instructions !!!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 // Clone of RegMem except the RM-byte's reg/opcode field is an ADLC-time constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 // and it never needs relocation information.
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 // Frequently used to move data between FPU's Stack Top and memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 enc_class RMopc_Mem_no_oop (immI rm_opcode, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 int rm_byte_opcode = $rm_opcode$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 assert( !$mem->disp_is_oop(), "No oops here because no relo info allowed" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2301
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 enc_class RMopc_Mem (immI rm_opcode, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 int rm_byte_opcode = $rm_opcode$$constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2311
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 enc_class RegLea (eRegI dst, eRegI src0, immI src1 ) %{ // emit_reg_lea
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 int reg_encoding = $dst$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 int index = 0x04; // 0x04 indicates no index
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 int scale = 0x00; // 0x00 indicates no scale
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 int displace = $src1$$constant; // 0x00 indicates no displacement
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 bool disp_is_oop = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2321
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 enc_class min_enc (eRegI dst, eRegI src) %{ // MIN
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 // Compare dst,src
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 emit_opcode(cbuf,0x3B);
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 // jmp dst < src around move
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 emit_opcode(cbuf,0x7C);
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 emit_d8(cbuf,2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 // move dst,src
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 emit_opcode(cbuf,0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2333
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 enc_class max_enc (eRegI dst, eRegI src) %{ // MAX
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 // Compare dst,src
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 emit_opcode(cbuf,0x3B);
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 // jmp dst > src around move
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 emit_opcode(cbuf,0x7F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 emit_d8(cbuf,2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 // move dst,src
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 emit_opcode(cbuf,0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2345
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 enc_class enc_FP_store(memory mem, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 // If src is FPR1, we can just FST to store it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 // Else we need to FLD it to FPR1, then FSTP to store/pop it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 int reg_encoding = 0x2; // Just store
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 if( $src$$reg != FPR1L_enc ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 reg_encoding = 0x3; // Store & pop
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 emit_opcode( cbuf, 0xD9 ); // FLD (i.e., push it)
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 emit_d8( cbuf, 0xC0-1+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 }
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
2360 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 emit_opcode(cbuf,$primary);
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2364
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 enc_class neg_reg(eRegI dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 // NEG $dst
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 emit_opcode(cbuf,0xF7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 emit_rm(cbuf, 0x3, 0x03, $dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2370
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 enc_class setLT_reg(eCXRegI dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 // SETLT $dst
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 emit_opcode(cbuf,0x9C);
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 emit_rm( cbuf, 0x3, 0x4, $dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2377
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 enc_class enc_cmpLTP(ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp) %{ // cadd_cmpLT
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 int tmpReg = $tmp$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2380
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 // SUB $p,$q
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 emit_opcode(cbuf,0x2B);
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 // SBB $tmp,$tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 emit_opcode(cbuf,0x1B);
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 emit_rm(cbuf, 0x3, tmpReg, tmpReg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 // AND $tmp,$y
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 emit_opcode(cbuf,0x23);
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 emit_rm(cbuf, 0x3, tmpReg, $y$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 // ADD $p,$tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 emit_opcode(cbuf,0x03);
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 emit_rm(cbuf, 0x3, $p$$reg, tmpReg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2394
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 enc_class enc_cmpLTP_mem(eRegI p, eRegI q, memory mem, eCXRegI tmp) %{ // cadd_cmpLT
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 int tmpReg = $tmp$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2397
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 // SUB $p,$q
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 emit_opcode(cbuf,0x2B);
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 // SBB $tmp,$tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 emit_opcode(cbuf,0x1B);
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 emit_rm(cbuf, 0x3, tmpReg, tmpReg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 // AND $tmp,$y
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
2405 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 emit_opcode(cbuf,0x23);
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 int reg_encoding = tmpReg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 bool disp_is_oop = $mem->disp_is_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 // ADD $p,$tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 emit_opcode(cbuf,0x03);
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 emit_rm(cbuf, 0x3, $p$$reg, tmpReg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2418
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 enc_class shift_left_long( eRegL dst, eCXRegI shift ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 // TEST shift,32
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 emit_opcode(cbuf,0xF7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 emit_rm(cbuf, 0x3, 0, ECX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 emit_d32(cbuf,0x20);
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 // JEQ,s small
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 emit_opcode(cbuf, 0x74);
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 emit_d8(cbuf, 0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 // MOV $dst.hi,$dst.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 emit_opcode( cbuf, 0x8B );
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 // CLR $dst.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 emit_opcode(cbuf, 0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 emit_rm(cbuf, 0x3, $dst$$reg, $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 // small:
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 // SHLD $dst.hi,$dst.lo,$shift
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 emit_opcode(cbuf,0xA5);
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 // SHL $dst.lo,$shift"
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 emit_opcode(cbuf,0xD3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 emit_rm(cbuf, 0x3, 0x4, $dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2442
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 enc_class shift_right_long( eRegL dst, eCXRegI shift ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 // TEST shift,32
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 emit_opcode(cbuf,0xF7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 emit_rm(cbuf, 0x3, 0, ECX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 emit_d32(cbuf,0x20);
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 // JEQ,s small
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 emit_opcode(cbuf, 0x74);
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 emit_d8(cbuf, 0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 // MOV $dst.lo,$dst.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 emit_opcode( cbuf, 0x8B );
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 // CLR $dst.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 emit_opcode(cbuf, 0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($dst$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 // small:
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 // SHRD $dst.lo,$dst.hi,$shift
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 emit_opcode(cbuf,0xAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 // SHR $dst.hi,$shift"
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 emit_opcode(cbuf,0xD3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 emit_rm(cbuf, 0x3, 0x5, HIGH_FROM_LOW($dst$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2466
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 enc_class shift_right_arith_long( eRegL dst, eCXRegI shift ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 // TEST shift,32
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 emit_opcode(cbuf,0xF7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 emit_rm(cbuf, 0x3, 0, ECX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 emit_d32(cbuf,0x20);
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 // JEQ,s small
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 emit_opcode(cbuf, 0x74);
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 emit_d8(cbuf, 0x05);
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 // MOV $dst.lo,$dst.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 emit_opcode( cbuf, 0x8B );
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 // SAR $dst.hi,31
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 emit_opcode(cbuf, 0xC1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 emit_rm(cbuf, 0x3, 7, HIGH_FROM_LOW($dst$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 emit_d8(cbuf, 0x1F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 // small:
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 // SHRD $dst.lo,$dst.hi,$shift
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 emit_opcode(cbuf,0xAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 // SAR $dst.hi,$shift"
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 emit_opcode(cbuf,0xD3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 emit_rm(cbuf, 0x3, 0x7, HIGH_FROM_LOW($dst$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2491
a61af66fc99e Initial load
duke
parents:
diff changeset
2492
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 // ----------------- Encodings for floating point unit -----------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 // May leave result in FPU-TOS or FPU reg depending on opcodes
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 enc_class OpcReg_F (regF src) %{ // FMUL, FDIV
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 $$$emit8$primary;
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 emit_rm(cbuf, 0x3, $secondary, $src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2499
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 // Pop argument in FPR0 with FSTP ST(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 enc_class PopFPU() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 emit_opcode( cbuf, 0xDD );
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 emit_d8( cbuf, 0xD8 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2505
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 // !!!!! equivalent to Pop_Reg_F
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 enc_class Pop_Reg_D( regD dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 emit_opcode( cbuf, 0xDD ); // FSTP ST(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 emit_d8( cbuf, 0xD8+$dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2511
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 enc_class Push_Reg_D( regD dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 emit_opcode( cbuf, 0xD9 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 emit_d8( cbuf, 0xC0-1+$dst$$reg ); // FLD ST(i-1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2516
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 enc_class strictfp_bias1( regD dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 emit_opcode( cbuf, 0xDB ); // FLD m80real
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 emit_opcode( cbuf, 0x2D );
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias1() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 emit_opcode( cbuf, 0xC8+$dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2524
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 enc_class strictfp_bias2( regD dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 emit_opcode( cbuf, 0xDB ); // FLD m80real
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 emit_opcode( cbuf, 0x2D );
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias2() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 emit_opcode( cbuf, 0xC8+$dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2532
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 // Special case for moving an integer register to a stack slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 enc_class OpcPRegSS( stackSlotI dst, eRegI src ) %{ // RegSS
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 store_to_stackslot( cbuf, $primary, $src$$reg, $dst$$disp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2537
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 // Special case for moving a register to a stack slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 enc_class RegSS( stackSlotI dst, eRegI src ) %{ // RegSS
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 // Opcode already emitted
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 emit_rm( cbuf, 0x02, $src$$reg, ESP_enc ); // R/M byte
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 emit_d32(cbuf, $dst$$disp); // Displacement
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2545
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 // Push the integer in stackSlot 'src' onto FP-stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 enc_class Push_Mem_I( memory src ) %{ // FILD [ESP+src]
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 store_to_stackslot( cbuf, $primary, $secondary, $src$$disp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2550
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 // Push the float in stackSlot 'src' onto FP-stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 enc_class Push_Mem_F( memory src ) %{ // FLD_S [ESP+src]
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 store_to_stackslot( cbuf, 0xD9, 0x00, $src$$disp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2555
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 // Push the double in stackSlot 'src' onto FP-stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 enc_class Push_Mem_D( memory src ) %{ // FLD_D [ESP+src]
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 store_to_stackslot( cbuf, 0xDD, 0x00, $src$$disp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2560
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 // Push FPU's TOS float to a stack-slot, and pop FPU-stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 enc_class Pop_Mem_F( stackSlotF dst ) %{ // FSTP_S [ESP+dst]
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 store_to_stackslot( cbuf, 0xD9, 0x03, $dst$$disp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2565
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 // Same as Pop_Mem_F except for opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 // Push FPU's TOS double to a stack-slot, and pop FPU-stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 enc_class Pop_Mem_D( stackSlotD dst ) %{ // FSTP_D [ESP+dst]
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 store_to_stackslot( cbuf, 0xDD, 0x03, $dst$$disp );
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2571
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 enc_class Pop_Reg_F( regF dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 emit_opcode( cbuf, 0xDD ); // FSTP ST(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 emit_d8( cbuf, 0xD8+$dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2576
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 enc_class Push_Reg_F( regF dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 emit_d8( cbuf, 0xC0-1+$dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2581
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 // Push FPU's float to a stack-slot, and pop FPU-stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 enc_class Pop_Mem_Reg_F( stackSlotF dst, regF src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 int pop = 0x02;
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 if ($src$$reg != FPR1L_enc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 emit_d8( cbuf, 0xC0-1+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 pop = 0x03;
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 store_to_stackslot( cbuf, 0xD9, pop, $dst$$disp ); // FST<P>_S [ESP+dst]
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2592
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 // Push FPU's double to a stack-slot, and pop FPU-stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 enc_class Pop_Mem_Reg_D( stackSlotD dst, regD src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 int pop = 0x02;
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 if ($src$$reg != FPR1L_enc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 emit_d8( cbuf, 0xC0-1+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 pop = 0x03;
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 store_to_stackslot( cbuf, 0xDD, pop, $dst$$disp ); // FST<P>_D [ESP+dst]
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2603
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 // Push FPU's double to a FPU-stack-slot, and pop FPU-stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 enc_class Pop_Reg_Reg_D( regD dst, regF src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 int pop = 0xD0 - 1; // -1 since we skip FLD
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 if ($src$$reg != FPR1L_enc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 emit_opcode( cbuf, 0xD9 ); // FLD ST(src-1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 emit_d8( cbuf, 0xC0-1+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 pop = 0xD8;
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 emit_opcode( cbuf, 0xDD );
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 emit_d8( cbuf, pop+$dst$$reg ); // FST<P> ST(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2615
a61af66fc99e Initial load
duke
parents:
diff changeset
2616
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 enc_class Mul_Add_F( regF dst, regF src, regF src1, regF src2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 masm.fld_s( $src1$$reg-1); // nothing at TOS, load TOS from src1.reg
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 masm.fmul( $src2$$reg+0); // value at TOS
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 masm.fadd( $src$$reg+0); // value at TOS
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 masm.fstp_d( $dst$$reg+0); // value at TOS, popped off after store
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2624
a61af66fc99e Initial load
duke
parents:
diff changeset
2625
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 enc_class Push_Reg_Mod_D( regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 // load dst in FPR0
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 emit_opcode( cbuf, 0xD9 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 emit_d8( cbuf, 0xC0-1+$dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 if ($src$$reg != FPR1L_enc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 // fincstp
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 emit_opcode (cbuf, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 emit_opcode (cbuf, 0xF7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 // swap src with FPR1:
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 // FXCH FPR1 with src
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 emit_opcode(cbuf, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 emit_d8(cbuf, 0xC8-1+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 // fdecstp
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 emit_opcode (cbuf, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 emit_opcode (cbuf, 0xF6);
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2643
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 enc_class Push_ModD_encoding( regXD src0, regXD src1) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 emit_opcode(cbuf,0x83); // SUB ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 emit_d8(cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
2649
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src1
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 encode_RegMem(cbuf, $src1$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2654
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2657
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src0
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 encode_RegMem(cbuf, $src0$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2662
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2665
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2667
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 enc_class Push_ModX_encoding( regX src0, regX src1) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 emit_opcode(cbuf,0x83); // SUB ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 emit_d8(cbuf,0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
2673
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src1
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 encode_RegMem(cbuf, $src1$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2678
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 emit_opcode(cbuf,0xD9 ); // FLD [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2681
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src0
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 encode_RegMem(cbuf, $src0$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2686
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 emit_opcode(cbuf,0xD9 ); // FLD [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2689
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2691
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 enc_class Push_ResultXD(regXD dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2694
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 // UseXmmLoadAndClearUpper ? movsd dst,[esp] : movlpd dst,[esp]
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 encode_RegMem(cbuf, $dst$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2700
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 emit_opcode(cbuf,0x83); // ADD ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 emit_opcode(cbuf,0xC4);
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 emit_d8(cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2705
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 enc_class Push_ResultX(regX dst, immI d8) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 store_to_stackslot( cbuf, 0xD9, 0x03, 0 ); //FSTP_S [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2708
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 emit_opcode (cbuf, 0xF3 ); // MOVSS dst(xmm), [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 emit_opcode (cbuf, 0x10 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 encode_RegMem(cbuf, $dst$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2713
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 emit_opcode(cbuf,0x83); // ADD ESP,d8 (4 or 8)
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 emit_opcode(cbuf,0xC4);
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 emit_d8(cbuf,$d8$$constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2718
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 enc_class Push_SrcXD(regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 emit_opcode(cbuf,0x83); // SUB ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 emit_d8(cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
2724
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2729
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2733
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 enc_class push_stack_temp_qword() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 emit_opcode(cbuf,0x83); // SUB ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 emit_d8 (cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2739
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 enc_class pop_stack_temp_qword() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 emit_opcode(cbuf,0x83); // ADD ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 emit_opcode(cbuf,0xC4);
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 emit_d8 (cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2745
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 enc_class push_xmm_to_fpr1( regXD xmm_src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], xmm_src
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 encode_RegMem(cbuf, $xmm_src$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2751
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2755
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 // Compute X^Y using Intel's fast hardware instructions, if possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 // Otherwise return a NaN.
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 enc_class pow_exp_core_encoding %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 // FPR1 holds Y*ln2(X). Compute FPR1 = 2^(Y*ln2(X))
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xC0); // fdup = fld st(0) Q Q
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xFC); // frndint int(Q) Q
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 emit_opcode(cbuf,0xDC); emit_opcode(cbuf,0xE9); // fsub st(1) -= st(0); int(Q) frac(Q)
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 emit_opcode(cbuf,0xDB); // FISTP [ESP] frac(Q)
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 emit_opcode(cbuf,0x1C);
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 emit_d8(cbuf,0x24);
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xF0); // f2xm1 2^frac(Q)-1
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xE8); // fld1 1 2^frac(Q)-1
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 emit_opcode(cbuf,0xDE); emit_opcode(cbuf,0xC1); // faddp 2^frac(Q)
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 emit_opcode(cbuf,0x8B); // mov rax,[esp+0]=int(Q)
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 encode_RegMem(cbuf, EAX_enc, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 emit_opcode(cbuf,0xC7); // mov rcx,0xFFFFF800 - overflow mask
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 emit_rm(cbuf, 0x3, 0x0, ECX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 emit_d32(cbuf,0xFFFFF800);
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 emit_opcode(cbuf,0x81); // add rax,1023 - the double exponent bias
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 emit_rm(cbuf, 0x3, 0x0, EAX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 emit_d32(cbuf,1023);
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 emit_opcode(cbuf,0x8B); // mov rbx,eax
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 emit_rm(cbuf, 0x3, EBX_enc, EAX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 emit_opcode(cbuf,0xC1); // shl rax,20 - Slide to exponent position
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 emit_rm(cbuf,0x3,0x4,EAX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 emit_d8(cbuf,20);
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 emit_opcode(cbuf,0x85); // test rbx,ecx - check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 emit_rm(cbuf, 0x3, EBX_enc, ECX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 emit_opcode(cbuf,0x0F); emit_opcode(cbuf,0x45); // CMOVne rax,ecx - overflow; stuff NAN into EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 emit_rm(cbuf, 0x3, EAX_enc, ECX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 emit_opcode(cbuf,0x89); // mov [esp+4],eax - Store as part of double word
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 encode_RegMem(cbuf, EAX_enc, ESP_enc, 0x4, 0, 4, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 emit_opcode(cbuf,0xC7); // mov [esp+0],0 - [ESP] = (double)(1<<int(Q)) = 2^int(Q)
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 emit_d32(cbuf,0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 emit_opcode(cbuf,0xDC); // fmul dword st(0),[esp+0]; FPR1 = 2^int(Q)*2^frac(Q) = 2^Q
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 encode_RegMem(cbuf, 0x1, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2794
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 // enc_class Pop_Reg_Mod_D( regD dst, regD src)
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 // was replaced by Push_Result_Mod_D followed by Pop_Reg_X() or Pop_Mem_X()
a61af66fc99e Initial load
duke
parents:
diff changeset
2797
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 enc_class Push_Result_Mod_D( regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 if ($src$$reg != FPR1L_enc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 // fincstp
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 emit_opcode (cbuf, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 emit_opcode (cbuf, 0xF7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 // FXCH FPR1 with src
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 emit_opcode(cbuf, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 emit_d8(cbuf, 0xC8-1+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 // fdecstp
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 emit_opcode (cbuf, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 emit_opcode (cbuf, 0xF6);
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 // // following asm replaced with Pop_Reg_F or Pop_Mem_F
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 // // FSTP FPR$dst$$reg
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 // emit_opcode( cbuf, 0xDD );
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 // emit_d8( cbuf, 0xD8+$dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2815
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 enc_class fnstsw_sahf_skip_parity() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 // fnstsw ax
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 emit_opcode( cbuf, 0xDF );
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 emit_opcode( cbuf, 0xE0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 // sahf
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 emit_opcode( cbuf, 0x9E );
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 // jnp ::skip
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 emit_opcode( cbuf, 0x7B );
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 emit_opcode( cbuf, 0x05 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2826
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 enc_class emitModD() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 // fprem must be iterative
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 // :: loop
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 // fprem
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 emit_opcode( cbuf, 0xD9 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 emit_opcode( cbuf, 0xF8 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 // wait
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 emit_opcode( cbuf, 0x9b );
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 // fnstsw ax
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 emit_opcode( cbuf, 0xDF );
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 emit_opcode( cbuf, 0xE0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 // sahf
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 emit_opcode( cbuf, 0x9E );
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 // jp ::loop
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 emit_opcode( cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 emit_opcode( cbuf, 0x8A );
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 emit_opcode( cbuf, 0xF4 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 emit_opcode( cbuf, 0xFF );
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 emit_opcode( cbuf, 0xFF );
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 emit_opcode( cbuf, 0xFF );
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2848
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 enc_class fpu_flags() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 // fnstsw_ax
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 emit_opcode( cbuf, 0xDF);
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 emit_opcode( cbuf, 0xE0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 // test ax,0x0400
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 emit_opcode( cbuf, 0x66 ); // operand-size prefix for 16-bit immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 emit_opcode( cbuf, 0xA9 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 emit_d16 ( cbuf, 0x0400 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 // // // This sequence works, but stalls for 12-16 cycles on PPro
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 // // test rax,0x0400
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 // emit_opcode( cbuf, 0xA9 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 // emit_d32 ( cbuf, 0x00000400 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 // jz exit (no unordered comparison)
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 emit_opcode( cbuf, 0x74 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 emit_d8 ( cbuf, 0x02 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 // mov ah,1 - treat as LT case (set carry flag)
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 emit_opcode( cbuf, 0xB4 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 emit_d8 ( cbuf, 0x01 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 // sahf
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 emit_opcode( cbuf, 0x9E);
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2871
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 enc_class cmpF_P6_fixup() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 // Fixup the integer flags in case comparison involved a NaN
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 // JNP exit (no unordered comparison, P-flag is set by NaN)
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 emit_opcode( cbuf, 0x7B );
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 emit_d8 ( cbuf, 0x03 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 // MOV AH,1 - treat as LT case (set carry flag)
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 emit_opcode( cbuf, 0xB4 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 emit_d8 ( cbuf, 0x01 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 // SAHF
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 emit_opcode( cbuf, 0x9E);
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 // NOP // target for branch to avoid branch to branch
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 emit_opcode( cbuf, 0x90);
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2886
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 // fnstsw_ax();
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 // sahf();
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 // movl(dst, nan_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 // jcc(Assembler::parity, exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 // movl(dst, less_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 // jcc(Assembler::below, exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 // movl(dst, equal_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 // jcc(Assembler::equal, exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 // movl(dst, greater_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2896
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 // less_result = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 // greater_result = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 // equal_result = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 // nan_result = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2901
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 enc_class CmpF_Result(eRegI dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 // fnstsw_ax();
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 emit_opcode( cbuf, 0xDF);
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 emit_opcode( cbuf, 0xE0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 // sahf
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 emit_opcode( cbuf, 0x9E);
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 // movl(dst, nan_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 emit_opcode( cbuf, 0xB8 + $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 emit_d32( cbuf, -1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 // jcc(Assembler::parity, exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 emit_opcode( cbuf, 0x7A );
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 emit_d8 ( cbuf, 0x13 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 // movl(dst, less_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 emit_opcode( cbuf, 0xB8 + $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 emit_d32( cbuf, -1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 // jcc(Assembler::below, exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 emit_opcode( cbuf, 0x72 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 emit_d8 ( cbuf, 0x0C );
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 // movl(dst, equal_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 emit_opcode( cbuf, 0xB8 + $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 emit_d32( cbuf, 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 // jcc(Assembler::equal, exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 emit_opcode( cbuf, 0x74 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 emit_d8 ( cbuf, 0x05 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 // movl(dst, greater_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 emit_opcode( cbuf, 0xB8 + $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 emit_d32( cbuf, 1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2930
a61af66fc99e Initial load
duke
parents:
diff changeset
2931
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 // XMM version of CmpF_Result. Because the XMM compare
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 // instructions set the EFLAGS directly. It becomes simpler than
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 // the float version above.
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 enc_class CmpX_Result(eRegI dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 Label nan, inc, done;
a61af66fc99e Initial load
duke
parents:
diff changeset
2938
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 __ jccb(Assembler::parity, nan);
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 __ jccb(Assembler::equal, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 __ jccb(Assembler::above, inc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 __ bind(nan);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
2943 __ decrement(as_Register($dst$$reg)); // NO L qqq
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 __ jmpb(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 __ bind(inc);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
2946 __ increment(as_Register($dst$$reg)); // NO L qqq
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 __ bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2949
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 // Compare the longs and set flags
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 // BROKEN! Do Not use as-is
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 enc_class cmpl_test( eRegL src1, eRegL src2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 // CMP $src1.hi,$src2.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 emit_opcode( cbuf, 0x3B );
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 // JNE,s done
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 emit_opcode(cbuf,0x75);
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 emit_d8(cbuf, 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 // CMP $src1.lo,$src2.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 emit_opcode( cbuf, 0x3B );
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 // done:
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2964
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 enc_class convert_int_long( regL dst, eRegI src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 // mov $dst.lo,$src
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 int dst_encoding = $dst$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 int src_encoding = $src$$reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 encode_Copy( cbuf, dst_encoding , src_encoding );
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 // mov $dst.hi,$src
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 encode_Copy( cbuf, HIGH_FROM_LOW(dst_encoding), src_encoding );
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 // sar $dst.hi,31
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 emit_opcode( cbuf, 0xC1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 emit_rm(cbuf, 0x3, 7, HIGH_FROM_LOW(dst_encoding) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 emit_d8(cbuf, 0x1F );
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2977
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 enc_class convert_long_double( eRegL src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 // push $src.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 emit_opcode(cbuf, 0x50+HIGH_FROM_LOW($src$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 // push $src.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 emit_opcode(cbuf, 0x50+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 // fild 64-bits at [SP]
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 emit_opcode(cbuf,0xdf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 emit_d8(cbuf, 0x6C);
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 emit_d8(cbuf, 0x24);
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 emit_d8(cbuf, 0x00);
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 // pop stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 emit_opcode(cbuf, 0x83); // add SP, #8
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 emit_rm(cbuf, 0x3, 0x00, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 emit_d8(cbuf, 0x8);
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
2993
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 enc_class multiply_con_and_shift_high( eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32_63 cnt, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 // IMUL EDX:EAX,$src1
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 emit_opcode( cbuf, 0xF7 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 emit_rm( cbuf, 0x3, 0x5, $src1$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 // SAR EDX,$cnt-32
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 int shift_count = ((int)$cnt$$constant) - 32;
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 if (shift_count > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 emit_opcode(cbuf, 0xC1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 emit_rm(cbuf, 0x3, 7, $dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 emit_d8(cbuf, shift_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3006
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 // this version doesn't have add sp, 8
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 enc_class convert_long_double2( eRegL src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 // push $src.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 emit_opcode(cbuf, 0x50+HIGH_FROM_LOW($src$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 // push $src.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 emit_opcode(cbuf, 0x50+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 // fild 64-bits at [SP]
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 emit_opcode(cbuf,0xdf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 emit_d8(cbuf, 0x6C);
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 emit_d8(cbuf, 0x24);
a61af66fc99e Initial load
duke
parents:
diff changeset
3017 emit_d8(cbuf, 0x00);
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3019
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 enc_class long_int_multiply( eADXRegL dst, nadxRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 // Basic idea: long = (long)int * (long)int
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 // IMUL EDX:EAX, src
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 emit_opcode( cbuf, 0xF7 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 emit_rm( cbuf, 0x3, 0x5, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3026
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 enc_class long_uint_multiply( eADXRegL dst, nadxRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 // MUL EDX:EAX, src
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 emit_opcode( cbuf, 0xF7 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 emit_rm( cbuf, 0x3, 0x4, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3033
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 enc_class long_multiply( eADXRegL dst, eRegL src, eRegI tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 // Basic idea: lo(result) = lo(x_lo * y_lo)
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi)
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 // MOV $tmp,$src.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 encode_Copy( cbuf, $tmp$$reg, $src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 // IMUL $tmp,EDX
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 emit_opcode( cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 emit_opcode( cbuf, 0xAF );
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 // MOV EDX,$src.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 encode_Copy( cbuf, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 // IMUL EDX,EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 emit_opcode( cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 emit_opcode( cbuf, 0xAF );
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 // ADD $tmp,EDX
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 emit_opcode( cbuf, 0x03 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 // MUL EDX:EAX,$src.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 emit_opcode( cbuf, 0xF7 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 emit_rm( cbuf, 0x3, 0x4, $src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 // ADD EDX,ESI
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 emit_opcode( cbuf, 0x03 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $tmp$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3059
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 enc_class long_multiply_con( eADXRegL dst, immL_127 src, eRegI tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 // Basic idea: lo(result) = lo(src * y_lo)
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 // hi(result) = hi(src * y_lo) + lo(src * y_hi)
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 // IMUL $tmp,EDX,$src
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 emit_opcode( cbuf, 0x6B );
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 emit_d8( cbuf, (int)$src$$constant );
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 // MOV EDX,$src
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 emit_opcode(cbuf, 0xB8 + EDX_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 emit_d32( cbuf, (int)$src$$constant );
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 // MUL EDX:EAX,EDX
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 emit_opcode( cbuf, 0xF7 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 emit_rm( cbuf, 0x3, 0x4, EDX_enc );
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 // ADD EDX,ESI
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 emit_opcode( cbuf, 0x03 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 emit_rm( cbuf, 0x3, EDX_enc, $tmp$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3077
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 enc_class long_div( eRegL src1, eRegL src2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 // PUSH src1.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 // PUSH src1.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 emit_opcode(cbuf, 0x50+$src1$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 // PUSH src2.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src2$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 // PUSH src2.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 emit_opcode(cbuf, 0x50+$src2$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 // CALL directly to the runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3088 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 emit_opcode(cbuf,0xE8); // Call into runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3090 emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::ldiv) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 // Restore stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 emit_opcode(cbuf, 0x83); // add SP, #framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 emit_rm(cbuf, 0x3, 0x00, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 emit_d8(cbuf, 4*4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3096
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 enc_class long_mod( eRegL src1, eRegL src2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 // PUSH src1.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 // PUSH src1.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 emit_opcode(cbuf, 0x50+$src1$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 // PUSH src2.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src2$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 // PUSH src2.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 emit_opcode(cbuf, 0x50+$src2$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 // CALL directly to the runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3107 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 emit_opcode(cbuf,0xE8); // Call into runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3109 emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::lrem ) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 // Restore stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 emit_opcode(cbuf, 0x83); // add SP, #framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 emit_rm(cbuf, 0x3, 0x00, ESP_enc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 emit_d8(cbuf, 4*4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3115
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 enc_class long_cmp_flags0( eRegL src, eRegI tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 // MOV $tmp,$src.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 emit_opcode(cbuf, 0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 // OR $tmp,$src.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 emit_opcode(cbuf, 0x0B);
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3124
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 enc_class long_cmp_flags1( eRegL src1, eRegL src2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 // CMP $src1.lo,$src2.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 emit_opcode( cbuf, 0x3B );
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 // JNE,s skip
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 emit_cc(cbuf, 0x70, 0x5);
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 emit_d8(cbuf,2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 // CMP $src1.hi,$src2.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 emit_opcode( cbuf, 0x3B );
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3136
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 enc_class long_cmp_flags2( eRegL src1, eRegL src2, eRegI tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 // CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 emit_opcode( cbuf, 0x3B );
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 // MOV $tmp,$src1.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 emit_opcode( cbuf, 0x8B );
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src1$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 // SBB $tmp,$src2.hi\t! Compute flags for long compare
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 emit_opcode( cbuf, 0x1B );
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src2$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3148
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 enc_class long_cmp_flags3( eRegL src, eRegI tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 // XOR $tmp,$tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 emit_opcode(cbuf,0x33); // XOR
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 emit_rm(cbuf,0x3, $tmp$$reg, $tmp$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 // CMP $tmp,$src.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 emit_opcode( cbuf, 0x3B );
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 // SBB $tmp,$src.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 emit_opcode( cbuf, 0x1B );
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3160
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 // Sniff, sniff... smells like Gnu Superoptimizer
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 enc_class neg_long( eRegL dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 emit_opcode(cbuf,0xF7); // NEG hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 emit_opcode(cbuf,0xF7); // NEG lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 emit_rm (cbuf,0x3, 0x3, $dst$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 emit_opcode(cbuf,0x83); // SBB hi,0
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 emit_d8 (cbuf,0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3171
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 enc_class movq_ld(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 MacroAssembler _masm(&cbuf);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
3174 __ movq($dst$$XMMRegister, $mem$$Address);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3175 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3176
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 enc_class movq_st(memory mem, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 MacroAssembler _masm(&cbuf);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
3179 __ movq($mem$$Address, $src$$XMMRegister);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3181
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 enc_class pshufd_8x8(regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3184
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 encode_CopyXD(cbuf, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 __ punpcklbw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg), 0x00);
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3189
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 enc_class pshufd_4x16(regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3192
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), 0x00);
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3195
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 enc_class pshufd(regXD dst, regXD src, int mode) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3198
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 __ pshufd(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), $mode);
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3201
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 enc_class pxor(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3204
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 __ pxor(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3207
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 enc_class mov_i2x(regXD dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 MacroAssembler _masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3210
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3211 __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3213
a61af66fc99e Initial load
duke
parents:
diff changeset
3214
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 // Because the transitions from emitted code to the runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 // monitorenter/exit helper stubs are so slow it's critical that
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 // we inline both the stack-locking fast-path and the inflated fast path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 // See also: cmpFastLock and cmpFastUnlock.
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 // What follows is a specialized inline transliteration of the code
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 // in slow_enter() and slow_exit(). If we're concerned about I$ bloat
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 // another option would be to emit TrySlowEnter and TrySlowExit methods
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 // at startup-time. These methods would accept arguments as
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 // (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 // indications in the icc.ZFlag. Fast_Lock and Fast_Unlock would simply
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 // marshal the arguments and emit calls to TrySlowEnter and TrySlowExit.
a61af66fc99e Initial load
duke
parents:
diff changeset
3228 // In practice, however, the # of lock sites is bounded and is usually small.
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 // Besides the call overhead, TrySlowEnter and TrySlowExit might suffer
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 // if the processor uses simple bimodal branch predictors keyed by EIP
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 // Since the helper routines would be called from multiple synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 // sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 // An even better approach would be write "MonitorEnter()" and "MonitorExit()"
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 // in java - using j.u.c and unsafe - and just bind the lock and unlock sites
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 // to those specialized methods. That'd give us a mostly platform-independent
a61af66fc99e Initial load
duke
parents:
diff changeset
3237 // implementation that the JITs could optimize and inline at their pleasure.
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 // Done correctly, the only time we'd need to cross to native could would be
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 // to park() or unpark() threads. We'd also need a few more unsafe operators
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 // to (a) prevent compiler-JIT reordering of non-volatile accesses, and
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 // (b) explicit barriers or fence operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 // TODO:
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 // * Arrange for C2 to pass "Self" into Fast_Lock and Fast_Unlock in one of the registers (scr).
a61af66fc99e Initial load
duke
parents:
diff changeset
3246 // This avoids manifesting the Self pointer in the Fast_Lock and Fast_Unlock terminals.
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 // Given TLAB allocation, Self is usually manifested in a register, so passing it into
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 // the lock operators would typically be faster than reifying Self.
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 // * Ideally I'd define the primitives as:
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 // fast_lock (nax Obj, nax box, EAX tmp, nax scr) where box, tmp and scr are KILLED.
a61af66fc99e Initial load
duke
parents:
diff changeset
3252 // fast_unlock (nax Obj, EAX box, nax tmp) where box and tmp are KILLED
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 // Unfortunately ADLC bugs prevent us from expressing the ideal form.
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 // Instead, we're stuck with a rather awkward and brittle register assignments below.
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 // Furthermore the register assignments are overconstrained, possibly resulting in
a61af66fc99e Initial load
duke
parents:
diff changeset
3256 // sub-optimal code near the synchronization site.
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3258 // * Eliminate the sp-proximity tests and just use "== Self" tests instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
3259 // Alternately, use a better sp-proximity test.
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 // * Currently ObjectMonitor._Owner can hold either an sp value or a (THREAD *) value.
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 // Either one is sufficient to uniquely identify a thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 // TODO: eliminate use of sp in _owner and use get_thread(tr) instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3265 // * Intrinsify notify() and notifyAll() for the common cases where the
a61af66fc99e Initial load
duke
parents:
diff changeset
3266 // object is locked by the calling thread but the waitlist is empty.
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 // avoid the expensive JNI call to JVM_Notify() and JVM_NotifyAll().
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 // * use jccb and jmpb instead of jcc and jmp to improve code density.
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 // But beware of excessive branch density on AMD Opterons.
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3272 // * Both Fast_Lock and Fast_Unlock set the ICC.ZF to indicate success
a61af66fc99e Initial load
duke
parents:
diff changeset
3273 // or failure of the fast-path. If the fast-path fails then we pass
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 // control to the slow-path, typically in C. In Fast_Lock and
a61af66fc99e Initial load
duke
parents:
diff changeset
3275 // Fast_Unlock we often branch to DONE_LABEL, just to find that C2
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 // will emit a conditional branch immediately after the node.
a61af66fc99e Initial load
duke
parents:
diff changeset
3277 // So we have branches to branches and lots of ICC.ZF games.
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 // Instead, it might be better to have C2 pass a "FailureLabel"
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 // into Fast_Lock and Fast_Unlock. In the case of success, control
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 // will drop through the node. ICC.ZF is undefined at exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 // In the case of failure, the node will branch directly to the
a61af66fc99e Initial load
duke
parents:
diff changeset
3282 // FailureLabel
a61af66fc99e Initial load
duke
parents:
diff changeset
3283
a61af66fc99e Initial load
duke
parents:
diff changeset
3284
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 // obj: object to lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 // box: on-stack box address (displaced header location) - KILLED
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 // rax,: tmp -- KILLED
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 // scr: tmp -- KILLED
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 enc_class Fast_Lock( eRegP obj, eRegP box, eAXRegI tmp, eRegP scr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3290
a61af66fc99e Initial load
duke
parents:
diff changeset
3291 Register objReg = as_Register($obj$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 Register boxReg = as_Register($box$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 Register tmpReg = as_Register($tmp$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 Register scrReg = as_Register($scr$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3295
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 // Ensure the register assignents are disjoint
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 guarantee (objReg != boxReg, "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 guarantee (objReg != tmpReg, "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 guarantee (objReg != scrReg, "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 guarantee (boxReg != tmpReg, "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 guarantee (boxReg != scrReg, "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 guarantee (tmpReg == as_Register(EAX_enc), "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3303
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3305
a61af66fc99e Initial load
duke
parents:
diff changeset
3306 if (_counters != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3307 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 if (EmitSync & 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 // set box->dhw = unused_mark (3)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3311 // Force all sync thru slow-path: slow_enter() and slow_exit()
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3312 masm.movptr (Address(boxReg, 0), int32_t(markOopDesc::unused_mark())) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3313 masm.cmpptr (rsp, (int32_t)0) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3314 } else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3315 if (EmitSync & 2) {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3316 Label DONE_LABEL ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3317 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
a61af66fc99e Initial load
duke
parents:
diff changeset
3319 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3321
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3322 masm.movptr(tmpReg, Address(objReg, 0)) ; // fetch markword
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3323 masm.orptr (tmpReg, 0x1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3324 masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 if (os::is_MP()) { masm.lock(); }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3326 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 masm.jcc(Assembler::equal, DONE_LABEL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3328 // Recursive locking
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3329 masm.subptr(tmpReg, rsp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3330 masm.andptr(tmpReg, (int32_t) 0xFFFFF003 );
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3331 masm.movptr(Address(boxReg, 0), tmpReg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3332 masm.bind(DONE_LABEL) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3333 } else {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3334 // Possible cases that we'll encounter in fast_lock
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 // ------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 // * Inflated
a61af66fc99e Initial load
duke
parents:
diff changeset
3337 // -- unlocked
a61af66fc99e Initial load
duke
parents:
diff changeset
3338 // -- Locked
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 // = by self
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 // = by other
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 // * biased
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 // -- by Self
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 // -- by other
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 // * neutral
a61af66fc99e Initial load
duke
parents:
diff changeset
3345 // * stack-locked
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 // -- by self
a61af66fc99e Initial load
duke
parents:
diff changeset
3347 // = sp-proximity test hits
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 // = sp-proximity test generates false-negative
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 // -- by other
a61af66fc99e Initial load
duke
parents:
diff changeset
3350 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3351
a61af66fc99e Initial load
duke
parents:
diff changeset
3352 Label IsInflated, DONE_LABEL, PopDone ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3353
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 // TODO: optimize away redundant LDs of obj->mark and improve the markword triage
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 // order to reduce the number of conditional branches in the most common cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 // Beware -- there's a subtle invariant that fetch of the markword
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 // at [FETCH], below, will never observe a biased encoding (*101b).
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 // If this invariant is not held we risk exclusion (safety) failure.
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
3359 if (UseBiasedLocking && !UseOptoBiasInlining) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3362
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3363 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3364 masm.testptr(tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3365 masm.jccb (Assembler::notZero, IsInflated) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3366
a61af66fc99e Initial load
duke
parents:
diff changeset
3367 // Attempt stack-locking ...
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3368 masm.orptr (tmpReg, 0x1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3369 masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 if (os::is_MP()) { masm.lock(); }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3371 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 if (_counters != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 masm.cond_inc32(Assembler::equal,
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 ExternalAddress((address)_counters->fast_path_entry_count_addr()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 masm.jccb (Assembler::equal, DONE_LABEL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3377
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 // Recursive locking
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3379 masm.subptr(tmpReg, rsp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3380 masm.andptr(tmpReg, 0xFFFFF003 );
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3381 masm.movptr(Address(boxReg, 0), tmpReg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3382 if (_counters != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 masm.cond_inc32(Assembler::equal,
a61af66fc99e Initial load
duke
parents:
diff changeset
3384 ExternalAddress((address)_counters->fast_path_entry_count_addr()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 masm.jmp (DONE_LABEL) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3387
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 masm.bind (IsInflated) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3389
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 // The object is inflated.
a61af66fc99e Initial load
duke
parents:
diff changeset
3391 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 // TODO-FIXME: eliminate the ugly use of manifest constants:
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 // Use markOopDesc::monitor_value instead of "2".
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 // use markOop::unused_mark() instead of "3".
a61af66fc99e Initial load
duke
parents:
diff changeset
3395 // The tmpReg value is an objectMonitor reference ORed with
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 // markOopDesc::monitor_value (2). We can either convert tmpReg to an
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 // objectmonitor pointer by masking off the "2" bit or we can just
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 // use tmpReg as an objectmonitor pointer but bias the objectmonitor
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 // field offsets with "-2" to compensate for and annul the low-order tag bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 // I use the latter as it avoids AGI stalls.
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 // As such, we write "mov r, [tmpReg+OFFSETOF(Owner)-2]"
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 // instead of "mov r, [tmpReg+OFFSETOF(Owner)]".
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 #define OFFSET_SKEWED(f) ((ObjectMonitor::f ## _offset_in_bytes())-2)
a61af66fc99e Initial load
duke
parents:
diff changeset
3406
a61af66fc99e Initial load
duke
parents:
diff changeset
3407 // boxReg refers to the on-stack BasicLock in the current frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 // We'd like to write:
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 // set box->_displaced_header = markOop::unused_mark(). Any non-0 value suffices.
a61af66fc99e Initial load
duke
parents:
diff changeset
3410 // This is convenient but results a ST-before-CAS penalty. The following CAS suffers
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 // additional latency as we have another ST in the store buffer that must drain.
a61af66fc99e Initial load
duke
parents:
diff changeset
3412
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3413 if (EmitSync & 8192) {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3414 masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3415 masm.get_thread (scrReg) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3416 masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2]
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 420
diff changeset
3417 masm.movptr(tmpReg, NULL_WORD); // consider: xor vs mov
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3418 if (os::is_MP()) { masm.lock(); }
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3419 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3420 } else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 if ((EmitSync & 128) == 0) { // avoid ST-before-CAS
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3422 masm.movptr(scrReg, boxReg) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3423 masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2]
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3424
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes
2479
15c9a0e16269 7035713: 3DNow Prefetch Instruction Support
kvn
parents: 2401
diff changeset
3426 if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3427 // prefetchw [eax + Offset(_owner)-2]
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3428 masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3430
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 if ((EmitSync & 64) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 // Optimistic form: consider XORL tmpReg,tmpReg
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 420
diff changeset
3433 masm.movptr(tmpReg, NULL_WORD) ;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3434 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 // Can suffer RTS->RTO upgrades on shared or cold $ lines
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 // Test-And-CAS instead of CAS
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3437 masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3438 masm.testptr(tmpReg, tmpReg) ; // Locked ?
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3439 masm.jccb (Assembler::notZero, DONE_LABEL) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3441
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 // Appears unlocked - try to swing _owner from null to non-null.
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 // Ideally, I'd manifest "Self" with get_thread and then attempt
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 // to CAS the register containing Self into m->Owner.
a61af66fc99e Initial load
duke
parents:
diff changeset
3445 // But we don't have enough registers, so instead we can either try to CAS
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 // rsp or the address of the box (in scr) into &m->owner. If the CAS succeeds
a61af66fc99e Initial load
duke
parents:
diff changeset
3447 // we later store "Self" into m->Owner. Transiently storing a stack address
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 // (rsp or the address of the box) into m->owner is harmless.
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand.
a61af66fc99e Initial load
duke
parents:
diff changeset
3450 if (os::is_MP()) { masm.lock(); }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3451 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3452 masm.movptr(Address(scrReg, 0), 3) ; // box->_displaced_header = 3
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3453 masm.jccb (Assembler::notZero, DONE_LABEL) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 masm.get_thread (scrReg) ; // beware: clobbers ICCs
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3455 masm.movptr(Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), scrReg) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3456 masm.xorptr(boxReg, boxReg) ; // set icc.ZFlag = 1 to indicate success
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3457
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3458 // If the CAS fails we can either retry or pass control to the slow-path.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3459 // We use the latter tactic.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 // Pass the CAS result in the icc.ZFlag into DONE_LABEL
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 // If the CAS was successful ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 // Self has acquired the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 // Intentional fall-through into DONE_LABEL ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 } else {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3466 masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3467 masm.movptr(boxReg, tmpReg) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3468
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes
2479
15c9a0e16269 7035713: 3DNow Prefetch Instruction Support
kvn
parents: 2401
diff changeset
3470 if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 // prefetchw [eax + Offset(_owner)-2]
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3472 masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3474
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 if ((EmitSync & 64) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 // Optimistic form
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3477 masm.xorptr (tmpReg, tmpReg) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3478 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 // Can suffer RTS->RTO upgrades on shared or cold $ lines
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3480 masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3481 masm.testptr(tmpReg, tmpReg) ; // Locked ?
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3482 masm.jccb (Assembler::notZero, DONE_LABEL) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3484
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 // Appears unlocked - try to swing _owner from null to non-null.
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 // Use either "Self" (in scr) or rsp as thread identity in _owner.
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand.
a61af66fc99e Initial load
duke
parents:
diff changeset
3488 masm.get_thread (scrReg) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 if (os::is_MP()) { masm.lock(); }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3490 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3491
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 // If the CAS fails we can either retry or pass control to the slow-path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 // We use the latter tactic.
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 // Pass the CAS result in the icc.ZFlag into DONE_LABEL
a61af66fc99e Initial load
duke
parents:
diff changeset
3495 // If the CAS was successful ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 // Self has acquired the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3497 // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 // Intentional fall-through into DONE_LABEL ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3500
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 // DONE_LABEL is a hot target - we'd really like to place it at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 // start of cache line by padding with NOPs.
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 // See the AMD and Intel software optimization manuals for the
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 // most efficient "long" NOP encodings.
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 // Unfortunately none of our alignment mechanisms suffice.
a61af66fc99e Initial load
duke
parents:
diff changeset
3506 masm.bind(DONE_LABEL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3507
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 // Avoid branch-to-branch on AMD processors
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 // This appears to be superstition.
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 if (EmitSync & 32) masm.nop() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3511
a61af66fc99e Initial load
duke
parents:
diff changeset
3512
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 // At DONE_LABEL the icc ZFlag is set as follows ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 // Fast_Unlock uses the same protocol.
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 // ZFlag == 1 -> Success
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 // ZFlag == 0 -> Failure - force control through the slow-path
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3519
a61af66fc99e Initial load
duke
parents:
diff changeset
3520 // obj: object to unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
3521 // box: box address (displaced header location), killed. Must be EAX.
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 // rbx,: killed tmp; cannot be obj nor box.
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3524 // Some commentary on balanced locking:
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 // Fast_Lock and Fast_Unlock are emitted only for provably balanced lock sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 // Methods that don't have provably balanced locking are forced to run in the
a61af66fc99e Initial load
duke
parents:
diff changeset
3528 // interpreter - such methods won't be compiled to use fast_lock and fast_unlock.
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 // The interpreter provides two properties:
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 // I1: At return-time the interpreter automatically and quietly unlocks any
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 // objects acquired the current activation (frame). Recall that the
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 // interpreter maintains an on-stack list of locks currently held by
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 // a frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 // I2: If a method attempts to unlock an object that is not held by the
a61af66fc99e Initial load
duke
parents:
diff changeset
3535 // the frame the interpreter throws IMSX.
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 // Lets say A(), which has provably balanced locking, acquires O and then calls B().
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 // B() doesn't have provably balanced locking so it runs in the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 // Control returns to A() and A() unlocks O. By I1 and I2, above, we know that O
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 // is still locked by A().
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 // The only other source of unbalanced locking would be JNI. The "Java Native Interface:
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 // Programmer's Guide and Specification" claims that an object locked by jni_monitorenter
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 // should not be unlocked by "normal" java-level locking and vice-versa. The specification
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 // doesn't specify what will occur if a program engages in such mixed-mode locking, however.
a61af66fc99e Initial load
duke
parents:
diff changeset
3546
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 enc_class Fast_Unlock( nabxRegP obj, eAXRegP box, eRegP tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3548
a61af66fc99e Initial load
duke
parents:
diff changeset
3549 Register objReg = as_Register($obj$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3550 Register boxReg = as_Register($box$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 Register tmpReg = as_Register($tmp$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3552
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 guarantee (objReg != boxReg, "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 guarantee (objReg != tmpReg, "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 guarantee (boxReg != tmpReg, "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 guarantee (boxReg == as_Register(EAX_enc), "") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 MacroAssembler masm(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3558
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 if (EmitSync & 4) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 // Disable - inhibit all inlining. Force control through the slow-path
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3561 masm.cmpptr (rsp, 0) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3562 } else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 if (EmitSync & 8) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 Label DONE_LABEL ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 // classic stack-locking code ...
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3569 masm.movptr(tmpReg, Address(boxReg, 0)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3570 masm.testptr(tmpReg, tmpReg) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3571 masm.jcc (Assembler::zero, DONE_LABEL) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3572 if (os::is_MP()) { masm.lock(); }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3573 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 masm.bind(DONE_LABEL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 Label DONE_LABEL, Stacked, CheckSucc, Inflated ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3577
a61af66fc99e Initial load
duke
parents:
diff changeset
3578 // Critically, the biased locking test must have precedence over
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 // and appear before the (box->dhw == 0) recursive stack-lock test.
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
3580 if (UseBiasedLocking && !UseOptoBiasInlining) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3583
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3584 masm.cmpptr(Address(boxReg, 0), 0) ; // Examine the displaced header
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3585 masm.movptr(tmpReg, Address(objReg, 0)) ; // Examine the object's markword
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 masm.jccb (Assembler::zero, DONE_LABEL) ; // 0 indicates recursive stack-lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3587
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3588 masm.testptr(tmpReg, 0x02) ; // Inflated?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 masm.jccb (Assembler::zero, Stacked) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3590
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 masm.bind (Inflated) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 // It's inflated.
a61af66fc99e Initial load
duke
parents:
diff changeset
3593 // Despite our balanced locking property we still check that m->_owner == Self
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 // as java routines or native JNI code called by this thread might
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 // have released the lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 // Refer to the comments in synchronizer.cpp for how we might encode extra
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 // state in _succ so we can avoid fetching EntryList|cxq.
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 // I'd like to add more cases in fast_lock() and fast_unlock() --
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 // such as recursive enter and exit -- but we have to be wary of
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 // I$ bloat, T$ effects and BP$ effects.
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 // If there's no contention try a 1-0 exit. That is, exit without
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 // a costly MEMBAR or CAS. See synchronizer.cpp for details on how
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 // we detect and recover from the race that the 1-0 exit admits.
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 // before it STs null into _owner, releasing the lock. Updates
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 // to data protected by the critical section must be visible before
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 // we drop the lock (and thus before any other thread could acquire
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 // the lock and observe the fields protected by the lock).
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 // IA32's memory-model is SPO, so STs are ordered with respect to
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 // each other and there's no need for an explicit barrier (fence).
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 // See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html.
a61af66fc99e Initial load
duke
parents:
diff changeset
3615
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 masm.get_thread (boxReg) ;
2479
15c9a0e16269 7035713: 3DNow Prefetch Instruction Support
kvn
parents: 2401
diff changeset
3617 if ((EmitSync & 4096) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3618 // prefetchw [ebx + Offset(_owner)-2]
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3619 masm.prefetchw(Address(rbx, ObjectMonitor::owner_offset_in_bytes()-2));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3621
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 // Note that we could employ various encoding schemes to reduce
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 // the number of loads below (currently 4) to just 2 or 3.
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 // Refer to the comments in synchronizer.cpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 // In practice the chain of fetches doesn't seem to impact performance, however.
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 if ((EmitSync & 65536) == 0 && (EmitSync & 256)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 // Attempt to reduce branch density - AMD's branch predictor.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3628 masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3629 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3630 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3631 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3632 masm.jccb (Assembler::notZero, DONE_LABEL) ;
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 420
diff changeset
3633 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3634 masm.jmpb (DONE_LABEL) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3635 } else {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3636 masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3637 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3638 masm.jccb (Assembler::notZero, DONE_LABEL) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3639 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3640 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3641 masm.jccb (Assembler::notZero, CheckSucc) ;
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 420
diff changeset
3642 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3643 masm.jmpb (DONE_LABEL) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3645
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 // The Following code fragment (EmitSync & 65536) improves the performance of
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 // contended applications and contended synchronization microbenchmarks.
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 // Unfortunately the emission of the code - even though not executed - causes regressions
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 // in scimark and jetstream, evidently because of $ effects. Replacing the code
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 // with an equal number of never-executed NOPs results in the same regression.
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 // We leave it off by default.
a61af66fc99e Initial load
duke
parents:
diff changeset
3652
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 if ((EmitSync & 65536) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 Label LSuccess, LGoSlowPath ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3655
a61af66fc99e Initial load
duke
parents:
diff changeset
3656 masm.bind (CheckSucc) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3657
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 // Optional pre-test ... it's safe to elide this
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3659 if ((EmitSync & 16) == 0) {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3660 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3661 masm.jccb (Assembler::zero, LGoSlowPath) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3663
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 // We have a classic Dekker-style idiom:
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 // ST m->_owner = 0 ; MEMBAR; LD m->_succ
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 // There are a number of ways to implement the barrier:
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 // (1) lock:andl &m->_owner, 0
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 // is fast, but mask doesn't currently support the "ANDL M,IMM32" form.
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 // LOCK: ANDL [ebx+Offset(_Owner)-2], 0
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 // Encodes as 81 31 OFF32 IMM32 or 83 63 OFF8 IMM8
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 // (2) If supported, an explicit MFENCE is appealing.
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 // In older IA32 processors MFENCE is slower than lock:add or xchg
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 // particularly if the write-buffer is full as might be the case if
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 // if stores closely precede the fence or fence-equivalent instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 // In more modern implementations MFENCE appears faster, however.
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 // (3) In lieu of an explicit fence, use lock:addl to the top-of-stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 // The $lines underlying the top-of-stack should be in M-state.
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 // The locked add instruction is serializing, of course.
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 // (4) Use xchg, which is serializing
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 // mov boxReg, 0; xchgl boxReg, [tmpReg + Offset(_owner)-2] also works
a61af66fc99e Initial load
duke
parents:
diff changeset
3681 // (5) ST m->_owner = 0 and then execute lock:orl &m->_succ, 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 // The integer condition codes will tell us if succ was 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 // Since _succ and _owner should reside in the same $line and
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 // we just stored into _owner, it's likely that the $line
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 // remains in M-state for the lock:orl.
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 // We currently use (3), although it's likely that switching to (2)
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 // is correct for the future.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3689
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 420
diff changeset
3690 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3691 if (os::is_MP()) {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3692 if (VM_Version::supports_sse2() && 1 == FenceInstruction) {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3693 masm.mfence();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3694 } else {
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3695 masm.lock () ; masm.addptr(Address(rsp, 0), 0) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 // Ratify _succ remains non-null
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3699 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3700 masm.jccb (Assembler::notZero, LSuccess) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3701
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3702 masm.xorptr(boxReg, boxReg) ; // box is really EAX
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 if (os::is_MP()) { masm.lock(); }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3704 masm.cmpxchgptr(rsp, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 masm.jccb (Assembler::notEqual, LSuccess) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 // Since we're low on registers we installed rsp as a placeholding in _owner.
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 // Now install Self over rsp. This is safe as we're transitioning from
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 // non-null to non=null
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 masm.get_thread (boxReg) ;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3710 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), boxReg) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 // Intentional fall-through into LGoSlowPath ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3712
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3713 masm.bind (LGoSlowPath) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3714 masm.orptr(boxReg, 1) ; // set ICC.ZF=0 to indicate failure
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3715 masm.jmpb (DONE_LABEL) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3716
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3717 masm.bind (LSuccess) ;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3718 masm.xorptr(boxReg, boxReg) ; // set ICC.ZF=1 to indicate success
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3719 masm.jmpb (DONE_LABEL) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3721
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 masm.bind (Stacked) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3723 // It's not inflated and it's not recursively stack-locked and it's not biased.
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 // It must be stack-locked.
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 // Try to reset the header to displaced header.
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 // The "box" value on the stack is stable, so we can reload
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 // and be assured we observe the same value as above.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3728 masm.movptr(tmpReg, Address(boxReg, 0)) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 if (os::is_MP()) { masm.lock(); }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
3730 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3731 // Intention fall-thru into DONE_LABEL
a61af66fc99e Initial load
duke
parents:
diff changeset
3732
a61af66fc99e Initial load
duke
parents:
diff changeset
3733
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 // DONE_LABEL is a hot target - we'd really like to place it at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 // start of cache line by padding with NOPs.
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 // See the AMD and Intel software optimization manuals for the
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 // most efficient "long" NOP encodings.
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 // Unfortunately none of our alignment mechanisms suffice.
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 if ((EmitSync & 65536) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 masm.bind (CheckSucc) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3742 masm.bind(DONE_LABEL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3743
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 // Avoid branch to branch on AMD processors
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 if (EmitSync & 32768) { masm.nop() ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
3746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3747 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3748
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 113
diff changeset
3749
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 enc_class enc_pop_rdx() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 emit_opcode(cbuf,0x5A);
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3753
a61af66fc99e Initial load
duke
parents:
diff changeset
3754 enc_class enc_rethrow() %{
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3755 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3756 emit_opcode(cbuf, 0xE9); // jmp entry
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3757 emit_d32_reloc(cbuf, (int)OptoRuntime::rethrow_stub() - ((int)cbuf.insts_end())-4,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3758 runtime_call_Relocation::spec(), RELOC_IMM32 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3760
a61af66fc99e Initial load
duke
parents:
diff changeset
3761
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 // Convert a double to an int. Java semantics require we do complex
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 // manglelations in the corner cases. So we set the rounding mode to
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 // 'zero', store the darned double down as an int, and reset the
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 // rounding mode to 'nearest'. The hardware throws an exception which
a61af66fc99e Initial load
duke
parents:
diff changeset
3766 // patches up the correct value directly to the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 enc_class D2I_encoding( regD src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 // Flip to round-to-zero mode. We attempted to allow invalid-op
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 // exceptions here, so that a NAN or other corner-case value will
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 // thrown an exception (but normal values get converted at full speed).
a61af66fc99e Initial load
duke
parents:
diff changeset
3771 // However, I2C adapters and other float-stack manglers leave pending
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 // invalid-op exceptions hanging. We would have to clear them before
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 // enabling them and that is more expensive than just testing for the
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 // invalid value Intel stores down in the corner cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 emit_opcode(cbuf,0xD9); // FLDCW trunc
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 emit_opcode(cbuf,0x2D);
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc());
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
3779 emit_opcode(cbuf,0x83); // SUB ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
3780 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 emit_d8(cbuf,0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
3782 // Encoding assumes a double has been pushed into FPR0.
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 // Store down the double as an int, popping the FPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3784 emit_opcode(cbuf,0xDB); // FISTP [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
3785 emit_opcode(cbuf,0x1C);
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 emit_d8(cbuf,0x24);
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 // Restore the rounding mode; mask the exception
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 emit_opcode(cbuf,0x2D);
a61af66fc99e Initial load
duke
parents:
diff changeset
3790 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode()
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24()
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 : (int)StubRoutines::addr_fpu_cntrl_wrd_std());
a61af66fc99e Initial load
duke
parents:
diff changeset
3793
a61af66fc99e Initial load
duke
parents:
diff changeset
3794 // Load the converted int; adjust CPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 emit_opcode(cbuf,0x58); // POP EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
3796 emit_opcode(cbuf,0x3D); // CMP EAX,imm
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 emit_d32 (cbuf,0x80000000); // 0x80000000
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 emit_opcode(cbuf,0x75); // JNE around_slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3799 emit_d8 (cbuf,0x07); // Size of slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3800 // Push src onto stack slow-path
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 emit_opcode(cbuf,0xD9 ); // FLD ST(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 emit_d8 (cbuf,0xC0-1+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3803 // CALL directly to the runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3804 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3805 emit_opcode(cbuf,0xE8); // Call into runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3806 emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 // Carry on here...
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3809
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 enc_class D2L_encoding( regD src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 emit_opcode(cbuf,0xD9); // FLDCW trunc
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 emit_opcode(cbuf,0x2D);
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc());
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
3815 emit_opcode(cbuf,0x83); // SUB ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3817 emit_d8(cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 // Encoding assumes a double has been pushed into FPR0.
a61af66fc99e Initial load
duke
parents:
diff changeset
3819 // Store down the double as a long, popping the FPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 emit_opcode(cbuf,0xDF); // FISTP [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 emit_opcode(cbuf,0x3C);
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 emit_d8(cbuf,0x24);
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 // Restore the rounding mode; mask the exception
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode
a61af66fc99e Initial load
duke
parents:
diff changeset
3825 emit_opcode(cbuf,0x2D);
a61af66fc99e Initial load
duke
parents:
diff changeset
3826 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode()
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24()
a61af66fc99e Initial load
duke
parents:
diff changeset
3828 : (int)StubRoutines::addr_fpu_cntrl_wrd_std());
a61af66fc99e Initial load
duke
parents:
diff changeset
3829
a61af66fc99e Initial load
duke
parents:
diff changeset
3830 // Load the converted int; adjust CPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3831 emit_opcode(cbuf,0x58); // POP EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
3832 emit_opcode(cbuf,0x5A); // POP EDX
a61af66fc99e Initial load
duke
parents:
diff changeset
3833 emit_opcode(cbuf,0x81); // CMP EDX,imm
a61af66fc99e Initial load
duke
parents:
diff changeset
3834 emit_d8 (cbuf,0xFA); // rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
3835 emit_d32 (cbuf,0x80000000); // 0x80000000
a61af66fc99e Initial load
duke
parents:
diff changeset
3836 emit_opcode(cbuf,0x75); // JNE around_slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3837 emit_d8 (cbuf,0x07+4); // Size of slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3838 emit_opcode(cbuf,0x85); // TEST EAX,EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 emit_opcode(cbuf,0xC0); // 2/rax,/rax,
a61af66fc99e Initial load
duke
parents:
diff changeset
3840 emit_opcode(cbuf,0x75); // JNE around_slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3841 emit_d8 (cbuf,0x07); // Size of slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3842 // Push src onto stack slow-path
a61af66fc99e Initial load
duke
parents:
diff changeset
3843 emit_opcode(cbuf,0xD9 ); // FLD ST(i)
a61af66fc99e Initial load
duke
parents:
diff changeset
3844 emit_d8 (cbuf,0xC0-1+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
3845 // CALL directly to the runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3846 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3847 emit_opcode(cbuf,0xE8); // Call into runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3848 emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 // Carry on here...
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3851
a61af66fc99e Initial load
duke
parents:
diff changeset
3852 enc_class X2L_encoding( regX src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 emit_opcode(cbuf,0x83); // SUB ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
3855 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 emit_d8(cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
3857
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src
a61af66fc99e Initial load
duke
parents:
diff changeset
3859 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3862
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 emit_opcode(cbuf,0xD9 ); // FLD_S [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3865
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 emit_opcode(cbuf,0xD9); // FLDCW trunc
a61af66fc99e Initial load
duke
parents:
diff changeset
3867 emit_opcode(cbuf,0x2D);
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc());
a61af66fc99e Initial load
duke
parents:
diff changeset
3869
a61af66fc99e Initial load
duke
parents:
diff changeset
3870 // Encoding assumes a double has been pushed into FPR0.
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 // Store down the double as a long, popping the FPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 emit_opcode(cbuf,0xDF); // FISTP [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 emit_opcode(cbuf,0x3C);
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 emit_d8(cbuf,0x24);
a61af66fc99e Initial load
duke
parents:
diff changeset
3875
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 // Restore the rounding mode; mask the exception
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 emit_opcode(cbuf,0x2D);
a61af66fc99e Initial load
duke
parents:
diff changeset
3879 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode()
a61af66fc99e Initial load
duke
parents:
diff changeset
3880 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24()
a61af66fc99e Initial load
duke
parents:
diff changeset
3881 : (int)StubRoutines::addr_fpu_cntrl_wrd_std());
a61af66fc99e Initial load
duke
parents:
diff changeset
3882
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 // Load the converted int; adjust CPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 emit_opcode(cbuf,0x58); // POP EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
3885
a61af66fc99e Initial load
duke
parents:
diff changeset
3886 emit_opcode(cbuf,0x5A); // POP EDX
a61af66fc99e Initial load
duke
parents:
diff changeset
3887
a61af66fc99e Initial load
duke
parents:
diff changeset
3888 emit_opcode(cbuf,0x81); // CMP EDX,imm
a61af66fc99e Initial load
duke
parents:
diff changeset
3889 emit_d8 (cbuf,0xFA); // rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 emit_d32 (cbuf,0x80000000);// 0x80000000
a61af66fc99e Initial load
duke
parents:
diff changeset
3891
a61af66fc99e Initial load
duke
parents:
diff changeset
3892 emit_opcode(cbuf,0x75); // JNE around_slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3893 emit_d8 (cbuf,0x13+4); // Size of slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3894
a61af66fc99e Initial load
duke
parents:
diff changeset
3895 emit_opcode(cbuf,0x85); // TEST EAX,EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
3896 emit_opcode(cbuf,0xC0); // 2/rax,/rax,
a61af66fc99e Initial load
duke
parents:
diff changeset
3897
a61af66fc99e Initial load
duke
parents:
diff changeset
3898 emit_opcode(cbuf,0x75); // JNE around_slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3899 emit_d8 (cbuf,0x13); // Size of slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3900
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
3902 emit_opcode(cbuf,0x83); // SUB ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
3903 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 emit_d8(cbuf,0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
3905
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
3908 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3909 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3910
a61af66fc99e Initial load
duke
parents:
diff changeset
3911 emit_opcode(cbuf,0xD9 ); // FLD_S [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3913
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 emit_opcode(cbuf,0x83); // ADD ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 emit_opcode(cbuf,0xC4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3916 emit_d8(cbuf,0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
3917
a61af66fc99e Initial load
duke
parents:
diff changeset
3918 // CALL directly to the runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3919 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3920 emit_opcode(cbuf,0xE8); // Call into runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3921 emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3922 // Carry on here...
a61af66fc99e Initial load
duke
parents:
diff changeset
3923 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3924
a61af66fc99e Initial load
duke
parents:
diff changeset
3925 enc_class XD2L_encoding( regXD src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
3927 emit_opcode(cbuf,0x83); // SUB ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
3928 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3929 emit_d8(cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
3930
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src
a61af66fc99e Initial load
duke
parents:
diff changeset
3932 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3934 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3935
a61af66fc99e Initial load
duke
parents:
diff changeset
3936 emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
3937 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3938
a61af66fc99e Initial load
duke
parents:
diff changeset
3939 emit_opcode(cbuf,0xD9); // FLDCW trunc
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 emit_opcode(cbuf,0x2D);
a61af66fc99e Initial load
duke
parents:
diff changeset
3941 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc());
a61af66fc99e Initial load
duke
parents:
diff changeset
3942
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 // Encoding assumes a double has been pushed into FPR0.
a61af66fc99e Initial load
duke
parents:
diff changeset
3944 // Store down the double as a long, popping the FPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 emit_opcode(cbuf,0xDF); // FISTP [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
3946 emit_opcode(cbuf,0x3C);
a61af66fc99e Initial load
duke
parents:
diff changeset
3947 emit_d8(cbuf,0x24);
a61af66fc99e Initial load
duke
parents:
diff changeset
3948
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 // Restore the rounding mode; mask the exception
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode
a61af66fc99e Initial load
duke
parents:
diff changeset
3951 emit_opcode(cbuf,0x2D);
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode()
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24()
a61af66fc99e Initial load
duke
parents:
diff changeset
3954 : (int)StubRoutines::addr_fpu_cntrl_wrd_std());
a61af66fc99e Initial load
duke
parents:
diff changeset
3955
a61af66fc99e Initial load
duke
parents:
diff changeset
3956 // Load the converted int; adjust CPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3957 emit_opcode(cbuf,0x58); // POP EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
3958
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 emit_opcode(cbuf,0x5A); // POP EDX
a61af66fc99e Initial load
duke
parents:
diff changeset
3960
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 emit_opcode(cbuf,0x81); // CMP EDX,imm
a61af66fc99e Initial load
duke
parents:
diff changeset
3962 emit_d8 (cbuf,0xFA); // rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 emit_d32 (cbuf,0x80000000); // 0x80000000
a61af66fc99e Initial load
duke
parents:
diff changeset
3964
a61af66fc99e Initial load
duke
parents:
diff changeset
3965 emit_opcode(cbuf,0x75); // JNE around_slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 emit_d8 (cbuf,0x13+4); // Size of slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3967
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 emit_opcode(cbuf,0x85); // TEST EAX,EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 emit_opcode(cbuf,0xC0); // 2/rax,/rax,
a61af66fc99e Initial load
duke
parents:
diff changeset
3970
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 emit_opcode(cbuf,0x75); // JNE around_slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 emit_d8 (cbuf,0x13); // Size of slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3973
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 // Push src onto stack slow-path
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 emit_opcode(cbuf,0x83); // SUB ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 emit_d8(cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
3979
a61af66fc99e Initial load
duke
parents:
diff changeset
3980 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3984
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 emit_opcode(cbuf,0xDD ); // FLD_D [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
3986 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3987
a61af66fc99e Initial load
duke
parents:
diff changeset
3988 emit_opcode(cbuf,0x83); // ADD ESP,8
a61af66fc99e Initial load
duke
parents:
diff changeset
3989 emit_opcode(cbuf,0xC4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3990 emit_d8(cbuf,0x08);
a61af66fc99e Initial load
duke
parents:
diff changeset
3991
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 // CALL directly to the runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3993 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 emit_opcode(cbuf,0xE8); // Call into runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
3995 emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3996 // Carry on here...
a61af66fc99e Initial load
duke
parents:
diff changeset
3997 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
3998
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 enc_class D2X_encoding( regX dst, regD src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4000 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
4001 emit_opcode(cbuf,0x83); // SUB ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
4002 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 emit_d8(cbuf,0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
4004 int pop = 0x02;
a61af66fc99e Initial load
duke
parents:
diff changeset
4005 if ($src$$reg != FPR1L_enc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4006 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1)
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 emit_d8( cbuf, 0xC0-1+$src$$reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 pop = 0x03;
a61af66fc99e Initial load
duke
parents:
diff changeset
4009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 store_to_stackslot( cbuf, 0xD9, pop, 0 ); // FST<P>_S [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
4011
a61af66fc99e Initial load
duke
parents:
diff changeset
4012 emit_opcode (cbuf, 0xF3 ); // MOVSS dst(xmm), [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
4014 emit_opcode (cbuf, 0x10 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4015 encode_RegMem(cbuf, $dst$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4016
a61af66fc99e Initial load
duke
parents:
diff changeset
4017 emit_opcode(cbuf,0x83); // ADD ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
4018 emit_opcode(cbuf,0xC4);
a61af66fc99e Initial load
duke
parents:
diff changeset
4019 emit_d8(cbuf,0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
4020 // Carry on here...
a61af66fc99e Initial load
duke
parents:
diff changeset
4021 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4022
a61af66fc99e Initial load
duke
parents:
diff changeset
4023 enc_class FX2I_encoding( regX src, eRegI dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4024 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4025
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 // Compare the result to see if we need to go to the slow path
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 emit_opcode(cbuf,0x81); // CMP dst,imm
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 emit_rm (cbuf,0x3,0x7,$dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4029 emit_d32 (cbuf,0x80000000); // 0x80000000
a61af66fc99e Initial load
duke
parents:
diff changeset
4030
a61af66fc99e Initial load
duke
parents:
diff changeset
4031 emit_opcode(cbuf,0x75); // JNE around_slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
4032 emit_d8 (cbuf,0x13); // Size of slow_call
a61af66fc99e Initial load
duke
parents:
diff changeset
4033 // Store xmm to a temp memory
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 // location and push it onto stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
4035
a61af66fc99e Initial load
duke
parents:
diff changeset
4036 emit_opcode(cbuf,0x83); // SUB ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
4037 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 emit_d8(cbuf, $primary ? 0x8 : 0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
4039
a61af66fc99e Initial load
duke
parents:
diff changeset
4040 emit_opcode (cbuf, $primary ? 0xF2 : 0xF3 ); // MOVSS [ESP], xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4044
a61af66fc99e Initial load
duke
parents:
diff changeset
4045 emit_opcode(cbuf, $primary ? 0xDD : 0xD9 ); // FLD [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
4046 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4047
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 emit_opcode(cbuf,0x83); // ADD ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
4049 emit_opcode(cbuf,0xC4);
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 emit_d8(cbuf, $primary ? 0x8 : 0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
4051
a61af66fc99e Initial load
duke
parents:
diff changeset
4052 // CALL directly to the runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
4053 cbuf.set_insts_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4054 emit_opcode(cbuf,0xE8); // Call into runtime
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
4055 emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4056
a61af66fc99e Initial load
duke
parents:
diff changeset
4057 // Carry on here...
a61af66fc99e Initial load
duke
parents:
diff changeset
4058 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4059
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 enc_class X2D_encoding( regD dst, regX src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 // Allocate a word
a61af66fc99e Initial load
duke
parents:
diff changeset
4062 emit_opcode(cbuf,0x83); // SUB ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
4063 emit_opcode(cbuf,0xEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
4064 emit_d8(cbuf,0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
4065
a61af66fc99e Initial load
duke
parents:
diff changeset
4066 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 emit_opcode (cbuf, 0x0F );
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 emit_opcode (cbuf, 0x11 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4069 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4070
a61af66fc99e Initial load
duke
parents:
diff changeset
4071 emit_opcode(cbuf,0xD9 ); // FLD_S [ESP]
a61af66fc99e Initial load
duke
parents:
diff changeset
4072 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4073
a61af66fc99e Initial load
duke
parents:
diff changeset
4074 emit_opcode(cbuf,0x83); // ADD ESP,4
a61af66fc99e Initial load
duke
parents:
diff changeset
4075 emit_opcode(cbuf,0xC4);
a61af66fc99e Initial load
duke
parents:
diff changeset
4076 emit_d8(cbuf,0x04);
a61af66fc99e Initial load
duke
parents:
diff changeset
4077
a61af66fc99e Initial load
duke
parents:
diff changeset
4078 // Carry on here...
a61af66fc99e Initial load
duke
parents:
diff changeset
4079 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4080
a61af66fc99e Initial load
duke
parents:
diff changeset
4081 enc_class AbsXF_encoding(regX dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4082 address signmask_address=(address)float_signmask_pool;
a61af66fc99e Initial load
duke
parents:
diff changeset
4083 // andpd:\tANDPS $dst,[signconst]
a61af66fc99e Initial load
duke
parents:
diff changeset
4084 emit_opcode(cbuf, 0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4085 emit_opcode(cbuf, 0x54);
a61af66fc99e Initial load
duke
parents:
diff changeset
4086 emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4087 emit_d32(cbuf, (int)signmask_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
4088 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4089
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 enc_class AbsXD_encoding(regXD dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4091 address signmask_address=(address)double_signmask_pool;
a61af66fc99e Initial load
duke
parents:
diff changeset
4092 // andpd:\tANDPD $dst,[signconst]
a61af66fc99e Initial load
duke
parents:
diff changeset
4093 emit_opcode(cbuf, 0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 emit_opcode(cbuf, 0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4095 emit_opcode(cbuf, 0x54);
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4097 emit_d32(cbuf, (int)signmask_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4099
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 enc_class NegXF_encoding(regX dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4101 address signmask_address=(address)float_signflip_pool;
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 // andpd:\tXORPS $dst,[signconst]
a61af66fc99e Initial load
duke
parents:
diff changeset
4103 emit_opcode(cbuf, 0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4104 emit_opcode(cbuf, 0x57);
a61af66fc99e Initial load
duke
parents:
diff changeset
4105 emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4106 emit_d32(cbuf, (int)signmask_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
4107 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4108
a61af66fc99e Initial load
duke
parents:
diff changeset
4109 enc_class NegXD_encoding(regXD dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 address signmask_address=(address)double_signflip_pool;
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 // andpd:\tXORPD $dst,[signconst]
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 emit_opcode(cbuf, 0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 emit_opcode(cbuf, 0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 emit_opcode(cbuf, 0x57);
a61af66fc99e Initial load
duke
parents:
diff changeset
4115 emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4116 emit_d32(cbuf, (int)signmask_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
4117 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4118
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 enc_class FMul_ST_reg( eRegF src1 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4120 // Operand was loaded from memory into fp ST (stack top)
a61af66fc99e Initial load
duke
parents:
diff changeset
4121 // FMUL ST,$src /* D8 C8+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 emit_opcode(cbuf, 0xD8);
a61af66fc99e Initial load
duke
parents:
diff changeset
4123 emit_opcode(cbuf, 0xC8 + $src1$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4124 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4125
a61af66fc99e Initial load
duke
parents:
diff changeset
4126 enc_class FAdd_ST_reg( eRegF src2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4127 // FADDP ST,src2 /* D8 C0+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
4128 emit_opcode(cbuf, 0xD8);
a61af66fc99e Initial load
duke
parents:
diff changeset
4129 emit_opcode(cbuf, 0xC0 + $src2$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4130 //could use FADDP src2,fpST /* DE C0+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
4131 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4132
a61af66fc99e Initial load
duke
parents:
diff changeset
4133 enc_class FAddP_reg_ST( eRegF src2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4134 // FADDP src2,ST /* DE C0+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
4135 emit_opcode(cbuf, 0xDE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4136 emit_opcode(cbuf, 0xC0 + $src2$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4137 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4138
a61af66fc99e Initial load
duke
parents:
diff changeset
4139 enc_class subF_divF_encode( eRegF src1, eRegF src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4140 // Operand has been loaded into fp ST (stack top)
a61af66fc99e Initial load
duke
parents:
diff changeset
4141 // FSUB ST,$src1
a61af66fc99e Initial load
duke
parents:
diff changeset
4142 emit_opcode(cbuf, 0xD8);
a61af66fc99e Initial load
duke
parents:
diff changeset
4143 emit_opcode(cbuf, 0xE0 + $src1$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4144
a61af66fc99e Initial load
duke
parents:
diff changeset
4145 // FDIV
a61af66fc99e Initial load
duke
parents:
diff changeset
4146 emit_opcode(cbuf, 0xD8);
a61af66fc99e Initial load
duke
parents:
diff changeset
4147 emit_opcode(cbuf, 0xF0 + $src2$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4148 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4149
a61af66fc99e Initial load
duke
parents:
diff changeset
4150 enc_class MulFAddF (eRegF src1, eRegF src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4151 // Operand was loaded from memory into fp ST (stack top)
a61af66fc99e Initial load
duke
parents:
diff changeset
4152 // FADD ST,$src /* D8 C0+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
4153 emit_opcode(cbuf, 0xD8);
a61af66fc99e Initial load
duke
parents:
diff changeset
4154 emit_opcode(cbuf, 0xC0 + $src1$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4155
a61af66fc99e Initial load
duke
parents:
diff changeset
4156 // FMUL ST,src2 /* D8 C*+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
4157 emit_opcode(cbuf, 0xD8);
a61af66fc99e Initial load
duke
parents:
diff changeset
4158 emit_opcode(cbuf, 0xC8 + $src2$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4159 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4160
a61af66fc99e Initial load
duke
parents:
diff changeset
4161
a61af66fc99e Initial load
duke
parents:
diff changeset
4162 enc_class MulFAddFreverse (eRegF src1, eRegF src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4163 // Operand was loaded from memory into fp ST (stack top)
a61af66fc99e Initial load
duke
parents:
diff changeset
4164 // FADD ST,$src /* D8 C0+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
4165 emit_opcode(cbuf, 0xD8);
a61af66fc99e Initial load
duke
parents:
diff changeset
4166 emit_opcode(cbuf, 0xC0 + $src1$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4167
a61af66fc99e Initial load
duke
parents:
diff changeset
4168 // FMULP src2,ST /* DE C8+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
4169 emit_opcode(cbuf, 0xDE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4170 emit_opcode(cbuf, 0xC8 + $src2$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4171 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4172
a61af66fc99e Initial load
duke
parents:
diff changeset
4173 // Atomically load the volatile long
a61af66fc99e Initial load
duke
parents:
diff changeset
4174 enc_class enc_loadL_volatile( memory mem, stackSlotL dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4175 emit_opcode(cbuf,0xDF);
a61af66fc99e Initial load
duke
parents:
diff changeset
4176 int rm_byte_opcode = 0x05;
a61af66fc99e Initial load
duke
parents:
diff changeset
4177 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
4178 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
4179 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4180 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4181 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
4182 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
4183 store_to_stackslot( cbuf, 0x0DF, 0x07, $dst$$disp );
a61af66fc99e Initial load
duke
parents:
diff changeset
4184 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4185
a61af66fc99e Initial load
duke
parents:
diff changeset
4186 enc_class enc_loadLX_volatile( memory mem, stackSlotL dst, regXD tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4187 { // Atomic long load
a61af66fc99e Initial load
duke
parents:
diff changeset
4188 // UseXmmLoadAndClearUpper ? movsd $tmp,$mem : movlpd $tmp,$mem
a61af66fc99e Initial load
duke
parents:
diff changeset
4189 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4190 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4191 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0x10 : 0x12);
a61af66fc99e Initial load
duke
parents:
diff changeset
4192 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
4193 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
4194 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4195 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4196 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
4197 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
4198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4199 { // MOVSD $dst,$tmp ! atomic long store
a61af66fc99e Initial load
duke
parents:
diff changeset
4200 emit_opcode(cbuf,0xF2);
a61af66fc99e Initial load
duke
parents:
diff changeset
4201 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4202 emit_opcode(cbuf,0x11);
a61af66fc99e Initial load
duke
parents:
diff changeset
4203 int base = $dst$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
4204 int index = $dst$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
4205 int scale = $dst$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4206 int displace = $dst$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4207 bool disp_is_oop = $dst->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
4208 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
4209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4210 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4211
a61af66fc99e Initial load
duke
parents:
diff changeset
4212 enc_class enc_loadLX_reg_volatile( memory mem, eRegL dst, regXD tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4213 { // Atomic long load
a61af66fc99e Initial load
duke
parents:
diff changeset
4214 // UseXmmLoadAndClearUpper ? movsd $tmp,$mem : movlpd $tmp,$mem
a61af66fc99e Initial load
duke
parents:
diff changeset
4215 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4216 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4217 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0x10 : 0x12);
a61af66fc99e Initial load
duke
parents:
diff changeset
4218 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
4219 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
4220 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4221 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4222 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
4223 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
4224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4225 { // MOVD $dst.lo,$tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
4226 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4227 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 emit_opcode(cbuf,0x7E);
a61af66fc99e Initial load
duke
parents:
diff changeset
4229 emit_rm(cbuf, 0x3, $tmp$$reg, $dst$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4231 { // PSRLQ $tmp,32
a61af66fc99e Initial load
duke
parents:
diff changeset
4232 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4233 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4234 emit_opcode(cbuf,0x73);
a61af66fc99e Initial load
duke
parents:
diff changeset
4235 emit_rm(cbuf, 0x3, 0x02, $tmp$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4236 emit_d8(cbuf, 0x20);
a61af66fc99e Initial load
duke
parents:
diff changeset
4237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4238 { // MOVD $dst.hi,$tmp
a61af66fc99e Initial load
duke
parents:
diff changeset
4239 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4240 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4241 emit_opcode(cbuf,0x7E);
a61af66fc99e Initial load
duke
parents:
diff changeset
4242 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4244 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4245
a61af66fc99e Initial load
duke
parents:
diff changeset
4246 // Volatile Store Long. Must be atomic, so move it into
a61af66fc99e Initial load
duke
parents:
diff changeset
4247 // the FP TOS and then do a 64-bit FIST. Has to probe the
a61af66fc99e Initial load
duke
parents:
diff changeset
4248 // target address before the store (for null-ptr checks)
a61af66fc99e Initial load
duke
parents:
diff changeset
4249 // so the memory operand is used twice in the encoding.
a61af66fc99e Initial load
duke
parents:
diff changeset
4250 enc_class enc_storeL_volatile( memory mem, stackSlotL src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4251 store_to_stackslot( cbuf, 0x0DF, 0x05, $src$$disp );
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
4252 cbuf.set_insts_mark(); // Mark start of FIST in case $mem has an oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4253 emit_opcode(cbuf,0xDF);
a61af66fc99e Initial load
duke
parents:
diff changeset
4254 int rm_byte_opcode = 0x07;
a61af66fc99e Initial load
duke
parents:
diff changeset
4255 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
4256 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
4257 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4258 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4259 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
4260 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
4261 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4262
a61af66fc99e Initial load
duke
parents:
diff changeset
4263 enc_class enc_storeLX_volatile( memory mem, stackSlotL src, regXD tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4264 { // Atomic long load
a61af66fc99e Initial load
duke
parents:
diff changeset
4265 // UseXmmLoadAndClearUpper ? movsd $tmp,[$src] : movlpd $tmp,[$src]
a61af66fc99e Initial load
duke
parents:
diff changeset
4266 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4267 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4268 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0x10 : 0x12);
a61af66fc99e Initial load
duke
parents:
diff changeset
4269 int base = $src$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
4270 int index = $src$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
4271 int scale = $src$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4272 int displace = $src$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4273 bool disp_is_oop = $src->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
4274 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
4275 }
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
4276 cbuf.set_insts_mark(); // Mark start of MOVSD in case $mem has an oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4277 { // MOVSD $mem,$tmp ! atomic long store
a61af66fc99e Initial load
duke
parents:
diff changeset
4278 emit_opcode(cbuf,0xF2);
a61af66fc99e Initial load
duke
parents:
diff changeset
4279 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4280 emit_opcode(cbuf,0x11);
a61af66fc99e Initial load
duke
parents:
diff changeset
4281 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
4282 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
4283 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4284 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4285 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
4286 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
4287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4288 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4289
a61af66fc99e Initial load
duke
parents:
diff changeset
4290 enc_class enc_storeLX_reg_volatile( memory mem, eRegL src, regXD tmp, regXD tmp2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4291 { // MOVD $tmp,$src.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
4292 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4293 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4294 emit_opcode(cbuf,0x6E);
a61af66fc99e Initial load
duke
parents:
diff changeset
4295 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4297 { // MOVD $tmp2,$src.hi
a61af66fc99e Initial load
duke
parents:
diff changeset
4298 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4299 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4300 emit_opcode(cbuf,0x6E);
a61af66fc99e Initial load
duke
parents:
diff changeset
4301 emit_rm(cbuf, 0x3, $tmp2$$reg, HIGH_FROM_LOW($src$$reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4303 { // PUNPCKLDQ $tmp,$tmp2
a61af66fc99e Initial load
duke
parents:
diff changeset
4304 emit_opcode(cbuf,0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
4305 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4306 emit_opcode(cbuf,0x62);
a61af66fc99e Initial load
duke
parents:
diff changeset
4307 emit_rm(cbuf, 0x3, $tmp$$reg, $tmp2$$reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4308 }
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
4309 cbuf.set_insts_mark(); // Mark start of MOVSD in case $mem has an oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4310 { // MOVSD $mem,$tmp ! atomic long store
a61af66fc99e Initial load
duke
parents:
diff changeset
4311 emit_opcode(cbuf,0xF2);
a61af66fc99e Initial load
duke
parents:
diff changeset
4312 emit_opcode(cbuf,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
4313 emit_opcode(cbuf,0x11);
a61af66fc99e Initial load
duke
parents:
diff changeset
4314 int base = $mem$$base;
a61af66fc99e Initial load
duke
parents:
diff changeset
4315 int index = $mem$$index;
a61af66fc99e Initial load
duke
parents:
diff changeset
4316 int scale = $mem$$scale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4317 int displace = $mem$$disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4318 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
a61af66fc99e Initial load
duke
parents:
diff changeset
4319 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
4320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4321 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4322
a61af66fc99e Initial load
duke
parents:
diff changeset
4323 // Safepoint Poll. This polls the safepoint page, and causes an
a61af66fc99e Initial load
duke
parents:
diff changeset
4324 // exception if it is not readable. Unfortunately, it kills the condition code
a61af66fc99e Initial load
duke
parents:
diff changeset
4325 // in the process
a61af66fc99e Initial load
duke
parents:
diff changeset
4326 // We current use TESTL [spp],EDI
a61af66fc99e Initial load
duke
parents:
diff changeset
4327 // A better choice might be TESTB [spp + pagesize() - CacheLineSize()],0
a61af66fc99e Initial load
duke
parents:
diff changeset
4328
a61af66fc99e Initial load
duke
parents:
diff changeset
4329 enc_class Safepoint_Poll() %{
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
4330 cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4331 emit_opcode(cbuf,0x85);
a61af66fc99e Initial load
duke
parents:
diff changeset
4332 emit_rm (cbuf, 0x0, 0x7, 0x5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4333 emit_d32(cbuf, (intptr_t)os::get_polling_page());
a61af66fc99e Initial load
duke
parents:
diff changeset
4334 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4335 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4336
a61af66fc99e Initial load
duke
parents:
diff changeset
4337
a61af66fc99e Initial load
duke
parents:
diff changeset
4338 //----------FRAME--------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4339 // Definition of frame structure and management information.
a61af66fc99e Initial load
duke
parents:
diff changeset
4340 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4341 // S T A C K L A Y O U T Allocators stack-slot number
a61af66fc99e Initial load
duke
parents:
diff changeset
4342 // | (to get allocators register number
a61af66fc99e Initial load
duke
parents:
diff changeset
4343 // G Owned by | | v add OptoReg::stack0())
a61af66fc99e Initial load
duke
parents:
diff changeset
4344 // r CALLER | |
a61af66fc99e Initial load
duke
parents:
diff changeset
4345 // o | +--------+ pad to even-align allocators stack-slot
a61af66fc99e Initial load
duke
parents:
diff changeset
4346 // w V | pad0 | numbers; owned by CALLER
a61af66fc99e Initial load
duke
parents:
diff changeset
4347 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
a61af66fc99e Initial load
duke
parents:
diff changeset
4348 // h ^ | in | 5
a61af66fc99e Initial load
duke
parents:
diff changeset
4349 // | | args | 4 Holes in incoming args owned by SELF
a61af66fc99e Initial load
duke
parents:
diff changeset
4350 // | | | | 3
a61af66fc99e Initial load
duke
parents:
diff changeset
4351 // | | +--------+
a61af66fc99e Initial load
duke
parents:
diff changeset
4352 // V | | old out| Empty on Intel, window on Sparc
a61af66fc99e Initial load
duke
parents:
diff changeset
4353 // | old |preserve| Must be even aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
4354 // | SP-+--------+----> Matcher::_old_SP, even aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
4355 // | | in | 3 area for Intel ret address
a61af66fc99e Initial load
duke
parents:
diff changeset
4356 // Owned by |preserve| Empty on Sparc.
a61af66fc99e Initial load
duke
parents:
diff changeset
4357 // SELF +--------+
a61af66fc99e Initial load
duke
parents:
diff changeset
4358 // | | pad2 | 2 pad to align old SP
a61af66fc99e Initial load
duke
parents:
diff changeset
4359 // | +--------+ 1
a61af66fc99e Initial load
duke
parents:
diff changeset
4360 // | | locks | 0
a61af66fc99e Initial load
duke
parents:
diff changeset
4361 // | +--------+----> OptoReg::stack0(), even aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
4362 // | | pad1 | 11 pad to align new SP
a61af66fc99e Initial load
duke
parents:
diff changeset
4363 // | +--------+
a61af66fc99e Initial load
duke
parents:
diff changeset
4364 // | | | 10
a61af66fc99e Initial load
duke
parents:
diff changeset
4365 // | | spills | 9 spills
a61af66fc99e Initial load
duke
parents:
diff changeset
4366 // V | | 8 (pad0 slot for callee)
a61af66fc99e Initial load
duke
parents:
diff changeset
4367 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
a61af66fc99e Initial load
duke
parents:
diff changeset
4368 // ^ | out | 7
a61af66fc99e Initial load
duke
parents:
diff changeset
4369 // | | args | 6 Holes in outgoing args owned by CALLEE
a61af66fc99e Initial load
duke
parents:
diff changeset
4370 // Owned by +--------+
a61af66fc99e Initial load
duke
parents:
diff changeset
4371 // CALLEE | new out| 6 Empty on Intel, window on Sparc
a61af66fc99e Initial load
duke
parents:
diff changeset
4372 // | new |preserve| Must be even-aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
4373 // | SP-+--------+----> Matcher::_new_SP, even aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
4374 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
4375 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4376 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
a61af66fc99e Initial load
duke
parents:
diff changeset
4377 // known from SELF's arguments and the Java calling convention.
a61af66fc99e Initial load
duke
parents:
diff changeset
4378 // Region 6-7 is determined per call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
4379 // Note 2: If the calling convention leaves holes in the incoming argument
a61af66fc99e Initial load
duke
parents:
diff changeset
4380 // area, those holes are owned by SELF. Holes in the outgoing area
a61af66fc99e Initial load
duke
parents:
diff changeset
4381 // are owned by the CALLEE. Holes should not be nessecary in the
a61af66fc99e Initial load
duke
parents:
diff changeset
4382 // incoming area, as the Java calling convention is completely under
a61af66fc99e Initial load
duke
parents:
diff changeset
4383 // the control of the AD file. Doubles can be sorted and packed to
a61af66fc99e Initial load
duke
parents:
diff changeset
4384 // avoid holes. Holes in the outgoing arguments may be nessecary for
a61af66fc99e Initial load
duke
parents:
diff changeset
4385 // varargs C calling conventions.
a61af66fc99e Initial load
duke
parents:
diff changeset
4386 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
a61af66fc99e Initial load
duke
parents:
diff changeset
4387 // even aligned with pad0 as needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
4388 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
a61af66fc99e Initial load
duke
parents:
diff changeset
4389 // region 6-11 is even aligned; it may be padded out more so that
a61af66fc99e Initial load
duke
parents:
diff changeset
4390 // the region from SP to FP meets the minimum stack alignment.
a61af66fc99e Initial load
duke
parents:
diff changeset
4391
a61af66fc99e Initial load
duke
parents:
diff changeset
4392 frame %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4393 // What direction does stack grow in (assumed to be same for C & Java)
a61af66fc99e Initial load
duke
parents:
diff changeset
4394 stack_direction(TOWARDS_LOW);
a61af66fc99e Initial load
duke
parents:
diff changeset
4395
a61af66fc99e Initial load
duke
parents:
diff changeset
4396 // These three registers define part of the calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
4397 // between compiled code and the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
4398 inline_cache_reg(EAX); // Inline Cache Register
a61af66fc99e Initial load
duke
parents:
diff changeset
4399 interpreter_method_oop_reg(EBX); // Method Oop Register when calling interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
4400
a61af66fc99e Initial load
duke
parents:
diff changeset
4401 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
a61af66fc99e Initial load
duke
parents:
diff changeset
4402 cisc_spilling_operand_name(indOffset32);
a61af66fc99e Initial load
duke
parents:
diff changeset
4403
a61af66fc99e Initial load
duke
parents:
diff changeset
4404 // Number of stack slots consumed by locking an object
a61af66fc99e Initial load
duke
parents:
diff changeset
4405 sync_stack_slots(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
4406
a61af66fc99e Initial load
duke
parents:
diff changeset
4407 // Compiled code's Frame Pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
4408 frame_pointer(ESP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4409 // Interpreter stores its frame pointer in a register which is
a61af66fc99e Initial load
duke
parents:
diff changeset
4410 // stored to the stack by I2CAdaptors.
a61af66fc99e Initial load
duke
parents:
diff changeset
4411 // I2CAdaptors convert from interpreted java to compiled java.
a61af66fc99e Initial load
duke
parents:
diff changeset
4412 interpreter_frame_pointer(EBP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4413
a61af66fc99e Initial load
duke
parents:
diff changeset
4414 // Stack alignment requirement
a61af66fc99e Initial load
duke
parents:
diff changeset
4415 // Alignment size in bytes (128-bit -> 16 bytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
4416 stack_alignment(StackAlignmentInBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
4417
a61af66fc99e Initial load
duke
parents:
diff changeset
4418 // Number of stack slots between incoming argument block and the start of
a61af66fc99e Initial load
duke
parents:
diff changeset
4419 // a new frame. The PROLOG must add this many slots to the stack. The
a61af66fc99e Initial load
duke
parents:
diff changeset
4420 // EPILOG must remove this many slots. Intel needs one slot for
a61af66fc99e Initial load
duke
parents:
diff changeset
4421 // return address and one for rbp, (must save rbp)
a61af66fc99e Initial load
duke
parents:
diff changeset
4422 in_preserve_stack_slots(2+VerifyStackAtCalls);
a61af66fc99e Initial load
duke
parents:
diff changeset
4423
a61af66fc99e Initial load
duke
parents:
diff changeset
4424 // Number of outgoing stack slots killed above the out_preserve_stack_slots
a61af66fc99e Initial load
duke
parents:
diff changeset
4425 // for calls to C. Supports the var-args backing area for register parms.
a61af66fc99e Initial load
duke
parents:
diff changeset
4426 varargs_C_out_slots_killed(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4427
a61af66fc99e Initial load
duke
parents:
diff changeset
4428 // The after-PROLOG location of the return address. Location of
a61af66fc99e Initial load
duke
parents:
diff changeset
4429 // return address specifies a type (REG or STACK) and a number
a61af66fc99e Initial load
duke
parents:
diff changeset
4430 // representing the register number (i.e. - use a register name) or
a61af66fc99e Initial load
duke
parents:
diff changeset
4431 // stack slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
4432 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
a61af66fc99e Initial load
duke
parents:
diff changeset
4433 // Otherwise, it is above the locks and verification slot and alignment word
a61af66fc99e Initial load
duke
parents:
diff changeset
4434 return_addr(STACK - 1 +
a61af66fc99e Initial load
duke
parents:
diff changeset
4435 round_to(1+VerifyStackAtCalls+
a61af66fc99e Initial load
duke
parents:
diff changeset
4436 Compile::current()->fixed_slots(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4437 (StackAlignmentInBytes/wordSize)));
a61af66fc99e Initial load
duke
parents:
diff changeset
4438
a61af66fc99e Initial load
duke
parents:
diff changeset
4439 // Body of function which returns an integer array locating
a61af66fc99e Initial load
duke
parents:
diff changeset
4440 // arguments either in registers or in stack slots. Passed an array
a61af66fc99e Initial load
duke
parents:
diff changeset
4441 // of ideal registers called "sig" and a "length" count. Stack-slot
a61af66fc99e Initial load
duke
parents:
diff changeset
4442 // offsets are based on outgoing arguments, i.e. a CALLER setting up
a61af66fc99e Initial load
duke
parents:
diff changeset
4443 // arguments for a CALLEE. Incoming stack arguments are
a61af66fc99e Initial load
duke
parents:
diff changeset
4444 // automatically biased by the preserve_stack_slots field above.
a61af66fc99e Initial load
duke
parents:
diff changeset
4445 calling_convention %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4446 // No difference between ingoing/outgoing just pass false
a61af66fc99e Initial load
duke
parents:
diff changeset
4447 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4448 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4449
a61af66fc99e Initial load
duke
parents:
diff changeset
4450
a61af66fc99e Initial load
duke
parents:
diff changeset
4451 // Body of function which returns an integer array locating
a61af66fc99e Initial load
duke
parents:
diff changeset
4452 // arguments either in registers or in stack slots. Passed an array
a61af66fc99e Initial load
duke
parents:
diff changeset
4453 // of ideal registers called "sig" and a "length" count. Stack-slot
a61af66fc99e Initial load
duke
parents:
diff changeset
4454 // offsets are based on outgoing arguments, i.e. a CALLER setting up
a61af66fc99e Initial load
duke
parents:
diff changeset
4455 // arguments for a CALLEE. Incoming stack arguments are
a61af66fc99e Initial load
duke
parents:
diff changeset
4456 // automatically biased by the preserve_stack_slots field above.
a61af66fc99e Initial load
duke
parents:
diff changeset
4457 c_calling_convention %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4458 // This is obviously always outgoing
a61af66fc99e Initial load
duke
parents:
diff changeset
4459 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length);
a61af66fc99e Initial load
duke
parents:
diff changeset
4460 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4461
a61af66fc99e Initial load
duke
parents:
diff changeset
4462 // Location of C & interpreter return values
a61af66fc99e Initial load
duke
parents:
diff changeset
4463 c_return_value %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4464 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 71
diff changeset
4465 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num };
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 71
diff changeset
4466 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num };
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4467
a61af66fc99e Initial load
duke
parents:
diff changeset
4468 // in SSE2+ mode we want to keep the FPU stack clean so pretend
a61af66fc99e Initial load
duke
parents:
diff changeset
4469 // that C functions return float and double results in XMM0.
a61af66fc99e Initial load
duke
parents:
diff changeset
4470 if( ideal_reg == Op_RegD && UseSSE>=2 )
a61af66fc99e Initial load
duke
parents:
diff changeset
4471 return OptoRegPair(XMM0b_num,XMM0a_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
4472 if( ideal_reg == Op_RegF && UseSSE>=2 )
a61af66fc99e Initial load
duke
parents:
diff changeset
4473 return OptoRegPair(OptoReg::Bad,XMM0a_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
4474
a61af66fc99e Initial load
duke
parents:
diff changeset
4475 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
a61af66fc99e Initial load
duke
parents:
diff changeset
4476 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4477
a61af66fc99e Initial load
duke
parents:
diff changeset
4478 // Location of return values
a61af66fc99e Initial load
duke
parents:
diff changeset
4479 return_value %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4480 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 71
diff changeset
4481 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num };
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 71
diff changeset
4482 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num };
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4483 if( ideal_reg == Op_RegD && UseSSE>=2 )
a61af66fc99e Initial load
duke
parents:
diff changeset
4484 return OptoRegPair(XMM0b_num,XMM0a_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
4485 if( ideal_reg == Op_RegF && UseSSE>=1 )
a61af66fc99e Initial load
duke
parents:
diff changeset
4486 return OptoRegPair(OptoReg::Bad,XMM0a_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
4487 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
a61af66fc99e Initial load
duke
parents:
diff changeset
4488 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4489
a61af66fc99e Initial load
duke
parents:
diff changeset
4490 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4491
a61af66fc99e Initial load
duke
parents:
diff changeset
4492 //----------ATTRIBUTES---------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4493 //----------Operand Attributes-------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4494 op_attrib op_cost(0); // Required cost attribute
a61af66fc99e Initial load
duke
parents:
diff changeset
4495
a61af66fc99e Initial load
duke
parents:
diff changeset
4496 //----------Instruction Attributes---------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4497 ins_attrib ins_cost(100); // Required cost attribute
a61af66fc99e Initial load
duke
parents:
diff changeset
4498 ins_attrib ins_size(8); // Required size attribute (in bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
4499 ins_attrib ins_pc_relative(0); // Required PC Relative flag
a61af66fc99e Initial load
duke
parents:
diff changeset
4500 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
a61af66fc99e Initial load
duke
parents:
diff changeset
4501 // non-matching short branch variant of some
a61af66fc99e Initial load
duke
parents:
diff changeset
4502 // long branch?
a61af66fc99e Initial load
duke
parents:
diff changeset
4503 ins_attrib ins_alignment(1); // Required alignment attribute (must be a power of 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
4504 // specifies the alignment that some part of the instruction (not
a61af66fc99e Initial load
duke
parents:
diff changeset
4505 // necessarily the start) requires. If > 1, a compute_padding()
a61af66fc99e Initial load
duke
parents:
diff changeset
4506 // function must be provided for the instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
4507
a61af66fc99e Initial load
duke
parents:
diff changeset
4508 //----------OPERANDS-----------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4509 // Operand definitions must precede instruction definitions for correct parsing
a61af66fc99e Initial load
duke
parents:
diff changeset
4510 // in the ADLC because operands constitute user defined types which are used in
a61af66fc99e Initial load
duke
parents:
diff changeset
4511 // instruction definitions.
a61af66fc99e Initial load
duke
parents:
diff changeset
4512
a61af66fc99e Initial load
duke
parents:
diff changeset
4513 //----------Simple Operands----------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4514 // Immediate Operands
a61af66fc99e Initial load
duke
parents:
diff changeset
4515 // Integer Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
4516 operand immI() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4517 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4518
a61af66fc99e Initial load
duke
parents:
diff changeset
4519 op_cost(10);
a61af66fc99e Initial load
duke
parents:
diff changeset
4520 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4521 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4522 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4523
a61af66fc99e Initial load
duke
parents:
diff changeset
4524 // Constant for test vs zero
a61af66fc99e Initial load
duke
parents:
diff changeset
4525 operand immI0() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4526 predicate(n->get_int() == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4527 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4528
a61af66fc99e Initial load
duke
parents:
diff changeset
4529 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4530 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4531 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4532 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4533
a61af66fc99e Initial load
duke
parents:
diff changeset
4534 // Constant for increment
a61af66fc99e Initial load
duke
parents:
diff changeset
4535 operand immI1() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4536 predicate(n->get_int() == 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
4537 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4538
a61af66fc99e Initial load
duke
parents:
diff changeset
4539 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4540 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4541 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4542 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4543
a61af66fc99e Initial load
duke
parents:
diff changeset
4544 // Constant for decrement
a61af66fc99e Initial load
duke
parents:
diff changeset
4545 operand immI_M1() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4546 predicate(n->get_int() == -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
4547 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4548
a61af66fc99e Initial load
duke
parents:
diff changeset
4549 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4550 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4551 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4552 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4553
a61af66fc99e Initial load
duke
parents:
diff changeset
4554 // Valid scale values for addressing modes
a61af66fc99e Initial load
duke
parents:
diff changeset
4555 operand immI2() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4556 predicate(0 <= n->get_int() && (n->get_int() <= 3));
a61af66fc99e Initial load
duke
parents:
diff changeset
4557 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4558
a61af66fc99e Initial load
duke
parents:
diff changeset
4559 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4560 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4561 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4562
a61af66fc99e Initial load
duke
parents:
diff changeset
4563 operand immI8() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4564 predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
a61af66fc99e Initial load
duke
parents:
diff changeset
4565 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4566
a61af66fc99e Initial load
duke
parents:
diff changeset
4567 op_cost(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4568 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4569 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4570 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4571
a61af66fc99e Initial load
duke
parents:
diff changeset
4572 operand immI16() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4573 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
a61af66fc99e Initial load
duke
parents:
diff changeset
4574 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4575
a61af66fc99e Initial load
duke
parents:
diff changeset
4576 op_cost(10);
a61af66fc99e Initial load
duke
parents:
diff changeset
4577 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4578 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4579 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4580
a61af66fc99e Initial load
duke
parents:
diff changeset
4581 // Constant for long shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
4582 operand immI_32() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4583 predicate( n->get_int() == 32 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4584 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4585
a61af66fc99e Initial load
duke
parents:
diff changeset
4586 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4587 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4588 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4589 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4590
a61af66fc99e Initial load
duke
parents:
diff changeset
4591 operand immI_1_31() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4592 predicate( n->get_int() >= 1 && n->get_int() <= 31 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4593 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4594
a61af66fc99e Initial load
duke
parents:
diff changeset
4595 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4596 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4597 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4598 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4599
a61af66fc99e Initial load
duke
parents:
diff changeset
4600 operand immI_32_63() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4601 predicate( n->get_int() >= 32 && n->get_int() <= 63 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4602 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4603 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4604
a61af66fc99e Initial load
duke
parents:
diff changeset
4605 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4606 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4607 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4608
219
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4609 operand immI_1() %{
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4610 predicate( n->get_int() == 1 );
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4611 match(ConI);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4612
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4613 op_cost(0);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4614 format %{ %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4615 interface(CONST_INTER);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4616 %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4617
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4618 operand immI_2() %{
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4619 predicate( n->get_int() == 2 );
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4620 match(ConI);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4621
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4622 op_cost(0);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4623 format %{ %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4624 interface(CONST_INTER);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4625 %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4626
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4627 operand immI_3() %{
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4628 predicate( n->get_int() == 3 );
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4629 match(ConI);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4630
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4631 op_cost(0);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4632 format %{ %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4633 interface(CONST_INTER);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4634 %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
4635
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4636 // Pointer Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
4637 operand immP() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4638 match(ConP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4639
a61af66fc99e Initial load
duke
parents:
diff changeset
4640 op_cost(10);
a61af66fc99e Initial load
duke
parents:
diff changeset
4641 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4642 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4643 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4644
a61af66fc99e Initial load
duke
parents:
diff changeset
4645 // NULL Pointer Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
4646 operand immP0() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4647 predicate( n->get_ptr() == 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4648 match(ConP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4649 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4650
a61af66fc99e Initial load
duke
parents:
diff changeset
4651 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4652 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4653 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4654
a61af66fc99e Initial load
duke
parents:
diff changeset
4655 // Long Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
4656 operand immL() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4657 match(ConL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4658
a61af66fc99e Initial load
duke
parents:
diff changeset
4659 op_cost(20);
a61af66fc99e Initial load
duke
parents:
diff changeset
4660 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4661 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4662 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4663
a61af66fc99e Initial load
duke
parents:
diff changeset
4664 // Long Immediate zero
a61af66fc99e Initial load
duke
parents:
diff changeset
4665 operand immL0() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4666 predicate( n->get_long() == 0L );
a61af66fc99e Initial load
duke
parents:
diff changeset
4667 match(ConL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4668 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4669
a61af66fc99e Initial load
duke
parents:
diff changeset
4670 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4671 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4672 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4673
403
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4674 // Long Immediate zero
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4675 operand immL_M1() %{
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4676 predicate( n->get_long() == -1L );
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4677 match(ConL);
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4678 op_cost(0);
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4679
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4680 format %{ %}
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4681 interface(CONST_INTER);
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4682 %}
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
4683
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4684 // Long immediate from 0 to 127.
a61af66fc99e Initial load
duke
parents:
diff changeset
4685 // Used for a shorter form of long mul by 10.
a61af66fc99e Initial load
duke
parents:
diff changeset
4686 operand immL_127() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4687 predicate((0 <= n->get_long()) && (n->get_long() <= 127));
a61af66fc99e Initial load
duke
parents:
diff changeset
4688 match(ConL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4689 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4690
a61af66fc99e Initial load
duke
parents:
diff changeset
4691 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4692 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4693 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4694
a61af66fc99e Initial load
duke
parents:
diff changeset
4695 // Long Immediate: low 32-bit mask
a61af66fc99e Initial load
duke
parents:
diff changeset
4696 operand immL_32bits() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4697 predicate(n->get_long() == 0xFFFFFFFFL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4698 match(ConL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4699 op_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4700
a61af66fc99e Initial load
duke
parents:
diff changeset
4701 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4702 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4703 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4704
a61af66fc99e Initial load
duke
parents:
diff changeset
4705 // Long Immediate: low 32-bit mask
a61af66fc99e Initial load
duke
parents:
diff changeset
4706 operand immL32() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4707 predicate(n->get_long() == (int)(n->get_long()));
a61af66fc99e Initial load
duke
parents:
diff changeset
4708 match(ConL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4709 op_cost(20);
a61af66fc99e Initial load
duke
parents:
diff changeset
4710
a61af66fc99e Initial load
duke
parents:
diff changeset
4711 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4712 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4713 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4714
a61af66fc99e Initial load
duke
parents:
diff changeset
4715 //Double Immediate zero
a61af66fc99e Initial load
duke
parents:
diff changeset
4716 operand immD0() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4717 // Do additional (and counter-intuitive) test against NaN to work around VC++
a61af66fc99e Initial load
duke
parents:
diff changeset
4718 // bug that generates code such that NaNs compare equal to 0.0
a61af66fc99e Initial load
duke
parents:
diff changeset
4719 predicate( UseSSE<=1 && n->getd() == 0.0 && !g_isnan(n->getd()) );
a61af66fc99e Initial load
duke
parents:
diff changeset
4720 match(ConD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4721
a61af66fc99e Initial load
duke
parents:
diff changeset
4722 op_cost(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4723 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4724 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4725 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4726
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4727 // Double Immediate one
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4728 operand immD1() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4729 predicate( UseSSE<=1 && n->getd() == 1.0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4730 match(ConD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4731
a61af66fc99e Initial load
duke
parents:
diff changeset
4732 op_cost(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4733 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4734 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4735 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4736
a61af66fc99e Initial load
duke
parents:
diff changeset
4737 // Double Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
4738 operand immD() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4739 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
4740 match(ConD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4741
a61af66fc99e Initial load
duke
parents:
diff changeset
4742 op_cost(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4743 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4744 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4745 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4746
a61af66fc99e Initial load
duke
parents:
diff changeset
4747 operand immXD() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4748 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
4749 match(ConD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4750
a61af66fc99e Initial load
duke
parents:
diff changeset
4751 op_cost(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4752 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4753 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4754 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4755
a61af66fc99e Initial load
duke
parents:
diff changeset
4756 // Double Immediate zero
a61af66fc99e Initial load
duke
parents:
diff changeset
4757 operand immXD0() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4758 // Do additional (and counter-intuitive) test against NaN to work around VC++
a61af66fc99e Initial load
duke
parents:
diff changeset
4759 // bug that generates code such that NaNs compare equal to 0.0 AND do not
a61af66fc99e Initial load
duke
parents:
diff changeset
4760 // compare equal to -0.0.
a61af66fc99e Initial load
duke
parents:
diff changeset
4761 predicate( UseSSE>=2 && jlong_cast(n->getd()) == 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4762 match(ConD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4763
a61af66fc99e Initial load
duke
parents:
diff changeset
4764 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4765 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4766 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4767
a61af66fc99e Initial load
duke
parents:
diff changeset
4768 // Float Immediate zero
a61af66fc99e Initial load
duke
parents:
diff changeset
4769 operand immF0() %{
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4770 predicate(UseSSE == 0 && n->getf() == 0.0F);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4771 match(ConF);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4772
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4773 op_cost(5);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4774 format %{ %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4775 interface(CONST_INTER);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4776 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4777
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4778 // Float Immediate one
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4779 operand immF1() %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
4780 predicate(UseSSE == 0 && n->getf() == 1.0F);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4781 match(ConF);
a61af66fc99e Initial load
duke
parents:
diff changeset
4782
a61af66fc99e Initial load
duke
parents:
diff changeset
4783 op_cost(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4784 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4785 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4786 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4787
a61af66fc99e Initial load
duke
parents:
diff changeset
4788 // Float Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
4789 operand immF() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4790 predicate( UseSSE == 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4791 match(ConF);
a61af66fc99e Initial load
duke
parents:
diff changeset
4792
a61af66fc99e Initial load
duke
parents:
diff changeset
4793 op_cost(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4794 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4795 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4796 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4797
a61af66fc99e Initial load
duke
parents:
diff changeset
4798 // Float Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
4799 operand immXF() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4800 predicate(UseSSE >= 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
4801 match(ConF);
a61af66fc99e Initial load
duke
parents:
diff changeset
4802
a61af66fc99e Initial load
duke
parents:
diff changeset
4803 op_cost(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4804 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4805 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4806 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4807
a61af66fc99e Initial load
duke
parents:
diff changeset
4808 // Float Immediate zero. Zero and not -0.0
a61af66fc99e Initial load
duke
parents:
diff changeset
4809 operand immXF0() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4810 predicate( UseSSE >= 1 && jint_cast(n->getf()) == 0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4811 match(ConF);
a61af66fc99e Initial load
duke
parents:
diff changeset
4812
a61af66fc99e Initial load
duke
parents:
diff changeset
4813 op_cost(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
4814 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4815 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4816 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4817
a61af66fc99e Initial load
duke
parents:
diff changeset
4818 // Immediates for special shifts (sign extend)
a61af66fc99e Initial load
duke
parents:
diff changeset
4819
a61af66fc99e Initial load
duke
parents:
diff changeset
4820 // Constants for increment
a61af66fc99e Initial load
duke
parents:
diff changeset
4821 operand immI_16() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4822 predicate( n->get_int() == 16 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4823 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4824
a61af66fc99e Initial load
duke
parents:
diff changeset
4825 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4826 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4827 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4828
a61af66fc99e Initial load
duke
parents:
diff changeset
4829 operand immI_24() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4830 predicate( n->get_int() == 24 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4831 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4832
a61af66fc99e Initial load
duke
parents:
diff changeset
4833 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4834 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4835 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4836
a61af66fc99e Initial load
duke
parents:
diff changeset
4837 // Constant for byte-wide masking
a61af66fc99e Initial load
duke
parents:
diff changeset
4838 operand immI_255() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4839 predicate( n->get_int() == 255 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4840 match(ConI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4841
a61af66fc99e Initial load
duke
parents:
diff changeset
4842 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4843 interface(CONST_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4844 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4845
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
4846 // Constant for short-wide masking
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
4847 operand immI_65535() %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
4848 predicate(n->get_int() == 65535);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
4849 match(ConI);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
4850
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
4851 format %{ %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
4852 interface(CONST_INTER);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
4853 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
4854
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4855 // Register Operands
a61af66fc99e Initial load
duke
parents:
diff changeset
4856 // Integer Register
a61af66fc99e Initial load
duke
parents:
diff changeset
4857 operand eRegI() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4858 constraint(ALLOC_IN_RC(e_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4859 match(RegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4860 match(xRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4861 match(eAXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4862 match(eBXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4863 match(eCXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4864 match(eDXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4865 match(eDIRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4866 match(eSIRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4867
a61af66fc99e Initial load
duke
parents:
diff changeset
4868 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4869 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4870 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4871
a61af66fc99e Initial load
duke
parents:
diff changeset
4872 // Subset of Integer Register
a61af66fc99e Initial load
duke
parents:
diff changeset
4873 operand xRegI(eRegI reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4874 constraint(ALLOC_IN_RC(x_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4875 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4876 match(eAXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4877 match(eBXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4878 match(eCXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4879 match(eDXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4880
a61af66fc99e Initial load
duke
parents:
diff changeset
4881 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4882 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4883 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4884
a61af66fc99e Initial load
duke
parents:
diff changeset
4885 // Special Registers
a61af66fc99e Initial load
duke
parents:
diff changeset
4886 operand eAXRegI(xRegI reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4887 constraint(ALLOC_IN_RC(eax_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4888 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4889 match(eRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4890
a61af66fc99e Initial load
duke
parents:
diff changeset
4891 format %{ "EAX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4892 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4893 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4894
a61af66fc99e Initial load
duke
parents:
diff changeset
4895 // Special Registers
a61af66fc99e Initial load
duke
parents:
diff changeset
4896 operand eBXRegI(xRegI reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4897 constraint(ALLOC_IN_RC(ebx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4898 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4899 match(eRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4900
a61af66fc99e Initial load
duke
parents:
diff changeset
4901 format %{ "EBX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4902 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4903 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4904
a61af66fc99e Initial load
duke
parents:
diff changeset
4905 operand eCXRegI(xRegI reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4906 constraint(ALLOC_IN_RC(ecx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4907 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4908 match(eRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4909
a61af66fc99e Initial load
duke
parents:
diff changeset
4910 format %{ "ECX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4911 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4912 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4913
a61af66fc99e Initial load
duke
parents:
diff changeset
4914 operand eDXRegI(xRegI reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4915 constraint(ALLOC_IN_RC(edx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4916 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4917 match(eRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4918
a61af66fc99e Initial load
duke
parents:
diff changeset
4919 format %{ "EDX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4920 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4921 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4922
a61af66fc99e Initial load
duke
parents:
diff changeset
4923 operand eDIRegI(xRegI reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4924 constraint(ALLOC_IN_RC(edi_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4925 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4926 match(eRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4927
a61af66fc99e Initial load
duke
parents:
diff changeset
4928 format %{ "EDI" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4929 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4930 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4931
a61af66fc99e Initial load
duke
parents:
diff changeset
4932 operand naxRegI() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4933 constraint(ALLOC_IN_RC(nax_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4934 match(RegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4935 match(eCXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4936 match(eDXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4937 match(eSIRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4938 match(eDIRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4939
a61af66fc99e Initial load
duke
parents:
diff changeset
4940 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4941 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4942 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4943
a61af66fc99e Initial load
duke
parents:
diff changeset
4944 operand nadxRegI() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4945 constraint(ALLOC_IN_RC(nadx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4946 match(RegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4947 match(eBXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4948 match(eCXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4949 match(eSIRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4950 match(eDIRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4951
a61af66fc99e Initial load
duke
parents:
diff changeset
4952 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4953 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4954 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4955
a61af66fc99e Initial load
duke
parents:
diff changeset
4956 operand ncxRegI() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4957 constraint(ALLOC_IN_RC(ncx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4958 match(RegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4959 match(eAXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4960 match(eDXRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4961 match(eSIRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4962 match(eDIRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4963
a61af66fc99e Initial load
duke
parents:
diff changeset
4964 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4965 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4966 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4967
a61af66fc99e Initial load
duke
parents:
diff changeset
4968 // // This operand was used by cmpFastUnlock, but conflicted with 'object' reg
a61af66fc99e Initial load
duke
parents:
diff changeset
4969 // //
a61af66fc99e Initial load
duke
parents:
diff changeset
4970 operand eSIRegI(xRegI reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4971 constraint(ALLOC_IN_RC(esi_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4972 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4973 match(eRegI);
a61af66fc99e Initial load
duke
parents:
diff changeset
4974
a61af66fc99e Initial load
duke
parents:
diff changeset
4975 format %{ "ESI" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4976 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4977 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4978
a61af66fc99e Initial load
duke
parents:
diff changeset
4979 // Pointer Register
a61af66fc99e Initial load
duke
parents:
diff changeset
4980 operand anyRegP() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4981 constraint(ALLOC_IN_RC(any_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4982 match(RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4983 match(eAXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4984 match(eBXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4985 match(eCXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4986 match(eDIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4987 match(eRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4988
a61af66fc99e Initial load
duke
parents:
diff changeset
4989 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4990 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4991 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
4992
a61af66fc99e Initial load
duke
parents:
diff changeset
4993 operand eRegP() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
4994 constraint(ALLOC_IN_RC(e_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
4995 match(RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4996 match(eAXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4997 match(eBXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4998 match(eCXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4999 match(eDIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5000
a61af66fc99e Initial load
duke
parents:
diff changeset
5001 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5002 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5003 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5004
a61af66fc99e Initial load
duke
parents:
diff changeset
5005 // On windows95, EBP is not safe to use for implicit null tests.
a61af66fc99e Initial load
duke
parents:
diff changeset
5006 operand eRegP_no_EBP() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5007 constraint(ALLOC_IN_RC(e_reg_no_rbp));
a61af66fc99e Initial load
duke
parents:
diff changeset
5008 match(RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5009 match(eAXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5010 match(eBXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5011 match(eCXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5012 match(eDIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5013
a61af66fc99e Initial load
duke
parents:
diff changeset
5014 op_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5015 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5016 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5017 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5018
a61af66fc99e Initial load
duke
parents:
diff changeset
5019 operand naxRegP() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5020 constraint(ALLOC_IN_RC(nax_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5021 match(RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5022 match(eBXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5023 match(eDXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5024 match(eCXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5025 match(eSIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5026 match(eDIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5027
a61af66fc99e Initial load
duke
parents:
diff changeset
5028 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5029 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5030 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5031
a61af66fc99e Initial load
duke
parents:
diff changeset
5032 operand nabxRegP() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5033 constraint(ALLOC_IN_RC(nabx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5034 match(RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5035 match(eCXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5036 match(eDXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5037 match(eSIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5038 match(eDIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5039
a61af66fc99e Initial load
duke
parents:
diff changeset
5040 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5041 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5042 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5043
a61af66fc99e Initial load
duke
parents:
diff changeset
5044 operand pRegP() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5045 constraint(ALLOC_IN_RC(p_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5046 match(RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5047 match(eBXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5048 match(eDXRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5049 match(eSIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5050 match(eDIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5051
a61af66fc99e Initial load
duke
parents:
diff changeset
5052 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5053 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5054 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5055
a61af66fc99e Initial load
duke
parents:
diff changeset
5056 // Special Registers
a61af66fc99e Initial load
duke
parents:
diff changeset
5057 // Return a pointer value
a61af66fc99e Initial load
duke
parents:
diff changeset
5058 operand eAXRegP(eRegP reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5059 constraint(ALLOC_IN_RC(eax_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5060 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5061 format %{ "EAX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5062 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5063 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5064
a61af66fc99e Initial load
duke
parents:
diff changeset
5065 // Used in AtomicAdd
a61af66fc99e Initial load
duke
parents:
diff changeset
5066 operand eBXRegP(eRegP reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5067 constraint(ALLOC_IN_RC(ebx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5068 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5069 format %{ "EBX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5070 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5071 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5072
a61af66fc99e Initial load
duke
parents:
diff changeset
5073 // Tail-call (interprocedural jump) to interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
5074 operand eCXRegP(eRegP reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5075 constraint(ALLOC_IN_RC(ecx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5076 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5077 format %{ "ECX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5078 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5079 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5080
a61af66fc99e Initial load
duke
parents:
diff changeset
5081 operand eSIRegP(eRegP reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5082 constraint(ALLOC_IN_RC(esi_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5083 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5084 format %{ "ESI" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5085 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5086 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5087
a61af66fc99e Initial load
duke
parents:
diff changeset
5088 // Used in rep stosw
a61af66fc99e Initial load
duke
parents:
diff changeset
5089 operand eDIRegP(eRegP reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5090 constraint(ALLOC_IN_RC(edi_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5091 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5092 format %{ "EDI" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5093 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5094 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5095
a61af66fc99e Initial load
duke
parents:
diff changeset
5096 operand eBPRegP() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5097 constraint(ALLOC_IN_RC(ebp_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5098 match(RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5099 format %{ "EBP" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5100 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5101 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5102
a61af66fc99e Initial load
duke
parents:
diff changeset
5103 operand eRegL() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5104 constraint(ALLOC_IN_RC(long_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5105 match(RegL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5106 match(eADXRegL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5107
a61af66fc99e Initial load
duke
parents:
diff changeset
5108 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5109 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5110 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5111
a61af66fc99e Initial load
duke
parents:
diff changeset
5112 operand eADXRegL( eRegL reg ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5113 constraint(ALLOC_IN_RC(eadx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5114 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5115
a61af66fc99e Initial load
duke
parents:
diff changeset
5116 format %{ "EDX:EAX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5117 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5118 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5119
a61af66fc99e Initial load
duke
parents:
diff changeset
5120 operand eBCXRegL( eRegL reg ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5121 constraint(ALLOC_IN_RC(ebcx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5122 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5123
a61af66fc99e Initial load
duke
parents:
diff changeset
5124 format %{ "EBX:ECX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5125 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5126 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5127
a61af66fc99e Initial load
duke
parents:
diff changeset
5128 // Special case for integer high multiply
a61af66fc99e Initial load
duke
parents:
diff changeset
5129 operand eADXRegL_low_only() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5130 constraint(ALLOC_IN_RC(eadx_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5131 match(RegL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5132
a61af66fc99e Initial load
duke
parents:
diff changeset
5133 format %{ "EAX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5134 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5135 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5136
a61af66fc99e Initial load
duke
parents:
diff changeset
5137 // Flags register, used as output of compare instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
5138 operand eFlagsReg() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5139 constraint(ALLOC_IN_RC(int_flags));
a61af66fc99e Initial load
duke
parents:
diff changeset
5140 match(RegFlags);
a61af66fc99e Initial load
duke
parents:
diff changeset
5141
a61af66fc99e Initial load
duke
parents:
diff changeset
5142 format %{ "EFLAGS" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5143 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5144 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5145
a61af66fc99e Initial load
duke
parents:
diff changeset
5146 // Flags register, used as output of FLOATING POINT compare instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
5147 operand eFlagsRegU() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5148 constraint(ALLOC_IN_RC(int_flags));
a61af66fc99e Initial load
duke
parents:
diff changeset
5149 match(RegFlags);
a61af66fc99e Initial load
duke
parents:
diff changeset
5150
a61af66fc99e Initial load
duke
parents:
diff changeset
5151 format %{ "EFLAGS_U" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5152 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5153 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5154
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5155 operand eFlagsRegUCF() %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5156 constraint(ALLOC_IN_RC(int_flags));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5157 match(RegFlags);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5158 predicate(false);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5159
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5160 format %{ "EFLAGS_U_CF" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5161 interface(REG_INTER);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5162 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5163
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5164 // Condition Code Register used by long compare
a61af66fc99e Initial load
duke
parents:
diff changeset
5165 operand flagsReg_long_LTGE() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5166 constraint(ALLOC_IN_RC(int_flags));
a61af66fc99e Initial load
duke
parents:
diff changeset
5167 match(RegFlags);
a61af66fc99e Initial load
duke
parents:
diff changeset
5168 format %{ "FLAGS_LTGE" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5169 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5170 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5171 operand flagsReg_long_EQNE() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5172 constraint(ALLOC_IN_RC(int_flags));
a61af66fc99e Initial load
duke
parents:
diff changeset
5173 match(RegFlags);
a61af66fc99e Initial load
duke
parents:
diff changeset
5174 format %{ "FLAGS_EQNE" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5175 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5176 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5177 operand flagsReg_long_LEGT() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5178 constraint(ALLOC_IN_RC(int_flags));
a61af66fc99e Initial load
duke
parents:
diff changeset
5179 match(RegFlags);
a61af66fc99e Initial load
duke
parents:
diff changeset
5180 format %{ "FLAGS_LEGT" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5181 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5182 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5183
a61af66fc99e Initial load
duke
parents:
diff changeset
5184 // Float register operands
a61af66fc99e Initial load
duke
parents:
diff changeset
5185 operand regD() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5186 predicate( UseSSE < 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5187 constraint(ALLOC_IN_RC(dbl_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5188 match(RegD);
a61af66fc99e Initial load
duke
parents:
diff changeset
5189 match(regDPR1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5190 match(regDPR2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5191 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5192 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5193 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5194
a61af66fc99e Initial load
duke
parents:
diff changeset
5195 operand regDPR1(regD reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5196 predicate( UseSSE < 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5197 constraint(ALLOC_IN_RC(dbl_reg0));
a61af66fc99e Initial load
duke
parents:
diff changeset
5198 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5199 format %{ "FPR1" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5200 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5201 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5202
a61af66fc99e Initial load
duke
parents:
diff changeset
5203 operand regDPR2(regD reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5204 predicate( UseSSE < 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5205 constraint(ALLOC_IN_RC(dbl_reg1));
a61af66fc99e Initial load
duke
parents:
diff changeset
5206 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5207 format %{ "FPR2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5208 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5209 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5210
a61af66fc99e Initial load
duke
parents:
diff changeset
5211 operand regnotDPR1(regD reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5212 predicate( UseSSE < 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5213 constraint(ALLOC_IN_RC(dbl_notreg0));
a61af66fc99e Initial load
duke
parents:
diff changeset
5214 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5215 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5216 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5217 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5218
a61af66fc99e Initial load
duke
parents:
diff changeset
5219 // XMM Double register operands
a61af66fc99e Initial load
duke
parents:
diff changeset
5220 operand regXD() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5221 predicate( UseSSE>=2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5222 constraint(ALLOC_IN_RC(xdb_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5223 match(RegD);
a61af66fc99e Initial load
duke
parents:
diff changeset
5224 match(regXD6);
a61af66fc99e Initial load
duke
parents:
diff changeset
5225 match(regXD7);
a61af66fc99e Initial load
duke
parents:
diff changeset
5226 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5227 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5228 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5229
a61af66fc99e Initial load
duke
parents:
diff changeset
5230 // XMM6 double register operands
a61af66fc99e Initial load
duke
parents:
diff changeset
5231 operand regXD6(regXD reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5232 predicate( UseSSE>=2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5233 constraint(ALLOC_IN_RC(xdb_reg6));
a61af66fc99e Initial load
duke
parents:
diff changeset
5234 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5235 format %{ "XMM6" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5236 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5237 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5238
a61af66fc99e Initial load
duke
parents:
diff changeset
5239 // XMM7 double register operands
a61af66fc99e Initial load
duke
parents:
diff changeset
5240 operand regXD7(regXD reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5241 predicate( UseSSE>=2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5242 constraint(ALLOC_IN_RC(xdb_reg7));
a61af66fc99e Initial load
duke
parents:
diff changeset
5243 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5244 format %{ "XMM7" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5245 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5246 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5247
a61af66fc99e Initial load
duke
parents:
diff changeset
5248 // Float register operands
a61af66fc99e Initial load
duke
parents:
diff changeset
5249 operand regF() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5250 predicate( UseSSE < 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5251 constraint(ALLOC_IN_RC(flt_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5252 match(RegF);
a61af66fc99e Initial load
duke
parents:
diff changeset
5253 match(regFPR1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5254 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5255 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5256 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5257
a61af66fc99e Initial load
duke
parents:
diff changeset
5258 // Float register operands
a61af66fc99e Initial load
duke
parents:
diff changeset
5259 operand regFPR1(regF reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5260 predicate( UseSSE < 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5261 constraint(ALLOC_IN_RC(flt_reg0));
a61af66fc99e Initial load
duke
parents:
diff changeset
5262 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5263 format %{ "FPR1" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5264 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5265 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5266
a61af66fc99e Initial load
duke
parents:
diff changeset
5267 // XMM register operands
a61af66fc99e Initial load
duke
parents:
diff changeset
5268 operand regX() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5269 predicate( UseSSE>=1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5270 constraint(ALLOC_IN_RC(xmm_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5271 match(RegF);
a61af66fc99e Initial load
duke
parents:
diff changeset
5272 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5273 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5274 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5275
a61af66fc99e Initial load
duke
parents:
diff changeset
5276
a61af66fc99e Initial load
duke
parents:
diff changeset
5277 //----------Memory Operands----------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5278 // Direct Memory Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5279 operand direct(immP addr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5280 match(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
5281
a61af66fc99e Initial load
duke
parents:
diff changeset
5282 format %{ "[$addr]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5283 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5284 base(0xFFFFFFFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
5285 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5286 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5287 disp($addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
5288 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5289 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5290
a61af66fc99e Initial load
duke
parents:
diff changeset
5291 // Indirect Memory Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5292 operand indirect(eRegP reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5293 constraint(ALLOC_IN_RC(e_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5294 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5295
a61af66fc99e Initial load
duke
parents:
diff changeset
5296 format %{ "[$reg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5297 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5298 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5299 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5300 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5301 disp(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5302 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5303 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5304
a61af66fc99e Initial load
duke
parents:
diff changeset
5305 // Indirect Memory Plus Short Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5306 operand indOffset8(eRegP reg, immI8 off) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5307 match(AddP reg off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5308
a61af66fc99e Initial load
duke
parents:
diff changeset
5309 format %{ "[$reg + $off]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5310 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5311 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5312 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5313 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5314 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5315 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5316 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5317
a61af66fc99e Initial load
duke
parents:
diff changeset
5318 // Indirect Memory Plus Long Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5319 operand indOffset32(eRegP reg, immI off) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5320 match(AddP reg off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5321
a61af66fc99e Initial load
duke
parents:
diff changeset
5322 format %{ "[$reg + $off]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5323 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5324 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5325 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5326 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5327 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5328 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5329 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5330
a61af66fc99e Initial load
duke
parents:
diff changeset
5331 // Indirect Memory Plus Long Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5332 operand indOffset32X(eRegI reg, immP off) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5333 match(AddP off reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5334
a61af66fc99e Initial load
duke
parents:
diff changeset
5335 format %{ "[$reg + $off]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5336 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5337 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5338 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5339 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5340 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5341 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5342 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5343
a61af66fc99e Initial load
duke
parents:
diff changeset
5344 // Indirect Memory Plus Index Register Plus Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5345 operand indIndexOffset(eRegP reg, eRegI ireg, immI off) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5346 match(AddP (AddP reg ireg) off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5347
a61af66fc99e Initial load
duke
parents:
diff changeset
5348 op_cost(10);
a61af66fc99e Initial load
duke
parents:
diff changeset
5349 format %{"[$reg + $off + $ireg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5350 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5351 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5352 index($ireg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5353 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5354 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5355 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5356 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5357
a61af66fc99e Initial load
duke
parents:
diff changeset
5358 // Indirect Memory Plus Index Register Plus Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5359 operand indIndex(eRegP reg, eRegI ireg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5360 match(AddP reg ireg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5361
a61af66fc99e Initial load
duke
parents:
diff changeset
5362 op_cost(10);
a61af66fc99e Initial load
duke
parents:
diff changeset
5363 format %{"[$reg + $ireg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5364 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5365 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5366 index($ireg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5367 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5368 disp(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5369 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5370 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5371
a61af66fc99e Initial load
duke
parents:
diff changeset
5372 // // -------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5373 // // 486 architecture doesn't support "scale * index + offset" with out a base
a61af66fc99e Initial load
duke
parents:
diff changeset
5374 // // -------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5375 // // Scaled Memory Operands
a61af66fc99e Initial load
duke
parents:
diff changeset
5376 // // Indirect Memory Times Scale Plus Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5377 // operand indScaleOffset(immP off, eRegI ireg, immI2 scale) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5378 // match(AddP off (LShiftI ireg scale));
a61af66fc99e Initial load
duke
parents:
diff changeset
5379 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5380 // op_cost(10);
a61af66fc99e Initial load
duke
parents:
diff changeset
5381 // format %{"[$off + $ireg << $scale]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5382 // interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5383 // base(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5384 // index($ireg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5385 // scale($scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
5386 // disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5387 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5388 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5389
a61af66fc99e Initial load
duke
parents:
diff changeset
5390 // Indirect Memory Times Scale Plus Index Register
a61af66fc99e Initial load
duke
parents:
diff changeset
5391 operand indIndexScale(eRegP reg, eRegI ireg, immI2 scale) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5392 match(AddP reg (LShiftI ireg scale));
a61af66fc99e Initial load
duke
parents:
diff changeset
5393
a61af66fc99e Initial load
duke
parents:
diff changeset
5394 op_cost(10);
a61af66fc99e Initial load
duke
parents:
diff changeset
5395 format %{"[$reg + $ireg << $scale]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5396 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5397 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5398 index($ireg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5399 scale($scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
5400 disp(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5401 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5402 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5403
a61af66fc99e Initial load
duke
parents:
diff changeset
5404 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5405 operand indIndexScaleOffset(eRegP reg, immI off, eRegI ireg, immI2 scale) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5406 match(AddP (AddP reg (LShiftI ireg scale)) off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5407
a61af66fc99e Initial load
duke
parents:
diff changeset
5408 op_cost(10);
a61af66fc99e Initial load
duke
parents:
diff changeset
5409 format %{"[$reg + $off + $ireg << $scale]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5410 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5411 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5412 index($ireg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5413 scale($scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
5414 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5415 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5416 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5417
a61af66fc99e Initial load
duke
parents:
diff changeset
5418 //----------Load Long Memory Operands------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5419 // The load-long idiom will use it's address expression again after loading
a61af66fc99e Initial load
duke
parents:
diff changeset
5420 // the first word of the long. If the load-long destination overlaps with
a61af66fc99e Initial load
duke
parents:
diff changeset
5421 // registers used in the addressing expression, the 2nd half will be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
5422 // from a clobbered address. Fix this by requiring that load-long use
a61af66fc99e Initial load
duke
parents:
diff changeset
5423 // address registers that do not overlap with the load-long target.
a61af66fc99e Initial load
duke
parents:
diff changeset
5424
a61af66fc99e Initial load
duke
parents:
diff changeset
5425 // load-long support
a61af66fc99e Initial load
duke
parents:
diff changeset
5426 operand load_long_RegP() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5427 constraint(ALLOC_IN_RC(esi_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5428 match(RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5429 match(eSIRegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5430 op_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5431 format %{ %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5432 interface(REG_INTER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5433 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5434
a61af66fc99e Initial load
duke
parents:
diff changeset
5435 // Indirect Memory Operand Long
a61af66fc99e Initial load
duke
parents:
diff changeset
5436 operand load_long_indirect(load_long_RegP reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5437 constraint(ALLOC_IN_RC(esi_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5438 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5439
a61af66fc99e Initial load
duke
parents:
diff changeset
5440 format %{ "[$reg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5441 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5442 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5443 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5444 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5445 disp(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5446 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5447 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5448
a61af66fc99e Initial load
duke
parents:
diff changeset
5449 // Indirect Memory Plus Long Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5450 operand load_long_indOffset32(load_long_RegP reg, immI off) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5451 match(AddP reg off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5452
a61af66fc99e Initial load
duke
parents:
diff changeset
5453 format %{ "[$reg + $off]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5454 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5455 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5456 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5457 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5458 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5459 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5460 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5461
a61af66fc99e Initial load
duke
parents:
diff changeset
5462 opclass load_long_memory(load_long_indirect, load_long_indOffset32);
a61af66fc99e Initial load
duke
parents:
diff changeset
5463
a61af66fc99e Initial load
duke
parents:
diff changeset
5464
a61af66fc99e Initial load
duke
parents:
diff changeset
5465 //----------Special Memory Operands--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5466 // Stack Slot Operand - This operand is used for loading and storing temporary
a61af66fc99e Initial load
duke
parents:
diff changeset
5467 // values on the stack where a match requires a value to
a61af66fc99e Initial load
duke
parents:
diff changeset
5468 // flow through memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
5469 operand stackSlotP(sRegP reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5470 constraint(ALLOC_IN_RC(stack_slots));
a61af66fc99e Initial load
duke
parents:
diff changeset
5471 // No match rule because this operand is only generated in matching
a61af66fc99e Initial load
duke
parents:
diff changeset
5472 format %{ "[$reg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5473 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5474 base(0x4); // ESP
a61af66fc99e Initial load
duke
parents:
diff changeset
5475 index(0x4); // No Index
a61af66fc99e Initial load
duke
parents:
diff changeset
5476 scale(0x0); // No Scale
a61af66fc99e Initial load
duke
parents:
diff changeset
5477 disp($reg); // Stack Offset
a61af66fc99e Initial load
duke
parents:
diff changeset
5478 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5479 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5480
a61af66fc99e Initial load
duke
parents:
diff changeset
5481 operand stackSlotI(sRegI reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5482 constraint(ALLOC_IN_RC(stack_slots));
a61af66fc99e Initial load
duke
parents:
diff changeset
5483 // No match rule because this operand is only generated in matching
a61af66fc99e Initial load
duke
parents:
diff changeset
5484 format %{ "[$reg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5485 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5486 base(0x4); // ESP
a61af66fc99e Initial load
duke
parents:
diff changeset
5487 index(0x4); // No Index
a61af66fc99e Initial load
duke
parents:
diff changeset
5488 scale(0x0); // No Scale
a61af66fc99e Initial load
duke
parents:
diff changeset
5489 disp($reg); // Stack Offset
a61af66fc99e Initial load
duke
parents:
diff changeset
5490 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5491 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5492
a61af66fc99e Initial load
duke
parents:
diff changeset
5493 operand stackSlotF(sRegF reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5494 constraint(ALLOC_IN_RC(stack_slots));
a61af66fc99e Initial load
duke
parents:
diff changeset
5495 // No match rule because this operand is only generated in matching
a61af66fc99e Initial load
duke
parents:
diff changeset
5496 format %{ "[$reg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5497 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5498 base(0x4); // ESP
a61af66fc99e Initial load
duke
parents:
diff changeset
5499 index(0x4); // No Index
a61af66fc99e Initial load
duke
parents:
diff changeset
5500 scale(0x0); // No Scale
a61af66fc99e Initial load
duke
parents:
diff changeset
5501 disp($reg); // Stack Offset
a61af66fc99e Initial load
duke
parents:
diff changeset
5502 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5503 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5504
a61af66fc99e Initial load
duke
parents:
diff changeset
5505 operand stackSlotD(sRegD reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5506 constraint(ALLOC_IN_RC(stack_slots));
a61af66fc99e Initial load
duke
parents:
diff changeset
5507 // No match rule because this operand is only generated in matching
a61af66fc99e Initial load
duke
parents:
diff changeset
5508 format %{ "[$reg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5509 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5510 base(0x4); // ESP
a61af66fc99e Initial load
duke
parents:
diff changeset
5511 index(0x4); // No Index
a61af66fc99e Initial load
duke
parents:
diff changeset
5512 scale(0x0); // No Scale
a61af66fc99e Initial load
duke
parents:
diff changeset
5513 disp($reg); // Stack Offset
a61af66fc99e Initial load
duke
parents:
diff changeset
5514 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5515 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5516
a61af66fc99e Initial load
duke
parents:
diff changeset
5517 operand stackSlotL(sRegL reg) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5518 constraint(ALLOC_IN_RC(stack_slots));
a61af66fc99e Initial load
duke
parents:
diff changeset
5519 // No match rule because this operand is only generated in matching
a61af66fc99e Initial load
duke
parents:
diff changeset
5520 format %{ "[$reg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5521 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5522 base(0x4); // ESP
a61af66fc99e Initial load
duke
parents:
diff changeset
5523 index(0x4); // No Index
a61af66fc99e Initial load
duke
parents:
diff changeset
5524 scale(0x0); // No Scale
a61af66fc99e Initial load
duke
parents:
diff changeset
5525 disp($reg); // Stack Offset
a61af66fc99e Initial load
duke
parents:
diff changeset
5526 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5527 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5528
a61af66fc99e Initial load
duke
parents:
diff changeset
5529 //----------Memory Operands - Win95 Implicit Null Variants----------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5530 // Indirect Memory Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5531 operand indirect_win95_safe(eRegP_no_EBP reg)
a61af66fc99e Initial load
duke
parents:
diff changeset
5532 %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5533 constraint(ALLOC_IN_RC(e_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
5534 match(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5535
a61af66fc99e Initial load
duke
parents:
diff changeset
5536 op_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5537 format %{ "[$reg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5538 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5539 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5540 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5541 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5542 disp(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5543 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5544 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5545
a61af66fc99e Initial load
duke
parents:
diff changeset
5546 // Indirect Memory Plus Short Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5547 operand indOffset8_win95_safe(eRegP_no_EBP reg, immI8 off)
a61af66fc99e Initial load
duke
parents:
diff changeset
5548 %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5549 match(AddP reg off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5550
a61af66fc99e Initial load
duke
parents:
diff changeset
5551 op_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5552 format %{ "[$reg + $off]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5553 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5554 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5555 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5556 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5557 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5558 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5559 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5560
a61af66fc99e Initial load
duke
parents:
diff changeset
5561 // Indirect Memory Plus Long Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5562 operand indOffset32_win95_safe(eRegP_no_EBP reg, immI off)
a61af66fc99e Initial load
duke
parents:
diff changeset
5563 %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5564 match(AddP reg off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5565
a61af66fc99e Initial load
duke
parents:
diff changeset
5566 op_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5567 format %{ "[$reg + $off]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5568 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5569 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5570 index(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5571 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5572 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5573 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5574 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5575
a61af66fc99e Initial load
duke
parents:
diff changeset
5576 // Indirect Memory Plus Index Register Plus Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5577 operand indIndexOffset_win95_safe(eRegP_no_EBP reg, eRegI ireg, immI off)
a61af66fc99e Initial load
duke
parents:
diff changeset
5578 %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5579 match(AddP (AddP reg ireg) off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5580
a61af66fc99e Initial load
duke
parents:
diff changeset
5581 op_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5582 format %{"[$reg + $off + $ireg]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5583 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5584 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5585 index($ireg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5586 scale(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5587 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5588 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5589 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5590
a61af66fc99e Initial load
duke
parents:
diff changeset
5591 // Indirect Memory Times Scale Plus Index Register
a61af66fc99e Initial load
duke
parents:
diff changeset
5592 operand indIndexScale_win95_safe(eRegP_no_EBP reg, eRegI ireg, immI2 scale)
a61af66fc99e Initial load
duke
parents:
diff changeset
5593 %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5594 match(AddP reg (LShiftI ireg scale));
a61af66fc99e Initial load
duke
parents:
diff changeset
5595
a61af66fc99e Initial load
duke
parents:
diff changeset
5596 op_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5597 format %{"[$reg + $ireg << $scale]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5598 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5599 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5600 index($ireg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5601 scale($scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
5602 disp(0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5603 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5604 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5605
a61af66fc99e Initial load
duke
parents:
diff changeset
5606 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
5607 operand indIndexScaleOffset_win95_safe(eRegP_no_EBP reg, immI off, eRegI ireg, immI2 scale)
a61af66fc99e Initial load
duke
parents:
diff changeset
5608 %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5609 match(AddP (AddP reg (LShiftI ireg scale)) off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5610
a61af66fc99e Initial load
duke
parents:
diff changeset
5611 op_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5612 format %{"[$reg + $off + $ireg << $scale]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5613 interface(MEMORY_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5614 base($reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5615 index($ireg);
a61af66fc99e Initial load
duke
parents:
diff changeset
5616 scale($scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
5617 disp($off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5618 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5619 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5620
a61af66fc99e Initial load
duke
parents:
diff changeset
5621 //----------Conditional Branch Operands----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5622 // Comparison Op - This is the operation of the comparison, and is limited to
a61af66fc99e Initial load
duke
parents:
diff changeset
5623 // the following set of codes:
a61af66fc99e Initial load
duke
parents:
diff changeset
5624 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
a61af66fc99e Initial load
duke
parents:
diff changeset
5625 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5626 // Other attributes of the comparison, such as unsignedness, are specified
a61af66fc99e Initial load
duke
parents:
diff changeset
5627 // by the comparison instruction that sets a condition code flags register.
a61af66fc99e Initial load
duke
parents:
diff changeset
5628 // That result is represented by a flags operand whose subtype is appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
5629 // to the unsignedness (etc.) of the comparison.
a61af66fc99e Initial load
duke
parents:
diff changeset
5630 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5631 // Later, the instruction which matches both the Comparison Op (a Bool) and
a61af66fc99e Initial load
duke
parents:
diff changeset
5632 // the flags (produced by the Cmp) specifies the coding of the comparison op
a61af66fc99e Initial load
duke
parents:
diff changeset
5633 // by matching a specific subtype of Bool operand below, such as cmpOpU.
a61af66fc99e Initial load
duke
parents:
diff changeset
5634
a61af66fc99e Initial load
duke
parents:
diff changeset
5635 // Comparision Code
a61af66fc99e Initial load
duke
parents:
diff changeset
5636 operand cmpOp() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5637 match(Bool);
a61af66fc99e Initial load
duke
parents:
diff changeset
5638
a61af66fc99e Initial load
duke
parents:
diff changeset
5639 format %{ "" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5640 interface(COND_INTER) %{
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5641 equal(0x4, "e");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5642 not_equal(0x5, "ne");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5643 less(0xC, "l");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5644 greater_equal(0xD, "ge");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5645 less_equal(0xE, "le");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5646 greater(0xF, "g");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5647 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5648 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5649
a61af66fc99e Initial load
duke
parents:
diff changeset
5650 // Comparison Code, unsigned compare. Used by FP also, with
a61af66fc99e Initial load
duke
parents:
diff changeset
5651 // C2 (unordered) turned into GT or LT already. The other bits
a61af66fc99e Initial load
duke
parents:
diff changeset
5652 // C0 and C3 are turned into Carry & Zero flags.
a61af66fc99e Initial load
duke
parents:
diff changeset
5653 operand cmpOpU() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5654 match(Bool);
a61af66fc99e Initial load
duke
parents:
diff changeset
5655
a61af66fc99e Initial load
duke
parents:
diff changeset
5656 format %{ "" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5657 interface(COND_INTER) %{
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5658 equal(0x4, "e");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5659 not_equal(0x5, "ne");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5660 less(0x2, "b");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5661 greater_equal(0x3, "nb");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5662 less_equal(0x6, "be");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5663 greater(0x7, "nbe");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5664 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5665 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5666
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5667 // Floating comparisons that don't require any fixup for the unordered case
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5668 operand cmpOpUCF() %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5669 match(Bool);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5670 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5671 n->as_Bool()->_test._test == BoolTest::ge ||
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5672 n->as_Bool()->_test._test == BoolTest::le ||
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5673 n->as_Bool()->_test._test == BoolTest::gt);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5674 format %{ "" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5675 interface(COND_INTER) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5676 equal(0x4, "e");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5677 not_equal(0x5, "ne");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5678 less(0x2, "b");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5679 greater_equal(0x3, "nb");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5680 less_equal(0x6, "be");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5681 greater(0x7, "nbe");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5682 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5683 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5684
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5685
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5686 // Floating comparisons that can be fixed up with extra conditional jumps
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5687 operand cmpOpUCF2() %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5688 match(Bool);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5689 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5690 n->as_Bool()->_test._test == BoolTest::eq);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5691 format %{ "" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5692 interface(COND_INTER) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5693 equal(0x4, "e");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5694 not_equal(0x5, "ne");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5695 less(0x2, "b");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5696 greater_equal(0x3, "nb");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5697 less_equal(0x6, "be");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5698 greater(0x7, "nbe");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5699 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5700 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5701
a61af66fc99e Initial load
duke
parents:
diff changeset
5702 // Comparison Code for FP conditional move
a61af66fc99e Initial load
duke
parents:
diff changeset
5703 operand cmpOp_fcmov() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5704 match(Bool);
a61af66fc99e Initial load
duke
parents:
diff changeset
5705
a61af66fc99e Initial load
duke
parents:
diff changeset
5706 format %{ "" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5707 interface(COND_INTER) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5708 equal (0x0C8);
a61af66fc99e Initial load
duke
parents:
diff changeset
5709 not_equal (0x1C8);
a61af66fc99e Initial load
duke
parents:
diff changeset
5710 less (0x0C0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5711 greater_equal(0x1C0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5712 less_equal (0x0D0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5713 greater (0x1D0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5714 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5715 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5716
a61af66fc99e Initial load
duke
parents:
diff changeset
5717 // Comparision Code used in long compares
a61af66fc99e Initial load
duke
parents:
diff changeset
5718 operand cmpOp_commute() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5719 match(Bool);
a61af66fc99e Initial load
duke
parents:
diff changeset
5720
a61af66fc99e Initial load
duke
parents:
diff changeset
5721 format %{ "" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5722 interface(COND_INTER) %{
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5723 equal(0x4, "e");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5724 not_equal(0x5, "ne");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5725 less(0xF, "g");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5726 greater_equal(0xE, "le");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5727 less_equal(0xD, "ge");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
5728 greater(0xC, "l");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5729 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5730 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5731
a61af66fc99e Initial load
duke
parents:
diff changeset
5732 //----------OPERAND CLASSES----------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5733 // Operand Classes are groups of operands that are used as to simplify
605
98cb887364d3 6810672: Comment typos
twisti
parents: 570
diff changeset
5734 // instruction definitions by not requiring the AD writer to specify separate
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5735 // instructions for every form of operand when the instruction accepts
a61af66fc99e Initial load
duke
parents:
diff changeset
5736 // multiple operand types with the same basic encoding and format. The classic
a61af66fc99e Initial load
duke
parents:
diff changeset
5737 // case of this is memory operands.
a61af66fc99e Initial load
duke
parents:
diff changeset
5738
a61af66fc99e Initial load
duke
parents:
diff changeset
5739 opclass memory(direct, indirect, indOffset8, indOffset32, indOffset32X, indIndexOffset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5740 indIndex, indIndexScale, indIndexScaleOffset);
a61af66fc99e Initial load
duke
parents:
diff changeset
5741
a61af66fc99e Initial load
duke
parents:
diff changeset
5742 // Long memory operations are encoded in 2 instructions and a +4 offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
5743 // This means some kind of offset is always required and you cannot use
a61af66fc99e Initial load
duke
parents:
diff changeset
5744 // an oop as the offset (done when working on static globals).
a61af66fc99e Initial load
duke
parents:
diff changeset
5745 opclass long_memory(direct, indirect, indOffset8, indOffset32, indIndexOffset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5746 indIndex, indIndexScale, indIndexScaleOffset);
a61af66fc99e Initial load
duke
parents:
diff changeset
5747
a61af66fc99e Initial load
duke
parents:
diff changeset
5748
a61af66fc99e Initial load
duke
parents:
diff changeset
5749 //----------PIPELINE-----------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5750 // Rules which define the behavior of the target architectures pipeline.
a61af66fc99e Initial load
duke
parents:
diff changeset
5751 pipeline %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5752
a61af66fc99e Initial load
duke
parents:
diff changeset
5753 //----------ATTRIBUTES---------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5754 attributes %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5755 variable_size_instructions; // Fixed size instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
5756 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
a61af66fc99e Initial load
duke
parents:
diff changeset
5757 instruction_unit_size = 1; // An instruction is 1 bytes long
a61af66fc99e Initial load
duke
parents:
diff changeset
5758 instruction_fetch_unit_size = 16; // The processor fetches one line
a61af66fc99e Initial load
duke
parents:
diff changeset
5759 instruction_fetch_units = 1; // of 16 bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
5760
a61af66fc99e Initial load
duke
parents:
diff changeset
5761 // List of nop instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
5762 nops( MachNop );
a61af66fc99e Initial load
duke
parents:
diff changeset
5763 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5764
a61af66fc99e Initial load
duke
parents:
diff changeset
5765 //----------RESOURCES----------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5766 // Resources are the functional units available to the machine
a61af66fc99e Initial load
duke
parents:
diff changeset
5767
a61af66fc99e Initial load
duke
parents:
diff changeset
5768 // Generic P2/P3 pipeline
a61af66fc99e Initial load
duke
parents:
diff changeset
5769 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of
a61af66fc99e Initial load
duke
parents:
diff changeset
5770 // 3 instructions decoded per cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
5771 // 2 load/store ops per cycle, 1 branch, 1 FPU,
a61af66fc99e Initial load
duke
parents:
diff changeset
5772 // 2 ALU op, only ALU0 handles mul/div instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
5773 resources( D0, D1, D2, DECODE = D0 | D1 | D2,
a61af66fc99e Initial load
duke
parents:
diff changeset
5774 MS0, MS1, MEM = MS0 | MS1,
a61af66fc99e Initial load
duke
parents:
diff changeset
5775 BR, FPU,
a61af66fc99e Initial load
duke
parents:
diff changeset
5776 ALU0, ALU1, ALU = ALU0 | ALU1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
5777
a61af66fc99e Initial load
duke
parents:
diff changeset
5778 //----------PIPELINE DESCRIPTION-----------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5779 // Pipeline Description specifies the stages in the machine's pipeline
a61af66fc99e Initial load
duke
parents:
diff changeset
5780
a61af66fc99e Initial load
duke
parents:
diff changeset
5781 // Generic P2/P3 pipeline
a61af66fc99e Initial load
duke
parents:
diff changeset
5782 pipe_desc(S0, S1, S2, S3, S4, S5);
a61af66fc99e Initial load
duke
parents:
diff changeset
5783
a61af66fc99e Initial load
duke
parents:
diff changeset
5784 //----------PIPELINE CLASSES---------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5785 // Pipeline Classes describe the stages in which input and output are
a61af66fc99e Initial load
duke
parents:
diff changeset
5786 // referenced by the hardware pipeline.
a61af66fc99e Initial load
duke
parents:
diff changeset
5787
a61af66fc99e Initial load
duke
parents:
diff changeset
5788 // Naming convention: ialu or fpu
a61af66fc99e Initial load
duke
parents:
diff changeset
5789 // Then: _reg
a61af66fc99e Initial load
duke
parents:
diff changeset
5790 // Then: _reg if there is a 2nd register
a61af66fc99e Initial load
duke
parents:
diff changeset
5791 // Then: _long if it's a pair of instructions implementing a long
a61af66fc99e Initial load
duke
parents:
diff changeset
5792 // Then: _fat if it requires the big decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5793 // Or: _mem if it requires the big decoder and a memory unit.
a61af66fc99e Initial load
duke
parents:
diff changeset
5794
a61af66fc99e Initial load
duke
parents:
diff changeset
5795 // Integer ALU reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5796 pipe_class ialu_reg(eRegI dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5797 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5798 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5799 dst : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5800 DECODE : S0; // any decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5801 ALU : S3; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5802 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5803
a61af66fc99e Initial load
duke
parents:
diff changeset
5804 // Long ALU reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5805 pipe_class ialu_reg_long(eRegL dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5806 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5807 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5808 dst : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5809 DECODE : S0(2); // any 2 decoders
a61af66fc99e Initial load
duke
parents:
diff changeset
5810 ALU : S3(2); // both alus
a61af66fc99e Initial load
duke
parents:
diff changeset
5811 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5812
a61af66fc99e Initial load
duke
parents:
diff changeset
5813 // Integer ALU reg operation using big decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5814 pipe_class ialu_reg_fat(eRegI dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5815 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5816 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5817 dst : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5818 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
5819 ALU : S3; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5820 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5821
a61af66fc99e Initial load
duke
parents:
diff changeset
5822 // Long ALU reg operation using big decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5823 pipe_class ialu_reg_long_fat(eRegL dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5824 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5825 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5826 dst : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5827 D0 : S0(2); // big decoder only; twice
a61af66fc99e Initial load
duke
parents:
diff changeset
5828 ALU : S3(2); // any 2 alus
a61af66fc99e Initial load
duke
parents:
diff changeset
5829 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5830
a61af66fc99e Initial load
duke
parents:
diff changeset
5831 // Integer ALU reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5832 pipe_class ialu_reg_reg(eRegI dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5833 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5834 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5835 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5836 DECODE : S0; // any decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5837 ALU : S3; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5838 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5839
a61af66fc99e Initial load
duke
parents:
diff changeset
5840 // Long ALU reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5841 pipe_class ialu_reg_reg_long(eRegL dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5842 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5843 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5844 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5845 DECODE : S0(2); // any 2 decoders
a61af66fc99e Initial load
duke
parents:
diff changeset
5846 ALU : S3(2); // both alus
a61af66fc99e Initial load
duke
parents:
diff changeset
5847 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5848
a61af66fc99e Initial load
duke
parents:
diff changeset
5849 // Integer ALU reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5850 pipe_class ialu_reg_reg_fat(eRegI dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5851 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5852 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5853 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5854 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
5855 ALU : S3; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5856 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5857
a61af66fc99e Initial load
duke
parents:
diff changeset
5858 // Long ALU reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5859 pipe_class ialu_reg_reg_long_fat(eRegL dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5860 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5861 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5862 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5863 D0 : S0(2); // big decoder only; twice
a61af66fc99e Initial load
duke
parents:
diff changeset
5864 ALU : S3(2); // both alus
a61af66fc99e Initial load
duke
parents:
diff changeset
5865 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5866
a61af66fc99e Initial load
duke
parents:
diff changeset
5867 // Integer ALU reg-mem operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5868 pipe_class ialu_reg_mem(eRegI dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5869 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5870 dst : S5(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5871 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5872 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
5873 ALU : S4; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5874 MEM : S3; // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
5875 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5876
a61af66fc99e Initial load
duke
parents:
diff changeset
5877 // Long ALU reg-mem operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5878 pipe_class ialu_reg_long_mem(eRegL dst, load_long_memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5879 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5880 dst : S5(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5881 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5882 D0 : S0(2); // big decoder only; twice
a61af66fc99e Initial load
duke
parents:
diff changeset
5883 ALU : S4(2); // any 2 alus
a61af66fc99e Initial load
duke
parents:
diff changeset
5884 MEM : S3(2); // both mems
a61af66fc99e Initial load
duke
parents:
diff changeset
5885 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5886
a61af66fc99e Initial load
duke
parents:
diff changeset
5887 // Integer mem operation (prefetch)
a61af66fc99e Initial load
duke
parents:
diff changeset
5888 pipe_class ialu_mem(memory mem)
a61af66fc99e Initial load
duke
parents:
diff changeset
5889 %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5890 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5891 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5892 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
5893 MEM : S3; // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
5894 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5895
a61af66fc99e Initial load
duke
parents:
diff changeset
5896 // Integer Store to Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
5897 pipe_class ialu_mem_reg(memory mem, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5898 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5899 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5900 src : S5(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5901 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
5902 ALU : S4; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5903 MEM : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
5904 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5905
a61af66fc99e Initial load
duke
parents:
diff changeset
5906 // Long Store to Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
5907 pipe_class ialu_mem_long_reg(memory mem, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5908 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5909 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5910 src : S5(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5911 D0 : S0(2); // big decoder only; twice
a61af66fc99e Initial load
duke
parents:
diff changeset
5912 ALU : S4(2); // any 2 alus
a61af66fc99e Initial load
duke
parents:
diff changeset
5913 MEM : S3(2); // Both mems
a61af66fc99e Initial load
duke
parents:
diff changeset
5914 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5915
a61af66fc99e Initial load
duke
parents:
diff changeset
5916 // Integer Store to Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
5917 pipe_class ialu_mem_imm(memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5918 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5919 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5920 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
5921 ALU : S4; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5922 MEM : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
5923 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5924
a61af66fc99e Initial load
duke
parents:
diff changeset
5925 // Integer ALU0 reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5926 pipe_class ialu_reg_reg_alu0(eRegI dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5927 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5928 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5929 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5930 D0 : S0; // Big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
5931 ALU0 : S3; // only alu0
a61af66fc99e Initial load
duke
parents:
diff changeset
5932 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5933
a61af66fc99e Initial load
duke
parents:
diff changeset
5934 // Integer ALU0 reg-mem operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5935 pipe_class ialu_reg_mem_alu0(eRegI dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5936 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5937 dst : S5(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5938 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5939 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
5940 ALU0 : S4; // ALU0 only
a61af66fc99e Initial load
duke
parents:
diff changeset
5941 MEM : S3; // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
5942 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5943
a61af66fc99e Initial load
duke
parents:
diff changeset
5944 // Integer ALU reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5945 pipe_class ialu_cr_reg_reg(eFlagsReg cr, eRegI src1, eRegI src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5946 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5947 cr : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5948 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5949 src2 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5950 DECODE : S0; // any decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5951 ALU : S3; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5952 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5953
a61af66fc99e Initial load
duke
parents:
diff changeset
5954 // Integer ALU reg-imm operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5955 pipe_class ialu_cr_reg_imm(eFlagsReg cr, eRegI src1) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5956 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5957 cr : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5958 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5959 DECODE : S0; // any decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5960 ALU : S3; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5961 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5962
a61af66fc99e Initial load
duke
parents:
diff changeset
5963 // Integer ALU reg-mem operation
a61af66fc99e Initial load
duke
parents:
diff changeset
5964 pipe_class ialu_cr_reg_mem(eFlagsReg cr, eRegI src1, memory src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5965 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5966 cr : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5967 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5968 src2 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5969 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
5970 ALU : S4; // any alu
a61af66fc99e Initial load
duke
parents:
diff changeset
5971 MEM : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
5972 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5973
a61af66fc99e Initial load
duke
parents:
diff changeset
5974 // Conditional move reg-reg
a61af66fc99e Initial load
duke
parents:
diff changeset
5975 pipe_class pipe_cmplt( eRegI p, eRegI q, eRegI y ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5976 instruction_count(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
5977 y : S4(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5978 q : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5979 p : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5980 DECODE : S0(4); // any decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5981 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5982
a61af66fc99e Initial load
duke
parents:
diff changeset
5983 // Conditional move reg-reg
a61af66fc99e Initial load
duke
parents:
diff changeset
5984 pipe_class pipe_cmov_reg( eRegI dst, eRegI src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5985 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5986 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5987 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5988 cr : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5989 DECODE : S0; // any decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5990 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
5991
a61af66fc99e Initial load
duke
parents:
diff changeset
5992 // Conditional move reg-mem
a61af66fc99e Initial load
duke
parents:
diff changeset
5993 pipe_class pipe_cmov_mem( eFlagsReg cr, eRegI dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
5994 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
5995 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
5996 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5997 cr : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
5998 DECODE : S0; // any decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
5999 MEM : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
6000 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6001
a61af66fc99e Initial load
duke
parents:
diff changeset
6002 // Conditional move reg-reg long
a61af66fc99e Initial load
duke
parents:
diff changeset
6003 pipe_class pipe_cmov_reg_long( eFlagsReg cr, eRegL dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6004 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
6005 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6006 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6007 cr : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6008 DECODE : S0(2); // any 2 decoders
a61af66fc99e Initial load
duke
parents:
diff changeset
6009 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6010
a61af66fc99e Initial load
duke
parents:
diff changeset
6011 // Conditional move double reg-reg
a61af66fc99e Initial load
duke
parents:
diff changeset
6012 pipe_class pipe_cmovD_reg( eFlagsReg cr, regDPR1 dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6013 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
6014 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6015 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6016 cr : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6017 DECODE : S0; // any decoder
a61af66fc99e Initial load
duke
parents:
diff changeset
6018 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6019
a61af66fc99e Initial load
duke
parents:
diff changeset
6020 // Float reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
6021 pipe_class fpu_reg(regD dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6022 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6023 dst : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6024 DECODE : S0(2); // any 2 decoders
a61af66fc99e Initial load
duke
parents:
diff changeset
6025 FPU : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
6026 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6027
a61af66fc99e Initial load
duke
parents:
diff changeset
6028 // Float reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
6029 pipe_class fpu_reg_reg(regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6030 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6031 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6032 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6033 DECODE : S0(2); // any 2 decoders
a61af66fc99e Initial load
duke
parents:
diff changeset
6034 FPU : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
6035 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6036
a61af66fc99e Initial load
duke
parents:
diff changeset
6037 // Float reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
6038 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6039 instruction_count(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
6040 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6041 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6042 src2 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6043 DECODE : S0(3); // any 3 decoders
a61af66fc99e Initial load
duke
parents:
diff changeset
6044 FPU : S3(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6045 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6046
a61af66fc99e Initial load
duke
parents:
diff changeset
6047 // Float reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
6048 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6049 instruction_count(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
6050 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6051 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6052 src2 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6053 src3 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6054 DECODE : S0(4); // any 3 decoders
a61af66fc99e Initial load
duke
parents:
diff changeset
6055 FPU : S3(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6056 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6057
a61af66fc99e Initial load
duke
parents:
diff changeset
6058 // Float reg-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
6059 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6060 instruction_count(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
6061 dst : S4(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6062 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6063 src2 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6064 src3 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6065 DECODE : S1(3); // any 3 decoders
a61af66fc99e Initial load
duke
parents:
diff changeset
6066 D0 : S0; // Big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
6067 FPU : S3(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6068 MEM : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
6069 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6070
a61af66fc99e Initial load
duke
parents:
diff changeset
6071 // Float reg-mem operation
a61af66fc99e Initial load
duke
parents:
diff changeset
6072 pipe_class fpu_reg_mem(regD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6073 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6074 dst : S5(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6075 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6076 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
6077 DECODE : S1; // any decoder for FPU POP
a61af66fc99e Initial load
duke
parents:
diff changeset
6078 FPU : S4;
a61af66fc99e Initial load
duke
parents:
diff changeset
6079 MEM : S3; // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6080 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6081
a61af66fc99e Initial load
duke
parents:
diff changeset
6082 // Float reg-mem operation
a61af66fc99e Initial load
duke
parents:
diff changeset
6083 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6084 instruction_count(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
6085 dst : S5(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6086 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6087 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6088 D0 : S0; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
6089 DECODE : S1(2); // any decoder for FPU POP
a61af66fc99e Initial load
duke
parents:
diff changeset
6090 FPU : S4;
a61af66fc99e Initial load
duke
parents:
diff changeset
6091 MEM : S3; // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6092 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6093
a61af66fc99e Initial load
duke
parents:
diff changeset
6094 // Float mem-reg operation
a61af66fc99e Initial load
duke
parents:
diff changeset
6095 pipe_class fpu_mem_reg(memory mem, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6096 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6097 src : S5(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6098 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6099 DECODE : S0; // any decoder for FPU PUSH
a61af66fc99e Initial load
duke
parents:
diff changeset
6100 D0 : S1; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
6101 FPU : S4;
a61af66fc99e Initial load
duke
parents:
diff changeset
6102 MEM : S3; // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6103 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6104
a61af66fc99e Initial load
duke
parents:
diff changeset
6105 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6106 instruction_count(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
6107 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6108 src2 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6109 mem : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6110 DECODE : S0(2); // any decoder for FPU PUSH
a61af66fc99e Initial load
duke
parents:
diff changeset
6111 D0 : S1; // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
6112 FPU : S4;
a61af66fc99e Initial load
duke
parents:
diff changeset
6113 MEM : S3; // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6114 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6115
a61af66fc99e Initial load
duke
parents:
diff changeset
6116 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6117 instruction_count(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
6118 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6119 src2 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6120 mem : S4(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6121 DECODE : S0; // any decoder for FPU PUSH
a61af66fc99e Initial load
duke
parents:
diff changeset
6122 D0 : S0(2); // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
6123 FPU : S4;
a61af66fc99e Initial load
duke
parents:
diff changeset
6124 MEM : S3(2); // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6125 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6126
a61af66fc99e Initial load
duke
parents:
diff changeset
6127 pipe_class fpu_mem_mem(memory dst, memory src1) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6128 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6129 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6130 dst : S4(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6131 D0 : S0(2); // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
6132 MEM : S3(2); // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6133 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6134
a61af66fc99e Initial load
duke
parents:
diff changeset
6135 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6136 instruction_count(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
6137 src1 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6138 src2 : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6139 dst : S4(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6140 D0 : S0(3); // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
6141 FPU : S4;
a61af66fc99e Initial load
duke
parents:
diff changeset
6142 MEM : S3(3); // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6143 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6144
a61af66fc99e Initial load
duke
parents:
diff changeset
6145 pipe_class fpu_mem_reg_con(memory mem, regD src1) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6146 instruction_count(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
6147 src1 : S4(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6148 mem : S4(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6149 DECODE : S0; // any decoder for FPU PUSH
a61af66fc99e Initial load
duke
parents:
diff changeset
6150 D0 : S0(2); // big decoder only
a61af66fc99e Initial load
duke
parents:
diff changeset
6151 FPU : S4;
a61af66fc99e Initial load
duke
parents:
diff changeset
6152 MEM : S3(2); // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6153 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6154
a61af66fc99e Initial load
duke
parents:
diff changeset
6155 // Float load constant
a61af66fc99e Initial load
duke
parents:
diff changeset
6156 pipe_class fpu_reg_con(regD dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6157 instruction_count(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6158 dst : S5(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6159 D0 : S0; // big decoder only for the load
a61af66fc99e Initial load
duke
parents:
diff changeset
6160 DECODE : S1; // any decoder for FPU POP
a61af66fc99e Initial load
duke
parents:
diff changeset
6161 FPU : S4;
a61af66fc99e Initial load
duke
parents:
diff changeset
6162 MEM : S3; // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6163 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6164
a61af66fc99e Initial load
duke
parents:
diff changeset
6165 // Float load constant
a61af66fc99e Initial load
duke
parents:
diff changeset
6166 pipe_class fpu_reg_reg_con(regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6167 instruction_count(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
6168 dst : S5(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6169 src : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6170 D0 : S0; // big decoder only for the load
a61af66fc99e Initial load
duke
parents:
diff changeset
6171 DECODE : S1(2); // any decoder for FPU POP
a61af66fc99e Initial load
duke
parents:
diff changeset
6172 FPU : S4;
a61af66fc99e Initial load
duke
parents:
diff changeset
6173 MEM : S3; // any mem
a61af66fc99e Initial load
duke
parents:
diff changeset
6174 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6175
a61af66fc99e Initial load
duke
parents:
diff changeset
6176 // UnConditional branch
a61af66fc99e Initial load
duke
parents:
diff changeset
6177 pipe_class pipe_jmp( label labl ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6178 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
6179 BR : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
6180 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6181
a61af66fc99e Initial load
duke
parents:
diff changeset
6182 // Conditional branch
a61af66fc99e Initial load
duke
parents:
diff changeset
6183 pipe_class pipe_jcc( cmpOp cmp, eFlagsReg cr, label labl ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6184 single_instruction;
a61af66fc99e Initial load
duke
parents:
diff changeset
6185 cr : S1(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6186 BR : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
6187 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6188
a61af66fc99e Initial load
duke
parents:
diff changeset
6189 // Allocation idiom
a61af66fc99e Initial load
duke
parents:
diff changeset
6190 pipe_class pipe_cmpxchg( eRegP dst, eRegP heap_ptr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6191 instruction_count(1); force_serialization;
a61af66fc99e Initial load
duke
parents:
diff changeset
6192 fixed_latency(6);
a61af66fc99e Initial load
duke
parents:
diff changeset
6193 heap_ptr : S3(read);
a61af66fc99e Initial load
duke
parents:
diff changeset
6194 DECODE : S0(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
6195 D0 : S2;
a61af66fc99e Initial load
duke
parents:
diff changeset
6196 MEM : S3;
a61af66fc99e Initial load
duke
parents:
diff changeset
6197 ALU : S3(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6198 dst : S5(write);
a61af66fc99e Initial load
duke
parents:
diff changeset
6199 BR : S5;
a61af66fc99e Initial load
duke
parents:
diff changeset
6200 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6201
a61af66fc99e Initial load
duke
parents:
diff changeset
6202 // Generic big/slow expanded idiom
a61af66fc99e Initial load
duke
parents:
diff changeset
6203 pipe_class pipe_slow( ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6204 instruction_count(10); multiple_bundles; force_serialization;
a61af66fc99e Initial load
duke
parents:
diff changeset
6205 fixed_latency(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
6206 D0 : S0(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6207 MEM : S3(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6208 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6209
a61af66fc99e Initial load
duke
parents:
diff changeset
6210 // The real do-nothing guy
a61af66fc99e Initial load
duke
parents:
diff changeset
6211 pipe_class empty( ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6212 instruction_count(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
6213 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6214
a61af66fc99e Initial load
duke
parents:
diff changeset
6215 // Define the class for the Nop node
a61af66fc99e Initial load
duke
parents:
diff changeset
6216 define %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6217 MachNop = empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
6218 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6219
a61af66fc99e Initial load
duke
parents:
diff changeset
6220 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6221
a61af66fc99e Initial load
duke
parents:
diff changeset
6222 //----------INSTRUCTIONS-------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
6223 //
a61af66fc99e Initial load
duke
parents:
diff changeset
6224 // match -- States which machine-independent subtree may be replaced
a61af66fc99e Initial load
duke
parents:
diff changeset
6225 // by this instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
6226 // ins_cost -- The estimated cost of this instruction is used by instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
6227 // selection to identify a minimum cost tree of machine
a61af66fc99e Initial load
duke
parents:
diff changeset
6228 // instructions that matches a tree of machine-independent
a61af66fc99e Initial load
duke
parents:
diff changeset
6229 // instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
6230 // format -- A string providing the disassembly for this instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
6231 // The value of an instruction's operand may be inserted
a61af66fc99e Initial load
duke
parents:
diff changeset
6232 // by referring to it with a '$' prefix.
a61af66fc99e Initial load
duke
parents:
diff changeset
6233 // opcode -- Three instruction opcodes may be provided. These are referred
a61af66fc99e Initial load
duke
parents:
diff changeset
6234 // to within an encode class as $primary, $secondary, and $tertiary
a61af66fc99e Initial load
duke
parents:
diff changeset
6235 // respectively. The primary opcode is commonly used to
a61af66fc99e Initial load
duke
parents:
diff changeset
6236 // indicate the type of machine instruction, while secondary
a61af66fc99e Initial load
duke
parents:
diff changeset
6237 // and tertiary are often used for prefix options or addressing
a61af66fc99e Initial load
duke
parents:
diff changeset
6238 // modes.
a61af66fc99e Initial load
duke
parents:
diff changeset
6239 // ins_encode -- A list of encode classes with parameters. The encode class
a61af66fc99e Initial load
duke
parents:
diff changeset
6240 // name must have been defined in an 'enc_class' specification
a61af66fc99e Initial load
duke
parents:
diff changeset
6241 // in the encode section of the architecture description.
a61af66fc99e Initial load
duke
parents:
diff changeset
6242
a61af66fc99e Initial load
duke
parents:
diff changeset
6243 //----------BSWAP-Instruction--------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
6244 instruct bytes_reverse_int(eRegI dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6245 match(Set dst (ReverseBytesI dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
6246
a61af66fc99e Initial load
duke
parents:
diff changeset
6247 format %{ "BSWAP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6248 opcode(0x0F, 0xC8);
a61af66fc99e Initial load
duke
parents:
diff changeset
6249 ins_encode( OpcP, OpcSReg(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
6250 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
6251 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6252
a61af66fc99e Initial load
duke
parents:
diff changeset
6253 instruct bytes_reverse_long(eRegL dst) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6254 match(Set dst (ReverseBytesL dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
6255
a61af66fc99e Initial load
duke
parents:
diff changeset
6256 format %{ "BSWAP $dst.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
6257 "BSWAP $dst.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
6258 "XCHG $dst.lo $dst.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6259
a61af66fc99e Initial load
duke
parents:
diff changeset
6260 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
6261 ins_encode( bswap_long_bytes(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
6262 ins_pipe( ialu_reg_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
6263 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6264
1396
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6265 instruct bytes_reverse_unsigned_short(eRegI dst) %{
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6266 match(Set dst (ReverseBytesUS dst));
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6267
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6268 format %{ "BSWAP $dst\n\t"
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6269 "SHR $dst,16\n\t" %}
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6270 ins_encode %{
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6271 __ bswapl($dst$$Register);
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6272 __ shrl($dst$$Register, 16);
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6273 %}
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6274 ins_pipe( ialu_reg );
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6275 %}
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6276
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6277 instruct bytes_reverse_short(eRegI dst) %{
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6278 match(Set dst (ReverseBytesS dst));
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6279
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6280 format %{ "BSWAP $dst\n\t"
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6281 "SAR $dst,16\n\t" %}
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6282 ins_encode %{
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6283 __ bswapl($dst$$Register);
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6284 __ sarl($dst$$Register, 16);
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6285 %}
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6286 ins_pipe( ialu_reg );
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6287 %}
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1274
diff changeset
6288
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6289
775
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6290 //---------- Zeros Count Instructions ------------------------------------------
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6291
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6292 instruct countLeadingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6293 predicate(UseCountLeadingZerosInstruction);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6294 match(Set dst (CountLeadingZerosI src));
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6295 effect(KILL cr);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6296
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6297 format %{ "LZCNT $dst, $src\t# count leading zeros (int)" %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6298 ins_encode %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6299 __ lzcntl($dst$$Register, $src$$Register);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6300 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6301 ins_pipe(ialu_reg);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6302 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6303
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6304 instruct countLeadingZerosI_bsr(eRegI dst, eRegI src, eFlagsReg cr) %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6305 predicate(!UseCountLeadingZerosInstruction);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6306 match(Set dst (CountLeadingZerosI src));
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6307 effect(KILL cr);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6308
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6309 format %{ "BSR $dst, $src\t# count leading zeros (int)\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6310 "JNZ skip\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6311 "MOV $dst, -1\n"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6312 "skip:\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6313 "NEG $dst\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6314 "ADD $dst, 31" %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6315 ins_encode %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6316 Register Rdst = $dst$$Register;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6317 Register Rsrc = $src$$Register;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6318 Label skip;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6319 __ bsrl(Rdst, Rsrc);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6320 __ jccb(Assembler::notZero, skip);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6321 __ movl(Rdst, -1);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6322 __ bind(skip);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6323 __ negl(Rdst);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6324 __ addl(Rdst, BitsPerInt - 1);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6325 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6326 ins_pipe(ialu_reg);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6327 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6328
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6329 instruct countLeadingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6330 predicate(UseCountLeadingZerosInstruction);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6331 match(Set dst (CountLeadingZerosL src));
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6332 effect(TEMP dst, KILL cr);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6333
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6334 format %{ "LZCNT $dst, $src.hi\t# count leading zeros (long)\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6335 "JNC done\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6336 "LZCNT $dst, $src.lo\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6337 "ADD $dst, 32\n"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6338 "done:" %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6339 ins_encode %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6340 Register Rdst = $dst$$Register;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6341 Register Rsrc = $src$$Register;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6342 Label done;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6343 __ lzcntl(Rdst, HIGH_FROM_LOW(Rsrc));
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6344 __ jccb(Assembler::carryClear, done);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6345 __ lzcntl(Rdst, Rsrc);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6346 __ addl(Rdst, BitsPerInt);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6347 __ bind(done);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6348 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6349 ins_pipe(ialu_reg);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6350 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6351
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6352 instruct countLeadingZerosL_bsr(eRegI dst, eRegL src, eFlagsReg cr) %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6353 predicate(!UseCountLeadingZerosInstruction);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6354 match(Set dst (CountLeadingZerosL src));
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6355 effect(TEMP dst, KILL cr);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6356
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6357 format %{ "BSR $dst, $src.hi\t# count leading zeros (long)\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6358 "JZ msw_is_zero\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6359 "ADD $dst, 32\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6360 "JMP not_zero\n"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6361 "msw_is_zero:\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6362 "BSR $dst, $src.lo\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6363 "JNZ not_zero\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6364 "MOV $dst, -1\n"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6365 "not_zero:\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6366 "NEG $dst\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6367 "ADD $dst, 63\n" %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6368 ins_encode %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6369 Register Rdst = $dst$$Register;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6370 Register Rsrc = $src$$Register;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6371 Label msw_is_zero;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6372 Label not_zero;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6373 __ bsrl(Rdst, HIGH_FROM_LOW(Rsrc));
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6374 __ jccb(Assembler::zero, msw_is_zero);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6375 __ addl(Rdst, BitsPerInt);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6376 __ jmpb(not_zero);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6377 __ bind(msw_is_zero);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6378 __ bsrl(Rdst, Rsrc);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6379 __ jccb(Assembler::notZero, not_zero);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6380 __ movl(Rdst, -1);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6381 __ bind(not_zero);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6382 __ negl(Rdst);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6383 __ addl(Rdst, BitsPerLong - 1);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6384 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6385 ins_pipe(ialu_reg);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6386 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6387
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6388 instruct countTrailingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6389 match(Set dst (CountTrailingZerosI src));
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6390 effect(KILL cr);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6391
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6392 format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6393 "JNZ done\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6394 "MOV $dst, 32\n"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6395 "done:" %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6396 ins_encode %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6397 Register Rdst = $dst$$Register;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6398 Label done;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6399 __ bsfl(Rdst, $src$$Register);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6400 __ jccb(Assembler::notZero, done);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6401 __ movl(Rdst, BitsPerInt);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6402 __ bind(done);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6403 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6404 ins_pipe(ialu_reg);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6405 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6406
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6407 instruct countTrailingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6408 match(Set dst (CountTrailingZerosL src));
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6409 effect(TEMP dst, KILL cr);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6410
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6411 format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6412 "JNZ done\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6413 "BSF $dst, $src.hi\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6414 "JNZ msw_not_zero\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6415 "MOV $dst, 32\n"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6416 "msw_not_zero:\n\t"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6417 "ADD $dst, 32\n"
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6418 "done:" %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6419 ins_encode %{
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6420 Register Rdst = $dst$$Register;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6421 Register Rsrc = $src$$Register;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6422 Label msw_not_zero;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6423 Label done;
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6424 __ bsfl(Rdst, Rsrc);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6425 __ jccb(Assembler::notZero, done);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6426 __ bsfl(Rdst, HIGH_FROM_LOW(Rsrc));
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6427 __ jccb(Assembler::notZero, msw_not_zero);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6428 __ movl(Rdst, BitsPerInt);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6429 __ bind(msw_not_zero);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6430 __ addl(Rdst, BitsPerInt);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6431 __ bind(done);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6432 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6433 ins_pipe(ialu_reg);
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6434 %}
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6435
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 681
diff changeset
6436
643
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6437 //---------- Population Count Instructions -------------------------------------
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6438
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6439 instruct popCountI(eRegI dst, eRegI src) %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6440 predicate(UsePopCountInstruction);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6441 match(Set dst (PopCountI src));
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6442
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6443 format %{ "POPCNT $dst, $src" %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6444 ins_encode %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6445 __ popcntl($dst$$Register, $src$$Register);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6446 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6447 ins_pipe(ialu_reg);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6448 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6449
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6450 instruct popCountI_mem(eRegI dst, memory mem) %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6451 predicate(UsePopCountInstruction);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6452 match(Set dst (PopCountI (LoadI mem)));
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6453
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6454 format %{ "POPCNT $dst, $mem" %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6455 ins_encode %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6456 __ popcntl($dst$$Register, $mem$$Address);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6457 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6458 ins_pipe(ialu_reg);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6459 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6460
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6461 // Note: Long.bitCount(long) returns an int.
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6462 instruct popCountL(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6463 predicate(UsePopCountInstruction);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6464 match(Set dst (PopCountL src));
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6465 effect(KILL cr, TEMP tmp, TEMP dst);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6466
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6467 format %{ "POPCNT $dst, $src.lo\n\t"
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6468 "POPCNT $tmp, $src.hi\n\t"
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6469 "ADD $dst, $tmp" %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6470 ins_encode %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6471 __ popcntl($dst$$Register, $src$$Register);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6472 __ popcntl($tmp$$Register, HIGH_FROM_LOW($src$$Register));
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6473 __ addl($dst$$Register, $tmp$$Register);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6474 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6475 ins_pipe(ialu_reg);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6476 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6477
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6478 // Note: Long.bitCount(long) returns an int.
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6479 instruct popCountL_mem(eRegI dst, memory mem, eRegI tmp, eFlagsReg cr) %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6480 predicate(UsePopCountInstruction);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6481 match(Set dst (PopCountL (LoadL mem)));
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6482 effect(KILL cr, TEMP tmp, TEMP dst);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6483
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6484 format %{ "POPCNT $dst, $mem\n\t"
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6485 "POPCNT $tmp, $mem+4\n\t"
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6486 "ADD $dst, $tmp" %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6487 ins_encode %{
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6488 //__ popcntl($dst$$Register, $mem$$Address$$first);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6489 //__ popcntl($tmp$$Register, $mem$$Address$$second);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6490 __ popcntl($dst$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false));
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6491 __ popcntl($tmp$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false));
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6492 __ addl($dst$$Register, $tmp$$Register);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6493 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6494 ins_pipe(ialu_reg);
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6495 %}
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6496
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 624
diff changeset
6497
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6498 //----------Load/Store/Move Instructions---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
6499 //----------Load Instructions--------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
6500 // Load Byte (8bit signed)
a61af66fc99e Initial load
duke
parents:
diff changeset
6501 instruct loadB(xRegI dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6502 match(Set dst (LoadB mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6503
a61af66fc99e Initial load
duke
parents:
diff changeset
6504 ins_cost(125);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6505 format %{ "MOVSX8 $dst,$mem\t# byte" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6506
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6507 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6508 __ movsbl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6509 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6510
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6511 ins_pipe(ialu_reg_mem);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6512 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6513
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6514 // Load Byte (8bit signed) into Long Register
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6515 instruct loadB2L(eRegL dst, memory mem, eFlagsReg cr) %{
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6516 match(Set dst (ConvI2L (LoadB mem)));
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6517 effect(KILL cr);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6518
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6519 ins_cost(375);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6520 format %{ "MOVSX8 $dst.lo,$mem\t# byte -> long\n\t"
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6521 "MOV $dst.hi,$dst.lo\n\t"
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6522 "SAR $dst.hi,7" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6523
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6524 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6525 __ movsbl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6526 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6527 __ sarl(HIGH_FROM_LOW($dst$$Register), 7); // 24+1 MSB are already signed extended.
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6528 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6529
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6530 ins_pipe(ialu_reg_mem);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6531 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6532
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6533 // Load Unsigned Byte (8bit UNsigned)
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6534 instruct loadUB(xRegI dst, memory mem) %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6535 match(Set dst (LoadUB mem));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6536
a61af66fc99e Initial load
duke
parents:
diff changeset
6537 ins_cost(125);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6538 format %{ "MOVZX8 $dst,$mem\t# ubyte -> int" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6539
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6540 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6541 __ movzbl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6542 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6543
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6544 ins_pipe(ialu_reg_mem);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6545 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6546
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6547 // Load Unsigned Byte (8 bit UNsigned) into Long Register
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6548 instruct loadUB2L(eRegL dst, memory mem, eFlagsReg cr) %{
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6549 match(Set dst (ConvI2L (LoadUB mem)));
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6550 effect(KILL cr);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6551
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6552 ins_cost(250);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6553 format %{ "MOVZX8 $dst.lo,$mem\t# ubyte -> long\n\t"
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6554 "XOR $dst.hi,$dst.hi" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6555
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6556 ins_encode %{
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6557 Register Rdst = $dst$$Register;
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6558 __ movzbl(Rdst, $mem$$Address);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6559 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6560 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6561
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6562 ins_pipe(ialu_reg_mem);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6563 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6564
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6565 // Load Unsigned Byte (8 bit UNsigned) with mask into Long Register
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6566 instruct loadUB2L_immI8(eRegL dst, memory mem, immI8 mask, eFlagsReg cr) %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6567 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6568 effect(KILL cr);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6569
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6570 format %{ "MOVZX8 $dst.lo,$mem\t# ubyte & 8-bit mask -> long\n\t"
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6571 "XOR $dst.hi,$dst.hi\n\t"
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6572 "AND $dst.lo,$mask" %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6573 ins_encode %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6574 Register Rdst = $dst$$Register;
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6575 __ movzbl(Rdst, $mem$$Address);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6576 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6577 __ andl(Rdst, $mask$$constant);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6578 %}
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6579 ins_pipe(ialu_reg_mem);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6580 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6581
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6582 // Load Short (16bit signed)
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6583 instruct loadS(eRegI dst, memory mem) %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6584 match(Set dst (LoadS mem));
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6585
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6586 ins_cost(125);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6587 format %{ "MOVSX $dst,$mem\t# short" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6588
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6589 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6590 __ movswl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6591 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6592
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6593 ins_pipe(ialu_reg_mem);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6594 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6595
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6596 // Load Short (16 bit signed) to Byte (8 bit signed)
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6597 instruct loadS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6598 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6599
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6600 ins_cost(125);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6601 format %{ "MOVSX $dst, $mem\t# short -> byte" %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6602 ins_encode %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6603 __ movsbl($dst$$Register, $mem$$Address);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6604 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6605 ins_pipe(ialu_reg_mem);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6606 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6607
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6608 // Load Short (16bit signed) into Long Register
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6609 instruct loadS2L(eRegL dst, memory mem, eFlagsReg cr) %{
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6610 match(Set dst (ConvI2L (LoadS mem)));
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6611 effect(KILL cr);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6612
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6613 ins_cost(375);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6614 format %{ "MOVSX $dst.lo,$mem\t# short -> long\n\t"
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6615 "MOV $dst.hi,$dst.lo\n\t"
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6616 "SAR $dst.hi,15" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6617
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6618 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6619 __ movswl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6620 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6621 __ sarl(HIGH_FROM_LOW($dst$$Register), 15); // 16+1 MSB are already signed extended.
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6622 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6623
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6624 ins_pipe(ialu_reg_mem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6625 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6626
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 420
diff changeset
6627 // Load Unsigned Short/Char (16bit unsigned)
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 420
diff changeset
6628 instruct loadUS(eRegI dst, memory mem) %{
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 420
diff changeset
6629 match(Set dst (LoadUS mem));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6630
a61af66fc99e Initial load
duke
parents:
diff changeset
6631 ins_cost(125);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6632 format %{ "MOVZX $dst,$mem\t# ushort/char -> int" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6633
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6634 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6635 __ movzwl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6636 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6637
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6638 ins_pipe(ialu_reg_mem);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6639 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6640
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6641 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6642 instruct loadUS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6643 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6644
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6645 ins_cost(125);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6646 format %{ "MOVSX $dst, $mem\t# ushort -> byte" %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6647 ins_encode %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6648 __ movsbl($dst$$Register, $mem$$Address);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6649 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6650 ins_pipe(ialu_reg_mem);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6651 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6652
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6653 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6654 instruct loadUS2L(eRegL dst, memory mem, eFlagsReg cr) %{
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6655 match(Set dst (ConvI2L (LoadUS mem)));
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6656 effect(KILL cr);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6657
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6658 ins_cost(250);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6659 format %{ "MOVZX $dst.lo,$mem\t# ushort/char -> long\n\t"
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6660 "XOR $dst.hi,$dst.hi" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6661
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6662 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6663 __ movzwl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6664 __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6665 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6666
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6667 ins_pipe(ialu_reg_mem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6668 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6669
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6670 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6671 instruct loadUS2L_immI_255(eRegL dst, memory mem, immI_255 mask, eFlagsReg cr) %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6672 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6673 effect(KILL cr);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6674
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6675 format %{ "MOVZX8 $dst.lo,$mem\t# ushort/char & 0xFF -> long\n\t"
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6676 "XOR $dst.hi,$dst.hi" %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6677 ins_encode %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6678 Register Rdst = $dst$$Register;
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6679 __ movzbl(Rdst, $mem$$Address);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6680 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6681 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6682 ins_pipe(ialu_reg_mem);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6683 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6684
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6685 // Load Unsigned Short/Char (16 bit UNsigned) with a 16-bit mask into Long Register
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6686 instruct loadUS2L_immI16(eRegL dst, memory mem, immI16 mask, eFlagsReg cr) %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6687 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6688 effect(KILL cr);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6689
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6690 format %{ "MOVZX $dst.lo, $mem\t# ushort/char & 16-bit mask -> long\n\t"
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6691 "XOR $dst.hi,$dst.hi\n\t"
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6692 "AND $dst.lo,$mask" %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6693 ins_encode %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6694 Register Rdst = $dst$$Register;
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6695 __ movzwl(Rdst, $mem$$Address);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6696 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6697 __ andl(Rdst, $mask$$constant);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6698 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6699 ins_pipe(ialu_reg_mem);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6700 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6701
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6702 // Load Integer
a61af66fc99e Initial load
duke
parents:
diff changeset
6703 instruct loadI(eRegI dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6704 match(Set dst (LoadI mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6705
a61af66fc99e Initial load
duke
parents:
diff changeset
6706 ins_cost(125);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6707 format %{ "MOV $dst,$mem\t# int" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6708
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6709 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6710 __ movl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6711 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6712
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6713 ins_pipe(ialu_reg_mem);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6714 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6715
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6716 // Load Integer (32 bit signed) to Byte (8 bit signed)
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6717 instruct loadI2B(eRegI dst, memory mem, immI_24 twentyfour) %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6718 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6719
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6720 ins_cost(125);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6721 format %{ "MOVSX $dst, $mem\t# int -> byte" %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6722 ins_encode %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6723 __ movsbl($dst$$Register, $mem$$Address);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6724 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6725 ins_pipe(ialu_reg_mem);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6726 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6727
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6728 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6729 instruct loadI2UB(eRegI dst, memory mem, immI_255 mask) %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6730 match(Set dst (AndI (LoadI mem) mask));
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6731
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6732 ins_cost(125);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6733 format %{ "MOVZX $dst, $mem\t# int -> ubyte" %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6734 ins_encode %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6735 __ movzbl($dst$$Register, $mem$$Address);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6736 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6737 ins_pipe(ialu_reg_mem);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6738 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6739
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6740 // Load Integer (32 bit signed) to Short (16 bit signed)
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6741 instruct loadI2S(eRegI dst, memory mem, immI_16 sixteen) %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6742 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6743
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6744 ins_cost(125);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6745 format %{ "MOVSX $dst, $mem\t# int -> short" %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6746 ins_encode %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6747 __ movswl($dst$$Register, $mem$$Address);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6748 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6749 ins_pipe(ialu_reg_mem);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6750 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6751
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6752 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6753 instruct loadI2US(eRegI dst, memory mem, immI_65535 mask) %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6754 match(Set dst (AndI (LoadI mem) mask));
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6755
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6756 ins_cost(125);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6757 format %{ "MOVZX $dst, $mem\t# int -> ushort/char" %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6758 ins_encode %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6759 __ movzwl($dst$$Register, $mem$$Address);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6760 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6761 ins_pipe(ialu_reg_mem);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6762 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
6763
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6764 // Load Integer into Long Register
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6765 instruct loadI2L(eRegL dst, memory mem, eFlagsReg cr) %{
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6766 match(Set dst (ConvI2L (LoadI mem)));
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6767 effect(KILL cr);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6768
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6769 ins_cost(375);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6770 format %{ "MOV $dst.lo,$mem\t# int -> long\n\t"
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6771 "MOV $dst.hi,$dst.lo\n\t"
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6772 "SAR $dst.hi,31" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6773
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6774 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6775 __ movl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6776 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6777 __ sarl(HIGH_FROM_LOW($dst$$Register), 31);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6778 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6779
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6780 ins_pipe(ialu_reg_mem);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6781 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6782
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6783 // Load Integer with mask 0xFF into Long Register
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6784 instruct loadI2L_immI_255(eRegL dst, memory mem, immI_255 mask, eFlagsReg cr) %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6785 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6786 effect(KILL cr);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6787
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6788 format %{ "MOVZX8 $dst.lo,$mem\t# int & 0xFF -> long\n\t"
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6789 "XOR $dst.hi,$dst.hi" %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6790 ins_encode %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6791 Register Rdst = $dst$$Register;
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6792 __ movzbl(Rdst, $mem$$Address);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6793 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6794 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6795 ins_pipe(ialu_reg_mem);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6796 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6797
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6798 // Load Integer with mask 0xFFFF into Long Register
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6799 instruct loadI2L_immI_65535(eRegL dst, memory mem, immI_65535 mask, eFlagsReg cr) %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6800 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6801 effect(KILL cr);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6802
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6803 format %{ "MOVZX $dst.lo,$mem\t# int & 0xFFFF -> long\n\t"
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6804 "XOR $dst.hi,$dst.hi" %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6805 ins_encode %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6806 Register Rdst = $dst$$Register;
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6807 __ movzwl(Rdst, $mem$$Address);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6808 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6809 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6810 ins_pipe(ialu_reg_mem);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6811 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6812
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6813 // Load Integer with 32-bit mask into Long Register
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6814 instruct loadI2L_immI(eRegL dst, memory mem, immI mask, eFlagsReg cr) %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6815 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6816 effect(KILL cr);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6817
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6818 format %{ "MOV $dst.lo,$mem\t# int & 32-bit mask -> long\n\t"
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6819 "XOR $dst.hi,$dst.hi\n\t"
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6820 "AND $dst.lo,$mask" %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6821 ins_encode %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6822 Register Rdst = $dst$$Register;
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6823 __ movl(Rdst, $mem$$Address);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6824 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6825 __ andl(Rdst, $mask$$constant);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6826 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6827 ins_pipe(ialu_reg_mem);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6828 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6829
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6830 // Load Unsigned Integer into Long Register
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6831 instruct loadUI2L(eRegL dst, memory mem, eFlagsReg cr) %{
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6832 match(Set dst (LoadUI2L mem));
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
6833 effect(KILL cr);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6834
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6835 ins_cost(250);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6836 format %{ "MOV $dst.lo,$mem\t# uint -> long\n\t"
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6837 "XOR $dst.hi,$dst.hi" %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6838
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6839 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6840 __ movl($dst$$Register, $mem$$Address);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6841 __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6842 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6843
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6844 ins_pipe(ialu_reg_mem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6845 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6846
a61af66fc99e Initial load
duke
parents:
diff changeset
6847 // Load Long. Cannot clobber address while loading, so restrict address
a61af66fc99e Initial load
duke
parents:
diff changeset
6848 // register to ESI
a61af66fc99e Initial load
duke
parents:
diff changeset
6849 instruct loadL(eRegL dst, load_long_memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6850 predicate(!((LoadLNode*)n)->require_atomic_access());
a61af66fc99e Initial load
duke
parents:
diff changeset
6851 match(Set dst (LoadL mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6852
a61af66fc99e Initial load
duke
parents:
diff changeset
6853 ins_cost(250);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6854 format %{ "MOV $dst.lo,$mem\t# long\n\t"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6855 "MOV $dst.hi,$mem+4" %}
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6856
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6857 ins_encode %{
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6858 Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6859 Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6860 __ movl($dst$$Register, Amemlo);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6861 __ movl(HIGH_FROM_LOW($dst$$Register), Amemhi);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6862 %}
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6863
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
6864 ins_pipe(ialu_reg_long_mem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6865 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6866
a61af66fc99e Initial load
duke
parents:
diff changeset
6867 // Volatile Load Long. Must be atomic, so do 64-bit FILD
a61af66fc99e Initial load
duke
parents:
diff changeset
6868 // then store it down to the stack and reload on the int
a61af66fc99e Initial load
duke
parents:
diff changeset
6869 // side.
a61af66fc99e Initial load
duke
parents:
diff changeset
6870 instruct loadL_volatile(stackSlotL dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6871 predicate(UseSSE<=1 && ((LoadLNode*)n)->require_atomic_access());
a61af66fc99e Initial load
duke
parents:
diff changeset
6872 match(Set dst (LoadL mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6873
a61af66fc99e Initial load
duke
parents:
diff changeset
6874 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
6875 format %{ "FILD $mem\t# Atomic volatile long load\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
6876 "FISTp $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6877 ins_encode(enc_loadL_volatile(mem,dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
6878 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
6879 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6880
a61af66fc99e Initial load
duke
parents:
diff changeset
6881 instruct loadLX_volatile(stackSlotL dst, memory mem, regXD tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6882 predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access());
a61af66fc99e Initial load
duke
parents:
diff changeset
6883 match(Set dst (LoadL mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6884 effect(TEMP tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
6885 ins_cost(180);
a61af66fc99e Initial load
duke
parents:
diff changeset
6886 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
6887 "MOVSD $dst,$tmp" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6888 ins_encode(enc_loadLX_volatile(mem, dst, tmp));
a61af66fc99e Initial load
duke
parents:
diff changeset
6889 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
6890 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6891
a61af66fc99e Initial load
duke
parents:
diff changeset
6892 instruct loadLX_reg_volatile(eRegL dst, memory mem, regXD tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6893 predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access());
a61af66fc99e Initial load
duke
parents:
diff changeset
6894 match(Set dst (LoadL mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6895 effect(TEMP tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
6896 ins_cost(160);
a61af66fc99e Initial load
duke
parents:
diff changeset
6897 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
6898 "MOVD $dst.lo,$tmp\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
6899 "PSRLQ $tmp,32\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
6900 "MOVD $dst.hi,$tmp" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6901 ins_encode(enc_loadLX_reg_volatile(mem, dst, tmp));
a61af66fc99e Initial load
duke
parents:
diff changeset
6902 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
6903 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6904
a61af66fc99e Initial load
duke
parents:
diff changeset
6905 // Load Range
a61af66fc99e Initial load
duke
parents:
diff changeset
6906 instruct loadRange(eRegI dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6907 match(Set dst (LoadRange mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6908
a61af66fc99e Initial load
duke
parents:
diff changeset
6909 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
6910 format %{ "MOV $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6911 opcode(0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
6912 ins_encode( OpcP, RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6913 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
6914 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6915
a61af66fc99e Initial load
duke
parents:
diff changeset
6916
a61af66fc99e Initial load
duke
parents:
diff changeset
6917 // Load Pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
6918 instruct loadP(eRegP dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6919 match(Set dst (LoadP mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6920
a61af66fc99e Initial load
duke
parents:
diff changeset
6921 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
6922 format %{ "MOV $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6923 opcode(0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
6924 ins_encode( OpcP, RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6925 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
6926 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6927
a61af66fc99e Initial load
duke
parents:
diff changeset
6928 // Load Klass Pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
6929 instruct loadKlass(eRegP dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6930 match(Set dst (LoadKlass mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6931
a61af66fc99e Initial load
duke
parents:
diff changeset
6932 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
6933 format %{ "MOV $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6934 opcode(0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
6935 ins_encode( OpcP, RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6936 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
6937 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6938
a61af66fc99e Initial load
duke
parents:
diff changeset
6939 // Load Double
a61af66fc99e Initial load
duke
parents:
diff changeset
6940 instruct loadD(regD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6941 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
6942 match(Set dst (LoadD mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6943
a61af66fc99e Initial load
duke
parents:
diff changeset
6944 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
6945 format %{ "FLD_D ST,$mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
6946 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6947 opcode(0xDD); /* DD /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
6948 ins_encode( OpcP, RMopc_Mem(0x00,mem),
a61af66fc99e Initial load
duke
parents:
diff changeset
6949 Pop_Reg_D(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
6950 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
6951 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6952
a61af66fc99e Initial load
duke
parents:
diff changeset
6953 // Load Double to XMM
a61af66fc99e Initial load
duke
parents:
diff changeset
6954 instruct loadXD(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6955 predicate(UseSSE>=2 && UseXmmLoadAndClearUpper);
a61af66fc99e Initial load
duke
parents:
diff changeset
6956 match(Set dst (LoadD mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6957 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
6958 format %{ "MOVSD $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6959 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x10), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6960 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
6961 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6962
a61af66fc99e Initial load
duke
parents:
diff changeset
6963 instruct loadXD_partial(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6964 predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper);
a61af66fc99e Initial load
duke
parents:
diff changeset
6965 match(Set dst (LoadD mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6966 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
6967 format %{ "MOVLPD $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6968 ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x12), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6969 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
6970 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6971
a61af66fc99e Initial load
duke
parents:
diff changeset
6972 // Load to XMM register (single-precision floating point)
a61af66fc99e Initial load
duke
parents:
diff changeset
6973 // MOVSS instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
6974 instruct loadX(regX dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6975 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
6976 match(Set dst (LoadF mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6977 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
6978 format %{ "MOVSS $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6979 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6980 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
6981 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6982
a61af66fc99e Initial load
duke
parents:
diff changeset
6983 // Load Float
a61af66fc99e Initial load
duke
parents:
diff changeset
6984 instruct loadF(regF dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6985 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
6986 match(Set dst (LoadF mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
6987
a61af66fc99e Initial load
duke
parents:
diff changeset
6988 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
6989 format %{ "FLD_S ST,$mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
6990 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6991 opcode(0xD9); /* D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
6992 ins_encode( OpcP, RMopc_Mem(0x00,mem),
a61af66fc99e Initial load
duke
parents:
diff changeset
6993 Pop_Reg_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
6994 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
6995 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
6996
a61af66fc99e Initial load
duke
parents:
diff changeset
6997 // Load Aligned Packed Byte to XMM register
a61af66fc99e Initial load
duke
parents:
diff changeset
6998 instruct loadA8B(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
6999 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7000 match(Set dst (Load8B mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7001 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7002 format %{ "MOVQ $dst,$mem\t! packed8B" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7003 ins_encode( movq_ld(dst, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7004 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7005 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7006
a61af66fc99e Initial load
duke
parents:
diff changeset
7007 // Load Aligned Packed Short to XMM register
a61af66fc99e Initial load
duke
parents:
diff changeset
7008 instruct loadA4S(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7009 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7010 match(Set dst (Load4S mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7011 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7012 format %{ "MOVQ $dst,$mem\t! packed4S" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7013 ins_encode( movq_ld(dst, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7014 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7015 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7016
a61af66fc99e Initial load
duke
parents:
diff changeset
7017 // Load Aligned Packed Char to XMM register
a61af66fc99e Initial load
duke
parents:
diff changeset
7018 instruct loadA4C(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7019 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7020 match(Set dst (Load4C mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7021 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7022 format %{ "MOVQ $dst,$mem\t! packed4C" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7023 ins_encode( movq_ld(dst, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7024 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7025 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7026
a61af66fc99e Initial load
duke
parents:
diff changeset
7027 // Load Aligned Packed Integer to XMM register
a61af66fc99e Initial load
duke
parents:
diff changeset
7028 instruct load2IU(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7029 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7030 match(Set dst (Load2I mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7031 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7032 format %{ "MOVQ $dst,$mem\t! packed2I" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7033 ins_encode( movq_ld(dst, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7034 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7035 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7036
a61af66fc99e Initial load
duke
parents:
diff changeset
7037 // Load Aligned Packed Single to XMM
a61af66fc99e Initial load
duke
parents:
diff changeset
7038 instruct loadA2F(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7039 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7040 match(Set dst (Load2F mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7041 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
7042 format %{ "MOVQ $dst,$mem\t! packed2F" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7043 ins_encode( movq_ld(dst, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7044 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7045 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7046
a61af66fc99e Initial load
duke
parents:
diff changeset
7047 // Load Effective Address
a61af66fc99e Initial load
duke
parents:
diff changeset
7048 instruct leaP8(eRegP dst, indOffset8 mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7049 match(Set dst mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7050
a61af66fc99e Initial load
duke
parents:
diff changeset
7051 ins_cost(110);
a61af66fc99e Initial load
duke
parents:
diff changeset
7052 format %{ "LEA $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7053 opcode(0x8D);
a61af66fc99e Initial load
duke
parents:
diff changeset
7054 ins_encode( OpcP, RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7055 ins_pipe( ialu_reg_reg_fat );
a61af66fc99e Initial load
duke
parents:
diff changeset
7056 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7057
a61af66fc99e Initial load
duke
parents:
diff changeset
7058 instruct leaP32(eRegP dst, indOffset32 mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7059 match(Set dst mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7060
a61af66fc99e Initial load
duke
parents:
diff changeset
7061 ins_cost(110);
a61af66fc99e Initial load
duke
parents:
diff changeset
7062 format %{ "LEA $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7063 opcode(0x8D);
a61af66fc99e Initial load
duke
parents:
diff changeset
7064 ins_encode( OpcP, RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7065 ins_pipe( ialu_reg_reg_fat );
a61af66fc99e Initial load
duke
parents:
diff changeset
7066 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7067
a61af66fc99e Initial load
duke
parents:
diff changeset
7068 instruct leaPIdxOff(eRegP dst, indIndexOffset mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7069 match(Set dst mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7070
a61af66fc99e Initial load
duke
parents:
diff changeset
7071 ins_cost(110);
a61af66fc99e Initial load
duke
parents:
diff changeset
7072 format %{ "LEA $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7073 opcode(0x8D);
a61af66fc99e Initial load
duke
parents:
diff changeset
7074 ins_encode( OpcP, RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7075 ins_pipe( ialu_reg_reg_fat );
a61af66fc99e Initial load
duke
parents:
diff changeset
7076 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7077
a61af66fc99e Initial load
duke
parents:
diff changeset
7078 instruct leaPIdxScale(eRegP dst, indIndexScale mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7079 match(Set dst mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7080
a61af66fc99e Initial load
duke
parents:
diff changeset
7081 ins_cost(110);
a61af66fc99e Initial load
duke
parents:
diff changeset
7082 format %{ "LEA $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7083 opcode(0x8D);
a61af66fc99e Initial load
duke
parents:
diff changeset
7084 ins_encode( OpcP, RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7085 ins_pipe( ialu_reg_reg_fat );
a61af66fc99e Initial load
duke
parents:
diff changeset
7086 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7087
a61af66fc99e Initial load
duke
parents:
diff changeset
7088 instruct leaPIdxScaleOff(eRegP dst, indIndexScaleOffset mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7089 match(Set dst mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7090
a61af66fc99e Initial load
duke
parents:
diff changeset
7091 ins_cost(110);
a61af66fc99e Initial load
duke
parents:
diff changeset
7092 format %{ "LEA $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7093 opcode(0x8D);
a61af66fc99e Initial load
duke
parents:
diff changeset
7094 ins_encode( OpcP, RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7095 ins_pipe( ialu_reg_reg_fat );
a61af66fc99e Initial load
duke
parents:
diff changeset
7096 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7097
a61af66fc99e Initial load
duke
parents:
diff changeset
7098 // Load Constant
a61af66fc99e Initial load
duke
parents:
diff changeset
7099 instruct loadConI(eRegI dst, immI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7100 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7101
a61af66fc99e Initial load
duke
parents:
diff changeset
7102 format %{ "MOV $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7103 ins_encode( LdImmI(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7104 ins_pipe( ialu_reg_fat );
a61af66fc99e Initial load
duke
parents:
diff changeset
7105 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7106
a61af66fc99e Initial load
duke
parents:
diff changeset
7107 // Load Constant zero
a61af66fc99e Initial load
duke
parents:
diff changeset
7108 instruct loadConI0(eRegI dst, immI0 src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7109 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7110 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7111
a61af66fc99e Initial load
duke
parents:
diff changeset
7112 ins_cost(50);
a61af66fc99e Initial load
duke
parents:
diff changeset
7113 format %{ "XOR $dst,$dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7114 opcode(0x33); /* + rd */
a61af66fc99e Initial load
duke
parents:
diff changeset
7115 ins_encode( OpcP, RegReg( dst, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7116 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7117 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7118
a61af66fc99e Initial load
duke
parents:
diff changeset
7119 instruct loadConP(eRegP dst, immP src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7120 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7121
a61af66fc99e Initial load
duke
parents:
diff changeset
7122 format %{ "MOV $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7123 opcode(0xB8); /* + rd */
a61af66fc99e Initial load
duke
parents:
diff changeset
7124 ins_encode( LdImmP(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7125 ins_pipe( ialu_reg_fat );
a61af66fc99e Initial load
duke
parents:
diff changeset
7126 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7127
a61af66fc99e Initial load
duke
parents:
diff changeset
7128 instruct loadConL(eRegL dst, immL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7129 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7130 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7131 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
7132 format %{ "MOV $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7133 "MOV $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7134 opcode(0xB8);
a61af66fc99e Initial load
duke
parents:
diff changeset
7135 ins_encode( LdImmL_Lo(dst, src), LdImmL_Hi(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7136 ins_pipe( ialu_reg_long_fat );
a61af66fc99e Initial load
duke
parents:
diff changeset
7137 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7138
a61af66fc99e Initial load
duke
parents:
diff changeset
7139 instruct loadConL0(eRegL dst, immL0 src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7140 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7141 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7142 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
7143 format %{ "XOR $dst.lo,$dst.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7144 "XOR $dst.hi,$dst.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7145 opcode(0x33,0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
7146 ins_encode( RegReg_Lo(dst,dst), RegReg_Hi(dst, dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7147 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
7148 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7149
a61af66fc99e Initial load
duke
parents:
diff changeset
7150 // The instruction usage is guarded by predicate in operand immF().
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7151 instruct loadConF(regF dst, immF con) %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7152 match(Set dst con);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7153 ins_cost(125);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7154 format %{ "FLD_S ST,[$constantaddress]\t# load from constant table: float=$con\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7155 "FSTP $dst" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7156 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7157 __ fld_s($constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7158 __ fstp_d($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7159 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7160 ins_pipe(fpu_reg_con);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7161 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7162
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7163 // The instruction usage is guarded by predicate in operand immF0().
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7164 instruct loadConF0(regF dst, immF0 con) %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7165 match(Set dst con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7166 ins_cost(125);
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7167 format %{ "FLDZ ST\n\t"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7168 "FSTP $dst" %}
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7169 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7170 __ fldz();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7171 __ fstp_d($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7172 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7173 ins_pipe(fpu_reg_con);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7174 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7175
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7176 // The instruction usage is guarded by predicate in operand immF1().
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7177 instruct loadConF1(regF dst, immF1 con) %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7178 match(Set dst con);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7179 ins_cost(125);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7180 format %{ "FLD1 ST\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7181 "FSTP $dst" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7182 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7183 __ fld1();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7184 __ fstp_d($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7185 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7186 ins_pipe(fpu_reg_con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7187 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7188
a61af66fc99e Initial load
duke
parents:
diff changeset
7189 // The instruction usage is guarded by predicate in operand immXF().
a61af66fc99e Initial load
duke
parents:
diff changeset
7190 instruct loadConX(regX dst, immXF con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7191 match(Set dst con);
a61af66fc99e Initial load
duke
parents:
diff changeset
7192 ins_cost(125);
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7193 format %{ "MOVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7194 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7195 __ movflt($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7196 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7197 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7198 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7199
a61af66fc99e Initial load
duke
parents:
diff changeset
7200 // The instruction usage is guarded by predicate in operand immXF0().
a61af66fc99e Initial load
duke
parents:
diff changeset
7201 instruct loadConX0(regX dst, immXF0 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7202 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7203 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7204 format %{ "XORPS $dst,$dst\t# float 0.0" %}
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7205 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7206 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7207 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7208 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7209 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7210
a61af66fc99e Initial load
duke
parents:
diff changeset
7211 // The instruction usage is guarded by predicate in operand immD().
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7212 instruct loadConD(regD dst, immD con) %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7213 match(Set dst con);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7214 ins_cost(125);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7215
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7216 format %{ "FLD_D ST,[$constantaddress]\t# load from constant table: double=$con\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7217 "FSTP $dst" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7218 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7219 __ fld_d($constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7220 __ fstp_d($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7221 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7222 ins_pipe(fpu_reg_con);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7223 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7224
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7225 // The instruction usage is guarded by predicate in operand immD0().
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7226 instruct loadConD0(regD dst, immD0 con) %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7227 match(Set dst con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7228 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7229
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7230 format %{ "FLDZ ST\n\t"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7231 "FSTP $dst" %}
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7232 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7233 __ fldz();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7234 __ fstp_d($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7235 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7236 ins_pipe(fpu_reg_con);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7237 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7238
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7239 // The instruction usage is guarded by predicate in operand immD1().
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7240 instruct loadConD1(regD dst, immD1 con) %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7241 match(Set dst con);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7242 ins_cost(125);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7243
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7244 format %{ "FLD1 ST\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7245 "FSTP $dst" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7246 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7247 __ fld1();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7248 __ fstp_d($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7249 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7250 ins_pipe(fpu_reg_con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7251 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7252
a61af66fc99e Initial load
duke
parents:
diff changeset
7253 // The instruction usage is guarded by predicate in operand immXD().
a61af66fc99e Initial load
duke
parents:
diff changeset
7254 instruct loadConXD(regXD dst, immXD con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7255 match(Set dst con);
a61af66fc99e Initial load
duke
parents:
diff changeset
7256 ins_cost(125);
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7257 format %{ "MOVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7258 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7259 __ movdbl($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7260 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
7261 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7262 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7263
a61af66fc99e Initial load
duke
parents:
diff changeset
7264 // The instruction usage is guarded by predicate in operand immXD0().
a61af66fc99e Initial load
duke
parents:
diff changeset
7265 instruct loadConXD0(regXD dst, immXD0 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7266 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7267 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7268 format %{ "XORPD $dst,$dst\t# double 0.0" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7269 ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x57), RegReg(dst,dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
7270 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7271 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7272
a61af66fc99e Initial load
duke
parents:
diff changeset
7273 // Load Stack Slot
a61af66fc99e Initial load
duke
parents:
diff changeset
7274 instruct loadSSI(eRegI dst, stackSlotI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7275 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7276 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7277
a61af66fc99e Initial load
duke
parents:
diff changeset
7278 format %{ "MOV $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7279 opcode(0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
7280 ins_encode( OpcP, RegMem(dst,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7281 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
7282 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7283
a61af66fc99e Initial load
duke
parents:
diff changeset
7284 instruct loadSSL(eRegL dst, stackSlotL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7285 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7286
a61af66fc99e Initial load
duke
parents:
diff changeset
7287 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
7288 format %{ "MOV $dst,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7289 "MOV $dst+4,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7290 opcode(0x8B, 0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
7291 ins_encode( OpcP, RegMem( dst, src ), OpcS, RegMem_Hi( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7292 ins_pipe( ialu_mem_long_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7293 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7294
a61af66fc99e Initial load
duke
parents:
diff changeset
7295 // Load Stack Slot
a61af66fc99e Initial load
duke
parents:
diff changeset
7296 instruct loadSSP(eRegP dst, stackSlotP src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7297 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7298 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7299
a61af66fc99e Initial load
duke
parents:
diff changeset
7300 format %{ "MOV $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7301 opcode(0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
7302 ins_encode( OpcP, RegMem(dst,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7303 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
7304 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7305
a61af66fc99e Initial load
duke
parents:
diff changeset
7306 // Load Stack Slot
a61af66fc99e Initial load
duke
parents:
diff changeset
7307 instruct loadSSF(regF dst, stackSlotF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7308 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7309 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7310
a61af66fc99e Initial load
duke
parents:
diff changeset
7311 format %{ "FLD_S $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7312 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7313 opcode(0xD9); /* D9 /0, FLD m32real */
a61af66fc99e Initial load
duke
parents:
diff changeset
7314 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
a61af66fc99e Initial load
duke
parents:
diff changeset
7315 Pop_Reg_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7316 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
7317 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7318
a61af66fc99e Initial load
duke
parents:
diff changeset
7319 // Load Stack Slot
a61af66fc99e Initial load
duke
parents:
diff changeset
7320 instruct loadSSD(regD dst, stackSlotD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7321 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7322 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7323
a61af66fc99e Initial load
duke
parents:
diff changeset
7324 format %{ "FLD_D $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7325 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7326 opcode(0xDD); /* DD /0, FLD m64real */
a61af66fc99e Initial load
duke
parents:
diff changeset
7327 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
a61af66fc99e Initial load
duke
parents:
diff changeset
7328 Pop_Reg_D(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7329 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
7330 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7331
a61af66fc99e Initial load
duke
parents:
diff changeset
7332 // Prefetch instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
7333 // Must be safe to execute with invalid address (cannot fault).
a61af66fc99e Initial load
duke
parents:
diff changeset
7334
a61af66fc99e Initial load
duke
parents:
diff changeset
7335 instruct prefetchr0( memory mem ) %{
2479
15c9a0e16269 7035713: 3DNow Prefetch Instruction Support
kvn
parents: 2401
diff changeset
7336 predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7337 match(PrefetchRead mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7338 ins_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7339 size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7340 format %{ "PREFETCHR (non-SSE is empty encoding)" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7341 ins_encode();
a61af66fc99e Initial load
duke
parents:
diff changeset
7342 ins_pipe(empty);
a61af66fc99e Initial load
duke
parents:
diff changeset
7343 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7344
a61af66fc99e Initial load
duke
parents:
diff changeset
7345 instruct prefetchr( memory mem ) %{
2479
15c9a0e16269 7035713: 3DNow Prefetch Instruction Support
kvn
parents: 2401
diff changeset
7346 predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || ReadPrefetchInstr==3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7347 match(PrefetchRead mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7348 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7349
a61af66fc99e Initial load
duke
parents:
diff changeset
7350 format %{ "PREFETCHR $mem\t! Prefetch into level 1 cache for read" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7351 opcode(0x0F, 0x0d); /* Opcode 0F 0d /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7352 ins_encode(OpcP, OpcS, RMopc_Mem(0x00,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7353 ins_pipe(ialu_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7354 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7355
a61af66fc99e Initial load
duke
parents:
diff changeset
7356 instruct prefetchrNTA( memory mem ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7357 predicate(UseSSE>=1 && ReadPrefetchInstr==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7358 match(PrefetchRead mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7359 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7360
a61af66fc99e Initial load
duke
parents:
diff changeset
7361 format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for read" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7362 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7363 ins_encode(OpcP, OpcS, RMopc_Mem(0x00,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7364 ins_pipe(ialu_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7365 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7366
a61af66fc99e Initial load
duke
parents:
diff changeset
7367 instruct prefetchrT0( memory mem ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7368 predicate(UseSSE>=1 && ReadPrefetchInstr==1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7369 match(PrefetchRead mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7370 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7371
a61af66fc99e Initial load
duke
parents:
diff changeset
7372 format %{ "PREFETCHT0 $mem\t! Prefetch into L1 and L2 caches for read" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7373 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7374 ins_encode(OpcP, OpcS, RMopc_Mem(0x01,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7375 ins_pipe(ialu_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7376 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7377
a61af66fc99e Initial load
duke
parents:
diff changeset
7378 instruct prefetchrT2( memory mem ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7379 predicate(UseSSE>=1 && ReadPrefetchInstr==2);
a61af66fc99e Initial load
duke
parents:
diff changeset
7380 match(PrefetchRead mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7381 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7382
a61af66fc99e Initial load
duke
parents:
diff changeset
7383 format %{ "PREFETCHT2 $mem\t! Prefetch into L2 cache for read" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7384 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7385 ins_encode(OpcP, OpcS, RMopc_Mem(0x03,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7386 ins_pipe(ialu_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7387 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7388
a61af66fc99e Initial load
duke
parents:
diff changeset
7389 instruct prefetchw0( memory mem ) %{
2479
15c9a0e16269 7035713: 3DNow Prefetch Instruction Support
kvn
parents: 2401
diff changeset
7390 predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7391 match(PrefetchWrite mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7392 ins_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7393 size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7394 format %{ "Prefetch (non-SSE is empty encoding)" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7395 ins_encode();
a61af66fc99e Initial load
duke
parents:
diff changeset
7396 ins_pipe(empty);
a61af66fc99e Initial load
duke
parents:
diff changeset
7397 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7398
a61af66fc99e Initial load
duke
parents:
diff changeset
7399 instruct prefetchw( memory mem ) %{
2479
15c9a0e16269 7035713: 3DNow Prefetch Instruction Support
kvn
parents: 2401
diff changeset
7400 predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || AllocatePrefetchInstr==3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7401 match( PrefetchWrite mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
7402 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7403
a61af66fc99e Initial load
duke
parents:
diff changeset
7404 format %{ "PREFETCHW $mem\t! Prefetch into L1 cache and mark modified" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7405 opcode(0x0F, 0x0D); /* Opcode 0F 0D /1 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7406 ins_encode(OpcP, OpcS, RMopc_Mem(0x01,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7407 ins_pipe(ialu_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7408 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7409
a61af66fc99e Initial load
duke
parents:
diff changeset
7410 instruct prefetchwNTA( memory mem ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7411 predicate(UseSSE>=1 && AllocatePrefetchInstr==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7412 match(PrefetchWrite mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7413 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7414
a61af66fc99e Initial load
duke
parents:
diff changeset
7415 format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for write" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7416 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7417 ins_encode(OpcP, OpcS, RMopc_Mem(0x00,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7418 ins_pipe(ialu_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7419 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7420
a61af66fc99e Initial load
duke
parents:
diff changeset
7421 instruct prefetchwT0( memory mem ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7422 predicate(UseSSE>=1 && AllocatePrefetchInstr==1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7423 match(PrefetchWrite mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7424 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7425
a61af66fc99e Initial load
duke
parents:
diff changeset
7426 format %{ "PREFETCHT0 $mem\t! Prefetch into L1 and L2 caches for write" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7427 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7428 ins_encode(OpcP, OpcS, RMopc_Mem(0x01,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7429 ins_pipe(ialu_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7430 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7431
a61af66fc99e Initial load
duke
parents:
diff changeset
7432 instruct prefetchwT2( memory mem ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7433 predicate(UseSSE>=1 && AllocatePrefetchInstr==2);
a61af66fc99e Initial load
duke
parents:
diff changeset
7434 match(PrefetchWrite mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7435 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7436
a61af66fc99e Initial load
duke
parents:
diff changeset
7437 format %{ "PREFETCHT2 $mem\t! Prefetch into L2 cache for write" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7438 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7439 ins_encode(OpcP, OpcS, RMopc_Mem(0x03,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7440 ins_pipe(ialu_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
7441 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7442
a61af66fc99e Initial load
duke
parents:
diff changeset
7443 //----------Store Instructions-------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
7444
a61af66fc99e Initial load
duke
parents:
diff changeset
7445 // Store Byte
a61af66fc99e Initial load
duke
parents:
diff changeset
7446 instruct storeB(memory mem, xRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7447 match(Set mem (StoreB mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7448
a61af66fc99e Initial load
duke
parents:
diff changeset
7449 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7450 format %{ "MOV8 $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7451 opcode(0x88);
a61af66fc99e Initial load
duke
parents:
diff changeset
7452 ins_encode( OpcP, RegMem( src, mem ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7453 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7454 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7455
a61af66fc99e Initial load
duke
parents:
diff changeset
7456 // Store Char/Short
a61af66fc99e Initial load
duke
parents:
diff changeset
7457 instruct storeC(memory mem, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7458 match(Set mem (StoreC mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7459
a61af66fc99e Initial load
duke
parents:
diff changeset
7460 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7461 format %{ "MOV16 $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7462 opcode(0x89, 0x66);
a61af66fc99e Initial load
duke
parents:
diff changeset
7463 ins_encode( OpcS, OpcP, RegMem( src, mem ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7464 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7465 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7466
a61af66fc99e Initial load
duke
parents:
diff changeset
7467 // Store Integer
a61af66fc99e Initial load
duke
parents:
diff changeset
7468 instruct storeI(memory mem, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7469 match(Set mem (StoreI mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7470
a61af66fc99e Initial load
duke
parents:
diff changeset
7471 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7472 format %{ "MOV $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7473 opcode(0x89);
a61af66fc99e Initial load
duke
parents:
diff changeset
7474 ins_encode( OpcP, RegMem( src, mem ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7475 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7476 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7477
a61af66fc99e Initial load
duke
parents:
diff changeset
7478 // Store Long
a61af66fc99e Initial load
duke
parents:
diff changeset
7479 instruct storeL(long_memory mem, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7480 predicate(!((StoreLNode*)n)->require_atomic_access());
a61af66fc99e Initial load
duke
parents:
diff changeset
7481 match(Set mem (StoreL mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7482
a61af66fc99e Initial load
duke
parents:
diff changeset
7483 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
7484 format %{ "MOV $mem,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7485 "MOV $mem+4,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7486 opcode(0x89, 0x89);
a61af66fc99e Initial load
duke
parents:
diff changeset
7487 ins_encode( OpcP, RegMem( src, mem ), OpcS, RegMem_Hi( src, mem ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7488 ins_pipe( ialu_mem_long_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7489 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7490
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7491 // Store Long to Integer
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7492 instruct storeL2I(memory mem, eRegL src) %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7493 match(Set mem (StoreI mem (ConvL2I src)));
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7494
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7495 format %{ "MOV $mem,$src.lo\t# long -> int" %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7496 ins_encode %{
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7497 __ movl($mem$$Address, $src$$Register);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7498 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7499 ins_pipe(ialu_mem_reg);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7500 %}
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 785
diff changeset
7501
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7502 // Volatile Store Long. Must be atomic, so move it into
a61af66fc99e Initial load
duke
parents:
diff changeset
7503 // the FP TOS and then do a 64-bit FIST. Has to probe the
a61af66fc99e Initial load
duke
parents:
diff changeset
7504 // target address before the store (for null-ptr checks)
a61af66fc99e Initial load
duke
parents:
diff changeset
7505 // so the memory operand is used twice in the encoding.
a61af66fc99e Initial load
duke
parents:
diff changeset
7506 instruct storeL_volatile(memory mem, stackSlotL src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7507 predicate(UseSSE<=1 && ((StoreLNode*)n)->require_atomic_access());
a61af66fc99e Initial load
duke
parents:
diff changeset
7508 match(Set mem (StoreL mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7509 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
7510 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
7511 format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7512 "FILD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7513 "FISTp $mem\t # 64-bit atomic volatile long store" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7514 opcode(0x3B);
a61af66fc99e Initial load
duke
parents:
diff changeset
7515 ins_encode( OpcP, RegMem( EAX, mem ), enc_storeL_volatile(mem,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7516 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
7517 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7518
a61af66fc99e Initial load
duke
parents:
diff changeset
7519 instruct storeLX_volatile(memory mem, stackSlotL src, regXD tmp, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7520 predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access());
a61af66fc99e Initial load
duke
parents:
diff changeset
7521 match(Set mem (StoreL mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7522 effect( TEMP tmp, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
7523 ins_cost(380);
a61af66fc99e Initial load
duke
parents:
diff changeset
7524 format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7525 "MOVSD $tmp,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7526 "MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7527 opcode(0x3B);
a61af66fc99e Initial load
duke
parents:
diff changeset
7528 ins_encode( OpcP, RegMem( EAX, mem ), enc_storeLX_volatile(mem, src, tmp));
a61af66fc99e Initial load
duke
parents:
diff changeset
7529 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7530 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7531
a61af66fc99e Initial load
duke
parents:
diff changeset
7532 instruct storeLX_reg_volatile(memory mem, eRegL src, regXD tmp2, regXD tmp, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7533 predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access());
a61af66fc99e Initial load
duke
parents:
diff changeset
7534 match(Set mem (StoreL mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7535 effect( TEMP tmp2 , TEMP tmp, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
7536 ins_cost(360);
a61af66fc99e Initial load
duke
parents:
diff changeset
7537 format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7538 "MOVD $tmp,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7539 "MOVD $tmp2,$src.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7540 "PUNPCKLDQ $tmp,$tmp2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7541 "MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7542 opcode(0x3B);
a61af66fc99e Initial load
duke
parents:
diff changeset
7543 ins_encode( OpcP, RegMem( EAX, mem ), enc_storeLX_reg_volatile(mem, src, tmp, tmp2));
a61af66fc99e Initial load
duke
parents:
diff changeset
7544 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7545 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7546
a61af66fc99e Initial load
duke
parents:
diff changeset
7547 // Store Pointer; for storing unknown oops and raw pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
7548 instruct storeP(memory mem, anyRegP src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7549 match(Set mem (StoreP mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7550
a61af66fc99e Initial load
duke
parents:
diff changeset
7551 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
7552 format %{ "MOV $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7553 opcode(0x89);
a61af66fc99e Initial load
duke
parents:
diff changeset
7554 ins_encode( OpcP, RegMem( src, mem ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7555 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7556 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7557
a61af66fc99e Initial load
duke
parents:
diff changeset
7558 // Store Integer Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
7559 instruct storeImmI(memory mem, immI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7560 match(Set mem (StoreI mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7561
a61af66fc99e Initial load
duke
parents:
diff changeset
7562 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
7563 format %{ "MOV $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7564 opcode(0xC7); /* C7 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7565 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32( src ));
a61af66fc99e Initial load
duke
parents:
diff changeset
7566 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
7567 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7568
a61af66fc99e Initial load
duke
parents:
diff changeset
7569 // Store Short/Char Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
7570 instruct storeImmI16(memory mem, immI16 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7571 predicate(UseStoreImmI16);
a61af66fc99e Initial load
duke
parents:
diff changeset
7572 match(Set mem (StoreC mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7573
a61af66fc99e Initial load
duke
parents:
diff changeset
7574 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
7575 format %{ "MOV16 $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7576 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
a61af66fc99e Initial load
duke
parents:
diff changeset
7577 ins_encode( SizePrefix, OpcP, RMopc_Mem(0x00,mem), Con16( src ));
a61af66fc99e Initial load
duke
parents:
diff changeset
7578 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
7579 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7580
a61af66fc99e Initial load
duke
parents:
diff changeset
7581 // Store Pointer Immediate; null pointers or constant oops that do not
a61af66fc99e Initial load
duke
parents:
diff changeset
7582 // need card-mark barriers.
a61af66fc99e Initial load
duke
parents:
diff changeset
7583 instruct storeImmP(memory mem, immP src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7584 match(Set mem (StoreP mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7585
a61af66fc99e Initial load
duke
parents:
diff changeset
7586 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
7587 format %{ "MOV $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7588 opcode(0xC7); /* C7 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7589 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32( src ));
a61af66fc99e Initial load
duke
parents:
diff changeset
7590 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
7591 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7592
a61af66fc99e Initial load
duke
parents:
diff changeset
7593 // Store Byte Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
7594 instruct storeImmB(memory mem, immI8 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7595 match(Set mem (StoreB mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7596
a61af66fc99e Initial load
duke
parents:
diff changeset
7597 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
7598 format %{ "MOV8 $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7599 opcode(0xC6); /* C6 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7600 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src ));
a61af66fc99e Initial load
duke
parents:
diff changeset
7601 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
7602 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7603
a61af66fc99e Initial load
duke
parents:
diff changeset
7604 // Store Aligned Packed Byte XMM register to memory
a61af66fc99e Initial load
duke
parents:
diff changeset
7605 instruct storeA8B(memory mem, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7606 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7607 match(Set mem (Store8B mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7608 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
7609 format %{ "MOVQ $mem,$src\t! packed8B" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7610 ins_encode( movq_st(mem, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7611 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7612 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7613
a61af66fc99e Initial load
duke
parents:
diff changeset
7614 // Store Aligned Packed Char/Short XMM register to memory
a61af66fc99e Initial load
duke
parents:
diff changeset
7615 instruct storeA4C(memory mem, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7616 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7617 match(Set mem (Store4C mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7618 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
7619 format %{ "MOVQ $mem,$src\t! packed4C" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7620 ins_encode( movq_st(mem, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7621 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7622 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7623
a61af66fc99e Initial load
duke
parents:
diff changeset
7624 // Store Aligned Packed Integer XMM register to memory
a61af66fc99e Initial load
duke
parents:
diff changeset
7625 instruct storeA2I(memory mem, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7626 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7627 match(Set mem (Store2I mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7628 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
7629 format %{ "MOVQ $mem,$src\t! packed2I" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7630 ins_encode( movq_st(mem, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7631 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7632 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7633
a61af66fc99e Initial load
duke
parents:
diff changeset
7634 // Store CMS card-mark Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
7635 instruct storeImmCM(memory mem, immI8 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7636 match(Set mem (StoreCM mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7637
a61af66fc99e Initial load
duke
parents:
diff changeset
7638 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
7639 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7640 opcode(0xC6); /* C6 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7641 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src ));
a61af66fc99e Initial load
duke
parents:
diff changeset
7642 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
7643 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7644
a61af66fc99e Initial load
duke
parents:
diff changeset
7645 // Store Double
a61af66fc99e Initial load
duke
parents:
diff changeset
7646 instruct storeD( memory mem, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7647 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7648 match(Set mem (StoreD mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7649
a61af66fc99e Initial load
duke
parents:
diff changeset
7650 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7651 format %{ "FST_D $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7652 opcode(0xDD); /* DD /2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7653 ins_encode( enc_FP_store(mem,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7654 ins_pipe( fpu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7655 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7656
a61af66fc99e Initial load
duke
parents:
diff changeset
7657 // Store double does rounding on x86
a61af66fc99e Initial load
duke
parents:
diff changeset
7658 instruct storeD_rounded( memory mem, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7659 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7660 match(Set mem (StoreD mem (RoundDouble src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
7661
a61af66fc99e Initial load
duke
parents:
diff changeset
7662 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7663 format %{ "FST_D $mem,$src\t# round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7664 opcode(0xDD); /* DD /2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7665 ins_encode( enc_FP_store(mem,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7666 ins_pipe( fpu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7667 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7668
a61af66fc99e Initial load
duke
parents:
diff changeset
7669 // Store XMM register to memory (double-precision floating points)
a61af66fc99e Initial load
duke
parents:
diff changeset
7670 // MOVSD instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
7671 instruct storeXD(memory mem, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7672 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
7673 match(Set mem (StoreD mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7674 ins_cost(95);
a61af66fc99e Initial load
duke
parents:
diff changeset
7675 format %{ "MOVSD $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7676 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x11), RegMem(src, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7677 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7678 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7679
a61af66fc99e Initial load
duke
parents:
diff changeset
7680 // Store XMM register to memory (single-precision floating point)
a61af66fc99e Initial load
duke
parents:
diff changeset
7681 // MOVSS instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
7682 instruct storeX(memory mem, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7683 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7684 match(Set mem (StoreF mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7685 ins_cost(95);
a61af66fc99e Initial load
duke
parents:
diff changeset
7686 format %{ "MOVSS $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7687 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x11), RegMem(src, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
7688 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7689 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7690
a61af66fc99e Initial load
duke
parents:
diff changeset
7691 // Store Aligned Packed Single Float XMM register to memory
a61af66fc99e Initial load
duke
parents:
diff changeset
7692 instruct storeA2F(memory mem, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7693 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7694 match(Set mem (Store2F mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7695 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
7696 format %{ "MOVQ $mem,$src\t! packed2F" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7697 ins_encode( movq_st(mem, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7698 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
7699 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7700
a61af66fc99e Initial load
duke
parents:
diff changeset
7701 // Store Float
a61af66fc99e Initial load
duke
parents:
diff changeset
7702 instruct storeF( memory mem, regFPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7703 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7704 match(Set mem (StoreF mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7705
a61af66fc99e Initial load
duke
parents:
diff changeset
7706 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7707 format %{ "FST_S $mem,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7708 opcode(0xD9); /* D9 /2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7709 ins_encode( enc_FP_store(mem,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7710 ins_pipe( fpu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7711 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7712
a61af66fc99e Initial load
duke
parents:
diff changeset
7713 // Store Float does rounding on x86
a61af66fc99e Initial load
duke
parents:
diff changeset
7714 instruct storeF_rounded( memory mem, regFPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7715 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7716 match(Set mem (StoreF mem (RoundFloat src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
7717
a61af66fc99e Initial load
duke
parents:
diff changeset
7718 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7719 format %{ "FST_S $mem,$src\t# round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7720 opcode(0xD9); /* D9 /2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7721 ins_encode( enc_FP_store(mem,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7722 ins_pipe( fpu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7723 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7724
a61af66fc99e Initial load
duke
parents:
diff changeset
7725 // Store Float does rounding on x86
a61af66fc99e Initial load
duke
parents:
diff changeset
7726 instruct storeF_Drounded( memory mem, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7727 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
7728 match(Set mem (StoreF mem (ConvD2F src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
7729
a61af66fc99e Initial load
duke
parents:
diff changeset
7730 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7731 format %{ "FST_S $mem,$src\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7732 opcode(0xD9); /* D9 /2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7733 ins_encode( enc_FP_store(mem,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7734 ins_pipe( fpu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7735 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7736
a61af66fc99e Initial load
duke
parents:
diff changeset
7737 // Store immediate Float value (it is faster than store from FPU register)
a61af66fc99e Initial load
duke
parents:
diff changeset
7738 // The instruction usage is guarded by predicate in operand immF().
a61af66fc99e Initial load
duke
parents:
diff changeset
7739 instruct storeF_imm( memory mem, immF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7740 match(Set mem (StoreF mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7741
a61af66fc99e Initial load
duke
parents:
diff changeset
7742 ins_cost(50);
a61af66fc99e Initial load
duke
parents:
diff changeset
7743 format %{ "MOV $mem,$src\t# store float" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7744 opcode(0xC7); /* C7 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7745 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32F_as_bits( src ));
a61af66fc99e Initial load
duke
parents:
diff changeset
7746 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
7747 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7748
a61af66fc99e Initial load
duke
parents:
diff changeset
7749 // Store immediate Float value (it is faster than store from XMM register)
a61af66fc99e Initial load
duke
parents:
diff changeset
7750 // The instruction usage is guarded by predicate in operand immXF().
a61af66fc99e Initial load
duke
parents:
diff changeset
7751 instruct storeX_imm( memory mem, immXF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7752 match(Set mem (StoreF mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7753
a61af66fc99e Initial load
duke
parents:
diff changeset
7754 ins_cost(50);
a61af66fc99e Initial load
duke
parents:
diff changeset
7755 format %{ "MOV $mem,$src\t# store float" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7756 opcode(0xC7); /* C7 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
7757 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32XF_as_bits( src ));
a61af66fc99e Initial load
duke
parents:
diff changeset
7758 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
7759 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7760
a61af66fc99e Initial load
duke
parents:
diff changeset
7761 // Store Integer to stack slot
a61af66fc99e Initial load
duke
parents:
diff changeset
7762 instruct storeSSI(stackSlotI dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7763 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7764
a61af66fc99e Initial load
duke
parents:
diff changeset
7765 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7766 format %{ "MOV $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7767 opcode(0x89);
a61af66fc99e Initial load
duke
parents:
diff changeset
7768 ins_encode( OpcPRegSS( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7769 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7770 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7771
a61af66fc99e Initial load
duke
parents:
diff changeset
7772 // Store Integer to stack slot
a61af66fc99e Initial load
duke
parents:
diff changeset
7773 instruct storeSSP(stackSlotP dst, eRegP src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7774 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7775
a61af66fc99e Initial load
duke
parents:
diff changeset
7776 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
7777 format %{ "MOV $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7778 opcode(0x89);
a61af66fc99e Initial load
duke
parents:
diff changeset
7779 ins_encode( OpcPRegSS( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7780 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7781 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7782
a61af66fc99e Initial load
duke
parents:
diff changeset
7783 // Store Long to stack slot
a61af66fc99e Initial load
duke
parents:
diff changeset
7784 instruct storeSSL(stackSlotL dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7785 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
7786
a61af66fc99e Initial load
duke
parents:
diff changeset
7787 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
7788 format %{ "MOV $dst,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7789 "MOV $dst+4,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7790 opcode(0x89, 0x89);
a61af66fc99e Initial load
duke
parents:
diff changeset
7791 ins_encode( OpcP, RegMem( src, dst ), OpcS, RegMem_Hi( src, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7792 ins_pipe( ialu_mem_long_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7793 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7794
a61af66fc99e Initial load
duke
parents:
diff changeset
7795 //----------MemBar Instructions-----------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
7796 // Memory barrier flavors
a61af66fc99e Initial load
duke
parents:
diff changeset
7797
a61af66fc99e Initial load
duke
parents:
diff changeset
7798 instruct membar_acquire() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7799 match(MemBarAcquire);
a61af66fc99e Initial load
duke
parents:
diff changeset
7800 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
7801
a61af66fc99e Initial load
duke
parents:
diff changeset
7802 size(0);
671
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7803 format %{ "MEMBAR-acquire ! (empty encoding)" %}
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7804 ins_encode();
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7805 ins_pipe(empty);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7806 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7807
a61af66fc99e Initial load
duke
parents:
diff changeset
7808 instruct membar_acquire_lock() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7809 match(MemBarAcquire);
a61af66fc99e Initial load
duke
parents:
diff changeset
7810 predicate(Matcher::prior_fast_lock(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
7811 ins_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7812
a61af66fc99e Initial load
duke
parents:
diff changeset
7813 size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7814 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7815 ins_encode( );
a61af66fc99e Initial load
duke
parents:
diff changeset
7816 ins_pipe(empty);
a61af66fc99e Initial load
duke
parents:
diff changeset
7817 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7818
a61af66fc99e Initial load
duke
parents:
diff changeset
7819 instruct membar_release() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7820 match(MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
7821 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
7822
a61af66fc99e Initial load
duke
parents:
diff changeset
7823 size(0);
671
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7824 format %{ "MEMBAR-release ! (empty encoding)" %}
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7825 ins_encode( );
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7826 ins_pipe(empty);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7827 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7828
a61af66fc99e Initial load
duke
parents:
diff changeset
7829 instruct membar_release_lock() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7830 match(MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
7831 predicate(Matcher::post_fast_unlock(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
7832 ins_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7833
a61af66fc99e Initial load
duke
parents:
diff changeset
7834 size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7835 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7836 ins_encode( );
a61af66fc99e Initial load
duke
parents:
diff changeset
7837 ins_pipe(empty);
a61af66fc99e Initial load
duke
parents:
diff changeset
7838 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7839
671
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7840 instruct membar_volatile(eFlagsReg cr) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7841 match(MemBarVolatile);
671
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7842 effect(KILL cr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7843 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
7844
671
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7845 format %{
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7846 $$template
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7847 if (os::is_MP()) {
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7848 $$emit$$"LOCK ADDL [ESP + #0], 0\t! membar_volatile"
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7849 } else {
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7850 $$emit$$"MEMBAR-volatile ! (empty encoding)"
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7851 }
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7852 %}
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7853 ins_encode %{
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7854 __ membar(Assembler::StoreLoad);
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
7855 %}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7856 ins_pipe(pipe_slow);
a61af66fc99e Initial load
duke
parents:
diff changeset
7857 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7858
a61af66fc99e Initial load
duke
parents:
diff changeset
7859 instruct unnecessary_membar_volatile() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7860 match(MemBarVolatile);
a61af66fc99e Initial load
duke
parents:
diff changeset
7861 predicate(Matcher::post_store_load_barrier(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
7862 ins_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7863
a61af66fc99e Initial load
duke
parents:
diff changeset
7864 size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7865 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7866 ins_encode( );
a61af66fc99e Initial load
duke
parents:
diff changeset
7867 ins_pipe(empty);
a61af66fc99e Initial load
duke
parents:
diff changeset
7868 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7869
a61af66fc99e Initial load
duke
parents:
diff changeset
7870 //----------Move Instructions--------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
7871 instruct castX2P(eAXRegP dst, eAXRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7872 match(Set dst (CastX2P src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7873 format %{ "# X2P $dst, $src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7874 ins_encode( /*empty encoding*/ );
a61af66fc99e Initial load
duke
parents:
diff changeset
7875 ins_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
7876 ins_pipe(empty);
a61af66fc99e Initial load
duke
parents:
diff changeset
7877 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7878
a61af66fc99e Initial load
duke
parents:
diff changeset
7879 instruct castP2X(eRegI dst, eRegP src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7880 match(Set dst (CastP2X src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7881 ins_cost(50);
a61af66fc99e Initial load
duke
parents:
diff changeset
7882 format %{ "MOV $dst, $src\t# CastP2X" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7883 ins_encode( enc_Copy( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7884 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7885 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7886
a61af66fc99e Initial load
duke
parents:
diff changeset
7887 //----------Conditional Move---------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
7888 // Conditional move
a61af66fc99e Initial load
duke
parents:
diff changeset
7889 instruct cmovI_reg(eRegI dst, eRegI src, eFlagsReg cr, cmpOp cop ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7890 predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
7891 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
7892 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
7893 format %{ "CMOV$cop $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7894 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
7895 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7896 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7897 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7898
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7899 instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7900 predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
7901 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
7902 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
7903 format %{ "CMOV$cop $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7904 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
7905 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7906 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7907 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7908
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7909 instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7910 predicate(VM_Version::supports_cmov() );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7911 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7912 ins_cost(200);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7913 expand %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7914 cmovI_regU(cop, cr, dst, src);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7915 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7916 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7917
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7918 // Conditional move
a61af66fc99e Initial load
duke
parents:
diff changeset
7919 instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7920 predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
7921 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
7922 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
7923 format %{ "CMOV$cop $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7924 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
7925 ins_encode( enc_cmov(cop), RegMem( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7926 ins_pipe( pipe_cmov_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
7927 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7928
a61af66fc99e Initial load
duke
parents:
diff changeset
7929 // Conditional move
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7930 instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7931 predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
7932 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
7933 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
7934 format %{ "CMOV$cop $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7935 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
7936 ins_encode( enc_cmov(cop), RegMem( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7937 ins_pipe( pipe_cmov_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
7938 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7939
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7940 instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7941 predicate(VM_Version::supports_cmov() );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7942 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7943 ins_cost(250);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7944 expand %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7945 cmovI_memU(cop, cr, dst, src);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7946 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7947 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7948
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7949 // Conditional move
a61af66fc99e Initial load
duke
parents:
diff changeset
7950 instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7951 predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
7952 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
7953 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
7954 format %{ "CMOV$cop $dst,$src\t# ptr" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7955 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
7956 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7957 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7958 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7959
a61af66fc99e Initial load
duke
parents:
diff changeset
7960 // Conditional move (non-P6 version)
a61af66fc99e Initial load
duke
parents:
diff changeset
7961 // Note: a CMoveP is generated for stubs and native wrappers
a61af66fc99e Initial load
duke
parents:
diff changeset
7962 // regardless of whether we are on a P6, so we
a61af66fc99e Initial load
duke
parents:
diff changeset
7963 // emulate a cmov here
a61af66fc99e Initial load
duke
parents:
diff changeset
7964 instruct cmovP_reg_nonP6(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
7965 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
7966 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
7967 format %{ "Jn$cop skip\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
7968 "MOV $dst,$src\t# pointer\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
7969 "skip:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7970 opcode(0x8b);
a61af66fc99e Initial load
duke
parents:
diff changeset
7971 ins_encode( enc_cmov_branch(cop, 0x2), OpcP, RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
7972 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7973 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7974
a61af66fc99e Initial load
duke
parents:
diff changeset
7975 // Conditional move
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7976 instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7977 predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
7978 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
7979 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
7980 format %{ "CMOV$cop $dst,$src\t# ptr" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7981 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
7982 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
7983 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
7984 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
7985
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7986 instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7987 predicate(VM_Version::supports_cmov() );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7988 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7989 ins_cost(200);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7990 expand %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7991 cmovP_regU(cop, cr, dst, src);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7992 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7993 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
7994
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7995 // DISABLED: Requires the ADLC to emit a bottom_type call that
a61af66fc99e Initial load
duke
parents:
diff changeset
7996 // correctly meets the two pointer arguments; one is an incoming
a61af66fc99e Initial load
duke
parents:
diff changeset
7997 // register but the other is a memory operand. ALSO appears to
a61af66fc99e Initial load
duke
parents:
diff changeset
7998 // be buggy with implicit null checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
7999 //
a61af66fc99e Initial load
duke
parents:
diff changeset
8000 //// Conditional move
a61af66fc99e Initial load
duke
parents:
diff changeset
8001 //instruct cmovP_mem(cmpOp cop, eFlagsReg cr, eRegP dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8002 // predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
8003 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
8004 // ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
8005 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8006 // opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
8007 // ins_encode( enc_cmov(cop), RegMem( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8008 // ins_pipe( pipe_cmov_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
8009 //%}
a61af66fc99e Initial load
duke
parents:
diff changeset
8010 //
a61af66fc99e Initial load
duke
parents:
diff changeset
8011 //// Conditional move
a61af66fc99e Initial load
duke
parents:
diff changeset
8012 //instruct cmovP_memU(cmpOpU cop, eFlagsRegU cr, eRegP dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8013 // predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
8014 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
8015 // ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
8016 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8017 // opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
8018 // ins_encode( enc_cmov(cop), RegMem( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8019 // ins_pipe( pipe_cmov_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
8020 //%}
a61af66fc99e Initial load
duke
parents:
diff changeset
8021
a61af66fc99e Initial load
duke
parents:
diff changeset
8022 // Conditional move
a61af66fc99e Initial load
duke
parents:
diff changeset
8023 instruct fcmovD_regU(cmpOp_fcmov cop, eFlagsRegU cr, regDPR1 dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8024 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
8025 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8026 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8027 format %{ "FCMOV$cop $dst,$src\t# double" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8028 opcode(0xDA);
a61af66fc99e Initial load
duke
parents:
diff changeset
8029 ins_encode( enc_cmov_d(cop,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8030 ins_pipe( pipe_cmovD_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8031 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8032
a61af66fc99e Initial load
duke
parents:
diff changeset
8033 // Conditional move
a61af66fc99e Initial load
duke
parents:
diff changeset
8034 instruct fcmovF_regU(cmpOp_fcmov cop, eFlagsRegU cr, regFPR1 dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8035 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
8036 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8037 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8038 format %{ "FCMOV$cop $dst,$src\t# float" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8039 opcode(0xDA);
a61af66fc99e Initial load
duke
parents:
diff changeset
8040 ins_encode( enc_cmov_d(cop,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8041 ins_pipe( pipe_cmovD_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8042 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8043
a61af66fc99e Initial load
duke
parents:
diff changeset
8044 // Float CMOV on Intel doesn't handle *signed* compares, only unsigned.
a61af66fc99e Initial load
duke
parents:
diff changeset
8045 instruct fcmovD_regS(cmpOp cop, eFlagsReg cr, regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8046 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
8047 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8048 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8049 format %{ "Jn$cop skip\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8050 "MOV $dst,$src\t# double\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8051 "skip:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8052 opcode (0xdd, 0x3); /* DD D8+i or DD /3 */
a61af66fc99e Initial load
duke
parents:
diff changeset
8053 ins_encode( enc_cmov_branch( cop, 0x4 ), Push_Reg_D(src), OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8054 ins_pipe( pipe_cmovD_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8055 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8056
a61af66fc99e Initial load
duke
parents:
diff changeset
8057 // Float CMOV on Intel doesn't handle *signed* compares, only unsigned.
a61af66fc99e Initial load
duke
parents:
diff changeset
8058 instruct fcmovF_regS(cmpOp cop, eFlagsReg cr, regF dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8059 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
8060 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8061 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8062 format %{ "Jn$cop skip\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8063 "MOV $dst,$src\t# float\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8064 "skip:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8065 opcode (0xdd, 0x3); /* DD D8+i or DD /3 */
a61af66fc99e Initial load
duke
parents:
diff changeset
8066 ins_encode( enc_cmov_branch( cop, 0x4 ), Push_Reg_F(src), OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8067 ins_pipe( pipe_cmovD_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8068 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8069
a61af66fc99e Initial load
duke
parents:
diff changeset
8070 // No CMOVE with SSE/SSE2
a61af66fc99e Initial load
duke
parents:
diff changeset
8071 instruct fcmovX_regS(cmpOp cop, eFlagsReg cr, regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8072 predicate (UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
8073 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8074 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8075 format %{ "Jn$cop skip\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8076 "MOVSS $dst,$src\t# float\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8077 "skip:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8078 ins_encode %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8079 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
8080 // Invert sense of branch from sense of CMOV
a61af66fc99e Initial load
duke
parents:
diff changeset
8081 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
8082 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
a61af66fc99e Initial load
duke
parents:
diff changeset
8083 __ bind(skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
8084 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8085 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8086 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8087
a61af66fc99e Initial load
duke
parents:
diff changeset
8088 // No CMOVE with SSE/SSE2
a61af66fc99e Initial load
duke
parents:
diff changeset
8089 instruct fcmovXD_regS(cmpOp cop, eFlagsReg cr, regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8090 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8091 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8092 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8093 format %{ "Jn$cop skip\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8094 "MOVSD $dst,$src\t# float\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8095 "skip:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8096 ins_encode %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8097 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
8098 // Invert sense of branch from sense of CMOV
a61af66fc99e Initial load
duke
parents:
diff changeset
8099 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
8100 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
a61af66fc99e Initial load
duke
parents:
diff changeset
8101 __ bind(skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
8102 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8103 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8104 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8105
a61af66fc99e Initial load
duke
parents:
diff changeset
8106 // unsigned version
a61af66fc99e Initial load
duke
parents:
diff changeset
8107 instruct fcmovX_regU(cmpOpU cop, eFlagsRegU cr, regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8108 predicate (UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
8109 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8110 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8111 format %{ "Jn$cop skip\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8112 "MOVSS $dst,$src\t# float\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8113 "skip:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8114 ins_encode %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8115 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
8116 // Invert sense of branch from sense of CMOV
a61af66fc99e Initial load
duke
parents:
diff changeset
8117 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
8118 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
a61af66fc99e Initial load
duke
parents:
diff changeset
8119 __ bind(skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
8120 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8121 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8122 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8123
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8124 instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8125 predicate (UseSSE>=1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8126 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8127 ins_cost(200);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8128 expand %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8129 fcmovX_regU(cop, cr, dst, src);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8130 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8131 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8132
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8133 // unsigned version
a61af66fc99e Initial load
duke
parents:
diff changeset
8134 instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8135 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8136 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8137 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8138 format %{ "Jn$cop skip\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8139 "MOVSD $dst,$src\t# float\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8140 "skip:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8141 ins_encode %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8142 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
8143 // Invert sense of branch from sense of CMOV
a61af66fc99e Initial load
duke
parents:
diff changeset
8144 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
8145 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
a61af66fc99e Initial load
duke
parents:
diff changeset
8146 __ bind(skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
8147 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8148 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8149 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8150
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8151 instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8152 predicate (UseSSE>=2);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8153 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8154 ins_cost(200);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8155 expand %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8156 fcmovXD_regU(cop, cr, dst, src);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8157 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8158 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8159
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8160 instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8161 predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
8162 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8163 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8164 format %{ "CMOV$cop $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8165 "CMOV$cop $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8166 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
8167 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8168 ins_pipe( pipe_cmov_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
8169 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8170
a61af66fc99e Initial load
duke
parents:
diff changeset
8171 instruct cmovL_regU(cmpOpU cop, eFlagsRegU cr, eRegL dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8172 predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
8173 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8174 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8175 format %{ "CMOV$cop $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8176 "CMOV$cop $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8177 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
8178 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8179 ins_pipe( pipe_cmov_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
8180 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8181
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8182 instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8183 predicate(VM_Version::supports_cmov() );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8184 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8185 ins_cost(200);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8186 expand %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8187 cmovL_regU(cop, cr, dst, src);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8188 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8189 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
8190
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8191 //----------Arithmetic Instructions--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
8192 //----------Addition Instructions----------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
8193 // Integer Addition Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
8194 instruct addI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8195 match(Set dst (AddI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8196 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8197
a61af66fc99e Initial load
duke
parents:
diff changeset
8198 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8199 format %{ "ADD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8200 opcode(0x03);
a61af66fc99e Initial load
duke
parents:
diff changeset
8201 ins_encode( OpcP, RegReg( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8202 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8203 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8204
a61af66fc99e Initial load
duke
parents:
diff changeset
8205 instruct addI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8206 match(Set dst (AddI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8207 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8208
a61af66fc99e Initial load
duke
parents:
diff changeset
8209 format %{ "ADD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8210 opcode(0x81, 0x00); /* /0 id */
a61af66fc99e Initial load
duke
parents:
diff changeset
8211 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8212 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8213 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8214
a61af66fc99e Initial load
duke
parents:
diff changeset
8215 instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8216 predicate(UseIncDec);
a61af66fc99e Initial load
duke
parents:
diff changeset
8217 match(Set dst (AddI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8218 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8219
a61af66fc99e Initial load
duke
parents:
diff changeset
8220 size(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
8221 format %{ "INC $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8222 opcode(0x40); /* */
a61af66fc99e Initial load
duke
parents:
diff changeset
8223 ins_encode( Opc_plus( primary, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8224 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8225 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8226
a61af66fc99e Initial load
duke
parents:
diff changeset
8227 instruct leaI_eReg_immI(eRegI dst, eRegI src0, immI src1) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8228 match(Set dst (AddI src0 src1));
a61af66fc99e Initial load
duke
parents:
diff changeset
8229 ins_cost(110);
a61af66fc99e Initial load
duke
parents:
diff changeset
8230
a61af66fc99e Initial load
duke
parents:
diff changeset
8231 format %{ "LEA $dst,[$src0 + $src1]" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8232 opcode(0x8D); /* 0x8D /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
8233 ins_encode( OpcP, RegLea( dst, src0, src1 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8234 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8235 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8236
a61af66fc99e Initial load
duke
parents:
diff changeset
8237 instruct leaP_eReg_immI(eRegP dst, eRegP src0, immI src1) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8238 match(Set dst (AddP src0 src1));
a61af66fc99e Initial load
duke
parents:
diff changeset
8239 ins_cost(110);
a61af66fc99e Initial load
duke
parents:
diff changeset
8240
a61af66fc99e Initial load
duke
parents:
diff changeset
8241 format %{ "LEA $dst,[$src0 + $src1]\t# ptr" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8242 opcode(0x8D); /* 0x8D /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
8243 ins_encode( OpcP, RegLea( dst, src0, src1 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8244 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8245 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8246
a61af66fc99e Initial load
duke
parents:
diff changeset
8247 instruct decI_eReg(eRegI dst, immI_M1 src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8248 predicate(UseIncDec);
a61af66fc99e Initial load
duke
parents:
diff changeset
8249 match(Set dst (AddI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8250 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8251
a61af66fc99e Initial load
duke
parents:
diff changeset
8252 size(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
8253 format %{ "DEC $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8254 opcode(0x48); /* */
a61af66fc99e Initial load
duke
parents:
diff changeset
8255 ins_encode( Opc_plus( primary, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8256 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8257 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8258
a61af66fc99e Initial load
duke
parents:
diff changeset
8259 instruct addP_eReg(eRegP dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8260 match(Set dst (AddP dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8261 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8262
a61af66fc99e Initial load
duke
parents:
diff changeset
8263 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8264 format %{ "ADD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8265 opcode(0x03);
a61af66fc99e Initial load
duke
parents:
diff changeset
8266 ins_encode( OpcP, RegReg( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8267 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8268 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8269
a61af66fc99e Initial load
duke
parents:
diff changeset
8270 instruct addP_eReg_imm(eRegP dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8271 match(Set dst (AddP dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8272 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8273
a61af66fc99e Initial load
duke
parents:
diff changeset
8274 format %{ "ADD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8275 opcode(0x81,0x00); /* Opcode 81 /0 id */
a61af66fc99e Initial load
duke
parents:
diff changeset
8276 // ins_encode( RegImm( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8277 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8278 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8279 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8280
a61af66fc99e Initial load
duke
parents:
diff changeset
8281 instruct addI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8282 match(Set dst (AddI dst (LoadI src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8283 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8284
a61af66fc99e Initial load
duke
parents:
diff changeset
8285 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
8286 format %{ "ADD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8287 opcode(0x03);
a61af66fc99e Initial load
duke
parents:
diff changeset
8288 ins_encode( OpcP, RegMem( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8289 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
8290 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8291
a61af66fc99e Initial load
duke
parents:
diff changeset
8292 instruct addI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8293 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8294 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8295
a61af66fc99e Initial load
duke
parents:
diff changeset
8296 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
8297 format %{ "ADD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8298 opcode(0x01); /* Opcode 01 /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
8299 ins_encode( OpcP, RegMem( src, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8300 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8301 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8302
a61af66fc99e Initial load
duke
parents:
diff changeset
8303 // Add Memory with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
8304 instruct addI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8305 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8306 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8307
a61af66fc99e Initial load
duke
parents:
diff changeset
8308 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
8309 format %{ "ADD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8310 opcode(0x81); /* Opcode 81 /0 id */
a61af66fc99e Initial load
duke
parents:
diff changeset
8311 ins_encode( OpcSE( src ), RMopc_Mem(0x00,dst), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8312 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
8313 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8314
a61af66fc99e Initial load
duke
parents:
diff changeset
8315 instruct incI_mem(memory dst, immI1 src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8316 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8317 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8318
a61af66fc99e Initial load
duke
parents:
diff changeset
8319 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
8320 format %{ "INC $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8321 opcode(0xFF); /* Opcode FF /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
8322 ins_encode( OpcP, RMopc_Mem(0x00,dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
8323 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
8324 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8325
a61af66fc99e Initial load
duke
parents:
diff changeset
8326 instruct decI_mem(memory dst, immI_M1 src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8327 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8328 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8329
a61af66fc99e Initial load
duke
parents:
diff changeset
8330 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
8331 format %{ "DEC $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8332 opcode(0xFF); /* Opcode FF /1 */
a61af66fc99e Initial load
duke
parents:
diff changeset
8333 ins_encode( OpcP, RMopc_Mem(0x01,dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
8334 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
8335 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8336
a61af66fc99e Initial load
duke
parents:
diff changeset
8337
a61af66fc99e Initial load
duke
parents:
diff changeset
8338 instruct checkCastPP( eRegP dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8339 match(Set dst (CheckCastPP dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
8340
a61af66fc99e Initial load
duke
parents:
diff changeset
8341 size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
8342 format %{ "#checkcastPP of $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8343 ins_encode( /*empty encoding*/ );
a61af66fc99e Initial load
duke
parents:
diff changeset
8344 ins_pipe( empty );
a61af66fc99e Initial load
duke
parents:
diff changeset
8345 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8346
a61af66fc99e Initial load
duke
parents:
diff changeset
8347 instruct castPP( eRegP dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8348 match(Set dst (CastPP dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
8349 format %{ "#castPP of $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8350 ins_encode( /*empty encoding*/ );
a61af66fc99e Initial load
duke
parents:
diff changeset
8351 ins_pipe( empty );
a61af66fc99e Initial load
duke
parents:
diff changeset
8352 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8353
a61af66fc99e Initial load
duke
parents:
diff changeset
8354 instruct castII( eRegI dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8355 match(Set dst (CastII dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
8356 format %{ "#castII of $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8357 ins_encode( /*empty encoding*/ );
a61af66fc99e Initial load
duke
parents:
diff changeset
8358 ins_cost(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
8359 ins_pipe( empty );
a61af66fc99e Initial load
duke
parents:
diff changeset
8360 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8361
a61af66fc99e Initial load
duke
parents:
diff changeset
8362
a61af66fc99e Initial load
duke
parents:
diff changeset
8363 // Load-locked - same as a regular pointer load when used with compare-swap
a61af66fc99e Initial load
duke
parents:
diff changeset
8364 instruct loadPLocked(eRegP dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8365 match(Set dst (LoadPLocked mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
8366
a61af66fc99e Initial load
duke
parents:
diff changeset
8367 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
8368 format %{ "MOV $dst,$mem\t# Load ptr. locked" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8369 opcode(0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
8370 ins_encode( OpcP, RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
8371 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
8372 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8373
a61af66fc99e Initial load
duke
parents:
diff changeset
8374 // LoadLong-locked - same as a volatile long load when used with compare-swap
a61af66fc99e Initial load
duke
parents:
diff changeset
8375 instruct loadLLocked(stackSlotL dst, load_long_memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8376 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
8377 match(Set dst (LoadLLocked mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
8378
a61af66fc99e Initial load
duke
parents:
diff changeset
8379 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
8380 format %{ "FILD $mem\t# Atomic volatile long load\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8381 "FISTp $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8382 ins_encode(enc_loadL_volatile(mem,dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
8383 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
8384 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8385
a61af66fc99e Initial load
duke
parents:
diff changeset
8386 instruct loadLX_Locked(stackSlotL dst, load_long_memory mem, regXD tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8387 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8388 match(Set dst (LoadLLocked mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
8389 effect(TEMP tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
8390 ins_cost(180);
a61af66fc99e Initial load
duke
parents:
diff changeset
8391 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8392 "MOVSD $dst,$tmp" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8393 ins_encode(enc_loadLX_volatile(mem, dst, tmp));
a61af66fc99e Initial load
duke
parents:
diff changeset
8394 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8395 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8396
a61af66fc99e Initial load
duke
parents:
diff changeset
8397 instruct loadLX_reg_Locked(eRegL dst, load_long_memory mem, regXD tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8398 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8399 match(Set dst (LoadLLocked mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
8400 effect(TEMP tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
8401 ins_cost(160);
a61af66fc99e Initial load
duke
parents:
diff changeset
8402 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8403 "MOVD $dst.lo,$tmp\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8404 "PSRLQ $tmp,32\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8405 "MOVD $dst.hi,$tmp" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8406 ins_encode(enc_loadLX_reg_volatile(mem, dst, tmp));
a61af66fc99e Initial load
duke
parents:
diff changeset
8407 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8408 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8409
a61af66fc99e Initial load
duke
parents:
diff changeset
8410 // Conditional-store of the updated heap-top.
a61af66fc99e Initial load
duke
parents:
diff changeset
8411 // Used during allocation of the shared heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
8412 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
a61af66fc99e Initial load
duke
parents:
diff changeset
8413 instruct storePConditional( memory heap_top_ptr, eAXRegP oldval, eRegP newval, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8414 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8415 // EAX is killed if there is contention, but then it's also unused.
a61af66fc99e Initial load
duke
parents:
diff changeset
8416 // In the common case of no contention, EAX holds the new oop address.
a61af66fc99e Initial load
duke
parents:
diff changeset
8417 format %{ "CMPXCHG $heap_top_ptr,$newval\t# If EAX==$heap_top_ptr Then store $newval into $heap_top_ptr" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8418 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval,heap_top_ptr) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8419 ins_pipe( pipe_cmpxchg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8420 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8421
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8422 // Conditional-store of an int value.
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8423 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8424 instruct storeIConditional( memory mem, eAXRegI oldval, eRegI newval, eFlagsReg cr ) %{
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8425 match(Set cr (StoreIConditional mem (Binary oldval newval)));
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8426 effect(KILL oldval);
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8427 format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8428 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8429 ins_pipe( pipe_cmpxchg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8430 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8431
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8432 // Conditional-store of a long value.
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8433 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8434 instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8435 match(Set cr (StoreLConditional mem (Binary oldval newval)));
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8436 effect(KILL oldval);
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8437 format %{ "XCHG EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8438 "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8439 "XCHG EBX,ECX"
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8440 %}
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8441 ins_encode %{
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8442 // Note: we need to swap rbx, and rcx before and after the
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8443 // cmpxchg8 instruction because the instruction uses
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8444 // rcx as the high order word of the new value to store but
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8445 // our register encoding uses rbx.
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8446 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8447 if( os::is_MP() )
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8448 __ lock();
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
8449 __ cmpxchg8($mem$$Address);
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8450 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
8451 %}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8452 ins_pipe( pipe_cmpxchg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8453 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8454
a61af66fc99e Initial load
duke
parents:
diff changeset
8455 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
a61af66fc99e Initial load
duke
parents:
diff changeset
8456
a61af66fc99e Initial load
duke
parents:
diff changeset
8457 instruct compareAndSwapL( eRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8458 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8459 effect(KILL cr, KILL oldval);
a61af66fc99e Initial load
duke
parents:
diff changeset
8460 format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8461 "MOV $res,0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8462 "JNE,s fail\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8463 "MOV $res,1\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8464 "fail:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8465 ins_encode( enc_cmpxchg8(mem_ptr),
a61af66fc99e Initial load
duke
parents:
diff changeset
8466 enc_flags_ne_to_boolean(res) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8467 ins_pipe( pipe_cmpxchg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8468 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8469
a61af66fc99e Initial load
duke
parents:
diff changeset
8470 instruct compareAndSwapP( eRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8471 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8472 effect(KILL cr, KILL oldval);
a61af66fc99e Initial load
duke
parents:
diff changeset
8473 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8474 "MOV $res,0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8475 "JNE,s fail\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8476 "MOV $res,1\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8477 "fail:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8478 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8479 ins_pipe( pipe_cmpxchg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8480 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8481
a61af66fc99e Initial load
duke
parents:
diff changeset
8482 instruct compareAndSwapI( eRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8483 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8484 effect(KILL cr, KILL oldval);
a61af66fc99e Initial load
duke
parents:
diff changeset
8485 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8486 "MOV $res,0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8487 "JNE,s fail\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8488 "MOV $res,1\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8489 "fail:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8490 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8491 ins_pipe( pipe_cmpxchg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8492 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8493
a61af66fc99e Initial load
duke
parents:
diff changeset
8494 //----------Subtraction Instructions-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
8495 // Integer Subtraction Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
8496 instruct subI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8497 match(Set dst (SubI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8498 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8499
a61af66fc99e Initial load
duke
parents:
diff changeset
8500 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8501 format %{ "SUB $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8502 opcode(0x2B);
a61af66fc99e Initial load
duke
parents:
diff changeset
8503 ins_encode( OpcP, RegReg( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8504 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8505 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8506
a61af66fc99e Initial load
duke
parents:
diff changeset
8507 instruct subI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8508 match(Set dst (SubI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8509 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8510
a61af66fc99e Initial load
duke
parents:
diff changeset
8511 format %{ "SUB $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8512 opcode(0x81,0x05); /* Opcode 81 /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
8513 // ins_encode( RegImm( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8514 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8515 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8516 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8517
a61af66fc99e Initial load
duke
parents:
diff changeset
8518 instruct subI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8519 match(Set dst (SubI dst (LoadI src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8520 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8521
a61af66fc99e Initial load
duke
parents:
diff changeset
8522 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
8523 format %{ "SUB $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8524 opcode(0x2B);
a61af66fc99e Initial load
duke
parents:
diff changeset
8525 ins_encode( OpcP, RegMem( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8526 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
8527 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8528
a61af66fc99e Initial load
duke
parents:
diff changeset
8529 instruct subI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8530 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8531 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8532
a61af66fc99e Initial load
duke
parents:
diff changeset
8533 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
8534 format %{ "SUB $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8535 opcode(0x29); /* Opcode 29 /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
8536 ins_encode( OpcP, RegMem( src, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8537 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8538 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8539
a61af66fc99e Initial load
duke
parents:
diff changeset
8540 // Subtract from a pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
8541 instruct subP_eReg(eRegP dst, eRegI src, immI0 zero, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8542 match(Set dst (AddP dst (SubI zero src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8543 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8544
a61af66fc99e Initial load
duke
parents:
diff changeset
8545 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8546 format %{ "SUB $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8547 opcode(0x2B);
a61af66fc99e Initial load
duke
parents:
diff changeset
8548 ins_encode( OpcP, RegReg( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8549 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8550 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8551
a61af66fc99e Initial load
duke
parents:
diff changeset
8552 instruct negI_eReg(eRegI dst, immI0 zero, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8553 match(Set dst (SubI zero dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
8554 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8555
a61af66fc99e Initial load
duke
parents:
diff changeset
8556 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8557 format %{ "NEG $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8558 opcode(0xF7,0x03); // Opcode F7 /3
a61af66fc99e Initial load
duke
parents:
diff changeset
8559 ins_encode( OpcP, RegOpc( dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8560 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
8561 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8562
a61af66fc99e Initial load
duke
parents:
diff changeset
8563
a61af66fc99e Initial load
duke
parents:
diff changeset
8564 //----------Multiplication/Division Instructions-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
8565 // Integer Multiplication Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
8566 // Multiply Register
a61af66fc99e Initial load
duke
parents:
diff changeset
8567 instruct mulI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8568 match(Set dst (MulI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8569 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8570
a61af66fc99e Initial load
duke
parents:
diff changeset
8571 size(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
8572 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
8573 format %{ "IMUL $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8574 opcode(0xAF, 0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
8575 ins_encode( OpcS, OpcP, RegReg( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8576 ins_pipe( ialu_reg_reg_alu0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
8577 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8578
a61af66fc99e Initial load
duke
parents:
diff changeset
8579 // Multiply 32-bit Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
8580 instruct mulI_eReg_imm(eRegI dst, eRegI src, immI imm, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8581 match(Set dst (MulI src imm));
a61af66fc99e Initial load
duke
parents:
diff changeset
8582 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8583
a61af66fc99e Initial load
duke
parents:
diff changeset
8584 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
8585 format %{ "IMUL $dst,$src,$imm" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8586 opcode(0x69); /* 69 /r id */
a61af66fc99e Initial load
duke
parents:
diff changeset
8587 ins_encode( OpcSE(imm), RegReg( dst, src ), Con8or32( imm ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8588 ins_pipe( ialu_reg_reg_alu0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
8589 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8590
a61af66fc99e Initial load
duke
parents:
diff changeset
8591 instruct loadConL_low_only(eADXRegL_low_only dst, immL32 src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8592 match(Set dst src);
a61af66fc99e Initial load
duke
parents:
diff changeset
8593 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8594
a61af66fc99e Initial load
duke
parents:
diff changeset
8595 // Note that this is artificially increased to make it more expensive than loadConL
a61af66fc99e Initial load
duke
parents:
diff changeset
8596 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
8597 format %{ "MOV EAX,$src\t// low word only" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8598 opcode(0xB8);
a61af66fc99e Initial load
duke
parents:
diff changeset
8599 ins_encode( LdImmL_Lo(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8600 ins_pipe( ialu_reg_fat );
a61af66fc99e Initial load
duke
parents:
diff changeset
8601 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8602
a61af66fc99e Initial load
duke
parents:
diff changeset
8603 // Multiply by 32-bit Immediate, taking the shifted high order results
a61af66fc99e Initial load
duke
parents:
diff changeset
8604 // (special case for shift by 32)
a61af66fc99e Initial load
duke
parents:
diff changeset
8605 instruct mulI_imm_high(eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32 cnt, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8606 match(Set dst (ConvL2I (RShiftL (MulL (ConvI2L src1) src2) cnt)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8607 predicate( _kids[0]->_kids[0]->_kids[1]->_leaf->Opcode() == Op_ConL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8608 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() >= min_jint &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8609 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() <= max_jint );
a61af66fc99e Initial load
duke
parents:
diff changeset
8610 effect(USE src1, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8611
a61af66fc99e Initial load
duke
parents:
diff changeset
8612 // Note that this is adjusted by 150 to compensate for the overcosting of loadConL_low_only
a61af66fc99e Initial load
duke
parents:
diff changeset
8613 ins_cost(0*100 + 1*400 - 150);
a61af66fc99e Initial load
duke
parents:
diff changeset
8614 format %{ "IMUL EDX:EAX,$src1" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8615 ins_encode( multiply_con_and_shift_high( dst, src1, src2, cnt, cr ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8616 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8617 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8618
a61af66fc99e Initial load
duke
parents:
diff changeset
8619 // Multiply by 32-bit Immediate, taking the shifted high order results
a61af66fc99e Initial load
duke
parents:
diff changeset
8620 instruct mulI_imm_RShift_high(eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32_63 cnt, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8621 match(Set dst (ConvL2I (RShiftL (MulL (ConvI2L src1) src2) cnt)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8622 predicate( _kids[0]->_kids[0]->_kids[1]->_leaf->Opcode() == Op_ConL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8623 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() >= min_jint &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8624 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() <= max_jint );
a61af66fc99e Initial load
duke
parents:
diff changeset
8625 effect(USE src1, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8626
a61af66fc99e Initial load
duke
parents:
diff changeset
8627 // Note that this is adjusted by 150 to compensate for the overcosting of loadConL_low_only
a61af66fc99e Initial load
duke
parents:
diff changeset
8628 ins_cost(1*100 + 1*400 - 150);
a61af66fc99e Initial load
duke
parents:
diff changeset
8629 format %{ "IMUL EDX:EAX,$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8630 "SAR EDX,$cnt-32" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8631 ins_encode( multiply_con_and_shift_high( dst, src1, src2, cnt, cr ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8632 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8633 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8634
a61af66fc99e Initial load
duke
parents:
diff changeset
8635 // Multiply Memory 32-bit Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
8636 instruct mulI_mem_imm(eRegI dst, memory src, immI imm, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8637 match(Set dst (MulI (LoadI src) imm));
a61af66fc99e Initial load
duke
parents:
diff changeset
8638 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8639
a61af66fc99e Initial load
duke
parents:
diff changeset
8640 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
8641 format %{ "IMUL $dst,$src,$imm" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8642 opcode(0x69); /* 69 /r id */
a61af66fc99e Initial load
duke
parents:
diff changeset
8643 ins_encode( OpcSE(imm), RegMem( dst, src ), Con8or32( imm ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8644 ins_pipe( ialu_reg_mem_alu0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
8645 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8646
a61af66fc99e Initial load
duke
parents:
diff changeset
8647 // Multiply Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
8648 instruct mulI(eRegI dst, memory src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8649 match(Set dst (MulI dst (LoadI src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8650 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8651
a61af66fc99e Initial load
duke
parents:
diff changeset
8652 ins_cost(350);
a61af66fc99e Initial load
duke
parents:
diff changeset
8653 format %{ "IMUL $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8654 opcode(0xAF, 0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
8655 ins_encode( OpcS, OpcP, RegMem( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8656 ins_pipe( ialu_reg_mem_alu0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
8657 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8658
a61af66fc99e Initial load
duke
parents:
diff changeset
8659 // Multiply Register Int to Long
a61af66fc99e Initial load
duke
parents:
diff changeset
8660 instruct mulI2L(eADXRegL dst, eAXRegI src, nadxRegI src1, eFlagsReg flags) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8661 // Basic Idea: long = (long)int * (long)int
a61af66fc99e Initial load
duke
parents:
diff changeset
8662 match(Set dst (MulL (ConvI2L src) (ConvI2L src1)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8663 effect(DEF dst, USE src, USE src1, KILL flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
8664
a61af66fc99e Initial load
duke
parents:
diff changeset
8665 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
8666 format %{ "IMUL $dst,$src1" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8667
a61af66fc99e Initial load
duke
parents:
diff changeset
8668 ins_encode( long_int_multiply( dst, src1 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8669 ins_pipe( ialu_reg_reg_alu0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
8670 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8671
a61af66fc99e Initial load
duke
parents:
diff changeset
8672 instruct mulIS_eReg(eADXRegL dst, immL_32bits mask, eFlagsReg flags, eAXRegI src, nadxRegI src1) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8673 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL)
a61af66fc99e Initial load
duke
parents:
diff changeset
8674 match(Set dst (MulL (AndL (ConvI2L src) mask) (AndL (ConvI2L src1) mask)));
a61af66fc99e Initial load
duke
parents:
diff changeset
8675 effect(KILL flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
8676
a61af66fc99e Initial load
duke
parents:
diff changeset
8677 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
8678 format %{ "MUL $dst,$src1" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8679
a61af66fc99e Initial load
duke
parents:
diff changeset
8680 ins_encode( long_uint_multiply(dst, src1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8681 ins_pipe( ialu_reg_reg_alu0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
8682 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8683
a61af66fc99e Initial load
duke
parents:
diff changeset
8684 // Multiply Register Long
a61af66fc99e Initial load
duke
parents:
diff changeset
8685 instruct mulL_eReg(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8686 match(Set dst (MulL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8687 effect(KILL cr, TEMP tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
8688 ins_cost(4*100+3*400);
a61af66fc99e Initial load
duke
parents:
diff changeset
8689 // Basic idea: lo(result) = lo(x_lo * y_lo)
a61af66fc99e Initial load
duke
parents:
diff changeset
8690 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi)
a61af66fc99e Initial load
duke
parents:
diff changeset
8691 format %{ "MOV $tmp,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8692 "IMUL $tmp,EDX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8693 "MOV EDX,$src.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8694 "IMUL EDX,EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8695 "ADD $tmp,EDX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8696 "MUL EDX:EAX,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8697 "ADD EDX,$tmp" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8698 ins_encode( long_multiply( dst, src, tmp ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8699 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8700 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8701
1209
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8702 // Multiply Register Long where the left operand's high 32 bits are zero
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8703 instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8704 predicate(is_operand_hi32_zero(n->in(1)));
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8705 match(Set dst (MulL dst src));
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8706 effect(KILL cr, TEMP tmp);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8707 ins_cost(2*100+2*400);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8708 // Basic idea: lo(result) = lo(x_lo * y_lo)
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8709 // hi(result) = hi(x_lo * y_lo) + lo(x_lo * y_hi) where lo(x_hi * y_lo) = 0 because x_hi = 0
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8710 format %{ "MOV $tmp,$src.hi\n\t"
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8711 "IMUL $tmp,EAX\n\t"
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8712 "MUL EDX:EAX,$src.lo\n\t"
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8713 "ADD EDX,$tmp" %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8714 ins_encode %{
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8715 __ movl($tmp$$Register, HIGH_FROM_LOW($src$$Register));
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8716 __ imull($tmp$$Register, rax);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8717 __ mull($src$$Register);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8718 __ addl(rdx, $tmp$$Register);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8719 %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8720 ins_pipe( pipe_slow );
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8721 %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8722
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8723 // Multiply Register Long where the right operand's high 32 bits are zero
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8724 instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8725 predicate(is_operand_hi32_zero(n->in(2)));
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8726 match(Set dst (MulL dst src));
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8727 effect(KILL cr, TEMP tmp);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8728 ins_cost(2*100+2*400);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8729 // Basic idea: lo(result) = lo(x_lo * y_lo)
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8730 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) where lo(x_lo * y_hi) = 0 because y_hi = 0
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8731 format %{ "MOV $tmp,$src.lo\n\t"
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8732 "IMUL $tmp,EDX\n\t"
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8733 "MUL EDX:EAX,$src.lo\n\t"
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8734 "ADD EDX,$tmp" %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8735 ins_encode %{
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8736 __ movl($tmp$$Register, $src$$Register);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8737 __ imull($tmp$$Register, rdx);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8738 __ mull($src$$Register);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8739 __ addl(rdx, $tmp$$Register);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8740 %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8741 ins_pipe( pipe_slow );
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8742 %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8743
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8744 // Multiply Register Long where the left and the right operands' high 32 bits are zero
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8745 instruct mulL_eReg_hi0(eADXRegL dst, eRegL src, eFlagsReg cr) %{
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8746 predicate(is_operand_hi32_zero(n->in(1)) && is_operand_hi32_zero(n->in(2)));
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8747 match(Set dst (MulL dst src));
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8748 effect(KILL cr);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8749 ins_cost(1*400);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8750 // Basic idea: lo(result) = lo(x_lo * y_lo)
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8751 // hi(result) = hi(x_lo * y_lo) where lo(x_hi * y_lo) = 0 and lo(x_lo * y_hi) = 0 because x_hi = 0 and y_hi = 0
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8752 format %{ "MUL EDX:EAX,$src.lo\n\t" %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8753 ins_encode %{
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8754 __ mull($src$$Register);
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8755 %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8756 ins_pipe( pipe_slow );
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8757 %}
e8443c7be117 6921969: optimize 64 long multiply for case with high bits zero
never
parents: 1137
diff changeset
8758
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8759 // Multiply Register Long by small constant
a61af66fc99e Initial load
duke
parents:
diff changeset
8760 instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8761 match(Set dst (MulL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
8762 effect(KILL cr, TEMP tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
8763 ins_cost(2*100+2*400);
a61af66fc99e Initial load
duke
parents:
diff changeset
8764 size(12);
a61af66fc99e Initial load
duke
parents:
diff changeset
8765 // Basic idea: lo(result) = lo(src * EAX)
a61af66fc99e Initial load
duke
parents:
diff changeset
8766 // hi(result) = hi(src * EAX) + lo(src * EDX)
a61af66fc99e Initial load
duke
parents:
diff changeset
8767 format %{ "IMUL $tmp,EDX,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8768 "MOV EDX,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8769 "MUL EDX\t# EDX*EAX -> EDX:EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8770 "ADD EDX,$tmp" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8771 ins_encode( long_multiply_con( dst, src, tmp ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8772 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8773 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8774
a61af66fc99e Initial load
duke
parents:
diff changeset
8775 // Integer DIV with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
8776 instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8777 match(Set rax (DivI rax div));
a61af66fc99e Initial load
duke
parents:
diff changeset
8778 effect(KILL rdx, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8779 size(26);
a61af66fc99e Initial load
duke
parents:
diff changeset
8780 ins_cost(30*100+10*100);
a61af66fc99e Initial load
duke
parents:
diff changeset
8781 format %{ "CMP EAX,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8782 "JNE,s normal\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8783 "XOR EDX,EDX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8784 "CMP ECX,-1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8785 "JE,s done\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8786 "normal: CDQ\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8787 "IDIV $div\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8788 "done:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8789 opcode(0xF7, 0x7); /* Opcode F7 /7 */
a61af66fc99e Initial load
duke
parents:
diff changeset
8790 ins_encode( cdq_enc, OpcP, RegOpc(div) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8791 ins_pipe( ialu_reg_reg_alu0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
8792 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8793
a61af66fc99e Initial load
duke
parents:
diff changeset
8794 // Divide Register Long
a61af66fc99e Initial load
duke
parents:
diff changeset
8795 instruct divL_eReg( eADXRegL dst, eRegL src1, eRegL src2, eFlagsReg cr, eCXRegI cx, eBXRegI bx ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8796 match(Set dst (DivL src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
8797 effect( KILL cr, KILL cx, KILL bx );
a61af66fc99e Initial load
duke
parents:
diff changeset
8798 ins_cost(10000);
a61af66fc99e Initial load
duke
parents:
diff changeset
8799 format %{ "PUSH $src1.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8800 "PUSH $src1.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8801 "PUSH $src2.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8802 "PUSH $src2.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8803 "CALL SharedRuntime::ldiv\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8804 "ADD ESP,16" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8805 ins_encode( long_div(src1,src2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8806 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8807 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8808
a61af66fc99e Initial load
duke
parents:
diff changeset
8809 // Integer DIVMOD with Register, both quotient and mod results
a61af66fc99e Initial load
duke
parents:
diff changeset
8810 instruct divModI_eReg_divmod(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8811 match(DivModI rax div);
a61af66fc99e Initial load
duke
parents:
diff changeset
8812 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8813 size(26);
a61af66fc99e Initial load
duke
parents:
diff changeset
8814 ins_cost(30*100+10*100);
a61af66fc99e Initial load
duke
parents:
diff changeset
8815 format %{ "CMP EAX,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8816 "JNE,s normal\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8817 "XOR EDX,EDX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8818 "CMP ECX,-1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8819 "JE,s done\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
8820 "normal: CDQ\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8821 "IDIV $div\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8822 "done:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8823 opcode(0xF7, 0x7); /* Opcode F7 /7 */
a61af66fc99e Initial load
duke
parents:
diff changeset
8824 ins_encode( cdq_enc, OpcP, RegOpc(div) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8825 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8826 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8827
a61af66fc99e Initial load
duke
parents:
diff changeset
8828 // Integer MOD with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
8829 instruct modI_eReg(eDXRegI rdx, eAXRegI rax, eCXRegI div, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8830 match(Set rdx (ModI rax div));
a61af66fc99e Initial load
duke
parents:
diff changeset
8831 effect(KILL rax, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8832
a61af66fc99e Initial load
duke
parents:
diff changeset
8833 size(26);
a61af66fc99e Initial load
duke
parents:
diff changeset
8834 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
8835 format %{ "CDQ\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8836 "IDIV $div" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8837 opcode(0xF7, 0x7); /* Opcode F7 /7 */
a61af66fc99e Initial load
duke
parents:
diff changeset
8838 ins_encode( cdq_enc, OpcP, RegOpc(div) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8839 ins_pipe( ialu_reg_reg_alu0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
8840 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8841
a61af66fc99e Initial load
duke
parents:
diff changeset
8842 // Remainder Register Long
a61af66fc99e Initial load
duke
parents:
diff changeset
8843 instruct modL_eReg( eADXRegL dst, eRegL src1, eRegL src2, eFlagsReg cr, eCXRegI cx, eBXRegI bx ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8844 match(Set dst (ModL src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
8845 effect( KILL cr, KILL cx, KILL bx );
a61af66fc99e Initial load
duke
parents:
diff changeset
8846 ins_cost(10000);
a61af66fc99e Initial load
duke
parents:
diff changeset
8847 format %{ "PUSH $src1.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8848 "PUSH $src1.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8849 "PUSH $src2.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8850 "PUSH $src2.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8851 "CALL SharedRuntime::lrem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
8852 "ADD ESP,16" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8853 ins_encode( long_mod(src1,src2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
8854 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
8855 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
8856
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8857 // Divide Register Long (no special case since divisor != -1)
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8858 instruct divL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8859 match(Set dst (DivL dst imm));
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8860 effect( TEMP tmp, TEMP tmp2, KILL cr );
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8861 ins_cost(1000);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8862 format %{ "MOV $tmp,abs($imm) # ldiv EDX:EAX,$imm\n\t"
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8863 "XOR $tmp2,$tmp2\n\t"
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8864 "CMP $tmp,EDX\n\t"
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8865 "JA,s fast\n\t"
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8866 "MOV $tmp2,EAX\n\t"
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8867 "MOV EAX,EDX\n\t"
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8868 "MOV EDX,0\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8869 "JLE,s pos\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8870 "LNEG EAX : $tmp2\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8871 "DIV $tmp # unsigned division\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8872 "XCHG EAX,$tmp2\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8873 "DIV $tmp\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8874 "LNEG $tmp2 : EAX\n\t"
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8875 "JMP,s done\n"
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8876 "pos:\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8877 "DIV $tmp\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8878 "XCHG EAX,$tmp2\n"
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8879 "fast:\n\t"
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8880 "DIV $tmp\n"
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8881 "done:\n\t"
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8882 "MOV EDX,$tmp2\n\t"
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8883 "NEG EDX:EAX # if $imm < 0" %}
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8884 ins_encode %{
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8885 int con = (int)$imm$$constant;
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8886 assert(con != 0 && con != -1 && con != min_jint, "wrong divisor");
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8887 int pcon = (con > 0) ? con : -con;
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8888 Label Lfast, Lpos, Ldone;
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8889
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8890 __ movl($tmp$$Register, pcon);
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8891 __ xorl($tmp2$$Register,$tmp2$$Register);
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8892 __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register));
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8893 __ jccb(Assembler::above, Lfast); // result fits into 32 bit
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8894
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8895 __ movl($tmp2$$Register, $dst$$Register); // save
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8896 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8897 __ movl(HIGH_FROM_LOW($dst$$Register),0); // preserve flags
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8898 __ jccb(Assembler::lessEqual, Lpos); // result is positive
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8899
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8900 // Negative dividend.
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8901 // convert value to positive to use unsigned division
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8902 __ lneg($dst$$Register, $tmp2$$Register);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8903 __ divl($tmp$$Register);
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8904 __ xchgl($dst$$Register, $tmp2$$Register);
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8905 __ divl($tmp$$Register);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8906 // revert result back to negative
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8907 __ lneg($tmp2$$Register, $dst$$Register);
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8908 __ jmpb(Ldone);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8909
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8910 __ bind(Lpos);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8911 __ divl($tmp$$Register); // Use unsigned division
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8912 __ xchgl($dst$$Register, $tmp2$$Register);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8913 // Fallthrow for final divide, tmp2 has 32 bit hi result
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8914
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8915 __ bind(Lfast);
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8916 // fast path: src is positive
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8917 __ divl($tmp$$Register); // Use unsigned division
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8918
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8919 __ bind(Ldone);
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8920 __ movl(HIGH_FROM_LOW($dst$$Register),$tmp2$$Register);
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8921 if (con < 0) {
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8922 __ lneg(HIGH_FROM_LOW($dst$$Register), $dst$$Register);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8923 }
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8924 %}
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8925 ins_pipe( pipe_slow );
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8926 %}
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8927
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8928 // Remainder Register Long (remainder fit into 32 bits)
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8929 instruct modL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8930 match(Set dst (ModL dst imm));
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8931 effect( TEMP tmp, TEMP tmp2, KILL cr );
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8932 ins_cost(1000);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8933 format %{ "MOV $tmp,abs($imm) # lrem EDX:EAX,$imm\n\t"
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8934 "CMP $tmp,EDX\n\t"
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8935 "JA,s fast\n\t"
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8936 "MOV $tmp2,EAX\n\t"
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8937 "MOV EAX,EDX\n\t"
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8938 "MOV EDX,0\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8939 "JLE,s pos\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8940 "LNEG EAX : $tmp2\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8941 "DIV $tmp # unsigned division\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8942 "MOV EAX,$tmp2\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8943 "DIV $tmp\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8944 "NEG EDX\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8945 "JMP,s done\n"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8946 "pos:\n\t"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8947 "DIV $tmp\n\t"
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8948 "MOV EAX,$tmp2\n"
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8949 "fast:\n\t"
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8950 "DIV $tmp\n"
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8951 "done:\n\t"
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8952 "MOV EAX,EDX\n\t"
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8953 "SAR EDX,31\n\t" %}
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8954 ins_encode %{
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8955 int con = (int)$imm$$constant;
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8956 assert(con != 0 && con != -1 && con != min_jint, "wrong divisor");
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8957 int pcon = (con > 0) ? con : -con;
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8958 Label Lfast, Lpos, Ldone;
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8959
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8960 __ movl($tmp$$Register, pcon);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8961 __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register));
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8962 __ jccb(Assembler::above, Lfast); // src is positive and result fits into 32 bit
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8963
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8964 __ movl($tmp2$$Register, $dst$$Register); // save
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8965 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8966 __ movl(HIGH_FROM_LOW($dst$$Register),0); // preserve flags
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8967 __ jccb(Assembler::lessEqual, Lpos); // result is positive
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8968
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8969 // Negative dividend.
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8970 // convert value to positive to use unsigned division
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8971 __ lneg($dst$$Register, $tmp2$$Register);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8972 __ divl($tmp$$Register);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8973 __ movl($dst$$Register, $tmp2$$Register);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8974 __ divl($tmp$$Register);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8975 // revert remainder back to negative
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8976 __ negl(HIGH_FROM_LOW($dst$$Register));
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8977 __ jmpb(Ldone);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8978
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8979 __ bind(Lpos);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8980 __ divl($tmp$$Register);
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8981 __ movl($dst$$Register, $tmp2$$Register);
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8982
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8983 __ bind(Lfast);
1920
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8984 // fast path: src is positive
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8985 __ divl($tmp$$Register);
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8986
2fe998383789 6997311: SIGFPE in new long division asm code
kvn
parents: 1914
diff changeset
8987 __ bind(Ldone);
1914
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8988 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8989 __ sarl(HIGH_FROM_LOW($dst$$Register), 31); // result sign
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8990
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8991 %}
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8992 ins_pipe( pipe_slow );
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8993 %}
ae065c367d93 6987135: Performance regression on Intel platform with 32-bits edition between 6u13 and 6u14.
kvn
parents: 1748
diff changeset
8994
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8995 // Integer Shift Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
8996 // Shift Left by one
a61af66fc99e Initial load
duke
parents:
diff changeset
8997 instruct shlI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
8998 match(Set dst (LShiftI dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
8999 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9000
a61af66fc99e Initial load
duke
parents:
diff changeset
9001 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
9002 format %{ "SHL $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9003 opcode(0xD1, 0x4); /* D1 /4 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9004 ins_encode( OpcP, RegOpc( dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9005 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9006 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9007
a61af66fc99e Initial load
duke
parents:
diff changeset
9008 // Shift Left by 8-bit immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9009 instruct salI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9010 match(Set dst (LShiftI dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9011 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9012
a61af66fc99e Initial load
duke
parents:
diff changeset
9013 size(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
9014 format %{ "SHL $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9015 opcode(0xC1, 0x4); /* C1 /4 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9016 ins_encode( RegOpcImm( dst, shift) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9017 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9018 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9019
a61af66fc99e Initial load
duke
parents:
diff changeset
9020 // Shift Left by variable
a61af66fc99e Initial load
duke
parents:
diff changeset
9021 instruct salI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9022 match(Set dst (LShiftI dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9023 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9024
a61af66fc99e Initial load
duke
parents:
diff changeset
9025 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
9026 format %{ "SHL $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9027 opcode(0xD3, 0x4); /* D3 /4 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9028 ins_encode( OpcP, RegOpc( dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9029 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9030 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9031
a61af66fc99e Initial load
duke
parents:
diff changeset
9032 // Arithmetic shift right by one
a61af66fc99e Initial load
duke
parents:
diff changeset
9033 instruct sarI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9034 match(Set dst (RShiftI dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9035 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9036
a61af66fc99e Initial load
duke
parents:
diff changeset
9037 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
9038 format %{ "SAR $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9039 opcode(0xD1, 0x7); /* D1 /7 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9040 ins_encode( OpcP, RegOpc( dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9041 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9042 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9043
a61af66fc99e Initial load
duke
parents:
diff changeset
9044 // Arithmetic shift right by one
a61af66fc99e Initial load
duke
parents:
diff changeset
9045 instruct sarI_mem_1(memory dst, immI1 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9046 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9047 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9048 format %{ "SAR $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9049 opcode(0xD1, 0x7); /* D1 /7 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9050 ins_encode( OpcP, RMopc_Mem(secondary,dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9051 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
9052 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9053
a61af66fc99e Initial load
duke
parents:
diff changeset
9054 // Arithmetic Shift Right by 8-bit immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9055 instruct sarI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9056 match(Set dst (RShiftI dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9057 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9058
a61af66fc99e Initial load
duke
parents:
diff changeset
9059 size(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
9060 format %{ "SAR $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9061 opcode(0xC1, 0x7); /* C1 /7 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9062 ins_encode( RegOpcImm( dst, shift ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9063 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
9064 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9065
a61af66fc99e Initial load
duke
parents:
diff changeset
9066 // Arithmetic Shift Right by 8-bit immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9067 instruct sarI_mem_imm(memory dst, immI8 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9068 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9069 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9070
a61af66fc99e Initial load
duke
parents:
diff changeset
9071 format %{ "SAR $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9072 opcode(0xC1, 0x7); /* C1 /7 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9073 ins_encode( OpcP, RMopc_Mem(secondary, dst ), Con8or32( shift ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9074 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
9075 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9076
a61af66fc99e Initial load
duke
parents:
diff changeset
9077 // Arithmetic Shift Right by variable
a61af66fc99e Initial load
duke
parents:
diff changeset
9078 instruct sarI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9079 match(Set dst (RShiftI dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9080 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9081
a61af66fc99e Initial load
duke
parents:
diff changeset
9082 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
9083 format %{ "SAR $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9084 opcode(0xD3, 0x7); /* D3 /7 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9085 ins_encode( OpcP, RegOpc( dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9086 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9087 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9088
a61af66fc99e Initial load
duke
parents:
diff changeset
9089 // Logical shift right by one
a61af66fc99e Initial load
duke
parents:
diff changeset
9090 instruct shrI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9091 match(Set dst (URShiftI dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9092 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9093
a61af66fc99e Initial load
duke
parents:
diff changeset
9094 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
9095 format %{ "SHR $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9096 opcode(0xD1, 0x5); /* D1 /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9097 ins_encode( OpcP, RegOpc( dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9098 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9099 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9100
a61af66fc99e Initial load
duke
parents:
diff changeset
9101 // Logical Shift Right by 8-bit immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9102 instruct shrI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9103 match(Set dst (URShiftI dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9104 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9105
a61af66fc99e Initial load
duke
parents:
diff changeset
9106 size(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
9107 format %{ "SHR $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9108 opcode(0xC1, 0x5); /* C1 /5 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9109 ins_encode( RegOpcImm( dst, shift) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9110 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9111 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9112
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9113
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9114 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
a61af66fc99e Initial load
duke
parents:
diff changeset
9115 // This idiom is used by the compiler for the i2b bytecode.
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9116 instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9117 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
a61af66fc99e Initial load
duke
parents:
diff changeset
9118
a61af66fc99e Initial load
duke
parents:
diff changeset
9119 size(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
9120 format %{ "MOVSX $dst,$src :8" %}
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9121 ins_encode %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9122 __ movsbl($dst$$Register, $src$$Register);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9123 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9124 ins_pipe(ialu_reg_reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9125 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9126
a61af66fc99e Initial load
duke
parents:
diff changeset
9127 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
a61af66fc99e Initial load
duke
parents:
diff changeset
9128 // This idiom is used by the compiler the i2s bytecode.
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9129 instruct i2s(eRegI dst, xRegI src, immI_16 sixteen) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9130 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
a61af66fc99e Initial load
duke
parents:
diff changeset
9131
a61af66fc99e Initial load
duke
parents:
diff changeset
9132 size(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
9133 format %{ "MOVSX $dst,$src :16" %}
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9134 ins_encode %{
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9135 __ movswl($dst$$Register, $src$$Register);
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9136 %}
2056494941db 6814842: Load shortening optimizations
twisti
parents: 775
diff changeset
9137 ins_pipe(ialu_reg_reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9138 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9139
a61af66fc99e Initial load
duke
parents:
diff changeset
9140
a61af66fc99e Initial load
duke
parents:
diff changeset
9141 // Logical Shift Right by variable
a61af66fc99e Initial load
duke
parents:
diff changeset
9142 instruct shrI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9143 match(Set dst (URShiftI dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9144 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9145
a61af66fc99e Initial load
duke
parents:
diff changeset
9146 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
9147 format %{ "SHR $dst,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9148 opcode(0xD3, 0x5); /* D3 /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9149 ins_encode( OpcP, RegOpc( dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9150 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9151 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9152
a61af66fc99e Initial load
duke
parents:
diff changeset
9153
a61af66fc99e Initial load
duke
parents:
diff changeset
9154 //----------Logical Instructions-----------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
9155 //----------Integer Logical Instructions---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
9156 // And Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
9157 // And Register with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9158 instruct andI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9159 match(Set dst (AndI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9160 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9161
a61af66fc99e Initial load
duke
parents:
diff changeset
9162 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
9163 format %{ "AND $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9164 opcode(0x23);
a61af66fc99e Initial load
duke
parents:
diff changeset
9165 ins_encode( OpcP, RegReg( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9166 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9167 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9168
a61af66fc99e Initial load
duke
parents:
diff changeset
9169 // And Register with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9170 instruct andI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9171 match(Set dst (AndI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9172 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9173
a61af66fc99e Initial load
duke
parents:
diff changeset
9174 format %{ "AND $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9175 opcode(0x81,0x04); /* Opcode 81 /4 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9176 // ins_encode( RegImm( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9177 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9178 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9179 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9180
a61af66fc99e Initial load
duke
parents:
diff changeset
9181 // And Register with Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
9182 instruct andI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9183 match(Set dst (AndI dst (LoadI src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9184 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9185
a61af66fc99e Initial load
duke
parents:
diff changeset
9186 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9187 format %{ "AND $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9188 opcode(0x23);
a61af66fc99e Initial load
duke
parents:
diff changeset
9189 ins_encode( OpcP, RegMem( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9190 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
9191 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9192
a61af66fc99e Initial load
duke
parents:
diff changeset
9193 // And Memory with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9194 instruct andI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9195 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9196 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9197
a61af66fc99e Initial load
duke
parents:
diff changeset
9198 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
9199 format %{ "AND $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9200 opcode(0x21); /* Opcode 21 /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
9201 ins_encode( OpcP, RegMem( src, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9202 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9203 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9204
a61af66fc99e Initial load
duke
parents:
diff changeset
9205 // And Memory with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9206 instruct andI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9207 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9208 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9209
a61af66fc99e Initial load
duke
parents:
diff changeset
9210 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9211 format %{ "AND $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9212 opcode(0x81, 0x4); /* Opcode 81 /4 id */
a61af66fc99e Initial load
duke
parents:
diff changeset
9213 // ins_encode( MemImm( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9214 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9215 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
9216 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9217
a61af66fc99e Initial load
duke
parents:
diff changeset
9218 // Or Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
9219 // Or Register with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9220 instruct orI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9221 match(Set dst (OrI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9222 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9223
a61af66fc99e Initial load
duke
parents:
diff changeset
9224 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
9225 format %{ "OR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9226 opcode(0x0B);
a61af66fc99e Initial load
duke
parents:
diff changeset
9227 ins_encode( OpcP, RegReg( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9228 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9229 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9230
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9231 instruct orI_eReg_castP2X(eRegI dst, eRegP src, eFlagsReg cr) %{
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9232 match(Set dst (OrI dst (CastP2X src)));
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9233 effect(KILL cr);
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9234
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9235 size(2);
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9236 format %{ "OR $dst,$src" %}
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9237 opcode(0x0B);
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9238 ins_encode( OpcP, RegReg( dst, src) );
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9239 ins_pipe( ialu_reg_reg );
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9240 %}
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9241
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 415
diff changeset
9242
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9243 // Or Register with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9244 instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9245 match(Set dst (OrI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9246 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9247
a61af66fc99e Initial load
duke
parents:
diff changeset
9248 format %{ "OR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9249 opcode(0x81,0x01); /* Opcode 81 /1 id */
a61af66fc99e Initial load
duke
parents:
diff changeset
9250 // ins_encode( RegImm( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9251 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9252 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9253 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9254
a61af66fc99e Initial load
duke
parents:
diff changeset
9255 // Or Register with Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
9256 instruct orI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9257 match(Set dst (OrI dst (LoadI src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9258 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9259
a61af66fc99e Initial load
duke
parents:
diff changeset
9260 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9261 format %{ "OR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9262 opcode(0x0B);
a61af66fc99e Initial load
duke
parents:
diff changeset
9263 ins_encode( OpcP, RegMem( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9264 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
9265 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9266
a61af66fc99e Initial load
duke
parents:
diff changeset
9267 // Or Memory with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9268 instruct orI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9269 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9270 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9271
a61af66fc99e Initial load
duke
parents:
diff changeset
9272 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
9273 format %{ "OR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9274 opcode(0x09); /* Opcode 09 /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
9275 ins_encode( OpcP, RegMem( src, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9276 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9277 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9278
a61af66fc99e Initial load
duke
parents:
diff changeset
9279 // Or Memory with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9280 instruct orI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9281 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9282 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9283
a61af66fc99e Initial load
duke
parents:
diff changeset
9284 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9285 format %{ "OR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9286 opcode(0x81,0x1); /* Opcode 81 /1 id */
a61af66fc99e Initial load
duke
parents:
diff changeset
9287 // ins_encode( MemImm( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9288 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9289 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
9290 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9291
a61af66fc99e Initial load
duke
parents:
diff changeset
9292 // ROL/ROR
a61af66fc99e Initial load
duke
parents:
diff changeset
9293 // ROL expand
a61af66fc99e Initial load
duke
parents:
diff changeset
9294 instruct rolI_eReg_imm1(eRegI dst, immI1 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9295 effect(USE_DEF dst, USE shift, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9296
a61af66fc99e Initial load
duke
parents:
diff changeset
9297 format %{ "ROL $dst, $shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9298 opcode(0xD1, 0x0); /* Opcode D1 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9299 ins_encode( OpcP, RegOpc( dst ));
a61af66fc99e Initial load
duke
parents:
diff changeset
9300 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9301 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9302
a61af66fc99e Initial load
duke
parents:
diff changeset
9303 instruct rolI_eReg_imm8(eRegI dst, immI8 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9304 effect(USE_DEF dst, USE shift, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9305
a61af66fc99e Initial load
duke
parents:
diff changeset
9306 format %{ "ROL $dst, $shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9307 opcode(0xC1, 0x0); /*Opcode /C1 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9308 ins_encode( RegOpcImm(dst, shift) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9309 ins_pipe(ialu_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
9310 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9311
a61af66fc99e Initial load
duke
parents:
diff changeset
9312 instruct rolI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9313 effect(USE_DEF dst, USE shift, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9314
a61af66fc99e Initial load
duke
parents:
diff changeset
9315 format %{ "ROL $dst, $shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9316 opcode(0xD3, 0x0); /* Opcode D3 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9317 ins_encode(OpcP, RegOpc(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
9318 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9319 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9320 // end of ROL expand
a61af66fc99e Initial load
duke
parents:
diff changeset
9321
a61af66fc99e Initial load
duke
parents:
diff changeset
9322 // ROL 32bit by one once
a61af66fc99e Initial load
duke
parents:
diff changeset
9323 instruct rolI_eReg_i1(eRegI dst, immI1 lshift, immI_M1 rshift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9324 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9325
a61af66fc99e Initial load
duke
parents:
diff changeset
9326 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9327 rolI_eReg_imm1(dst, lshift, cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9328 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9329 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9330
a61af66fc99e Initial load
duke
parents:
diff changeset
9331 // ROL 32bit var by imm8 once
a61af66fc99e Initial load
duke
parents:
diff changeset
9332 instruct rolI_eReg_i8(eRegI dst, immI8 lshift, immI8 rshift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9333 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
a61af66fc99e Initial load
duke
parents:
diff changeset
9334 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9335
a61af66fc99e Initial load
duke
parents:
diff changeset
9336 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9337 rolI_eReg_imm8(dst, lshift, cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9338 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9339 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9340
a61af66fc99e Initial load
duke
parents:
diff changeset
9341 // ROL 32bit var by var once
a61af66fc99e Initial load
duke
parents:
diff changeset
9342 instruct rolI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9343 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
a61af66fc99e Initial load
duke
parents:
diff changeset
9344
a61af66fc99e Initial load
duke
parents:
diff changeset
9345 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9346 rolI_eReg_CL(dst, shift, cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9347 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9348 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9349
a61af66fc99e Initial load
duke
parents:
diff changeset
9350 // ROL 32bit var by var once
a61af66fc99e Initial load
duke
parents:
diff changeset
9351 instruct rolI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9352 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
a61af66fc99e Initial load
duke
parents:
diff changeset
9353
a61af66fc99e Initial load
duke
parents:
diff changeset
9354 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9355 rolI_eReg_CL(dst, shift, cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9356 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9357 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9358
a61af66fc99e Initial load
duke
parents:
diff changeset
9359 // ROR expand
a61af66fc99e Initial load
duke
parents:
diff changeset
9360 instruct rorI_eReg_imm1(eRegI dst, immI1 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9361 effect(USE_DEF dst, USE shift, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9362
a61af66fc99e Initial load
duke
parents:
diff changeset
9363 format %{ "ROR $dst, $shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9364 opcode(0xD1,0x1); /* Opcode D1 /1 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9365 ins_encode( OpcP, RegOpc( dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9366 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9367 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9368
a61af66fc99e Initial load
duke
parents:
diff changeset
9369 instruct rorI_eReg_imm8(eRegI dst, immI8 shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9370 effect (USE_DEF dst, USE shift, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9371
a61af66fc99e Initial load
duke
parents:
diff changeset
9372 format %{ "ROR $dst, $shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9373 opcode(0xC1, 0x1); /* Opcode /C1 /1 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9374 ins_encode( RegOpcImm(dst, shift) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9375 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9376 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9377
a61af66fc99e Initial load
duke
parents:
diff changeset
9378 instruct rorI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr)%{
a61af66fc99e Initial load
duke
parents:
diff changeset
9379 effect(USE_DEF dst, USE shift, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9380
a61af66fc99e Initial load
duke
parents:
diff changeset
9381 format %{ "ROR $dst, $shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9382 opcode(0xD3, 0x1); /* Opcode D3 /1 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9383 ins_encode(OpcP, RegOpc(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
9384 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9385 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9386 // end of ROR expand
a61af66fc99e Initial load
duke
parents:
diff changeset
9387
a61af66fc99e Initial load
duke
parents:
diff changeset
9388 // ROR right once
a61af66fc99e Initial load
duke
parents:
diff changeset
9389 instruct rorI_eReg_i1(eRegI dst, immI1 rshift, immI_M1 lshift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9390 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9391
a61af66fc99e Initial load
duke
parents:
diff changeset
9392 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9393 rorI_eReg_imm1(dst, rshift, cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9394 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9395 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9396
a61af66fc99e Initial load
duke
parents:
diff changeset
9397 // ROR 32bit by immI8 once
a61af66fc99e Initial load
duke
parents:
diff changeset
9398 instruct rorI_eReg_i8(eRegI dst, immI8 rshift, immI8 lshift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9399 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
a61af66fc99e Initial load
duke
parents:
diff changeset
9400 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9401
a61af66fc99e Initial load
duke
parents:
diff changeset
9402 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9403 rorI_eReg_imm8(dst, rshift, cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9404 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9405 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9406
a61af66fc99e Initial load
duke
parents:
diff changeset
9407 // ROR 32bit var by var once
a61af66fc99e Initial load
duke
parents:
diff changeset
9408 instruct rorI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9409 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
a61af66fc99e Initial load
duke
parents:
diff changeset
9410
a61af66fc99e Initial load
duke
parents:
diff changeset
9411 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9412 rorI_eReg_CL(dst, shift, cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9413 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9414 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9415
a61af66fc99e Initial load
duke
parents:
diff changeset
9416 // ROR 32bit var by var once
a61af66fc99e Initial load
duke
parents:
diff changeset
9417 instruct rorI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9418 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
a61af66fc99e Initial load
duke
parents:
diff changeset
9419
a61af66fc99e Initial load
duke
parents:
diff changeset
9420 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9421 rorI_eReg_CL(dst, shift, cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9422 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9423 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9424
a61af66fc99e Initial load
duke
parents:
diff changeset
9425 // Xor Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
9426 // Xor Register with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9427 instruct xorI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9428 match(Set dst (XorI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9429 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9430
a61af66fc99e Initial load
duke
parents:
diff changeset
9431 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
9432 format %{ "XOR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9433 opcode(0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
9434 ins_encode( OpcP, RegReg( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9435 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9436 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9437
403
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9438 // Xor Register with Immediate -1
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9439 instruct xorI_eReg_im1(eRegI dst, immI_M1 imm) %{
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9440 match(Set dst (XorI dst imm));
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9441
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9442 size(2);
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9443 format %{ "NOT $dst" %}
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9444 ins_encode %{
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9445 __ notl($dst$$Register);
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9446 %}
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9447 ins_pipe( ialu_reg );
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9448 %}
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9449
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9450 // Xor Register with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9451 instruct xorI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9452 match(Set dst (XorI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9453 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9454
a61af66fc99e Initial load
duke
parents:
diff changeset
9455 format %{ "XOR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9456 opcode(0x81,0x06); /* Opcode 81 /6 id */
a61af66fc99e Initial load
duke
parents:
diff changeset
9457 // ins_encode( RegImm( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9458 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9459 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9460 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9461
a61af66fc99e Initial load
duke
parents:
diff changeset
9462 // Xor Register with Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
9463 instruct xorI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9464 match(Set dst (XorI dst (LoadI src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9465 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9466
a61af66fc99e Initial load
duke
parents:
diff changeset
9467 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9468 format %{ "XOR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9469 opcode(0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
9470 ins_encode( OpcP, RegMem(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9471 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
9472 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9473
a61af66fc99e Initial load
duke
parents:
diff changeset
9474 // Xor Memory with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9475 instruct xorI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9476 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9477 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9478
a61af66fc99e Initial load
duke
parents:
diff changeset
9479 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
9480 format %{ "XOR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9481 opcode(0x31); /* Opcode 31 /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
9482 ins_encode( OpcP, RegMem( src, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9483 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9484 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9485
a61af66fc99e Initial load
duke
parents:
diff changeset
9486 // Xor Memory with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9487 instruct xorI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9488 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9489 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9490
a61af66fc99e Initial load
duke
parents:
diff changeset
9491 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9492 format %{ "XOR $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9493 opcode(0x81,0x6); /* Opcode 81 /6 id */
a61af66fc99e Initial load
duke
parents:
diff changeset
9494 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9495 ins_pipe( ialu_mem_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
9496 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9497
a61af66fc99e Initial load
duke
parents:
diff changeset
9498 //----------Convert Int to Boolean---------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
9499
a61af66fc99e Initial load
duke
parents:
diff changeset
9500 instruct movI_nocopy(eRegI dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9501 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
9502 format %{ "MOV $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9503 ins_encode( enc_Copy( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9504 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9505 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9506
a61af66fc99e Initial load
duke
parents:
diff changeset
9507 instruct ci2b( eRegI dst, eRegI src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9508 effect( USE_DEF dst, USE src, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
9509
a61af66fc99e Initial load
duke
parents:
diff changeset
9510 size(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
9511 format %{ "NEG $dst\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9512 "ADC $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9513 ins_encode( neg_reg(dst),
a61af66fc99e Initial load
duke
parents:
diff changeset
9514 OpcRegReg(0x13,dst,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9515 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9516 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9517
a61af66fc99e Initial load
duke
parents:
diff changeset
9518 instruct convI2B( eRegI dst, eRegI src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9519 match(Set dst (Conv2B src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9520
a61af66fc99e Initial load
duke
parents:
diff changeset
9521 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9522 movI_nocopy(dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
9523 ci2b(dst,src,cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9524 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9525 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9526
a61af66fc99e Initial load
duke
parents:
diff changeset
9527 instruct movP_nocopy(eRegI dst, eRegP src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9528 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
9529 format %{ "MOV $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9530 ins_encode( enc_Copy( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9531 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9532 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9533
a61af66fc99e Initial load
duke
parents:
diff changeset
9534 instruct cp2b( eRegI dst, eRegP src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9535 effect( USE_DEF dst, USE src, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
9536 format %{ "NEG $dst\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9537 "ADC $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9538 ins_encode( neg_reg(dst),
a61af66fc99e Initial load
duke
parents:
diff changeset
9539 OpcRegReg(0x13,dst,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9540 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9541 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9542
a61af66fc99e Initial load
duke
parents:
diff changeset
9543 instruct convP2B( eRegI dst, eRegP src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9544 match(Set dst (Conv2B src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9545
a61af66fc99e Initial load
duke
parents:
diff changeset
9546 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9547 movP_nocopy(dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
9548 cp2b(dst,src,cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9549 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9550 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9551
a61af66fc99e Initial load
duke
parents:
diff changeset
9552 instruct cmpLTMask( eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9553 match(Set dst (CmpLTMask p q));
a61af66fc99e Initial load
duke
parents:
diff changeset
9554 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
9555 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
9556
a61af66fc99e Initial load
duke
parents:
diff changeset
9557 // SETlt can only use low byte of EAX,EBX, ECX, or EDX as destination
a61af66fc99e Initial load
duke
parents:
diff changeset
9558 format %{ "XOR $dst,$dst\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9559 "CMP $p,$q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9560 "SETlt $dst\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9561 "NEG $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9562 ins_encode( OpcRegReg(0x33,dst,dst),
a61af66fc99e Initial load
duke
parents:
diff changeset
9563 OpcRegReg(0x3B,p,q),
a61af66fc99e Initial load
duke
parents:
diff changeset
9564 setLT_reg(dst), neg_reg(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9565 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
9566 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9567
a61af66fc99e Initial load
duke
parents:
diff changeset
9568 instruct cmpLTMask0( eRegI dst, immI0 zero, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9569 match(Set dst (CmpLTMask dst zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
9570 effect( DEF dst, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
9571 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
9572
a61af66fc99e Initial load
duke
parents:
diff changeset
9573 format %{ "SAR $dst,31" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9574 opcode(0xC1, 0x7); /* C1 /7 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9575 ins_encode( RegOpcImm( dst, 0x1F ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9576 ins_pipe( ialu_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
9577 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9578
a61af66fc99e Initial load
duke
parents:
diff changeset
9579
a61af66fc99e Initial load
duke
parents:
diff changeset
9580 instruct cadd_cmpLTMask( ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9581 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9582 effect( KILL tmp, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
9583 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
9584 // annoyingly, $tmp has no edges so you cant ask for it in
a61af66fc99e Initial load
duke
parents:
diff changeset
9585 // any format or encoding
a61af66fc99e Initial load
duke
parents:
diff changeset
9586 format %{ "SUB $p,$q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9587 "SBB ECX,ECX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9588 "AND ECX,$y\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9589 "ADD $p,ECX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9590 ins_encode( enc_cmpLTP(p,q,y,tmp) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9591 ins_pipe( pipe_cmplt );
a61af66fc99e Initial load
duke
parents:
diff changeset
9592 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9593
a61af66fc99e Initial load
duke
parents:
diff changeset
9594 /* If I enable this, I encourage spilling in the inner loop of compress.
a61af66fc99e Initial load
duke
parents:
diff changeset
9595 instruct cadd_cmpLTMask_mem( ncxRegI p, ncxRegI q, memory y, eCXRegI tmp, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9596 match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9597 effect( USE_KILL tmp, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
9598 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
9599
a61af66fc99e Initial load
duke
parents:
diff changeset
9600 format %{ "SUB $p,$q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9601 "SBB ECX,ECX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9602 "AND ECX,$y\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9603 "ADD $p,ECX" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9604 ins_encode( enc_cmpLTP_mem(p,q,y,tmp) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9605 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9606 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9607
a61af66fc99e Initial load
duke
parents:
diff changeset
9608 //----------Long Instructions------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
9609 // Add Long Register with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9610 instruct addL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9611 match(Set dst (AddL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9612 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9613 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
9614 format %{ "ADD $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9615 "ADC $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9616 opcode(0x03, 0x13);
a61af66fc99e Initial load
duke
parents:
diff changeset
9617 ins_encode( RegReg_Lo(dst, src), RegReg_Hi(dst,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9618 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9619 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9620
a61af66fc99e Initial load
duke
parents:
diff changeset
9621 // Add Long Register with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9622 instruct addL_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9623 match(Set dst (AddL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9624 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9625 format %{ "ADD $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9626 "ADC $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9627 opcode(0x81,0x00,0x02); /* Opcode 81 /0, 81 /2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9628 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9629 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9630 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9631
a61af66fc99e Initial load
duke
parents:
diff changeset
9632 // Add Long Register with Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
9633 instruct addL_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9634 match(Set dst (AddL dst (LoadL mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9635 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9636 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9637 format %{ "ADD $dst.lo,$mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9638 "ADC $dst.hi,$mem+4" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9639 opcode(0x03, 0x13);
a61af66fc99e Initial load
duke
parents:
diff changeset
9640 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9641 ins_pipe( ialu_reg_long_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
9642 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9643
a61af66fc99e Initial load
duke
parents:
diff changeset
9644 // Subtract Long Register with Register.
a61af66fc99e Initial load
duke
parents:
diff changeset
9645 instruct subL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9646 match(Set dst (SubL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9647 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9648 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
9649 format %{ "SUB $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9650 "SBB $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9651 opcode(0x2B, 0x1B);
a61af66fc99e Initial load
duke
parents:
diff changeset
9652 ins_encode( RegReg_Lo(dst, src), RegReg_Hi(dst,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9653 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9654 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9655
a61af66fc99e Initial load
duke
parents:
diff changeset
9656 // Subtract Long Register with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9657 instruct subL_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9658 match(Set dst (SubL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9659 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9660 format %{ "SUB $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9661 "SBB $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9662 opcode(0x81,0x05,0x03); /* Opcode 81 /5, 81 /3 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9663 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9664 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9665 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9666
a61af66fc99e Initial load
duke
parents:
diff changeset
9667 // Subtract Long Register with Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
9668 instruct subL_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9669 match(Set dst (SubL dst (LoadL mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9670 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9671 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9672 format %{ "SUB $dst.lo,$mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9673 "SBB $dst.hi,$mem+4" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9674 opcode(0x2B, 0x1B);
a61af66fc99e Initial load
duke
parents:
diff changeset
9675 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9676 ins_pipe( ialu_reg_long_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
9677 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9678
a61af66fc99e Initial load
duke
parents:
diff changeset
9679 instruct negL_eReg(eRegL dst, immL0 zero, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9680 match(Set dst (SubL zero dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
9681 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9682 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
9683 format %{ "NEG $dst.hi\n\tNEG $dst.lo\n\tSBB $dst.hi,0" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9684 ins_encode( neg_long(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9685 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9686 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9687
a61af66fc99e Initial load
duke
parents:
diff changeset
9688 // And Long Register with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9689 instruct andL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9690 match(Set dst (AndL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9691 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9692 format %{ "AND $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9693 "AND $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9694 opcode(0x23,0x23);
a61af66fc99e Initial load
duke
parents:
diff changeset
9695 ins_encode( RegReg_Lo( dst, src), RegReg_Hi( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9696 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9697 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9698
a61af66fc99e Initial load
duke
parents:
diff changeset
9699 // And Long Register with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9700 instruct andL_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9701 match(Set dst (AndL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9702 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9703 format %{ "AND $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9704 "AND $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9705 opcode(0x81,0x04,0x04); /* Opcode 81 /4, 81 /4 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9706 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9707 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9708 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9709
a61af66fc99e Initial load
duke
parents:
diff changeset
9710 // And Long Register with Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
9711 instruct andL_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9712 match(Set dst (AndL dst (LoadL mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9713 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9714 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9715 format %{ "AND $dst.lo,$mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9716 "AND $dst.hi,$mem+4" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9717 opcode(0x23, 0x23);
a61af66fc99e Initial load
duke
parents:
diff changeset
9718 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9719 ins_pipe( ialu_reg_long_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
9720 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9721
a61af66fc99e Initial load
duke
parents:
diff changeset
9722 // Or Long Register with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9723 instruct orl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9724 match(Set dst (OrL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9725 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9726 format %{ "OR $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9727 "OR $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9728 opcode(0x0B,0x0B);
a61af66fc99e Initial load
duke
parents:
diff changeset
9729 ins_encode( RegReg_Lo( dst, src), RegReg_Hi( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9730 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9731 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9732
a61af66fc99e Initial load
duke
parents:
diff changeset
9733 // Or Long Register with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9734 instruct orl_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9735 match(Set dst (OrL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9736 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9737 format %{ "OR $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9738 "OR $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9739 opcode(0x81,0x01,0x01); /* Opcode 81 /1, 81 /1 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9740 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9741 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9742 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9743
a61af66fc99e Initial load
duke
parents:
diff changeset
9744 // Or Long Register with Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
9745 instruct orl_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9746 match(Set dst (OrL dst (LoadL mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9747 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9748 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9749 format %{ "OR $dst.lo,$mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9750 "OR $dst.hi,$mem+4" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9751 opcode(0x0B,0x0B);
a61af66fc99e Initial load
duke
parents:
diff changeset
9752 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9753 ins_pipe( ialu_reg_long_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
9754 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9755
a61af66fc99e Initial load
duke
parents:
diff changeset
9756 // Xor Long Register with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
9757 instruct xorl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9758 match(Set dst (XorL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9759 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9760 format %{ "XOR $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9761 "XOR $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9762 opcode(0x33,0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
9763 ins_encode( RegReg_Lo( dst, src), RegReg_Hi( dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9764 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9765 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9766
403
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9767 // Xor Long Register with Immediate -1
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9768 instruct xorl_eReg_im1(eRegL dst, immL_M1 imm) %{
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9769 match(Set dst (XorL dst imm));
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9770 format %{ "NOT $dst.lo\n\t"
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9771 "NOT $dst.hi" %}
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9772 ins_encode %{
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9773 __ notl($dst$$Register);
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9774 __ notl(HIGH_FROM_LOW($dst$$Register));
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9775 %}
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9776 ins_pipe( ialu_reg_long );
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9777 %}
b744678d4d71 6752257: Use NOT instead of XOR -1 on x86
rasbold
parents: 304
diff changeset
9778
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9779 // Xor Long Register with Immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
9780 instruct xorl_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9781 match(Set dst (XorL dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
9782 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9783 format %{ "XOR $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9784 "XOR $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9785 opcode(0x81,0x06,0x06); /* Opcode 81 /6, 81 /6 */
a61af66fc99e Initial load
duke
parents:
diff changeset
9786 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9787 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9788 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9789
a61af66fc99e Initial load
duke
parents:
diff changeset
9790 // Xor Long Register with Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
9791 instruct xorl_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9792 match(Set dst (XorL dst (LoadL mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
9793 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9794 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
9795 format %{ "XOR $dst.lo,$mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9796 "XOR $dst.hi,$mem+4" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9797 opcode(0x33,0x33);
a61af66fc99e Initial load
duke
parents:
diff changeset
9798 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9799 ins_pipe( ialu_reg_long_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
9800 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9801
219
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9802 // Shift Left Long by 1
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9803 instruct shlL_eReg_1(eRegL dst, immI_1 cnt, eFlagsReg cr) %{
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9804 predicate(UseNewLongLShift);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9805 match(Set dst (LShiftL dst cnt));
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9806 effect(KILL cr);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9807 ins_cost(100);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9808 format %{ "ADD $dst.lo,$dst.lo\n\t"
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9809 "ADC $dst.hi,$dst.hi" %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9810 ins_encode %{
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9811 __ addl($dst$$Register,$dst$$Register);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9812 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9813 %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9814 ins_pipe( ialu_reg_long );
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9815 %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9816
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9817 // Shift Left Long by 2
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9818 instruct shlL_eReg_2(eRegL dst, immI_2 cnt, eFlagsReg cr) %{
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9819 predicate(UseNewLongLShift);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9820 match(Set dst (LShiftL dst cnt));
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9821 effect(KILL cr);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9822 ins_cost(100);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9823 format %{ "ADD $dst.lo,$dst.lo\n\t"
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9824 "ADC $dst.hi,$dst.hi\n\t"
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9825 "ADD $dst.lo,$dst.lo\n\t"
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9826 "ADC $dst.hi,$dst.hi" %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9827 ins_encode %{
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9828 __ addl($dst$$Register,$dst$$Register);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9829 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9830 __ addl($dst$$Register,$dst$$Register);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9831 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9832 %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9833 ins_pipe( ialu_reg_long );
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9834 %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9835
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9836 // Shift Left Long by 3
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9837 instruct shlL_eReg_3(eRegL dst, immI_3 cnt, eFlagsReg cr) %{
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9838 predicate(UseNewLongLShift);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9839 match(Set dst (LShiftL dst cnt));
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9840 effect(KILL cr);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9841 ins_cost(100);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9842 format %{ "ADD $dst.lo,$dst.lo\n\t"
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9843 "ADC $dst.hi,$dst.hi\n\t"
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9844 "ADD $dst.lo,$dst.lo\n\t"
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9845 "ADC $dst.hi,$dst.hi\n\t"
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9846 "ADD $dst.lo,$dst.lo\n\t"
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9847 "ADC $dst.hi,$dst.hi" %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9848 ins_encode %{
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9849 __ addl($dst$$Register,$dst$$Register);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9850 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9851 __ addl($dst$$Register,$dst$$Register);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9852 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9853 __ addl($dst$$Register,$dst$$Register);
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9854 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9855 %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9856 ins_pipe( ialu_reg_long );
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9857 %}
ab65a4c9b2e8 6708714: Optimize long LShift on 32-bits x86
kvn
parents: 169
diff changeset
9858
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9859 // Shift Left Long by 1-31
a61af66fc99e Initial load
duke
parents:
diff changeset
9860 instruct shlL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9861 match(Set dst (LShiftL dst cnt));
a61af66fc99e Initial load
duke
parents:
diff changeset
9862 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9863 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
9864 format %{ "SHLD $dst.hi,$dst.lo,$cnt\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9865 "SHL $dst.lo,$cnt" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9866 opcode(0xC1, 0x4, 0xA4); /* 0F/A4, then C1 /4 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9867 ins_encode( move_long_small_shift(dst,cnt) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9868 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9869 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9870
a61af66fc99e Initial load
duke
parents:
diff changeset
9871 // Shift Left Long by 32-63
a61af66fc99e Initial load
duke
parents:
diff changeset
9872 instruct shlL_eReg_32_63(eRegL dst, immI_32_63 cnt, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9873 match(Set dst (LShiftL dst cnt));
a61af66fc99e Initial load
duke
parents:
diff changeset
9874 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9875 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
9876 format %{ "MOV $dst.hi,$dst.lo\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9877 "\tSHL $dst.hi,$cnt-32\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9878 "\tXOR $dst.lo,$dst.lo" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9879 opcode(0xC1, 0x4); /* C1 /4 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9880 ins_encode( move_long_big_shift_clr(dst,cnt) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9881 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9882 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9883
a61af66fc99e Initial load
duke
parents:
diff changeset
9884 // Shift Left Long by variable
a61af66fc99e Initial load
duke
parents:
diff changeset
9885 instruct salL_eReg_CL(eRegL dst, eCXRegI shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9886 match(Set dst (LShiftL dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9887 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9888 ins_cost(500+200);
a61af66fc99e Initial load
duke
parents:
diff changeset
9889 size(17);
a61af66fc99e Initial load
duke
parents:
diff changeset
9890 format %{ "TEST $shift,32\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9891 "JEQ,s small\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9892 "MOV $dst.hi,$dst.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9893 "XOR $dst.lo,$dst.lo\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9894 "small:\tSHLD $dst.hi,$dst.lo,$shift\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9895 "SHL $dst.lo,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9896 ins_encode( shift_left_long( dst, shift ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9897 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
9898 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9899
a61af66fc99e Initial load
duke
parents:
diff changeset
9900 // Shift Right Long by 1-31
a61af66fc99e Initial load
duke
parents:
diff changeset
9901 instruct shrL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9902 match(Set dst (URShiftL dst cnt));
a61af66fc99e Initial load
duke
parents:
diff changeset
9903 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9904 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
9905 format %{ "SHRD $dst.lo,$dst.hi,$cnt\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9906 "SHR $dst.hi,$cnt" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9907 opcode(0xC1, 0x5, 0xAC); /* 0F/AC, then C1 /5 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9908 ins_encode( move_long_small_shift(dst,cnt) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9909 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9910 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9911
a61af66fc99e Initial load
duke
parents:
diff changeset
9912 // Shift Right Long by 32-63
a61af66fc99e Initial load
duke
parents:
diff changeset
9913 instruct shrL_eReg_32_63(eRegL dst, immI_32_63 cnt, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9914 match(Set dst (URShiftL dst cnt));
a61af66fc99e Initial load
duke
parents:
diff changeset
9915 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9916 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
9917 format %{ "MOV $dst.lo,$dst.hi\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9918 "\tSHR $dst.lo,$cnt-32\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9919 "\tXOR $dst.hi,$dst.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9920 opcode(0xC1, 0x5); /* C1 /5 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9921 ins_encode( move_long_big_shift_clr(dst,cnt) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9922 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9923 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9924
a61af66fc99e Initial load
duke
parents:
diff changeset
9925 // Shift Right Long by variable
a61af66fc99e Initial load
duke
parents:
diff changeset
9926 instruct shrL_eReg_CL(eRegL dst, eCXRegI shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9927 match(Set dst (URShiftL dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9928 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9929 ins_cost(600);
a61af66fc99e Initial load
duke
parents:
diff changeset
9930 size(17);
a61af66fc99e Initial load
duke
parents:
diff changeset
9931 format %{ "TEST $shift,32\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9932 "JEQ,s small\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9933 "MOV $dst.lo,$dst.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9934 "XOR $dst.hi,$dst.hi\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9935 "small:\tSHRD $dst.lo,$dst.hi,$shift\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9936 "SHR $dst.hi,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9937 ins_encode( shift_right_long( dst, shift ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9938 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
9939 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9940
a61af66fc99e Initial load
duke
parents:
diff changeset
9941 // Shift Right Long by 1-31
a61af66fc99e Initial load
duke
parents:
diff changeset
9942 instruct sarL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9943 match(Set dst (RShiftL dst cnt));
a61af66fc99e Initial load
duke
parents:
diff changeset
9944 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9945 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
9946 format %{ "SHRD $dst.lo,$dst.hi,$cnt\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9947 "SAR $dst.hi,$cnt" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9948 opcode(0xC1, 0x7, 0xAC); /* 0F/AC, then C1 /7 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9949 ins_encode( move_long_small_shift(dst,cnt) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9950 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9951 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9952
a61af66fc99e Initial load
duke
parents:
diff changeset
9953 // Shift Right Long by 32-63
a61af66fc99e Initial load
duke
parents:
diff changeset
9954 instruct sarL_eReg_32_63( eRegL dst, immI_32_63 cnt, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9955 match(Set dst (RShiftL dst cnt));
a61af66fc99e Initial load
duke
parents:
diff changeset
9956 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9957 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
9958 format %{ "MOV $dst.lo,$dst.hi\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9959 "\tSAR $dst.lo,$cnt-32\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9960 "\tSAR $dst.hi,31" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9961 opcode(0xC1, 0x7); /* C1 /7 ib */
a61af66fc99e Initial load
duke
parents:
diff changeset
9962 ins_encode( move_long_big_shift_sign(dst,cnt) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9963 ins_pipe( ialu_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
9964 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9965
a61af66fc99e Initial load
duke
parents:
diff changeset
9966 // Shift Right arithmetic Long by variable
a61af66fc99e Initial load
duke
parents:
diff changeset
9967 instruct sarL_eReg_CL(eRegL dst, eCXRegI shift, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9968 match(Set dst (RShiftL dst shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
9969 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9970 ins_cost(600);
a61af66fc99e Initial load
duke
parents:
diff changeset
9971 size(18);
a61af66fc99e Initial load
duke
parents:
diff changeset
9972 format %{ "TEST $shift,32\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9973 "JEQ,s small\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9974 "MOV $dst.lo,$dst.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9975 "SAR $dst.hi,31\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9976 "small:\tSHRD $dst.lo,$dst.hi,$shift\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9977 "SAR $dst.hi,$shift" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9978 ins_encode( shift_right_arith_long( dst, shift ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
9979 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
9980 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
9981
a61af66fc99e Initial load
duke
parents:
diff changeset
9982
a61af66fc99e Initial load
duke
parents:
diff changeset
9983 //----------Double Instructions------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
9984 // Double Math
a61af66fc99e Initial load
duke
parents:
diff changeset
9985
a61af66fc99e Initial load
duke
parents:
diff changeset
9986 // Compare & branch
a61af66fc99e Initial load
duke
parents:
diff changeset
9987
a61af66fc99e Initial load
duke
parents:
diff changeset
9988 // P6 version of float compare, sets condition codes in EFLAGS
a61af66fc99e Initial load
duke
parents:
diff changeset
9989 instruct cmpD_cc_P6(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
9990 predicate(VM_Version::supports_cmov() && UseSSE <=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
9991 match(Set cr (CmpD src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
9992 effect(KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
9993 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
9994 format %{ "FLD $src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9995 "FUCOMIP ST,$src2 // P6 instruction\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9996 "JNP exit\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9997 "MOV ah,1 // saw a NaN, set CF\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
9998 "SAHF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
9999 "exit:\tNOP // avoid branch to branch" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10000 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10001 ins_encode( Push_Reg_D(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
10002 OpcP, RegOpc(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
10003 cmpF_P6_fixup );
a61af66fc99e Initial load
duke
parents:
diff changeset
10004 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10005 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10006
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10007 instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10008 predicate(VM_Version::supports_cmov() && UseSSE <=1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10009 match(Set cr (CmpD src1 src2));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10010 ins_cost(150);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10011 format %{ "FLD $src1\n\t"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10012 "FUCOMIP ST,$src2 // P6 instruction" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10013 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10014 ins_encode( Push_Reg_D(src1),
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10015 OpcP, RegOpc(src2));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10016 ins_pipe( pipe_slow );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10017 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10018
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10019 // Compare & branch
a61af66fc99e Initial load
duke
parents:
diff changeset
10020 instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10021 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10022 match(Set cr (CmpD src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
10023 effect(KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
10024 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
10025 format %{ "FLD $src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10026 "FCOMp $src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10027 "FNSTSW AX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10028 "TEST AX,0x400\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10029 "JZ,s flags\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10030 "MOV AH,1\t# unordered treat as LT\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10031 "flags:\tSAHF" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10032 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10033 ins_encode( Push_Reg_D(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
10034 OpcP, RegOpc(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
10035 fpu_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
10036 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10037 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10038
a61af66fc99e Initial load
duke
parents:
diff changeset
10039 // Compare vs zero into -1,0,1
a61af66fc99e Initial load
duke
parents:
diff changeset
10040 instruct cmpD_0(eRegI dst, regD src1, immD0 zero, eAXRegI rax, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10041 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10042 match(Set dst (CmpD3 src1 zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
10043 effect(KILL cr, KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
10044 ins_cost(280);
a61af66fc99e Initial load
duke
parents:
diff changeset
10045 format %{ "FTSTD $dst,$src1" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10046 opcode(0xE4, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
10047 ins_encode( Push_Reg_D(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
10048 OpcS, OpcP, PopFPU,
a61af66fc99e Initial load
duke
parents:
diff changeset
10049 CmpF_Result(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10050 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10051 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10052
a61af66fc99e Initial load
duke
parents:
diff changeset
10053 // Compare into -1,0,1
a61af66fc99e Initial load
duke
parents:
diff changeset
10054 instruct cmpD_reg(eRegI dst, regD src1, regD src2, eAXRegI rax, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10055 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10056 match(Set dst (CmpD3 src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
10057 effect(KILL cr, KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
10058 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
10059 format %{ "FCMPD $dst,$src1,$src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10060 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10061 ins_encode( Push_Reg_D(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
10062 OpcP, RegOpc(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
10063 CmpF_Result(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10064 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10065 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10066
a61af66fc99e Initial load
duke
parents:
diff changeset
10067 // float compare and set condition codes in EFLAGS by XMM regs
a61af66fc99e Initial load
duke
parents:
diff changeset
10068 instruct cmpXD_cc(eFlagsRegU cr, regXD dst, regXD src, eAXRegI rax) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10069 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10070 match(Set cr (CmpD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10071 effect(KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
10072 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
10073 format %{ "COMISD $dst,$src\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10074 "\tJNP exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10075 "\tMOV ah,1 // saw a NaN, set CF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10076 "\tSAHF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10077 "exit:\tNOP // avoid branch to branch" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10078 opcode(0x66, 0x0F, 0x2F);
a61af66fc99e Initial load
duke
parents:
diff changeset
10079 ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src), cmpF_P6_fixup);
a61af66fc99e Initial load
duke
parents:
diff changeset
10080 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10081 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10082
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10083 instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10084 predicate(UseSSE>=2);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10085 match(Set cr (CmpD dst src));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10086 ins_cost(100);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10087 format %{ "COMISD $dst,$src" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10088 opcode(0x66, 0x0F, 0x2F);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10089 ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10090 ins_pipe( pipe_slow );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10091 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10092
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10093 // float compare and set condition codes in EFLAGS by XMM regs
a61af66fc99e Initial load
duke
parents:
diff changeset
10094 instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10095 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10096 match(Set cr (CmpD dst (LoadD src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10097 effect(KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
10098 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
10099 format %{ "COMISD $dst,$src\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10100 "\tJNP exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10101 "\tMOV ah,1 // saw a NaN, set CF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10102 "\tSAHF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10103 "exit:\tNOP // avoid branch to branch" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10104 opcode(0x66, 0x0F, 0x2F);
a61af66fc99e Initial load
duke
parents:
diff changeset
10105 ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src), cmpF_P6_fixup);
a61af66fc99e Initial load
duke
parents:
diff changeset
10106 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10107 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10108
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10109 instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10110 predicate(UseSSE>=2);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10111 match(Set cr (CmpD dst (LoadD src)));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10112 ins_cost(100);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10113 format %{ "COMISD $dst,$src" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10114 opcode(0x66, 0x0F, 0x2F);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10115 ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10116 ins_pipe( pipe_slow );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10117 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
10118
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10119 // Compare into -1,0,1 in XMM
a61af66fc99e Initial load
duke
parents:
diff changeset
10120 instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10121 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10122 match(Set dst (CmpD3 src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
10123 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
10124 ins_cost(255);
a61af66fc99e Initial load
duke
parents:
diff changeset
10125 format %{ "XOR $dst,$dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10126 "\tCOMISD $src1,$src2\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10127 "\tJP,s nan\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10128 "\tJEQ,s exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10129 "\tJA,s inc\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10130 "nan:\tDEC $dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10131 "\tJMP,s exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10132 "inc:\tINC $dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10133 "exit:"
a61af66fc99e Initial load
duke
parents:
diff changeset
10134 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10135 opcode(0x66, 0x0F, 0x2F);
a61af66fc99e Initial load
duke
parents:
diff changeset
10136 ins_encode(Xor_Reg(dst), OpcP, OpcS, Opcode(tertiary), RegReg(src1, src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
10137 CmpX_Result(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10138 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10139 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10140
a61af66fc99e Initial load
duke
parents:
diff changeset
10141 // Compare into -1,0,1 in XMM and memory
a61af66fc99e Initial load
duke
parents:
diff changeset
10142 instruct cmpXD_regmem(eRegI dst, regXD src1, memory mem, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10143 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10144 match(Set dst (CmpD3 src1 (LoadD mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10145 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
10146 ins_cost(275);
a61af66fc99e Initial load
duke
parents:
diff changeset
10147 format %{ "COMISD $src1,$mem\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10148 "\tMOV $dst,0\t\t# do not blow flags\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10149 "\tJP,s nan\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10150 "\tJEQ,s exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10151 "\tJA,s inc\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10152 "nan:\tDEC $dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10153 "\tJMP,s exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10154 "inc:\tINC $dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10155 "exit:"
a61af66fc99e Initial load
duke
parents:
diff changeset
10156 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10157 opcode(0x66, 0x0F, 0x2F);
a61af66fc99e Initial load
duke
parents:
diff changeset
10158 ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(src1, mem),
a61af66fc99e Initial load
duke
parents:
diff changeset
10159 LdImmI(dst,0x0), CmpX_Result(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10160 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10161 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10162
a61af66fc99e Initial load
duke
parents:
diff changeset
10163
a61af66fc99e Initial load
duke
parents:
diff changeset
10164 instruct subD_reg(regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10165 predicate (UseSSE <=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10166 match(Set dst (SubD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10167
a61af66fc99e Initial load
duke
parents:
diff changeset
10168 format %{ "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10169 "DSUBp $dst,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10170 opcode(0xDE, 0x5); /* DE E8+i or DE /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10171 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
10172 ins_encode( Push_Reg_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10173 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10174 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10175 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10176
a61af66fc99e Initial load
duke
parents:
diff changeset
10177 instruct subD_reg_round(stackSlotD dst, regD src1, regD src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10178 predicate (UseSSE <=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10179 match(Set dst (RoundDouble (SubD src1 src2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10180 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
10181
a61af66fc99e Initial load
duke
parents:
diff changeset
10182 format %{ "FLD $src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10183 "DSUB ST,$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10184 "FSTP_D $dst\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10185 opcode(0xD8, 0x5);
a61af66fc99e Initial load
duke
parents:
diff changeset
10186 ins_encode( Push_Reg_D(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
10187 OpcP, RegOpc(src1), Pop_Mem_D(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10188 ins_pipe( fpu_mem_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10189 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10190
a61af66fc99e Initial load
duke
parents:
diff changeset
10191
a61af66fc99e Initial load
duke
parents:
diff changeset
10192 instruct subD_reg_mem(regD dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10193 predicate (UseSSE <=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10194 match(Set dst (SubD dst (LoadD src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10195 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
10196
a61af66fc99e Initial load
duke
parents:
diff changeset
10197 format %{ "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10198 "DSUBp $dst,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10199 opcode(0xDE, 0x5, 0xDD); /* DE C0+i */ /* LoadD DD /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10200 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10201 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10202 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
10203 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10204
a61af66fc99e Initial load
duke
parents:
diff changeset
10205 instruct absD_reg(regDPR1 dst, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10206 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10207 match(Set dst (AbsD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10208 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
10209 format %{ "FABS" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10210 opcode(0xE1, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
10211 ins_encode( OpcS, OpcP );
a61af66fc99e Initial load
duke
parents:
diff changeset
10212 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10213 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10214
a61af66fc99e Initial load
duke
parents:
diff changeset
10215 instruct absXD_reg( regXD dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10216 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10217 match(Set dst (AbsD dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10218 format %{ "ANDPD $dst,[0x7FFFFFFFFFFFFFFF]\t# ABS D by sign masking" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10219 ins_encode( AbsXD_encoding(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10220 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10221 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10222
a61af66fc99e Initial load
duke
parents:
diff changeset
10223 instruct negD_reg(regDPR1 dst, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10224 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10225 match(Set dst (NegD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10226 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
10227 format %{ "FCHS" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10228 opcode(0xE0, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
10229 ins_encode( OpcS, OpcP );
a61af66fc99e Initial load
duke
parents:
diff changeset
10230 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10231 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10232
a61af66fc99e Initial load
duke
parents:
diff changeset
10233 instruct negXD_reg( regXD dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10234 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10235 match(Set dst (NegD dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10236 format %{ "XORPD $dst,[0x8000000000000000]\t# CHS D by sign flipping" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10237 ins_encode %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10238 __ xorpd($dst$$XMMRegister,
a61af66fc99e Initial load
duke
parents:
diff changeset
10239 ExternalAddress((address)double_signflip_pool));
a61af66fc99e Initial load
duke
parents:
diff changeset
10240 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10241 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10242 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10243
a61af66fc99e Initial load
duke
parents:
diff changeset
10244 instruct addD_reg(regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10245 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10246 match(Set dst (AddD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10247 format %{ "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10248 "DADD $dst,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10249 size(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
10250 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
10251 opcode(0xDE, 0x0); /* DE C0+i or DE /0*/
a61af66fc99e Initial load
duke
parents:
diff changeset
10252 ins_encode( Push_Reg_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10253 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10254 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10255 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10256
a61af66fc99e Initial load
duke
parents:
diff changeset
10257
a61af66fc99e Initial load
duke
parents:
diff changeset
10258 instruct addD_reg_round(stackSlotD dst, regD src1, regD src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10259 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10260 match(Set dst (RoundDouble (AddD src1 src2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10261 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
10262
a61af66fc99e Initial load
duke
parents:
diff changeset
10263 format %{ "FLD $src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10264 "DADD ST,$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10265 "FSTP_D $dst\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10266 opcode(0xD8, 0x0); /* D8 C0+i or D8 /0*/
a61af66fc99e Initial load
duke
parents:
diff changeset
10267 ins_encode( Push_Reg_D(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
10268 OpcP, RegOpc(src1), Pop_Mem_D(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10269 ins_pipe( fpu_mem_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10270 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10271
a61af66fc99e Initial load
duke
parents:
diff changeset
10272
a61af66fc99e Initial load
duke
parents:
diff changeset
10273 instruct addD_reg_mem(regD dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10274 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10275 match(Set dst (AddD dst (LoadD src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10276 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
10277
a61af66fc99e Initial load
duke
parents:
diff changeset
10278 format %{ "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10279 "DADDp $dst,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10280 opcode(0xDE, 0x0, 0xDD); /* DE C0+i */ /* LoadD DD /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10281 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10282 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10283 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
10284 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10285
a61af66fc99e Initial load
duke
parents:
diff changeset
10286 // add-to-memory
a61af66fc99e Initial load
duke
parents:
diff changeset
10287 instruct addD_mem_reg(memory dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10288 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10289 match(Set dst (StoreD dst (RoundDouble (AddD (LoadD dst) src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
10290 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
10291
a61af66fc99e Initial load
duke
parents:
diff changeset
10292 format %{ "FLD_D $dst\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10293 "DADD ST,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10294 "FST_D $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10295 opcode(0xDD, 0x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
10296 ins_encode( Opcode(0xDD), RMopc_Mem(0x00,dst),
a61af66fc99e Initial load
duke
parents:
diff changeset
10297 Opcode(0xD8), RegOpc(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10298 set_instruction_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
10299 Opcode(0xDD), RMopc_Mem(0x03,dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10300 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
10301 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10302
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10303 instruct addD_reg_imm1(regD dst, immD1 con) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10304 predicate(UseSSE<=1);
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10305 match(Set dst (AddD dst con));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10306 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
10307 format %{ "FLD1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10308 "DADDp $dst,ST" %}
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10309 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10310 __ fld1();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10311 __ faddp($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10312 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10313 ins_pipe(fpu_reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10314 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10315
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10316 instruct addD_reg_imm(regD dst, immD con) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10317 predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10318 match(Set dst (AddD dst con));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10319 ins_cost(200);
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10320 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10321 "DADDp $dst,ST" %}
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10322 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10323 __ fld_d($constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10324 __ faddp($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10325 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10326 ins_pipe(fpu_reg_mem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10327 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10328
a61af66fc99e Initial load
duke
parents:
diff changeset
10329 instruct addD_reg_imm_round(stackSlotD dst, regD src, immD con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10330 predicate(UseSSE<=1 && _kids[0]->_kids[1]->_leaf->getd() != 0.0 && _kids[0]->_kids[1]->_leaf->getd() != 1.0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
10331 match(Set dst (RoundDouble (AddD src con)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10332 ins_cost(200);
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10333 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10334 "DADD ST,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10335 "FSTP_D $dst\t# D-round" %}
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10336 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10337 __ fld_d($constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10338 __ fadd($src$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10339 __ fstp_d(Address(rsp, $dst$$disp));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10340 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10341 ins_pipe(fpu_mem_reg_con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10342 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10343
a61af66fc99e Initial load
duke
parents:
diff changeset
10344 // Add two double precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
10345 instruct addXD_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10346 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10347 match(Set dst (AddD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10348 format %{ "ADDSD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10349 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10350 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10351 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10352
a61af66fc99e Initial load
duke
parents:
diff changeset
10353 instruct addXD_imm(regXD dst, immXD con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10354 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10355 match(Set dst (AddD dst con));
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10356 format %{ "ADDSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10357 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10358 __ addsd($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10359 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10360 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10361 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10362
a61af66fc99e Initial load
duke
parents:
diff changeset
10363 instruct addXD_mem(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10364 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10365 match(Set dst (AddD dst (LoadD mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10366 format %{ "ADDSD $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10367 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
10368 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10369 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10370
a61af66fc99e Initial load
duke
parents:
diff changeset
10371 // Sub two double precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
10372 instruct subXD_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10373 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10374 match(Set dst (SubD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10375 format %{ "SUBSD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10376 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10377 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10378 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10379
a61af66fc99e Initial load
duke
parents:
diff changeset
10380 instruct subXD_imm(regXD dst, immXD con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10381 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10382 match(Set dst (SubD dst con));
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10383 format %{ "SUBSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10384 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10385 __ subsd($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10386 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10387 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10388 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10389
a61af66fc99e Initial load
duke
parents:
diff changeset
10390 instruct subXD_mem(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10391 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10392 match(Set dst (SubD dst (LoadD mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10393 format %{ "SUBSD $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10394 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
10395 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10396 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10397
a61af66fc99e Initial load
duke
parents:
diff changeset
10398 // Mul two double precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
10399 instruct mulXD_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10400 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10401 match(Set dst (MulD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10402 format %{ "MULSD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10403 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10404 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10405 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10406
a61af66fc99e Initial load
duke
parents:
diff changeset
10407 instruct mulXD_imm(regXD dst, immXD con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10408 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10409 match(Set dst (MulD dst con));
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10410 format %{ "MULSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10411 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10412 __ mulsd($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10413 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10414 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10415 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10416
a61af66fc99e Initial load
duke
parents:
diff changeset
10417 instruct mulXD_mem(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10418 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10419 match(Set dst (MulD dst (LoadD mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10420 format %{ "MULSD $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10421 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
10422 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10423 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10424
a61af66fc99e Initial load
duke
parents:
diff changeset
10425 // Div two double precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
10426 instruct divXD_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10427 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10428 match(Set dst (DivD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10429 format %{ "DIVSD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10430 opcode(0xF2, 0x0F, 0x5E);
a61af66fc99e Initial load
duke
parents:
diff changeset
10431 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10432 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10433 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10434
a61af66fc99e Initial load
duke
parents:
diff changeset
10435 instruct divXD_imm(regXD dst, immXD con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10436 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10437 match(Set dst (DivD dst con));
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10438 format %{ "DIVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10439 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10440 __ divsd($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10441 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10442 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10443 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10444
a61af66fc99e Initial load
duke
parents:
diff changeset
10445 instruct divXD_mem(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10446 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10447 match(Set dst (DivD dst (LoadD mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10448 format %{ "DIVSD $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10449 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
10450 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10451 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10452
a61af66fc99e Initial load
duke
parents:
diff changeset
10453
a61af66fc99e Initial load
duke
parents:
diff changeset
10454 instruct mulD_reg(regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10455 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10456 match(Set dst (MulD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10457 format %{ "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10458 "DMULp $dst,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10459 opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
a61af66fc99e Initial load
duke
parents:
diff changeset
10460 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
10461 ins_encode( Push_Reg_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10462 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10463 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10464 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10465
a61af66fc99e Initial load
duke
parents:
diff changeset
10466 // Strict FP instruction biases argument before multiply then
a61af66fc99e Initial load
duke
parents:
diff changeset
10467 // biases result to avoid double rounding of subnormals.
a61af66fc99e Initial load
duke
parents:
diff changeset
10468 //
a61af66fc99e Initial load
duke
parents:
diff changeset
10469 // scale arg1 by multiplying arg1 by 2^(-15360)
a61af66fc99e Initial load
duke
parents:
diff changeset
10470 // load arg2
a61af66fc99e Initial load
duke
parents:
diff changeset
10471 // multiply scaled arg1 by arg2
a61af66fc99e Initial load
duke
parents:
diff changeset
10472 // rescale product by 2^(15360)
a61af66fc99e Initial load
duke
parents:
diff changeset
10473 //
a61af66fc99e Initial load
duke
parents:
diff changeset
10474 instruct strictfp_mulD_reg(regDPR1 dst, regnotDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10475 predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() );
a61af66fc99e Initial load
duke
parents:
diff changeset
10476 match(Set dst (MulD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10477 ins_cost(1); // Select this instruction for all strict FP double multiplies
a61af66fc99e Initial load
duke
parents:
diff changeset
10478
a61af66fc99e Initial load
duke
parents:
diff changeset
10479 format %{ "FLD StubRoutines::_fpu_subnormal_bias1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10480 "DMULp $dst,ST\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10481 "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10482 "DMULp $dst,ST\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10483 "FLD StubRoutines::_fpu_subnormal_bias2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10484 "DMULp $dst,ST\n\t" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10485 opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
a61af66fc99e Initial load
duke
parents:
diff changeset
10486 ins_encode( strictfp_bias1(dst),
a61af66fc99e Initial load
duke
parents:
diff changeset
10487 Push_Reg_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10488 OpcP, RegOpc(dst),
a61af66fc99e Initial load
duke
parents:
diff changeset
10489 strictfp_bias2(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10490 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10491 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10492
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10493 instruct mulD_reg_imm(regD dst, immD con) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10494 predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10495 match(Set dst (MulD dst con));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10496 ins_cost(200);
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10497 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10498 "DMULp $dst,ST" %}
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10499 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10500 __ fld_d($constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10501 __ fmulp($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10502 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
10503 ins_pipe(fpu_reg_mem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
10504 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10505
a61af66fc99e Initial load
duke
parents:
diff changeset
10506
a61af66fc99e Initial load
duke
parents:
diff changeset
10507 instruct mulD_reg_mem(regD dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10508 predicate( UseSSE<=1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
10509 match(Set dst (MulD dst (LoadD src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10510 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
10511 format %{ "FLD_D $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10512 "DMULp $dst,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10513 opcode(0xDE, 0x1, 0xDD); /* DE C8+i or DE /1*/ /* LoadD DD /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10514 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10515 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10516 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
10517 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10518
a61af66fc99e Initial load
duke
parents:
diff changeset
10519 //
a61af66fc99e Initial load
duke
parents:
diff changeset
10520 // Cisc-alternate to reg-reg multiply
a61af66fc99e Initial load
duke
parents:
diff changeset
10521 instruct mulD_reg_mem_cisc(regD dst, regD src, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10522 predicate( UseSSE<=1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
10523 match(Set dst (MulD src (LoadD mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10524 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
10525 format %{ "FLD_D $mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10526 "DMUL ST,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10527 "FSTP_D $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10528 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i */ /* LoadD D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10529 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem),
a61af66fc99e Initial load
duke
parents:
diff changeset
10530 OpcReg_F(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10531 Pop_Reg_D(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10532 ins_pipe( fpu_reg_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
10533 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10534
a61af66fc99e Initial load
duke
parents:
diff changeset
10535
a61af66fc99e Initial load
duke
parents:
diff changeset
10536 // MACRO3 -- addD a mulD
a61af66fc99e Initial load
duke
parents:
diff changeset
10537 // This instruction is a '2-address' instruction in that the result goes
a61af66fc99e Initial load
duke
parents:
diff changeset
10538 // back to src2. This eliminates a move from the macro; possibly the
a61af66fc99e Initial load
duke
parents:
diff changeset
10539 // register allocator will have to add it back (and maybe not).
a61af66fc99e Initial load
duke
parents:
diff changeset
10540 instruct addD_mulD_reg(regD src2, regD src1, regD src0) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10541 predicate( UseSSE<=1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
10542 match(Set src2 (AddD (MulD src0 src1) src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
10543 format %{ "FLD $src0\t# ===MACRO3d===\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10544 "DMUL ST,$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10545 "DADDp $src2,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10546 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
10547 opcode(0xDD); /* LoadD DD /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10548 ins_encode( Push_Reg_F(src0),
a61af66fc99e Initial load
duke
parents:
diff changeset
10549 FMul_ST_reg(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
10550 FAddP_reg_ST(src2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10551 ins_pipe( fpu_reg_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10552 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10553
a61af66fc99e Initial load
duke
parents:
diff changeset
10554
a61af66fc99e Initial load
duke
parents:
diff changeset
10555 // MACRO3 -- subD a mulD
a61af66fc99e Initial load
duke
parents:
diff changeset
10556 instruct subD_mulD_reg(regD src2, regD src1, regD src0) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10557 predicate( UseSSE<=1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
10558 match(Set src2 (SubD (MulD src0 src1) src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
10559 format %{ "FLD $src0\t# ===MACRO3d===\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10560 "DMUL ST,$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10561 "DSUBRp $src2,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10562 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
10563 ins_encode( Push_Reg_F(src0),
a61af66fc99e Initial load
duke
parents:
diff changeset
10564 FMul_ST_reg(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
10565 Opcode(0xDE), Opc_plus(0xE0,src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
10566 ins_pipe( fpu_reg_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10567 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10568
a61af66fc99e Initial load
duke
parents:
diff changeset
10569
a61af66fc99e Initial load
duke
parents:
diff changeset
10570 instruct divD_reg(regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10571 predicate( UseSSE<=1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
10572 match(Set dst (DivD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10573
a61af66fc99e Initial load
duke
parents:
diff changeset
10574 format %{ "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10575 "FDIVp $dst,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10576 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/
a61af66fc99e Initial load
duke
parents:
diff changeset
10577 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
10578 ins_encode( Push_Reg_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10579 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10580 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10581 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10582
a61af66fc99e Initial load
duke
parents:
diff changeset
10583 // Strict FP instruction biases argument before division then
a61af66fc99e Initial load
duke
parents:
diff changeset
10584 // biases result, to avoid double rounding of subnormals.
a61af66fc99e Initial load
duke
parents:
diff changeset
10585 //
a61af66fc99e Initial load
duke
parents:
diff changeset
10586 // scale dividend by multiplying dividend by 2^(-15360)
a61af66fc99e Initial load
duke
parents:
diff changeset
10587 // load divisor
a61af66fc99e Initial load
duke
parents:
diff changeset
10588 // divide scaled dividend by divisor
a61af66fc99e Initial load
duke
parents:
diff changeset
10589 // rescale quotient by 2^(15360)
a61af66fc99e Initial load
duke
parents:
diff changeset
10590 //
a61af66fc99e Initial load
duke
parents:
diff changeset
10591 instruct strictfp_divD_reg(regDPR1 dst, regnotDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10592 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10593 match(Set dst (DivD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10594 predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() );
a61af66fc99e Initial load
duke
parents:
diff changeset
10595 ins_cost(01);
a61af66fc99e Initial load
duke
parents:
diff changeset
10596
a61af66fc99e Initial load
duke
parents:
diff changeset
10597 format %{ "FLD StubRoutines::_fpu_subnormal_bias1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10598 "DMULp $dst,ST\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10599 "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10600 "FDIVp $dst,ST\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10601 "FLD StubRoutines::_fpu_subnormal_bias2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10602 "DMULp $dst,ST\n\t" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10603 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/
a61af66fc99e Initial load
duke
parents:
diff changeset
10604 ins_encode( strictfp_bias1(dst),
a61af66fc99e Initial load
duke
parents:
diff changeset
10605 Push_Reg_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10606 OpcP, RegOpc(dst),
a61af66fc99e Initial load
duke
parents:
diff changeset
10607 strictfp_bias2(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10608 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10609 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10610
a61af66fc99e Initial load
duke
parents:
diff changeset
10611 instruct divD_reg_round(stackSlotD dst, regD src1, regD src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10612 predicate( UseSSE<=1 && !(Compile::current()->has_method() && Compile::current()->method()->is_strict()) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10613 match(Set dst (RoundDouble (DivD src1 src2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
10614
a61af66fc99e Initial load
duke
parents:
diff changeset
10615 format %{ "FLD $src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10616 "FDIV ST,$src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10617 "FSTP_D $dst\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10618 opcode(0xD8, 0x6); /* D8 F0+i or D8 /6 */
a61af66fc99e Initial load
duke
parents:
diff changeset
10619 ins_encode( Push_Reg_D(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
10620 OpcP, RegOpc(src2), Pop_Mem_D(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10621 ins_pipe( fpu_mem_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
10622 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10623
a61af66fc99e Initial load
duke
parents:
diff changeset
10624
a61af66fc99e Initial load
duke
parents:
diff changeset
10625 instruct modD_reg(regD dst, regD src, eAXRegI rax, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10626 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10627 match(Set dst (ModD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10628 effect(KILL rax, KILL cr); // emitModD() uses EAX and EFLAGS
a61af66fc99e Initial load
duke
parents:
diff changeset
10629
a61af66fc99e Initial load
duke
parents:
diff changeset
10630 format %{ "DMOD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10631 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
10632 ins_encode(Push_Reg_Mod_D(dst, src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10633 emitModD(),
a61af66fc99e Initial load
duke
parents:
diff changeset
10634 Push_Result_Mod_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10635 Pop_Reg_D(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10636 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10637 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10638
a61af66fc99e Initial load
duke
parents:
diff changeset
10639 instruct modXD_reg(regXD dst, regXD src0, regXD src1, eAXRegI rax, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10640 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10641 match(Set dst (ModD src0 src1));
a61af66fc99e Initial load
duke
parents:
diff changeset
10642 effect(KILL rax, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
10643
a61af66fc99e Initial load
duke
parents:
diff changeset
10644 format %{ "SUB ESP,8\t # DMOD\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10645 "\tMOVSD [ESP+0],$src1\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10646 "\tFLD_D [ESP+0]\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10647 "\tMOVSD [ESP+0],$src0\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10648 "\tFLD_D [ESP+0]\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10649 "loop:\tFPREM\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10650 "\tFWAIT\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10651 "\tFNSTSW AX\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10652 "\tSAHF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10653 "\tJP loop\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10654 "\tFSTP_D [ESP+0]\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10655 "\tMOVSD $dst,[ESP+0]\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10656 "\tADD ESP,8\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
10657 "\tFSTP ST0\t # Restore FPU Stack"
a61af66fc99e Initial load
duke
parents:
diff changeset
10658 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10659 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
10660 ins_encode( Push_ModD_encoding(src0, src1), emitModD(), Push_ResultXD(dst), PopFPU);
a61af66fc99e Initial load
duke
parents:
diff changeset
10661 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10662 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10663
a61af66fc99e Initial load
duke
parents:
diff changeset
10664 instruct sinD_reg(regDPR1 dst, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10665 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10666 match(Set dst (SinD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10667 ins_cost(1800);
a61af66fc99e Initial load
duke
parents:
diff changeset
10668 format %{ "DSIN $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10669 opcode(0xD9, 0xFE);
a61af66fc99e Initial load
duke
parents:
diff changeset
10670 ins_encode( OpcP, OpcS );
a61af66fc99e Initial load
duke
parents:
diff changeset
10671 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10672 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10673
a61af66fc99e Initial load
duke
parents:
diff changeset
10674 instruct sinXD_reg(regXD dst, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10675 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10676 match(Set dst (SinD dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10677 effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8"
a61af66fc99e Initial load
duke
parents:
diff changeset
10678 ins_cost(1800);
a61af66fc99e Initial load
duke
parents:
diff changeset
10679 format %{ "DSIN $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10680 opcode(0xD9, 0xFE);
a61af66fc99e Initial load
duke
parents:
diff changeset
10681 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10682 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10683 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10684
a61af66fc99e Initial load
duke
parents:
diff changeset
10685 instruct cosD_reg(regDPR1 dst, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10686 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10687 match(Set dst (CosD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10688 ins_cost(1800);
a61af66fc99e Initial load
duke
parents:
diff changeset
10689 format %{ "DCOS $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10690 opcode(0xD9, 0xFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
10691 ins_encode( OpcP, OpcS );
a61af66fc99e Initial load
duke
parents:
diff changeset
10692 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10693 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10694
a61af66fc99e Initial load
duke
parents:
diff changeset
10695 instruct cosXD_reg(regXD dst, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10696 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10697 match(Set dst (CosD dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10698 effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8"
a61af66fc99e Initial load
duke
parents:
diff changeset
10699 ins_cost(1800);
a61af66fc99e Initial load
duke
parents:
diff changeset
10700 format %{ "DCOS $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10701 opcode(0xD9, 0xFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
10702 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10703 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10704 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10705
a61af66fc99e Initial load
duke
parents:
diff changeset
10706 instruct tanD_reg(regDPR1 dst, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10707 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10708 match(Set dst(TanD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10709 format %{ "DTAN $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10710 ins_encode( Opcode(0xD9), Opcode(0xF2), // fptan
a61af66fc99e Initial load
duke
parents:
diff changeset
10711 Opcode(0xDD), Opcode(0xD8)); // fstp st
a61af66fc99e Initial load
duke
parents:
diff changeset
10712 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10713 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10714
a61af66fc99e Initial load
duke
parents:
diff changeset
10715 instruct tanXD_reg(regXD dst, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10716 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10717 match(Set dst(TanD dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10718 effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8"
a61af66fc99e Initial load
duke
parents:
diff changeset
10719 format %{ "DTAN $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10720 ins_encode( Push_SrcXD(dst),
a61af66fc99e Initial load
duke
parents:
diff changeset
10721 Opcode(0xD9), Opcode(0xF2), // fptan
a61af66fc99e Initial load
duke
parents:
diff changeset
10722 Opcode(0xDD), Opcode(0xD8), // fstp st
a61af66fc99e Initial load
duke
parents:
diff changeset
10723 Push_ResultXD(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10724 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10725 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10726
a61af66fc99e Initial load
duke
parents:
diff changeset
10727 instruct atanD_reg(regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10728 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10729 match(Set dst(AtanD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10730 format %{ "DATA $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10731 opcode(0xD9, 0xF3);
a61af66fc99e Initial load
duke
parents:
diff changeset
10732 ins_encode( Push_Reg_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10733 OpcP, OpcS, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10734 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10735 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10736
a61af66fc99e Initial load
duke
parents:
diff changeset
10737 instruct atanXD_reg(regXD dst, regXD src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10738 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10739 match(Set dst(AtanD dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10740 effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8"
a61af66fc99e Initial load
duke
parents:
diff changeset
10741 format %{ "DATA $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10742 opcode(0xD9, 0xF3);
a61af66fc99e Initial load
duke
parents:
diff changeset
10743 ins_encode( Push_SrcXD(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10744 OpcP, OpcS, Push_ResultXD(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10745 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10746 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10747
a61af66fc99e Initial load
duke
parents:
diff changeset
10748 instruct sqrtD_reg(regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10749 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10750 match(Set dst (SqrtD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10751 format %{ "DSQRT $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10752 opcode(0xFA, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
10753 ins_encode( Push_Reg_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10754 OpcS, OpcP, Pop_Reg_D(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10755 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10756 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10757
a61af66fc99e Initial load
duke
parents:
diff changeset
10758 instruct powD_reg(regD X, regDPR1 Y, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10759 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10760 match(Set Y (PowD X Y)); // Raise X to the Yth power
a61af66fc99e Initial load
duke
parents:
diff changeset
10761 effect(KILL rax, KILL rbx, KILL rcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
10762 format %{ "SUB ESP,8\t\t# Fast-path POW encoding\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10763 "FLD_D $X\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10764 "FYL2X \t\t\t# Q=Y*ln2(X)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10765
a61af66fc99e Initial load
duke
parents:
diff changeset
10766 "FDUP \t\t\t# Q Q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10767 "FRNDINT\t\t\t# int(Q) Q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10768 "FSUB ST(1),ST(0)\t# int(Q) frac(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10769 "FISTP dword [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10770 "F2XM1 \t\t\t# 2^frac(Q)-1 int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10771 "FLD1 \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10772 "FADDP \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead
a61af66fc99e Initial load
duke
parents:
diff changeset
10773 "MOV EAX,[ESP]\t# Pick up int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10774 "MOV ECX,0xFFFFF800\t# Overflow mask\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10775 "ADD EAX,1023\t\t# Double exponent bias\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10776 "MOV EBX,EAX\t\t# Preshifted biased expo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10777 "SHL EAX,20\t\t# Shift exponent into place\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10778 "TEST EBX,ECX\t\t# Check for overflow\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10779 "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10780 "MOV [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10781 "MOV [ESP+0],0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10782 "FMUL ST(0),[ESP+0]\t# Scale\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10783
a61af66fc99e Initial load
duke
parents:
diff changeset
10784 "ADD ESP,8"
a61af66fc99e Initial load
duke
parents:
diff changeset
10785 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10786 ins_encode( push_stack_temp_qword,
a61af66fc99e Initial load
duke
parents:
diff changeset
10787 Push_Reg_D(X),
a61af66fc99e Initial load
duke
parents:
diff changeset
10788 Opcode(0xD9), Opcode(0xF1), // fyl2x
a61af66fc99e Initial load
duke
parents:
diff changeset
10789 pow_exp_core_encoding,
a61af66fc99e Initial load
duke
parents:
diff changeset
10790 pop_stack_temp_qword);
a61af66fc99e Initial load
duke
parents:
diff changeset
10791 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10792 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10793
a61af66fc99e Initial load
duke
parents:
diff changeset
10794 instruct powXD_reg(regXD dst, regXD src0, regXD src1, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10795 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10796 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power
a61af66fc99e Initial load
duke
parents:
diff changeset
10797 effect(KILL tmp1, KILL rax, KILL rbx, KILL rcx );
a61af66fc99e Initial load
duke
parents:
diff changeset
10798 format %{ "SUB ESP,8\t\t# Fast-path POW encoding\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10799 "MOVSD [ESP],$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10800 "FLD FPR1,$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10801 "MOVSD [ESP],$src0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10802 "FLD FPR1,$src0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10803 "FYL2X \t\t\t# Q=Y*ln2(X)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10804
a61af66fc99e Initial load
duke
parents:
diff changeset
10805 "FDUP \t\t\t# Q Q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10806 "FRNDINT\t\t\t# int(Q) Q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10807 "FSUB ST(1),ST(0)\t# int(Q) frac(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10808 "FISTP dword [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10809 "F2XM1 \t\t\t# 2^frac(Q)-1 int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10810 "FLD1 \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10811 "FADDP \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead
a61af66fc99e Initial load
duke
parents:
diff changeset
10812 "MOV EAX,[ESP]\t# Pick up int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10813 "MOV ECX,0xFFFFF800\t# Overflow mask\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10814 "ADD EAX,1023\t\t# Double exponent bias\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10815 "MOV EBX,EAX\t\t# Preshifted biased expo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10816 "SHL EAX,20\t\t# Shift exponent into place\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10817 "TEST EBX,ECX\t\t# Check for overflow\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10818 "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10819 "MOV [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10820 "MOV [ESP+0],0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10821 "FMUL ST(0),[ESP+0]\t# Scale\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10822
a61af66fc99e Initial load
duke
parents:
diff changeset
10823 "FST_D [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10824 "MOVSD $dst,[ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10825 "ADD ESP,8"
a61af66fc99e Initial load
duke
parents:
diff changeset
10826 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10827 ins_encode( push_stack_temp_qword,
a61af66fc99e Initial load
duke
parents:
diff changeset
10828 push_xmm_to_fpr1(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
10829 push_xmm_to_fpr1(src0),
a61af66fc99e Initial load
duke
parents:
diff changeset
10830 Opcode(0xD9), Opcode(0xF1), // fyl2x
a61af66fc99e Initial load
duke
parents:
diff changeset
10831 pow_exp_core_encoding,
a61af66fc99e Initial load
duke
parents:
diff changeset
10832 Push_ResultXD(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10833 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10834 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10835
a61af66fc99e Initial load
duke
parents:
diff changeset
10836
a61af66fc99e Initial load
duke
parents:
diff changeset
10837 instruct expD_reg(regDPR1 dpr1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10838 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10839 match(Set dpr1 (ExpD dpr1));
a61af66fc99e Initial load
duke
parents:
diff changeset
10840 effect(KILL rax, KILL rbx, KILL rcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
10841 format %{ "SUB ESP,8\t\t# Fast-path EXP encoding"
a61af66fc99e Initial load
duke
parents:
diff changeset
10842 "FLDL2E \t\t\t# Ld log2(e) X\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10843 "FMULP \t\t\t# Q=X*log2(e)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10844
a61af66fc99e Initial load
duke
parents:
diff changeset
10845 "FDUP \t\t\t# Q Q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10846 "FRNDINT\t\t\t# int(Q) Q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10847 "FSUB ST(1),ST(0)\t# int(Q) frac(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10848 "FISTP dword [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10849 "F2XM1 \t\t\t# 2^frac(Q)-1 int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10850 "FLD1 \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10851 "FADDP \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead
a61af66fc99e Initial load
duke
parents:
diff changeset
10852 "MOV EAX,[ESP]\t# Pick up int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10853 "MOV ECX,0xFFFFF800\t# Overflow mask\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10854 "ADD EAX,1023\t\t# Double exponent bias\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10855 "MOV EBX,EAX\t\t# Preshifted biased expo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10856 "SHL EAX,20\t\t# Shift exponent into place\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10857 "TEST EBX,ECX\t\t# Check for overflow\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10858 "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10859 "MOV [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10860 "MOV [ESP+0],0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10861 "FMUL ST(0),[ESP+0]\t# Scale\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10862
a61af66fc99e Initial load
duke
parents:
diff changeset
10863 "ADD ESP,8"
a61af66fc99e Initial load
duke
parents:
diff changeset
10864 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10865 ins_encode( push_stack_temp_qword,
a61af66fc99e Initial load
duke
parents:
diff changeset
10866 Opcode(0xD9), Opcode(0xEA), // fldl2e
a61af66fc99e Initial load
duke
parents:
diff changeset
10867 Opcode(0xDE), Opcode(0xC9), // fmulp
a61af66fc99e Initial load
duke
parents:
diff changeset
10868 pow_exp_core_encoding,
a61af66fc99e Initial load
duke
parents:
diff changeset
10869 pop_stack_temp_qword);
a61af66fc99e Initial load
duke
parents:
diff changeset
10870 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10871 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10872
a61af66fc99e Initial load
duke
parents:
diff changeset
10873 instruct expXD_reg(regXD dst, regXD src, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10874 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10875 match(Set dst (ExpD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10876 effect(KILL tmp1, KILL rax, KILL rbx, KILL rcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
10877 format %{ "SUB ESP,8\t\t# Fast-path EXP encoding\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10878 "MOVSD [ESP],$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10879 "FLDL2E \t\t\t# Ld log2(e) X\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10880 "FMULP \t\t\t# Q=X*log2(e) X\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10881
a61af66fc99e Initial load
duke
parents:
diff changeset
10882 "FDUP \t\t\t# Q Q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10883 "FRNDINT\t\t\t# int(Q) Q\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10884 "FSUB ST(1),ST(0)\t# int(Q) frac(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10885 "FISTP dword [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10886 "F2XM1 \t\t\t# 2^frac(Q)-1 int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10887 "FLD1 \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10888 "FADDP \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead
a61af66fc99e Initial load
duke
parents:
diff changeset
10889 "MOV EAX,[ESP]\t# Pick up int(Q)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10890 "MOV ECX,0xFFFFF800\t# Overflow mask\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10891 "ADD EAX,1023\t\t# Double exponent bias\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10892 "MOV EBX,EAX\t\t# Preshifted biased expo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10893 "SHL EAX,20\t\t# Shift exponent into place\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10894 "TEST EBX,ECX\t\t# Check for overflow\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10895 "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10896 "MOV [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10897 "MOV [ESP+0],0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10898 "FMUL ST(0),[ESP+0]\t# Scale\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10899
a61af66fc99e Initial load
duke
parents:
diff changeset
10900 "FST_D [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10901 "MOVSD $dst,[ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10902 "ADD ESP,8"
a61af66fc99e Initial load
duke
parents:
diff changeset
10903 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10904 ins_encode( Push_SrcXD(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10905 Opcode(0xD9), Opcode(0xEA), // fldl2e
a61af66fc99e Initial load
duke
parents:
diff changeset
10906 Opcode(0xDE), Opcode(0xC9), // fmulp
a61af66fc99e Initial load
duke
parents:
diff changeset
10907 pow_exp_core_encoding,
a61af66fc99e Initial load
duke
parents:
diff changeset
10908 Push_ResultXD(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
10909 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10910 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10911
a61af66fc99e Initial load
duke
parents:
diff changeset
10912
a61af66fc99e Initial load
duke
parents:
diff changeset
10913
a61af66fc99e Initial load
duke
parents:
diff changeset
10914 instruct log10D_reg(regDPR1 dst, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10915 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10916 // The source Double operand on FPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
10917 match(Set dst (Log10D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10918 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number
a61af66fc99e Initial load
duke
parents:
diff changeset
10919 // fxch ; swap ST(0) with ST(1)
a61af66fc99e Initial load
duke
parents:
diff changeset
10920 // fyl2x ; compute log_10(2) * log_2(x)
a61af66fc99e Initial load
duke
parents:
diff changeset
10921 format %{ "FLDLG2 \t\t\t#Log10\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10922 "FXCH \n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10923 "FYL2X \t\t\t# Q=Log10*Log_2(x)"
a61af66fc99e Initial load
duke
parents:
diff changeset
10924 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10925 ins_encode( Opcode(0xD9), Opcode(0xEC), // fldlg2
a61af66fc99e Initial load
duke
parents:
diff changeset
10926 Opcode(0xD9), Opcode(0xC9), // fxch
a61af66fc99e Initial load
duke
parents:
diff changeset
10927 Opcode(0xD9), Opcode(0xF1)); // fyl2x
a61af66fc99e Initial load
duke
parents:
diff changeset
10928
a61af66fc99e Initial load
duke
parents:
diff changeset
10929 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10930 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10931
a61af66fc99e Initial load
duke
parents:
diff changeset
10932 instruct log10XD_reg(regXD dst, regXD src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10933 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10934 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
10935 match(Set dst (Log10D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10936 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number
a61af66fc99e Initial load
duke
parents:
diff changeset
10937 // fyl2x ; compute log_10(2) * log_2(x)
a61af66fc99e Initial load
duke
parents:
diff changeset
10938 format %{ "FLDLG2 \t\t\t#Log10\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10939 "FYL2X \t\t\t# Q=Log10*Log_2(x)"
a61af66fc99e Initial load
duke
parents:
diff changeset
10940 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10941 ins_encode( Opcode(0xD9), Opcode(0xEC), // fldlg2
a61af66fc99e Initial load
duke
parents:
diff changeset
10942 Push_SrcXD(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10943 Opcode(0xD9), Opcode(0xF1), // fyl2x
a61af66fc99e Initial load
duke
parents:
diff changeset
10944 Push_ResultXD(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10945
a61af66fc99e Initial load
duke
parents:
diff changeset
10946 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10947 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10948
a61af66fc99e Initial load
duke
parents:
diff changeset
10949 instruct logD_reg(regDPR1 dst, regDPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10950 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
10951 // The source Double operand on FPU stack
a61af66fc99e Initial load
duke
parents:
diff changeset
10952 match(Set dst (LogD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10953 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number
a61af66fc99e Initial load
duke
parents:
diff changeset
10954 // fxch ; swap ST(0) with ST(1)
a61af66fc99e Initial load
duke
parents:
diff changeset
10955 // fyl2x ; compute log_e(2) * log_2(x)
a61af66fc99e Initial load
duke
parents:
diff changeset
10956 format %{ "FLDLN2 \t\t\t#Log_e\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10957 "FXCH \n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10958 "FYL2X \t\t\t# Q=Log_e*Log_2(x)"
a61af66fc99e Initial load
duke
parents:
diff changeset
10959 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10960 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2
a61af66fc99e Initial load
duke
parents:
diff changeset
10961 Opcode(0xD9), Opcode(0xC9), // fxch
a61af66fc99e Initial load
duke
parents:
diff changeset
10962 Opcode(0xD9), Opcode(0xF1)); // fyl2x
a61af66fc99e Initial load
duke
parents:
diff changeset
10963
a61af66fc99e Initial load
duke
parents:
diff changeset
10964 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10965 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10966
a61af66fc99e Initial load
duke
parents:
diff changeset
10967 instruct logXD_reg(regXD dst, regXD src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
10968 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
10969 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
10970 // The source and result Double operands in XMM registers
a61af66fc99e Initial load
duke
parents:
diff changeset
10971 match(Set dst (LogD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
10972 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number
a61af66fc99e Initial load
duke
parents:
diff changeset
10973 // fyl2x ; compute log_e(2) * log_2(x)
a61af66fc99e Initial load
duke
parents:
diff changeset
10974 format %{ "FLDLN2 \t\t\t#Log_e\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
10975 "FYL2X \t\t\t# Q=Log_e*Log_2(x)"
a61af66fc99e Initial load
duke
parents:
diff changeset
10976 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10977 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2
a61af66fc99e Initial load
duke
parents:
diff changeset
10978 Push_SrcXD(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
10979 Opcode(0xD9), Opcode(0xF1), // fyl2x
a61af66fc99e Initial load
duke
parents:
diff changeset
10980 Push_ResultXD(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
10981 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
10982 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
10983
a61af66fc99e Initial load
duke
parents:
diff changeset
10984 //-------------Float Instructions-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
10985 // Float Math
a61af66fc99e Initial load
duke
parents:
diff changeset
10986
a61af66fc99e Initial load
duke
parents:
diff changeset
10987 // Code for float compare:
a61af66fc99e Initial load
duke
parents:
diff changeset
10988 // fcompp();
a61af66fc99e Initial load
duke
parents:
diff changeset
10989 // fwait(); fnstsw_ax();
a61af66fc99e Initial load
duke
parents:
diff changeset
10990 // sahf();
a61af66fc99e Initial load
duke
parents:
diff changeset
10991 // movl(dst, unordered_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
10992 // jcc(Assembler::parity, exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
10993 // movl(dst, less_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
10994 // jcc(Assembler::below, exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
10995 // movl(dst, equal_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
10996 // jcc(Assembler::equal, exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
10997 // movl(dst, greater_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
10998 // exit:
a61af66fc99e Initial load
duke
parents:
diff changeset
10999
a61af66fc99e Initial load
duke
parents:
diff changeset
11000 // P6 version of float compare, sets condition codes in EFLAGS
a61af66fc99e Initial load
duke
parents:
diff changeset
11001 instruct cmpF_cc_P6(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11002 predicate(VM_Version::supports_cmov() && UseSSE == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11003 match(Set cr (CmpF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11004 effect(KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
11005 ins_cost(150);
a61af66fc99e Initial load
duke
parents:
diff changeset
11006 format %{ "FLD $src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11007 "FUCOMIP ST,$src2 // P6 instruction\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11008 "JNP exit\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11009 "MOV ah,1 // saw a NaN, set CF (treat as LT)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11010 "SAHF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11011 "exit:\tNOP // avoid branch to branch" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11012 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11013 ins_encode( Push_Reg_D(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11014 OpcP, RegOpc(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11015 cmpF_P6_fixup );
a61af66fc99e Initial load
duke
parents:
diff changeset
11016 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11017 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11018
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11019 instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11020 predicate(VM_Version::supports_cmov() && UseSSE == 0);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11021 match(Set cr (CmpF src1 src2));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11022 ins_cost(100);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11023 format %{ "FLD $src1\n\t"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11024 "FUCOMIP ST,$src2 // P6 instruction" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11025 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11026 ins_encode( Push_Reg_D(src1),
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11027 OpcP, RegOpc(src2));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11028 ins_pipe( pipe_slow );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11029 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11030
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11031
a61af66fc99e Initial load
duke
parents:
diff changeset
11032 // Compare & branch
a61af66fc99e Initial load
duke
parents:
diff changeset
11033 instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11034 predicate(UseSSE == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11035 match(Set cr (CmpF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11036 effect(KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
11037 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
11038 format %{ "FLD $src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11039 "FCOMp $src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11040 "FNSTSW AX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11041 "TEST AX,0x400\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11042 "JZ,s flags\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11043 "MOV AH,1\t# unordered treat as LT\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11044 "flags:\tSAHF" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11045 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11046 ins_encode( Push_Reg_D(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11047 OpcP, RegOpc(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11048 fpu_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
11049 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11050 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11051
a61af66fc99e Initial load
duke
parents:
diff changeset
11052 // Compare vs zero into -1,0,1
a61af66fc99e Initial load
duke
parents:
diff changeset
11053 instruct cmpF_0(eRegI dst, regF src1, immF0 zero, eAXRegI rax, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11054 predicate(UseSSE == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11055 match(Set dst (CmpF3 src1 zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
11056 effect(KILL cr, KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
11057 ins_cost(280);
a61af66fc99e Initial load
duke
parents:
diff changeset
11058 format %{ "FTSTF $dst,$src1" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11059 opcode(0xE4, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
11060 ins_encode( Push_Reg_D(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11061 OpcS, OpcP, PopFPU,
a61af66fc99e Initial load
duke
parents:
diff changeset
11062 CmpF_Result(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11063 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11064 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11065
a61af66fc99e Initial load
duke
parents:
diff changeset
11066 // Compare into -1,0,1
a61af66fc99e Initial load
duke
parents:
diff changeset
11067 instruct cmpF_reg(eRegI dst, regF src1, regF src2, eAXRegI rax, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11068 predicate(UseSSE == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11069 match(Set dst (CmpF3 src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11070 effect(KILL cr, KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
11071 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
11072 format %{ "FCMPF $dst,$src1,$src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11073 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11074 ins_encode( Push_Reg_D(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11075 OpcP, RegOpc(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11076 CmpF_Result(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11077 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11078 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11079
a61af66fc99e Initial load
duke
parents:
diff changeset
11080 // float compare and set condition codes in EFLAGS by XMM regs
a61af66fc99e Initial load
duke
parents:
diff changeset
11081 instruct cmpX_cc(eFlagsRegU cr, regX dst, regX src, eAXRegI rax) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11082 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11083 match(Set cr (CmpF dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11084 effect(KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
11085 ins_cost(145);
a61af66fc99e Initial load
duke
parents:
diff changeset
11086 format %{ "COMISS $dst,$src\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11087 "\tJNP exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11088 "\tMOV ah,1 // saw a NaN, set CF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11089 "\tSAHF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11090 "exit:\tNOP // avoid branch to branch" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11091 opcode(0x0F, 0x2F);
a61af66fc99e Initial load
duke
parents:
diff changeset
11092 ins_encode(OpcP, OpcS, RegReg(dst, src), cmpF_P6_fixup);
a61af66fc99e Initial load
duke
parents:
diff changeset
11093 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11094 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11095
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11096 instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11097 predicate(UseSSE>=1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11098 match(Set cr (CmpF dst src));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11099 ins_cost(100);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11100 format %{ "COMISS $dst,$src" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11101 opcode(0x0F, 0x2F);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11102 ins_encode(OpcP, OpcS, RegReg(dst, src));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11103 ins_pipe( pipe_slow );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11104 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11105
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11106 // float compare and set condition codes in EFLAGS by XMM regs
a61af66fc99e Initial load
duke
parents:
diff changeset
11107 instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11108 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11109 match(Set cr (CmpF dst (LoadF src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11110 effect(KILL rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
11111 ins_cost(165);
a61af66fc99e Initial load
duke
parents:
diff changeset
11112 format %{ "COMISS $dst,$src\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11113 "\tJNP exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11114 "\tMOV ah,1 // saw a NaN, set CF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11115 "\tSAHF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11116 "exit:\tNOP // avoid branch to branch" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11117 opcode(0x0F, 0x2F);
a61af66fc99e Initial load
duke
parents:
diff changeset
11118 ins_encode(OpcP, OpcS, RegMem(dst, src), cmpF_P6_fixup);
a61af66fc99e Initial load
duke
parents:
diff changeset
11119 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11120 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11121
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11122 instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11123 predicate(UseSSE>=1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11124 match(Set cr (CmpF dst (LoadF src)));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11125 ins_cost(100);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11126 format %{ "COMISS $dst,$src" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11127 opcode(0x0F, 0x2F);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11128 ins_encode(OpcP, OpcS, RegMem(dst, src));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11129 ins_pipe( pipe_slow );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11130 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
11131
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11132 // Compare into -1,0,1 in XMM
a61af66fc99e Initial load
duke
parents:
diff changeset
11133 instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11134 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11135 match(Set dst (CmpF3 src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11136 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
11137 ins_cost(255);
a61af66fc99e Initial load
duke
parents:
diff changeset
11138 format %{ "XOR $dst,$dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11139 "\tCOMISS $src1,$src2\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11140 "\tJP,s nan\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11141 "\tJEQ,s exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11142 "\tJA,s inc\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11143 "nan:\tDEC $dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11144 "\tJMP,s exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11145 "inc:\tINC $dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11146 "exit:"
a61af66fc99e Initial load
duke
parents:
diff changeset
11147 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11148 opcode(0x0F, 0x2F);
a61af66fc99e Initial load
duke
parents:
diff changeset
11149 ins_encode(Xor_Reg(dst), OpcP, OpcS, RegReg(src1, src2), CmpX_Result(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11150 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11151 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11152
a61af66fc99e Initial load
duke
parents:
diff changeset
11153 // Compare into -1,0,1 in XMM and memory
a61af66fc99e Initial load
duke
parents:
diff changeset
11154 instruct cmpX_regmem(eRegI dst, regX src1, memory mem, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11155 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11156 match(Set dst (CmpF3 src1 (LoadF mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11157 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
11158 ins_cost(275);
a61af66fc99e Initial load
duke
parents:
diff changeset
11159 format %{ "COMISS $src1,$mem\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11160 "\tMOV $dst,0\t\t# do not blow flags\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11161 "\tJP,s nan\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11162 "\tJEQ,s exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11163 "\tJA,s inc\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11164 "nan:\tDEC $dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11165 "\tJMP,s exit\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11166 "inc:\tINC $dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11167 "exit:"
a61af66fc99e Initial load
duke
parents:
diff changeset
11168 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11169 opcode(0x0F, 0x2F);
a61af66fc99e Initial load
duke
parents:
diff changeset
11170 ins_encode(OpcP, OpcS, RegMem(src1, mem), LdImmI(dst,0x0), CmpX_Result(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11171 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11172 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11173
a61af66fc99e Initial load
duke
parents:
diff changeset
11174 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11175 instruct subF24_reg(stackSlotF dst, regF src1, regF src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11176 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11177 match(Set dst (SubF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11178
a61af66fc99e Initial load
duke
parents:
diff changeset
11179 format %{ "FSUB $dst,$src1 - $src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11180 opcode(0xD8, 0x4); /* D8 E0+i or D8 /4 mod==0x3 ;; result in TOS */
a61af66fc99e Initial load
duke
parents:
diff changeset
11181 ins_encode( Push_Reg_F(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11182 OpcReg_F(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11183 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11184 ins_pipe( fpu_mem_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11185 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11186 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11187 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11188 instruct subF_reg(regF dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11189 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11190 match(Set dst (SubF dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11191
a61af66fc99e Initial load
duke
parents:
diff changeset
11192 format %{ "FSUB $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11193 opcode(0xDE, 0x5); /* DE E8+i or DE /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11194 ins_encode( Push_Reg_F(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
11195 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11196 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11197 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11198
a61af66fc99e Initial load
duke
parents:
diff changeset
11199 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11200 instruct addF24_reg(stackSlotF dst, regF src1, regF src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11201 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11202 match(Set dst (AddF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11203
a61af66fc99e Initial load
duke
parents:
diff changeset
11204 format %{ "FADD $dst,$src1,$src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11205 opcode(0xD8, 0x0); /* D8 C0+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
11206 ins_encode( Push_Reg_F(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11207 OpcReg_F(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11208 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11209 ins_pipe( fpu_mem_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11210 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11211 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11212 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11213 instruct addF_reg(regF dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11214 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11215 match(Set dst (AddF dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11216
a61af66fc99e Initial load
duke
parents:
diff changeset
11217 format %{ "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11218 "FADDp $dst,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11219 opcode(0xDE, 0x0); /* DE C0+i or DE /0*/
a61af66fc99e Initial load
duke
parents:
diff changeset
11220 ins_encode( Push_Reg_F(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
11221 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11222 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11223 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11224
a61af66fc99e Initial load
duke
parents:
diff changeset
11225 // Add two single precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
11226 instruct addX_reg(regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11227 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11228 match(Set dst (AddF dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11229 format %{ "ADDSS $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11230 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11231 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11232 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11233
a61af66fc99e Initial load
duke
parents:
diff changeset
11234 instruct addX_imm(regX dst, immXF con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11235 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11236 match(Set dst (AddF dst con));
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11237 format %{ "ADDSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11238 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11239 __ addss($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11240 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11241 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11242 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11243
a61af66fc99e Initial load
duke
parents:
diff changeset
11244 instruct addX_mem(regX dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11245 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11246 match(Set dst (AddF dst (LoadF mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11247 format %{ "ADDSS $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11248 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegMem(dst, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
11249 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11250 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11251
a61af66fc99e Initial load
duke
parents:
diff changeset
11252 // Subtract two single precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
11253 instruct subX_reg(regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11254 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11255 match(Set dst (SubF dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11256 format %{ "SUBSS $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11257 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11258 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11259 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11260
a61af66fc99e Initial load
duke
parents:
diff changeset
11261 instruct subX_imm(regX dst, immXF con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11262 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11263 match(Set dst (SubF dst con));
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11264 format %{ "SUBSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11265 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11266 __ subss($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11267 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11268 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11269 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11270
a61af66fc99e Initial load
duke
parents:
diff changeset
11271 instruct subX_mem(regX dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11272 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11273 match(Set dst (SubF dst (LoadF mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11274 format %{ "SUBSS $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11275 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
11276 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11277 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11278
a61af66fc99e Initial load
duke
parents:
diff changeset
11279 // Multiply two single precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
11280 instruct mulX_reg(regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11281 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11282 match(Set dst (MulF dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11283 format %{ "MULSS $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11284 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11285 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11286 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11287
a61af66fc99e Initial load
duke
parents:
diff changeset
11288 instruct mulX_imm(regX dst, immXF con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11289 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11290 match(Set dst (MulF dst con));
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11291 format %{ "MULSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11292 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11293 __ mulss($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11294 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11295 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11296 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11297
a61af66fc99e Initial load
duke
parents:
diff changeset
11298 instruct mulX_mem(regX dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11299 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11300 match(Set dst (MulF dst (LoadF mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11301 format %{ "MULSS $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11302 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
11303 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11304 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11305
a61af66fc99e Initial load
duke
parents:
diff changeset
11306 // Divide two single precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
11307 instruct divX_reg(regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11308 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11309 match(Set dst (DivF dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11310 format %{ "DIVSS $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11311 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11312 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11313 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11314
a61af66fc99e Initial load
duke
parents:
diff changeset
11315 instruct divX_imm(regX dst, immXF con) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11316 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11317 match(Set dst (DivF dst con));
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11318 format %{ "DIVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11319 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11320 __ divss($dst$$XMMRegister, $constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11321 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11322 ins_pipe(pipe_slow);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11323 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11324
a61af66fc99e Initial load
duke
parents:
diff changeset
11325 instruct divX_mem(regX dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11326 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11327 match(Set dst (DivF dst (LoadF mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11328 format %{ "DIVSS $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11329 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
11330 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11331 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11332
a61af66fc99e Initial load
duke
parents:
diff changeset
11333 // Get the square root of a single precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
11334 instruct sqrtX_reg(regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11335 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11336 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
11337 format %{ "SQRTSS $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11338 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x51), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11339 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11340 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11341
a61af66fc99e Initial load
duke
parents:
diff changeset
11342 instruct sqrtX_mem(regX dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11343 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11344 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF mem)))));
a61af66fc99e Initial load
duke
parents:
diff changeset
11345 format %{ "SQRTSS $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11346 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x51), RegMem(dst, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
11347 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11348 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11349
a61af66fc99e Initial load
duke
parents:
diff changeset
11350 // Get the square root of a double precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
11351 instruct sqrtXD_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11352 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
11353 match(Set dst (SqrtD src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11354 format %{ "SQRTSD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11355 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x51), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11356 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11357 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11358
a61af66fc99e Initial load
duke
parents:
diff changeset
11359 instruct sqrtXD_mem(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11360 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
11361 match(Set dst (SqrtD (LoadD mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11362 format %{ "SQRTSD $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11363 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x51), RegMem(dst, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
11364 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11365 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11366
a61af66fc99e Initial load
duke
parents:
diff changeset
11367 instruct absF_reg(regFPR1 dst, regFPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11368 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11369 match(Set dst (AbsF src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11370 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
11371 format %{ "FABS" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11372 opcode(0xE1, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
11373 ins_encode( OpcS, OpcP );
a61af66fc99e Initial load
duke
parents:
diff changeset
11374 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11375 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11376
a61af66fc99e Initial load
duke
parents:
diff changeset
11377 instruct absX_reg(regX dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11378 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11379 match(Set dst (AbsF dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11380 format %{ "ANDPS $dst,[0x7FFFFFFF]\t# ABS F by sign masking" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11381 ins_encode( AbsXF_encoding(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11382 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11383 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11384
a61af66fc99e Initial load
duke
parents:
diff changeset
11385 instruct negF_reg(regFPR1 dst, regFPR1 src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11386 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11387 match(Set dst (NegF src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11388 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
11389 format %{ "FCHS" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11390 opcode(0xE0, 0xD9);
a61af66fc99e Initial load
duke
parents:
diff changeset
11391 ins_encode( OpcS, OpcP );
a61af66fc99e Initial load
duke
parents:
diff changeset
11392 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11393 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11394
a61af66fc99e Initial load
duke
parents:
diff changeset
11395 instruct negX_reg( regX dst ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11396 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11397 match(Set dst (NegF dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11398 format %{ "XORPS $dst,[0x80000000]\t# CHS F by sign flipping" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11399 ins_encode( NegXF_encoding(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11400 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11401 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11402
a61af66fc99e Initial load
duke
parents:
diff changeset
11403 // Cisc-alternate to addF_reg
a61af66fc99e Initial load
duke
parents:
diff changeset
11404 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11405 instruct addF24_reg_mem(stackSlotF dst, regF src1, memory src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11406 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11407 match(Set dst (AddF src1 (LoadF src2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11408
a61af66fc99e Initial load
duke
parents:
diff changeset
11409 format %{ "FLD $src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11410 "FADD ST,$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11411 "FSTP_S $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11412 opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11413 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11414 OpcReg_F(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11415 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11416 ins_pipe( fpu_mem_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
11417 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11418 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11419 // Cisc-alternate to addF_reg
a61af66fc99e Initial load
duke
parents:
diff changeset
11420 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11421 instruct addF_reg_mem(regF dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11422 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11423 match(Set dst (AddF dst (LoadF src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11424
a61af66fc99e Initial load
duke
parents:
diff changeset
11425 format %{ "FADD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11426 opcode(0xDE, 0x0, 0xD9); /* DE C0+i or DE /0*/ /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11427 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src),
a61af66fc99e Initial load
duke
parents:
diff changeset
11428 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11429 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
11430 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11431
a61af66fc99e Initial load
duke
parents:
diff changeset
11432 // // Following two instructions for _222_mpegaudio
a61af66fc99e Initial load
duke
parents:
diff changeset
11433 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11434 instruct addF24_mem_reg(stackSlotF dst, regF src2, memory src1 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11435 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11436 match(Set dst (AddF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11437
a61af66fc99e Initial load
duke
parents:
diff changeset
11438 format %{ "FADD $dst,$src1,$src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11439 opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11440 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11441 OpcReg_F(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11442 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11443 ins_pipe( fpu_mem_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
11444 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11445
a61af66fc99e Initial load
duke
parents:
diff changeset
11446 // Cisc-spill variant
a61af66fc99e Initial load
duke
parents:
diff changeset
11447 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11448 instruct addF24_mem_cisc(stackSlotF dst, memory src1, memory src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11449 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11450 match(Set dst (AddF src1 (LoadF src2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11451
a61af66fc99e Initial load
duke
parents:
diff changeset
11452 format %{ "FADD $dst,$src1,$src2 cisc" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11453 opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11454 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11455 set_instruction_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
11456 OpcP, RMopc_Mem(secondary,src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11457 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11458 ins_pipe( fpu_mem_mem_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
11459 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11460
a61af66fc99e Initial load
duke
parents:
diff changeset
11461 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11462 instruct addF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11463 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11464 match(Set dst (AddF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11465
a61af66fc99e Initial load
duke
parents:
diff changeset
11466 format %{ "FADD $dst,$src1,$src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11467 opcode(0xD8, 0x0, 0xD9); /* D8 /0 */ /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11468 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11469 set_instruction_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
11470 OpcP, RMopc_Mem(secondary,src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11471 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11472 ins_pipe( fpu_mem_mem_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
11473 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11474
a61af66fc99e Initial load
duke
parents:
diff changeset
11475
a61af66fc99e Initial load
duke
parents:
diff changeset
11476 // Spill to obtain 24-bit precision
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11477 instruct addF24_reg_imm(stackSlotF dst, regF src, immF con) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11478 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11479 match(Set dst (AddF src con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11480 format %{ "FLD $src\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11481 "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11482 "FSTP_S $dst" %}
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11483 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11484 __ fld_s($src$$reg - 1); // FLD ST(i-1)
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11485 __ fadd_s($constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11486 __ fstp_s(Address(rsp, $dst$$disp));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11487 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11488 ins_pipe(fpu_mem_reg_con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11489 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11490 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11491 // This instruction does not round to 24-bits
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11492 instruct addF_reg_imm(regF dst, regF src, immF con) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11493 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11494 match(Set dst (AddF src con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11495 format %{ "FLD $src\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11496 "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11497 "FSTP $dst" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11498 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11499 __ fld_s($src$$reg - 1); // FLD ST(i-1)
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11500 __ fadd_s($constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11501 __ fstp_d($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11502 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11503 ins_pipe(fpu_reg_reg_con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11504 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11505
a61af66fc99e Initial load
duke
parents:
diff changeset
11506 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11507 instruct mulF24_reg(stackSlotF dst, regF src1, regF src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11508 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11509 match(Set dst (MulF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11510
a61af66fc99e Initial load
duke
parents:
diff changeset
11511 format %{ "FLD $src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11512 "FMUL $src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11513 "FSTP_S $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11514 opcode(0xD8, 0x1); /* D8 C8+i or D8 /1 ;; result in TOS */
a61af66fc99e Initial load
duke
parents:
diff changeset
11515 ins_encode( Push_Reg_F(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11516 OpcReg_F(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11517 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11518 ins_pipe( fpu_mem_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11519 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11520 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11521 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11522 instruct mulF_reg(regF dst, regF src1, regF src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11523 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11524 match(Set dst (MulF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11525
a61af66fc99e Initial load
duke
parents:
diff changeset
11526 format %{ "FLD $src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11527 "FMUL $src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11528 "FSTP_S $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11529 opcode(0xD8, 0x1); /* D8 C8+i */
a61af66fc99e Initial load
duke
parents:
diff changeset
11530 ins_encode( Push_Reg_F(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11531 OpcReg_F(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11532 Pop_Reg_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11533 ins_pipe( fpu_reg_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11534 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11535
a61af66fc99e Initial load
duke
parents:
diff changeset
11536
a61af66fc99e Initial load
duke
parents:
diff changeset
11537 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11538 // Cisc-alternate to reg-reg multiply
a61af66fc99e Initial load
duke
parents:
diff changeset
11539 instruct mulF24_reg_mem(stackSlotF dst, regF src1, memory src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11540 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11541 match(Set dst (MulF src1 (LoadF src2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11542
a61af66fc99e Initial load
duke
parents:
diff changeset
11543 format %{ "FLD_S $src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11544 "FMUL $src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11545 "FSTP_S $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11546 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or DE /1*/ /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11547 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11548 OpcReg_F(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11549 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11550 ins_pipe( fpu_mem_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
11551 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11552 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11553 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11554 // Cisc-alternate to reg-reg multiply
a61af66fc99e Initial load
duke
parents:
diff changeset
11555 instruct mulF_reg_mem(regF dst, regF src1, memory src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11556 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11557 match(Set dst (MulF src1 (LoadF src2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
11558
a61af66fc99e Initial load
duke
parents:
diff changeset
11559 format %{ "FMUL $dst,$src1,$src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11560 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i */ /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11561 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11562 OpcReg_F(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11563 Pop_Reg_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11564 ins_pipe( fpu_reg_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
11565 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11566
a61af66fc99e Initial load
duke
parents:
diff changeset
11567 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11568 instruct mulF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11569 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11570 match(Set dst (MulF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11571
a61af66fc99e Initial load
duke
parents:
diff changeset
11572 format %{ "FMUL $dst,$src1,$src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11573 opcode(0xD8, 0x1, 0xD9); /* D8 /1 */ /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11574 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11575 set_instruction_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
11576 OpcP, RMopc_Mem(secondary,src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11577 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11578 ins_pipe( fpu_mem_mem_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
11579 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11580
a61af66fc99e Initial load
duke
parents:
diff changeset
11581 // Spill to obtain 24-bit precision
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11582 instruct mulF24_reg_imm(stackSlotF dst, regF src, immF con) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11583 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11584 match(Set dst (MulF src con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11585
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11586 format %{ "FLD $src\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11587 "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11588 "FSTP_S $dst" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11589 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11590 __ fld_s($src$$reg - 1); // FLD ST(i-1)
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11591 __ fmul_s($constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11592 __ fstp_s(Address(rsp, $dst$$disp));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11593 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11594 ins_pipe(fpu_mem_reg_con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11595 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11596 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11597 // This instruction does not round to 24-bits
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11598 instruct mulF_reg_imm(regF dst, regF src, immF con) %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11599 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11600 match(Set dst (MulF src con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11601
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11602 format %{ "FLD $src\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11603 "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11604 "FSTP $dst" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11605 ins_encode %{
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11606 __ fld_s($src$$reg - 1); // FLD ST(i-1)
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11607 __ fmul_s($constantaddress($con));
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11608 __ fstp_d($dst$$reg);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11609 %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
11610 ins_pipe(fpu_reg_reg_con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
11611 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11612
a61af66fc99e Initial load
duke
parents:
diff changeset
11613
a61af66fc99e Initial load
duke
parents:
diff changeset
11614 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11615 // MACRO1 -- subsume unshared load into mulF
a61af66fc99e Initial load
duke
parents:
diff changeset
11616 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11617 instruct mulF_reg_load1(regF dst, regF src, memory mem1 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11618 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11619 match(Set dst (MulF (LoadF mem1) src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11620
a61af66fc99e Initial load
duke
parents:
diff changeset
11621 format %{ "FLD $mem1 ===MACRO1===\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11622 "FMUL ST,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11623 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11624 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or D8 /1 */ /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11625 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11626 OpcReg_F(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
11627 Pop_Reg_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11628 ins_pipe( fpu_reg_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
11629 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11630 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11631 // MACRO2 -- addF a mulF which subsumed an unshared load
a61af66fc99e Initial load
duke
parents:
diff changeset
11632 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11633 instruct addF_mulF_reg_load1(regF dst, memory mem1, regF src1, regF src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11634 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11635 match(Set dst (AddF (MulF (LoadF mem1) src1) src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11636 ins_cost(95);
a61af66fc99e Initial load
duke
parents:
diff changeset
11637
a61af66fc99e Initial load
duke
parents:
diff changeset
11638 format %{ "FLD $mem1 ===MACRO2===\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11639 "FMUL ST,$src1 subsume mulF left load\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11640 "FADD ST,$src2\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11641 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11642 opcode(0xD9); /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11643 ins_encode( OpcP, RMopc_Mem(0x00,mem1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11644 FMul_ST_reg(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11645 FAdd_ST_reg(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11646 Pop_Reg_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11647 ins_pipe( fpu_reg_mem_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11648 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11649
a61af66fc99e Initial load
duke
parents:
diff changeset
11650 // MACRO3 -- addF a mulF
a61af66fc99e Initial load
duke
parents:
diff changeset
11651 // This instruction does not round to 24-bits. It is a '2-address'
a61af66fc99e Initial load
duke
parents:
diff changeset
11652 // instruction in that the result goes back to src2. This eliminates
a61af66fc99e Initial load
duke
parents:
diff changeset
11653 // a move from the macro; possibly the register allocator will have
a61af66fc99e Initial load
duke
parents:
diff changeset
11654 // to add it back (and maybe not).
a61af66fc99e Initial load
duke
parents:
diff changeset
11655 instruct addF_mulF_reg(regF src2, regF src1, regF src0) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11656 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11657 match(Set src2 (AddF (MulF src0 src1) src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11658
a61af66fc99e Initial load
duke
parents:
diff changeset
11659 format %{ "FLD $src0 ===MACRO3===\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11660 "FMUL ST,$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11661 "FADDP $src2,ST" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11662 opcode(0xD9); /* LoadF D9 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
11663 ins_encode( Push_Reg_F(src0),
a61af66fc99e Initial load
duke
parents:
diff changeset
11664 FMul_ST_reg(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11665 FAddP_reg_ST(src2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11666 ins_pipe( fpu_reg_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11667 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11668
a61af66fc99e Initial load
duke
parents:
diff changeset
11669 // MACRO4 -- divF subF
a61af66fc99e Initial load
duke
parents:
diff changeset
11670 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11671 instruct subF_divF_reg(regF dst, regF src1, regF src2, regF src3) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11672 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11673 match(Set dst (DivF (SubF src2 src1) src3));
a61af66fc99e Initial load
duke
parents:
diff changeset
11674
a61af66fc99e Initial load
duke
parents:
diff changeset
11675 format %{ "FLD $src2 ===MACRO4===\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11676 "FSUB ST,$src1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11677 "FDIV ST,$src3\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11678 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11679 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/
a61af66fc99e Initial load
duke
parents:
diff changeset
11680 ins_encode( Push_Reg_F(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11681 subF_divF_encode(src1,src3),
a61af66fc99e Initial load
duke
parents:
diff changeset
11682 Pop_Reg_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11683 ins_pipe( fpu_reg_reg_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11684 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11685
a61af66fc99e Initial load
duke
parents:
diff changeset
11686 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11687 instruct divF24_reg(stackSlotF dst, regF src1, regF src2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11688 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11689 match(Set dst (DivF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11690
a61af66fc99e Initial load
duke
parents:
diff changeset
11691 format %{ "FDIV $dst,$src1,$src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11692 opcode(0xD8, 0x6); /* D8 F0+i or DE /6*/
a61af66fc99e Initial load
duke
parents:
diff changeset
11693 ins_encode( Push_Reg_F(src1),
a61af66fc99e Initial load
duke
parents:
diff changeset
11694 OpcReg_F(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11695 Pop_Mem_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11696 ins_pipe( fpu_mem_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11697 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11698 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11699 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11700 instruct divF_reg(regF dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11701 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11702 match(Set dst (DivF dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11703
a61af66fc99e Initial load
duke
parents:
diff changeset
11704 format %{ "FDIV $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11705 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/
a61af66fc99e Initial load
duke
parents:
diff changeset
11706 ins_encode( Push_Reg_F(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
11707 OpcP, RegOpc(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11708 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11709 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11710
a61af66fc99e Initial load
duke
parents:
diff changeset
11711
a61af66fc99e Initial load
duke
parents:
diff changeset
11712 // Spill to obtain 24-bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11713 instruct modF24_reg(stackSlotF dst, regF src1, regF src2, eAXRegI rax, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11714 predicate( UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11715 match(Set dst (ModF src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
11716 effect(KILL rax, KILL cr); // emitModD() uses EAX and EFLAGS
a61af66fc99e Initial load
duke
parents:
diff changeset
11717
a61af66fc99e Initial load
duke
parents:
diff changeset
11718 format %{ "FMOD $dst,$src1,$src2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11719 ins_encode( Push_Reg_Mod_D(src1, src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11720 emitModD(),
a61af66fc99e Initial load
duke
parents:
diff changeset
11721 Push_Result_Mod_D(src2),
a61af66fc99e Initial load
duke
parents:
diff changeset
11722 Pop_Mem_F(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11723 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11724 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11725 //
a61af66fc99e Initial load
duke
parents:
diff changeset
11726 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
11727 instruct modF_reg(regF dst, regF src, eAXRegI rax, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11728 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
11729 match(Set dst (ModF dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11730 effect(KILL rax, KILL cr); // emitModD() uses EAX and EFLAGS
a61af66fc99e Initial load
duke
parents:
diff changeset
11731
a61af66fc99e Initial load
duke
parents:
diff changeset
11732 format %{ "FMOD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11733 ins_encode(Push_Reg_Mod_D(dst, src),
a61af66fc99e Initial load
duke
parents:
diff changeset
11734 emitModD(),
a61af66fc99e Initial load
duke
parents:
diff changeset
11735 Push_Result_Mod_D(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
11736 Pop_Reg_F(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11737 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11738 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11739
a61af66fc99e Initial load
duke
parents:
diff changeset
11740 instruct modX_reg(regX dst, regX src0, regX src1, eAXRegI rax, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11741 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11742 match(Set dst (ModF src0 src1));
a61af66fc99e Initial load
duke
parents:
diff changeset
11743 effect(KILL rax, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
11744 format %{ "SUB ESP,4\t # FMOD\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11745 "\tMOVSS [ESP+0],$src1\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11746 "\tFLD_S [ESP+0]\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11747 "\tMOVSS [ESP+0],$src0\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11748 "\tFLD_S [ESP+0]\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11749 "loop:\tFPREM\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11750 "\tFWAIT\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11751 "\tFNSTSW AX\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11752 "\tSAHF\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11753 "\tJP loop\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11754 "\tFSTP_S [ESP+0]\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11755 "\tMOVSS $dst,[ESP+0]\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11756 "\tADD ESP,4\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11757 "\tFSTP ST0\t # Restore FPU Stack"
a61af66fc99e Initial load
duke
parents:
diff changeset
11758 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11759 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
11760 ins_encode( Push_ModX_encoding(src0, src1), emitModD(), Push_ResultX(dst,0x4), PopFPU);
a61af66fc99e Initial load
duke
parents:
diff changeset
11761 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11762 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11763
a61af66fc99e Initial load
duke
parents:
diff changeset
11764
a61af66fc99e Initial load
duke
parents:
diff changeset
11765 //----------Arithmetic Conversion Instructions---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
11766 // The conversions operations are all Alpha sorted. Please keep it that way!
a61af66fc99e Initial load
duke
parents:
diff changeset
11767
a61af66fc99e Initial load
duke
parents:
diff changeset
11768 instruct roundFloat_mem_reg(stackSlotF dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11769 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11770 match(Set dst (RoundFloat src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11771 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
11772 format %{ "FST_S $dst,$src\t# F-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11773 ins_encode( Pop_Mem_Reg_F(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11774 ins_pipe( fpu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11775 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11776
a61af66fc99e Initial load
duke
parents:
diff changeset
11777 instruct roundDouble_mem_reg(stackSlotD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11778 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11779 match(Set dst (RoundDouble src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11780 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
11781 format %{ "FST_D $dst,$src\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11782 ins_encode( Pop_Mem_Reg_D(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11783 ins_pipe( fpu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11784 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11785
a61af66fc99e Initial load
duke
parents:
diff changeset
11786 // Force rounding to 24-bit precision and 6-bit exponent
a61af66fc99e Initial load
duke
parents:
diff changeset
11787 instruct convD2F_reg(stackSlotF dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11788 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11789 match(Set dst (ConvD2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11790 format %{ "FST_S $dst,$src\t# F-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11791 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11792 roundFloat_mem_reg(dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
11793 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11794 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11795
a61af66fc99e Initial load
duke
parents:
diff changeset
11796 // Force rounding to 24-bit precision and 6-bit exponent
a61af66fc99e Initial load
duke
parents:
diff changeset
11797 instruct convD2X_reg(regX dst, regD src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11798 predicate(UseSSE==1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11799 match(Set dst (ConvD2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11800 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
11801 format %{ "SUB ESP,4\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11802 "FST_S [ESP],$src\t# F-round\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11803 "MOVSS $dst,[ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11804 "ADD ESP,4" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11805 ins_encode( D2X_encoding(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11806 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11807 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11808
a61af66fc99e Initial load
duke
parents:
diff changeset
11809 // Force rounding double precision to single precision
a61af66fc99e Initial load
duke
parents:
diff changeset
11810 instruct convXD2X_reg(regX dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11811 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
11812 match(Set dst (ConvD2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11813 format %{ "CVTSD2SS $dst,$src\t# F-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11814 opcode(0xF2, 0x0F, 0x5A);
a61af66fc99e Initial load
duke
parents:
diff changeset
11815 ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11816 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11817 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11818
a61af66fc99e Initial load
duke
parents:
diff changeset
11819 instruct convF2D_reg_reg(regD dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11820 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11821 match(Set dst (ConvF2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11822 format %{ "FST_S $dst,$src\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11823 ins_encode( Pop_Reg_Reg_D(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11824 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
11825 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11826
a61af66fc99e Initial load
duke
parents:
diff changeset
11827 instruct convF2D_reg(stackSlotD dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11828 predicate(UseSSE==1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11829 match(Set dst (ConvF2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11830 format %{ "FST_D $dst,$src\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11831 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11832 roundDouble_mem_reg(dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
11833 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11834 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11835
a61af66fc99e Initial load
duke
parents:
diff changeset
11836 instruct convX2D_reg(regD dst, regX src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11837 predicate(UseSSE==1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11838 match(Set dst (ConvF2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11839 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
11840 format %{ "SUB ESP,4\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11841 "MOVSS [ESP] $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11842 "FLD_S [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11843 "ADD ESP,4\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11844 "FSTP $dst\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11845 ins_encode( X2D_encoding(dst, src), Pop_Reg_D(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11846 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11847 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11848
a61af66fc99e Initial load
duke
parents:
diff changeset
11849 instruct convX2XD_reg(regXD dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11850 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
11851 match(Set dst (ConvF2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11852 format %{ "CVTSS2SD $dst,$src\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11853 opcode(0xF3, 0x0F, 0x5A);
a61af66fc99e Initial load
duke
parents:
diff changeset
11854 ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11855 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11856 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11857
a61af66fc99e Initial load
duke
parents:
diff changeset
11858 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
11859 instruct convD2I_reg_reg( eAXRegI dst, eDXRegI tmp, regD src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11860 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11861 match(Set dst (ConvD2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11862 effect( KILL tmp, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
11863 format %{ "FLD $src\t# Convert double to int \n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11864 "FLDCW trunc mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11865 "SUB ESP,4\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11866 "FISTp [ESP + #0]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11867 "FLDCW std/24-bit mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11868 "POP EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11869 "CMP EAX,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11870 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11871 "FLD_D $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11872 "CALL d2i_wrapper\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11873 "fast:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11874 ins_encode( Push_Reg_D(src), D2I_encoding(src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11875 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11876 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11877
a61af66fc99e Initial load
duke
parents:
diff changeset
11878 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
11879 instruct convXD2I_reg_reg( eAXRegI dst, eDXRegI tmp, regXD src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11880 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
11881 match(Set dst (ConvD2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11882 effect( KILL tmp, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
11883 format %{ "CVTTSD2SI $dst, $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11884 "CMP $dst,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11885 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11886 "SUB ESP, 8\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11887 "MOVSD [ESP], $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11888 "FLD_D [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11889 "ADD ESP, 8\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11890 "CALL d2i_wrapper\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11891 "fast:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11892 opcode(0x1); // double-precision conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
11893 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x2C), FX2I_encoding(src,dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11894 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11895 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11896
a61af66fc99e Initial load
duke
parents:
diff changeset
11897 instruct convD2L_reg_reg( eADXRegL dst, regD src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11898 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11899 match(Set dst (ConvD2L src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11900 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
11901 format %{ "FLD $src\t# Convert double to long\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11902 "FLDCW trunc mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11903 "SUB ESP,8\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11904 "FISTp [ESP + #0]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11905 "FLDCW std/24-bit mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11906 "POP EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11907 "POP EDX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11908 "CMP EDX,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11909 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11910 "TEST EAX,EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11911 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11912 "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11913 "CALL d2l_wrapper\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11914 "fast:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11915 ins_encode( Push_Reg_D(src), D2L_encoding(src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11916 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11917 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11918
a61af66fc99e Initial load
duke
parents:
diff changeset
11919 // XMM lacks a float/double->long conversion, so use the old FPU stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
11920 instruct convXD2L_reg_reg( eADXRegL dst, regXD src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11921 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
11922 match(Set dst (ConvD2L src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11923 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
11924 format %{ "SUB ESP,8\t# Convert double to long\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11925 "MOVSD [ESP],$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11926 "FLD_D [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11927 "FLDCW trunc mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11928 "FISTp [ESP + #0]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11929 "FLDCW std/24-bit mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11930 "POP EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11931 "POP EDX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11932 "CMP EDX,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11933 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11934 "TEST EAX,EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11935 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11936 "SUB ESP,8\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11937 "MOVSD [ESP],$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11938 "FLD_D [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11939 "CALL d2l_wrapper\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11940 "fast:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11941 ins_encode( XD2L_encoding(src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11942 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11943 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11944
a61af66fc99e Initial load
duke
parents:
diff changeset
11945 // Convert a double to an int. Java semantics require we do complex
a61af66fc99e Initial load
duke
parents:
diff changeset
11946 // manglations in the corner cases. So we set the rounding mode to
a61af66fc99e Initial load
duke
parents:
diff changeset
11947 // 'zero', store the darned double down as an int, and reset the
a61af66fc99e Initial load
duke
parents:
diff changeset
11948 // rounding mode to 'nearest'. The hardware stores a flag value down
a61af66fc99e Initial load
duke
parents:
diff changeset
11949 // if we would overflow or converted a NAN; we check for this and
a61af66fc99e Initial load
duke
parents:
diff changeset
11950 // and go the slow path if needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
11951 instruct convF2I_reg_reg(eAXRegI dst, eDXRegI tmp, regF src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11952 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11953 match(Set dst (ConvF2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11954 effect( KILL tmp, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
11955 format %{ "FLD $src\t# Convert float to int \n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11956 "FLDCW trunc mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11957 "SUB ESP,4\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11958 "FISTp [ESP + #0]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11959 "FLDCW std/24-bit mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11960 "POP EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11961 "CMP EAX,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11962 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11963 "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11964 "CALL d2i_wrapper\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11965 "fast:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11966 // D2I_encoding works for F2I
a61af66fc99e Initial load
duke
parents:
diff changeset
11967 ins_encode( Push_Reg_F(src), D2I_encoding(src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
11968 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11969 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11970
a61af66fc99e Initial load
duke
parents:
diff changeset
11971 // Convert a float in xmm to an int reg.
a61af66fc99e Initial load
duke
parents:
diff changeset
11972 instruct convX2I_reg(eAXRegI dst, eDXRegI tmp, regX src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11973 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
11974 match(Set dst (ConvF2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11975 effect( KILL tmp, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
11976 format %{ "CVTTSS2SI $dst, $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11977 "CMP $dst,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11978 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11979 "SUB ESP, 4\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11980 "MOVSS [ESP], $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11981 "FLD [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11982 "ADD ESP, 4\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11983 "CALL d2i_wrapper\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
11984 "fast:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11985 opcode(0x0); // single-precision conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
11986 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x2C), FX2I_encoding(src,dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
11987 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
11988 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
11989
a61af66fc99e Initial load
duke
parents:
diff changeset
11990 instruct convF2L_reg_reg( eADXRegL dst, regF src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
11991 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
11992 match(Set dst (ConvF2L src));
a61af66fc99e Initial load
duke
parents:
diff changeset
11993 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
11994 format %{ "FLD $src\t# Convert float to long\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11995 "FLDCW trunc mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11996 "SUB ESP,8\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11997 "FISTp [ESP + #0]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11998 "FLDCW std/24-bit mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
11999 "POP EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12000 "POP EDX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12001 "CMP EDX,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12002 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12003 "TEST EAX,EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12004 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12005 "FLD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12006 "CALL d2l_wrapper\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
12007 "fast:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12008 // D2L_encoding works for F2L
a61af66fc99e Initial load
duke
parents:
diff changeset
12009 ins_encode( Push_Reg_F(src), D2L_encoding(src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12010 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12011 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12012
a61af66fc99e Initial load
duke
parents:
diff changeset
12013 // XMM lacks a float/double->long conversion, so use the old FPU stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
12014 instruct convX2L_reg_reg( eADXRegL dst, regX src, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12015 predicate (UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
12016 match(Set dst (ConvF2L src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12017 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
12018 format %{ "SUB ESP,8\t# Convert float to long\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12019 "MOVSS [ESP],$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12020 "FLD_S [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12021 "FLDCW trunc mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12022 "FISTp [ESP + #0]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12023 "FLDCW std/24-bit mode\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12024 "POP EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12025 "POP EDX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12026 "CMP EDX,0x80000000\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12027 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12028 "TEST EAX,EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12029 "JNE,s fast\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12030 "SUB ESP,4\t# Convert float to long\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12031 "MOVSS [ESP],$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12032 "FLD_S [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12033 "ADD ESP,4\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12034 "CALL d2l_wrapper\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
12035 "fast:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12036 ins_encode( X2L_encoding(src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12037 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12038 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12039
a61af66fc99e Initial load
duke
parents:
diff changeset
12040 instruct convI2D_reg(regD dst, stackSlotI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12041 predicate( UseSSE<=1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
12042 match(Set dst (ConvI2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12043 format %{ "FILD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12044 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12045 opcode(0xDB, 0x0); /* DB /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12046 ins_encode(Push_Mem_I(src), Pop_Reg_D(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12047 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12048 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12049
a61af66fc99e Initial load
duke
parents:
diff changeset
12050 instruct convI2XD_reg(regXD dst, eRegI src) %{
71
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12051 predicate( UseSSE>=2 && !UseXmmI2D );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12052 match(Set dst (ConvI2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12053 format %{ "CVTSI2SD $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12054 opcode(0xF2, 0x0F, 0x2A);
a61af66fc99e Initial load
duke
parents:
diff changeset
12055 ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12056 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12057 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12058
a61af66fc99e Initial load
duke
parents:
diff changeset
12059 instruct convI2XD_mem(regXD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12060 predicate( UseSSE>=2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
12061 match(Set dst (ConvI2D (LoadI mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
12062 format %{ "CVTSI2SD $dst,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12063 opcode(0xF2, 0x0F, 0x2A);
a61af66fc99e Initial load
duke
parents:
diff changeset
12064 ins_encode( OpcP, OpcS, Opcode(tertiary), RegMem(dst, mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
12065 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12066 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12067
71
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12068 instruct convXI2XD_reg(regXD dst, eRegI src)
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12069 %{
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12070 predicate( UseSSE>=2 && UseXmmI2D );
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12071 match(Set dst (ConvI2D src));
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12072
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12073 format %{ "MOVD $dst,$src\n\t"
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12074 "CVTDQ2PD $dst,$dst\t# i2d" %}
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12075 ins_encode %{
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
12076 __ movdl($dst$$XMMRegister, $src$$Register);
71
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12077 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12078 %}
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12079 ins_pipe(pipe_slow); // XXX
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12080 %}
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12081
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12082 instruct convI2D_mem(regD dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12083 predicate( UseSSE<=1 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
12084 match(Set dst (ConvI2D (LoadI mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
12085 format %{ "FILD $mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12086 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12087 opcode(0xDB); /* DB /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12088 ins_encode( OpcP, RMopc_Mem(0x00,mem),
a61af66fc99e Initial load
duke
parents:
diff changeset
12089 Pop_Reg_D(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12090 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12091 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12092
a61af66fc99e Initial load
duke
parents:
diff changeset
12093 // Convert a byte to a float; no rounding step needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
12094 instruct conv24I2F_reg(regF dst, stackSlotI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12095 predicate( UseSSE==0 && n->in(1)->Opcode() == Op_AndI && n->in(1)->in(2)->is_Con() && n->in(1)->in(2)->get_int() == 255 );
a61af66fc99e Initial load
duke
parents:
diff changeset
12096 match(Set dst (ConvI2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12097 format %{ "FILD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12098 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12099
a61af66fc99e Initial load
duke
parents:
diff changeset
12100 opcode(0xDB, 0x0); /* DB /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12101 ins_encode(Push_Mem_I(src), Pop_Reg_F(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12102 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12103 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12104
a61af66fc99e Initial load
duke
parents:
diff changeset
12105 // In 24-bit mode, force exponent rounding by storing back out
a61af66fc99e Initial load
duke
parents:
diff changeset
12106 instruct convI2F_SSF(stackSlotF dst, stackSlotI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12107 predicate( UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
12108 match(Set dst (ConvI2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12109 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
12110 format %{ "FILD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12111 "FSTP_S $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12112 opcode(0xDB, 0x0); /* DB /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12113 ins_encode( Push_Mem_I(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
12114 Pop_Mem_F(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12115 ins_pipe( fpu_mem_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12116 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12117
a61af66fc99e Initial load
duke
parents:
diff changeset
12118 // In 24-bit mode, force exponent rounding by storing back out
a61af66fc99e Initial load
duke
parents:
diff changeset
12119 instruct convI2F_SSF_mem(stackSlotF dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12120 predicate( UseSSE==0 && Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
12121 match(Set dst (ConvI2F (LoadI mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
12122 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
12123 format %{ "FILD $mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12124 "FSTP_S $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12125 opcode(0xDB); /* DB /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12126 ins_encode( OpcP, RMopc_Mem(0x00,mem),
a61af66fc99e Initial load
duke
parents:
diff changeset
12127 Pop_Mem_F(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12128 ins_pipe( fpu_mem_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12129 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12130
a61af66fc99e Initial load
duke
parents:
diff changeset
12131 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
12132 instruct convI2F_reg(regF dst, stackSlotI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12133 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
12134 match(Set dst (ConvI2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12135 format %{ "FILD $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12136 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12137 opcode(0xDB, 0x0); /* DB /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12138 ins_encode( Push_Mem_I(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
12139 Pop_Reg_F(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12140 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12141 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12142
a61af66fc99e Initial load
duke
parents:
diff changeset
12143 // This instruction does not round to 24-bits
a61af66fc99e Initial load
duke
parents:
diff changeset
12144 instruct convI2F_mem(regF dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12145 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr());
a61af66fc99e Initial load
duke
parents:
diff changeset
12146 match(Set dst (ConvI2F (LoadI mem)));
a61af66fc99e Initial load
duke
parents:
diff changeset
12147 format %{ "FILD $mem\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12148 "FSTP $dst" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12149 opcode(0xDB); /* DB /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12150 ins_encode( OpcP, RMopc_Mem(0x00,mem),
a61af66fc99e Initial load
duke
parents:
diff changeset
12151 Pop_Reg_F(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12152 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12153 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12154
a61af66fc99e Initial load
duke
parents:
diff changeset
12155 // Convert an int to a float in xmm; no rounding step needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
12156 instruct convI2X_reg(regX dst, eRegI src) %{
71
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12157 predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12158 match(Set dst (ConvI2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12159 format %{ "CVTSI2SS $dst, $src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12160
a61af66fc99e Initial load
duke
parents:
diff changeset
12161 opcode(0xF3, 0x0F, 0x2A); /* F3 0F 2A /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12162 ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12163 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12164 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12165
71
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12166 instruct convXI2X_reg(regX dst, eRegI src)
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12167 %{
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12168 predicate( UseSSE>=2 && UseXmmI2F );
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12169 match(Set dst (ConvI2F src));
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12170
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12171 format %{ "MOVD $dst,$src\n\t"
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12172 "CVTDQ2PS $dst,$dst\t# i2f" %}
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12173 ins_encode %{
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
12174 __ movdl($dst$$XMMRegister, $src$$Register);
71
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12175 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12176 %}
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12177 ins_pipe(pipe_slow); // XXX
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12178 %}
3d62cb85208d 6662967: Optimize I2D conversion on new x86
kvn
parents: 0
diff changeset
12179
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12180 instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12181 match(Set dst (ConvI2L src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12182 effect(KILL cr);
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
12183 ins_cost(375);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12184 format %{ "MOV $dst.lo,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12185 "MOV $dst.hi,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12186 "SAR $dst.hi,31" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12187 ins_encode(convert_int_long(dst,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12188 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
12189 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12190
a61af66fc99e Initial load
duke
parents:
diff changeset
12191 // Zero-extend convert int to long
a61af66fc99e Initial load
duke
parents:
diff changeset
12192 instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12193 match(Set dst (AndL (ConvI2L src) mask) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12194 effect( KILL flags );
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
12195 ins_cost(250);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12196 format %{ "MOV $dst.lo,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12197 "XOR $dst.hi,$dst.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12198 opcode(0x33); // XOR
a61af66fc99e Initial load
duke
parents:
diff changeset
12199 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12200 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
12201 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12202
a61af66fc99e Initial load
duke
parents:
diff changeset
12203 // Zero-extend long
a61af66fc99e Initial load
duke
parents:
diff changeset
12204 instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12205 match(Set dst (AndL src mask) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12206 effect( KILL flags );
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 622
diff changeset
12207 ins_cost(250);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12208 format %{ "MOV $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12209 "XOR $dst.hi,$dst.hi\n\t" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12210 opcode(0x33); // XOR
a61af66fc99e Initial load
duke
parents:
diff changeset
12211 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12212 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
12213 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12214
a61af66fc99e Initial load
duke
parents:
diff changeset
12215 instruct convL2D_reg( stackSlotD dst, eRegL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12216 predicate (UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
12217 match(Set dst (ConvL2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12218 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
12219 format %{ "PUSH $src.hi\t# Convert long to double\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12220 "PUSH $src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12221 "FILD ST,[ESP + #0]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12222 "ADD ESP,8\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12223 "FSTP_D $dst\t# D-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12224 opcode(0xDF, 0x5); /* DF /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12225 ins_encode(convert_long_double(src), Pop_Mem_D(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12226 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12227 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12228
a61af66fc99e Initial load
duke
parents:
diff changeset
12229 instruct convL2XD_reg( regXD dst, eRegL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12230 predicate (UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12231 match(Set dst (ConvL2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12232 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
12233 format %{ "PUSH $src.hi\t# Convert long to double\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12234 "PUSH $src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12235 "FILD_D [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12236 "FSTP_D [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12237 "MOVSD $dst,[ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12238 "ADD ESP,8" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12239 opcode(0xDF, 0x5); /* DF /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12240 ins_encode(convert_long_double2(src), Push_ResultXD(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12241 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12242 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12243
a61af66fc99e Initial load
duke
parents:
diff changeset
12244 instruct convL2X_reg( regX dst, eRegL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12245 predicate (UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
12246 match(Set dst (ConvL2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12247 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
12248 format %{ "PUSH $src.hi\t# Convert long to single float\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12249 "PUSH $src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12250 "FILD_D [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12251 "FSTP_S [ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12252 "MOVSS $dst,[ESP]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12253 "ADD ESP,8" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12254 opcode(0xDF, 0x5); /* DF /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12255 ins_encode(convert_long_double2(src), Push_ResultX(dst,0x8));
a61af66fc99e Initial load
duke
parents:
diff changeset
12256 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12257 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12258
a61af66fc99e Initial load
duke
parents:
diff changeset
12259 instruct convL2F_reg( stackSlotF dst, eRegL src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12260 match(Set dst (ConvL2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12261 effect( KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
12262 format %{ "PUSH $src.hi\t# Convert long to single float\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12263 "PUSH $src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12264 "FILD ST,[ESP + #0]\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12265 "ADD ESP,8\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12266 "FSTP_S $dst\t# F-round" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12267 opcode(0xDF, 0x5); /* DF /5 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12268 ins_encode(convert_long_double(src), Pop_Mem_F(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12269 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12270 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12271
a61af66fc99e Initial load
duke
parents:
diff changeset
12272 instruct convL2I_reg( eRegI dst, eRegL src ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12273 match(Set dst (ConvL2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12274 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
12275 format %{ "MOV $dst,$src.lo" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12276 ins_encode(enc_CopyL_Lo(dst,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12277 ins_pipe( ialu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12278 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12279
a61af66fc99e Initial load
duke
parents:
diff changeset
12280
a61af66fc99e Initial load
duke
parents:
diff changeset
12281 instruct MoveF2I_stack_reg(eRegI dst, stackSlotF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12282 match(Set dst (MoveF2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12283 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
12284 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
12285 format %{ "MOV $dst,$src\t# MoveF2I_stack_reg" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12286 opcode(0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
12287 ins_encode( OpcP, RegMem(dst,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12288 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12289 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12290
a61af66fc99e Initial load
duke
parents:
diff changeset
12291 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12292 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
12293 match(Set dst (MoveF2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12294 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
12295
a61af66fc99e Initial load
duke
parents:
diff changeset
12296 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
12297 format %{ "FST_S $dst,$src\t# MoveF2I_reg_stack" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12298 ins_encode( Pop_Mem_Reg_F(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12299 ins_pipe( fpu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12300 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12301
a61af66fc99e Initial load
duke
parents:
diff changeset
12302 instruct MoveF2I_reg_stack_sse(stackSlotI dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12303 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
12304 match(Set dst (MoveF2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12305 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
12306
a61af66fc99e Initial load
duke
parents:
diff changeset
12307 ins_cost(95);
a61af66fc99e Initial load
duke
parents:
diff changeset
12308 format %{ "MOVSS $dst,$src\t# MoveF2I_reg_stack_sse" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12309 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x11), RegMem(src, dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12310 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12311 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12312
a61af66fc99e Initial load
duke
parents:
diff changeset
12313 instruct MoveF2I_reg_reg_sse(eRegI dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12314 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12315 match(Set dst (MoveF2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12316 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
12317 ins_cost(85);
a61af66fc99e Initial load
duke
parents:
diff changeset
12318 format %{ "MOVD $dst,$src\t# MoveF2I_reg_reg_sse" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12319 ins_encode( MovX2I_reg(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12320 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12321 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12322
a61af66fc99e Initial load
duke
parents:
diff changeset
12323 instruct MoveI2F_reg_stack(stackSlotF dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12324 match(Set dst (MoveI2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12325 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
12326
a61af66fc99e Initial load
duke
parents:
diff changeset
12327 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
12328 format %{ "MOV $dst,$src\t# MoveI2F_reg_stack" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12329 opcode(0x89);
a61af66fc99e Initial load
duke
parents:
diff changeset
12330 ins_encode( OpcPRegSS( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12331 ins_pipe( ialu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12332 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12333
a61af66fc99e Initial load
duke
parents:
diff changeset
12334
a61af66fc99e Initial load
duke
parents:
diff changeset
12335 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12336 predicate(UseSSE==0);
a61af66fc99e Initial load
duke
parents:
diff changeset
12337 match(Set dst (MoveI2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12338 effect(DEF dst, USE src);
a61af66fc99e Initial load
duke
parents:
diff changeset
12339
a61af66fc99e Initial load
duke
parents:
diff changeset
12340 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
12341 format %{ "FLD_S $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12342 "FSTP $dst\t# MoveI2F_stack_reg" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12343 opcode(0xD9); /* D9 /0, FLD m32real */
a61af66fc99e Initial load
duke
parents:
diff changeset
12344 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
a61af66fc99e Initial load
duke
parents:
diff changeset
12345 Pop_Reg_F(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12346 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12347 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12348
a61af66fc99e Initial load
duke
parents:
diff changeset
12349 instruct MoveI2F_stack_reg_sse(regX dst, stackSlotI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12350 predicate(UseSSE>=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
12351 match(Set dst (MoveI2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12352 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
12353
a61af66fc99e Initial load
duke
parents:
diff changeset
12354 ins_cost(95);
a61af66fc99e Initial load
duke
parents:
diff changeset
12355 format %{ "MOVSS $dst,$src\t# MoveI2F_stack_reg_sse" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12356 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), RegMem(dst,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12357 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12358 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12359
a61af66fc99e Initial load
duke
parents:
diff changeset
12360 instruct MoveI2F_reg_reg_sse(regX dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12361 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12362 match(Set dst (MoveI2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12363 effect( DEF dst, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
12364
a61af66fc99e Initial load
duke
parents:
diff changeset
12365 ins_cost(85);
a61af66fc99e Initial load
duke
parents:
diff changeset
12366 format %{ "MOVD $dst,$src\t# MoveI2F_reg_reg_sse" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12367 ins_encode( MovI2X_reg(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12368 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12369 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12370
a61af66fc99e Initial load
duke
parents:
diff changeset
12371 instruct MoveD2L_stack_reg(eRegL dst, stackSlotD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12372 match(Set dst (MoveD2L src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12373 effect(DEF dst, USE src);
a61af66fc99e Initial load
duke
parents:
diff changeset
12374
a61af66fc99e Initial load
duke
parents:
diff changeset
12375 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
12376 format %{ "MOV $dst.lo,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12377 "MOV $dst.hi,$src+4\t# MoveD2L_stack_reg" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12378 opcode(0x8B, 0x8B);
a61af66fc99e Initial load
duke
parents:
diff changeset
12379 ins_encode( OpcP, RegMem(dst,src), OpcS, RegMem_Hi(dst,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12380 ins_pipe( ialu_mem_long_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12381 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12382
a61af66fc99e Initial load
duke
parents:
diff changeset
12383 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12384 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
12385 match(Set dst (MoveD2L src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12386 effect(DEF dst, USE src);
a61af66fc99e Initial load
duke
parents:
diff changeset
12387
a61af66fc99e Initial load
duke
parents:
diff changeset
12388 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
12389 format %{ "FST_D $dst,$src\t# MoveD2L_reg_stack" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12390 ins_encode( Pop_Mem_Reg_D(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12391 ins_pipe( fpu_mem_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12392 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12393
a61af66fc99e Initial load
duke
parents:
diff changeset
12394 instruct MoveD2L_reg_stack_sse(stackSlotL dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12395 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12396 match(Set dst (MoveD2L src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12397 effect(DEF dst, USE src);
a61af66fc99e Initial load
duke
parents:
diff changeset
12398 ins_cost(95);
a61af66fc99e Initial load
duke
parents:
diff changeset
12399
a61af66fc99e Initial load
duke
parents:
diff changeset
12400 format %{ "MOVSD $dst,$src\t# MoveD2L_reg_stack_sse" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12401 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x11), RegMem(src,dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12402 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12403 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12404
a61af66fc99e Initial load
duke
parents:
diff changeset
12405 instruct MoveD2L_reg_reg_sse(eRegL dst, regXD src, regXD tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12406 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12407 match(Set dst (MoveD2L src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12408 effect(DEF dst, USE src, TEMP tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
12409 ins_cost(85);
a61af66fc99e Initial load
duke
parents:
diff changeset
12410 format %{ "MOVD $dst.lo,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12411 "PSHUFLW $tmp,$src,0x4E\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12412 "MOVD $dst.hi,$tmp\t# MoveD2L_reg_reg_sse" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12413 ins_encode( MovXD2L_reg(dst, src, tmp) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12414 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12415 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12416
a61af66fc99e Initial load
duke
parents:
diff changeset
12417 instruct MoveL2D_reg_stack(stackSlotD dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12418 match(Set dst (MoveL2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12419 effect(DEF dst, USE src);
a61af66fc99e Initial load
duke
parents:
diff changeset
12420
a61af66fc99e Initial load
duke
parents:
diff changeset
12421 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
12422 format %{ "MOV $dst,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12423 "MOV $dst+4,$src.hi\t# MoveL2D_reg_stack" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12424 opcode(0x89, 0x89);
a61af66fc99e Initial load
duke
parents:
diff changeset
12425 ins_encode( OpcP, RegMem( src, dst ), OpcS, RegMem_Hi( src, dst ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12426 ins_pipe( ialu_mem_long_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12427 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12428
a61af66fc99e Initial load
duke
parents:
diff changeset
12429
a61af66fc99e Initial load
duke
parents:
diff changeset
12430 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12431 predicate(UseSSE<=1);
a61af66fc99e Initial load
duke
parents:
diff changeset
12432 match(Set dst (MoveL2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12433 effect(DEF dst, USE src);
a61af66fc99e Initial load
duke
parents:
diff changeset
12434 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
12435
a61af66fc99e Initial load
duke
parents:
diff changeset
12436 format %{ "FLD_D $src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12437 "FSTP $dst\t# MoveL2D_stack_reg" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12438 opcode(0xDD); /* DD /0, FLD m64real */
a61af66fc99e Initial load
duke
parents:
diff changeset
12439 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
a61af66fc99e Initial load
duke
parents:
diff changeset
12440 Pop_Reg_D(dst) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12441 ins_pipe( fpu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12442 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12443
a61af66fc99e Initial load
duke
parents:
diff changeset
12444
a61af66fc99e Initial load
duke
parents:
diff changeset
12445 instruct MoveL2D_stack_reg_sse(regXD dst, stackSlotL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12446 predicate(UseSSE>=2 && UseXmmLoadAndClearUpper);
a61af66fc99e Initial load
duke
parents:
diff changeset
12447 match(Set dst (MoveL2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12448 effect(DEF dst, USE src);
a61af66fc99e Initial load
duke
parents:
diff changeset
12449
a61af66fc99e Initial load
duke
parents:
diff changeset
12450 ins_cost(95);
a61af66fc99e Initial load
duke
parents:
diff changeset
12451 format %{ "MOVSD $dst,$src\t# MoveL2D_stack_reg_sse" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12452 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x10), RegMem(dst,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12453 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12454 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12455
a61af66fc99e Initial load
duke
parents:
diff changeset
12456 instruct MoveL2D_stack_reg_sse_partial(regXD dst, stackSlotL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12457 predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper);
a61af66fc99e Initial load
duke
parents:
diff changeset
12458 match(Set dst (MoveL2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12459 effect(DEF dst, USE src);
a61af66fc99e Initial load
duke
parents:
diff changeset
12460
a61af66fc99e Initial load
duke
parents:
diff changeset
12461 ins_cost(95);
a61af66fc99e Initial load
duke
parents:
diff changeset
12462 format %{ "MOVLPD $dst,$src\t# MoveL2D_stack_reg_sse" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12463 ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x12), RegMem(dst,src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12464 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12465 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12466
a61af66fc99e Initial load
duke
parents:
diff changeset
12467 instruct MoveL2D_reg_reg_sse(regXD dst, eRegL src, regXD tmp) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12468 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12469 match(Set dst (MoveL2D src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12470 effect(TEMP dst, USE src, TEMP tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
12471 ins_cost(85);
a61af66fc99e Initial load
duke
parents:
diff changeset
12472 format %{ "MOVD $dst,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12473 "MOVD $tmp,$src.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12474 "PUNPCKLDQ $dst,$tmp\t# MoveL2D_reg_reg_sse" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12475 ins_encode( MovL2XD_reg(dst, src, tmp) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12476 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12477 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12478
a61af66fc99e Initial load
duke
parents:
diff changeset
12479 // Replicate scalar to packed byte (1 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12480 instruct Repl8B_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12481 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12482 match(Set dst (Replicate8B src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12483 format %{ "MOVDQA $dst,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12484 "PUNPCKLBW $dst,$dst\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12485 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12486 ins_encode( pshufd_8x8(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12487 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12488 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12489
a61af66fc99e Initial load
duke
parents:
diff changeset
12490 // Replicate scalar to packed byte (1 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12491 instruct Repl8B_eRegI(regXD dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12492 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12493 match(Set dst (Replicate8B src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12494 format %{ "MOVD $dst,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12495 "PUNPCKLBW $dst,$dst\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12496 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12497 ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12498 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12499 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12500
a61af66fc99e Initial load
duke
parents:
diff changeset
12501 // Replicate scalar zero to packed byte (1 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12502 instruct Repl8B_immI0(regXD dst, immI0 zero) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12503 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12504 match(Set dst (Replicate8B zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12505 format %{ "PXOR $dst,$dst\t! replicate8B" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12506 ins_encode( pxor(dst, dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12507 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12508 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12509
a61af66fc99e Initial load
duke
parents:
diff changeset
12510 // Replicate scalar to packed shore (2 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12511 instruct Repl4S_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12512 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12513 match(Set dst (Replicate4S src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12514 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12515 ins_encode( pshufd_4x16(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12516 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12517 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12518
a61af66fc99e Initial load
duke
parents:
diff changeset
12519 // Replicate scalar to packed shore (2 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12520 instruct Repl4S_eRegI(regXD dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12521 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12522 match(Set dst (Replicate4S src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12523 format %{ "MOVD $dst,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12524 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12525 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12526 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12527 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12528
a61af66fc99e Initial load
duke
parents:
diff changeset
12529 // Replicate scalar zero to packed short (2 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12530 instruct Repl4S_immI0(regXD dst, immI0 zero) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12531 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12532 match(Set dst (Replicate4S zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12533 format %{ "PXOR $dst,$dst\t! replicate4S" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12534 ins_encode( pxor(dst, dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12535 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12536 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12537
a61af66fc99e Initial load
duke
parents:
diff changeset
12538 // Replicate scalar to packed char (2 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12539 instruct Repl4C_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12540 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12541 match(Set dst (Replicate4C src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12542 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12543 ins_encode( pshufd_4x16(dst, src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12544 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12545 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12546
a61af66fc99e Initial load
duke
parents:
diff changeset
12547 // Replicate scalar to packed char (2 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12548 instruct Repl4C_eRegI(regXD dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12549 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12550 match(Set dst (Replicate4C src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12551 format %{ "MOVD $dst,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12552 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12553 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12554 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12555 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12556
a61af66fc99e Initial load
duke
parents:
diff changeset
12557 // Replicate scalar zero to packed char (2 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12558 instruct Repl4C_immI0(regXD dst, immI0 zero) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12559 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12560 match(Set dst (Replicate4C zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12561 format %{ "PXOR $dst,$dst\t! replicate4C" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12562 ins_encode( pxor(dst, dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12563 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12564 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12565
a61af66fc99e Initial load
duke
parents:
diff changeset
12566 // Replicate scalar to packed integer (4 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12567 instruct Repl2I_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12568 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12569 match(Set dst (Replicate2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12570 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12571 ins_encode( pshufd(dst, src, 0x00));
a61af66fc99e Initial load
duke
parents:
diff changeset
12572 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12573 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12574
a61af66fc99e Initial load
duke
parents:
diff changeset
12575 // Replicate scalar to packed integer (4 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12576 instruct Repl2I_eRegI(regXD dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12577 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12578 match(Set dst (Replicate2I src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12579 format %{ "MOVD $dst,$src\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12580 "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12581 ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00));
a61af66fc99e Initial load
duke
parents:
diff changeset
12582 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12583 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12584
a61af66fc99e Initial load
duke
parents:
diff changeset
12585 // Replicate scalar zero to packed integer (2 byte) values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12586 instruct Repl2I_immI0(regXD dst, immI0 zero) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12587 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12588 match(Set dst (Replicate2I zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12589 format %{ "PXOR $dst,$dst\t! replicate2I" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12590 ins_encode( pxor(dst, dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12591 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12592 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12593
a61af66fc99e Initial load
duke
parents:
diff changeset
12594 // Replicate scalar to packed single precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12595 instruct Repl2F_reg(regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12596 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12597 match(Set dst (Replicate2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12598 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12599 ins_encode( pshufd(dst, src, 0xe0));
a61af66fc99e Initial load
duke
parents:
diff changeset
12600 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12601 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12602
a61af66fc99e Initial load
duke
parents:
diff changeset
12603 // Replicate scalar to packed single precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12604 instruct Repl2F_regX(regXD dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12605 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12606 match(Set dst (Replicate2F src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12607 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12608 ins_encode( pshufd(dst, src, 0xe0));
a61af66fc99e Initial load
duke
parents:
diff changeset
12609 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12610 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12611
a61af66fc99e Initial load
duke
parents:
diff changeset
12612 // Replicate scalar to packed single precision floating point values in xmm
a61af66fc99e Initial load
duke
parents:
diff changeset
12613 instruct Repl2F_immXF0(regXD dst, immXF0 zero) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12614 predicate(UseSSE>=2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12615 match(Set dst (Replicate2F zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12616 format %{ "PXOR $dst,$dst\t! replicate2F" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12617 ins_encode( pxor(dst, dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
12618 ins_pipe( fpu_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12619 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12620
a61af66fc99e Initial load
duke
parents:
diff changeset
12621 // =======================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
12622 // fast clearing of an array
a61af66fc99e Initial load
duke
parents:
diff changeset
12623 instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12624 match(Set dummy (ClearArray cnt base));
a61af66fc99e Initial load
duke
parents:
diff changeset
12625 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
12626 format %{ "SHL ECX,1\t# Convert doublewords to words\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12627 "XOR EAX,EAX\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
12628 "REP STOS\t# store EAX into [EDI++] while ECX--" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12629 opcode(0,0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
12630 ins_encode( Opcode(0xD1), RegOpc(ECX),
a61af66fc99e Initial load
duke
parents:
diff changeset
12631 OpcRegReg(0x33,EAX,EAX),
a61af66fc99e Initial load
duke
parents:
diff changeset
12632 Opcode(0xF3), Opcode(0xAB) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12633 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12634 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12635
2262
6bbaedb03534 7016474: string compare intrinsic improvements
never
parents: 2008
diff changeset
12636 instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
6bbaedb03534 7016474: string compare intrinsic improvements
never
parents: 2008
diff changeset
12637 eAXRegI result, regXD tmp1, eFlagsReg cr) %{
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12638 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
2262
6bbaedb03534 7016474: string compare intrinsic improvements
never
parents: 2008
diff changeset
12639 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
6bbaedb03534 7016474: string compare intrinsic improvements
never
parents: 2008
diff changeset
12640
6bbaedb03534 7016474: string compare intrinsic improvements
never
parents: 2008
diff changeset
12641 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12642 ins_encode %{
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12643 __ string_compare($str1$$Register, $str2$$Register,
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12644 $cnt1$$Register, $cnt2$$Register, $result$$Register,
2262
6bbaedb03534 7016474: string compare intrinsic improvements
never
parents: 2008
diff changeset
12645 $tmp1$$XMMRegister);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12646 %}
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 671
diff changeset
12647 ins_pipe( pipe_slow );
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 671
diff changeset
12648 %}
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 671
diff changeset
12649
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 671
diff changeset
12650 // fast string equals
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12651 instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result,
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12652 regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12653 match(Set result (StrEquals (Binary str1 str2) cnt));
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12654 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12655
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12656 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12657 ins_encode %{
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12658 __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12659 $cnt$$Register, $result$$Register, $tmp3$$Register,
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12660 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12661 %}
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12662 ins_pipe( pipe_slow );
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12663 %}
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12664
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12665 // fast search of substring with known size.
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12666 instruct string_indexof_con(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12667 eBXRegI result, regXD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12668 predicate(UseSSE42Intrinsics);
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12669 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12670 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12671
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12672 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12673 ins_encode %{
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12674 int icnt2 = (int)$int_cnt2$$constant;
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12675 if (icnt2 >= 8) {
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12676 // IndexOf for constant substrings with size >= 8 elements
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12677 // which don't need to be loaded through stack.
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12678 __ string_indexofC8($str1$$Register, $str2$$Register,
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12679 $cnt1$$Register, $cnt2$$Register,
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12680 icnt2, $result$$Register,
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12681 $vec$$XMMRegister, $tmp$$Register);
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12682 } else {
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12683 // Small strings are loaded through stack if they cross page boundary.
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12684 __ string_indexof($str1$$Register, $str2$$Register,
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12685 $cnt1$$Register, $cnt2$$Register,
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12686 icnt2, $result$$Register,
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12687 $vec$$XMMRegister, $tmp$$Register);
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12688 }
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12689 %}
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12690 ins_pipe( pipe_slow );
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12691 %}
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12692
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12693 instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12694 eBXRegI result, regXD vec, eCXRegI tmp, eFlagsReg cr) %{
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 671
diff changeset
12695 predicate(UseSSE42Intrinsics);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12696 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12697 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12698
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12699 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12700 ins_encode %{
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12701 __ string_indexof($str1$$Register, $str2$$Register,
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12702 $cnt1$$Register, $cnt2$$Register,
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12703 (-1), $result$$Register,
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 2262
diff changeset
12704 $vec$$XMMRegister, $tmp$$Register);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12705 %}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12706 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12707 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12708
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 113
diff changeset
12709 // fast array equals
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12710 instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12711 regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12712 %{
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 113
diff changeset
12713 match(Set result (AryEq ary1 ary2));
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 671
diff changeset
12714 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 113
diff changeset
12715 //ins_cost(300);
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 113
diff changeset
12716
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12717 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12718 ins_encode %{
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12719 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12720 $tmp3$$Register, $result$$Register, $tmp4$$Register,
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12721 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 824
diff changeset
12722 %}
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 113
diff changeset
12723 ins_pipe( pipe_slow );
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 113
diff changeset
12724 %}
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 113
diff changeset
12725
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12726 //----------Control Flow Instructions------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
12727 // Signed compare Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
12728 instruct compI_eReg(eFlagsReg cr, eRegI op1, eRegI op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12729 match(Set cr (CmpI op1 op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12730 effect( DEF cr, USE op1, USE op2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
12731 format %{ "CMP $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12732 opcode(0x3B); /* Opcode 3B /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12733 ins_encode( OpcP, RegReg( op1, op2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12734 ins_pipe( ialu_cr_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12735 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12736
a61af66fc99e Initial load
duke
parents:
diff changeset
12737 instruct compI_eReg_imm(eFlagsReg cr, eRegI op1, immI op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12738 match(Set cr (CmpI op1 op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12739 effect( DEF cr, USE op1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
12740 format %{ "CMP $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12741 opcode(0x81,0x07); /* Opcode 81 /7 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12742 // ins_encode( RegImm( op1, op2) ); /* Was CmpImm */
a61af66fc99e Initial load
duke
parents:
diff changeset
12743 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12744 ins_pipe( ialu_cr_reg_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
12745 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12746
a61af66fc99e Initial load
duke
parents:
diff changeset
12747 // Cisc-spilled version of cmpI_eReg
a61af66fc99e Initial load
duke
parents:
diff changeset
12748 instruct compI_eReg_mem(eFlagsReg cr, eRegI op1, memory op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12749 match(Set cr (CmpI op1 (LoadI op2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
12750
a61af66fc99e Initial load
duke
parents:
diff changeset
12751 format %{ "CMP $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12752 ins_cost(500);
a61af66fc99e Initial load
duke
parents:
diff changeset
12753 opcode(0x3B); /* Opcode 3B /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12754 ins_encode( OpcP, RegMem( op1, op2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12755 ins_pipe( ialu_cr_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12756 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12757
a61af66fc99e Initial load
duke
parents:
diff changeset
12758 instruct testI_reg( eFlagsReg cr, eRegI src, immI0 zero ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12759 match(Set cr (CmpI src zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12760 effect( DEF cr, USE src );
a61af66fc99e Initial load
duke
parents:
diff changeset
12761
a61af66fc99e Initial load
duke
parents:
diff changeset
12762 format %{ "TEST $src,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12763 opcode(0x85);
a61af66fc99e Initial load
duke
parents:
diff changeset
12764 ins_encode( OpcP, RegReg( src, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12765 ins_pipe( ialu_cr_reg_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
12766 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12767
a61af66fc99e Initial load
duke
parents:
diff changeset
12768 instruct testI_reg_imm( eFlagsReg cr, eRegI src, immI con, immI0 zero ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12769 match(Set cr (CmpI (AndI src con) zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12770
a61af66fc99e Initial load
duke
parents:
diff changeset
12771 format %{ "TEST $src,$con" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12772 opcode(0xF7,0x00);
a61af66fc99e Initial load
duke
parents:
diff changeset
12773 ins_encode( OpcP, RegOpc(src), Con32(con) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12774 ins_pipe( ialu_cr_reg_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
12775 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12776
a61af66fc99e Initial load
duke
parents:
diff changeset
12777 instruct testI_reg_mem( eFlagsReg cr, eRegI src, memory mem, immI0 zero ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12778 match(Set cr (CmpI (AndI src mem) zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12779
a61af66fc99e Initial load
duke
parents:
diff changeset
12780 format %{ "TEST $src,$mem" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12781 opcode(0x85);
a61af66fc99e Initial load
duke
parents:
diff changeset
12782 ins_encode( OpcP, RegMem( src, mem ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12783 ins_pipe( ialu_cr_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12784 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12785
a61af66fc99e Initial load
duke
parents:
diff changeset
12786 // Unsigned compare Instructions; really, same as signed except they
a61af66fc99e Initial load
duke
parents:
diff changeset
12787 // produce an eFlagsRegU instead of eFlagsReg.
a61af66fc99e Initial load
duke
parents:
diff changeset
12788 instruct compU_eReg(eFlagsRegU cr, eRegI op1, eRegI op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12789 match(Set cr (CmpU op1 op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12790
a61af66fc99e Initial load
duke
parents:
diff changeset
12791 format %{ "CMPu $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12792 opcode(0x3B); /* Opcode 3B /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12793 ins_encode( OpcP, RegReg( op1, op2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12794 ins_pipe( ialu_cr_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12795 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12796
a61af66fc99e Initial load
duke
parents:
diff changeset
12797 instruct compU_eReg_imm(eFlagsRegU cr, eRegI op1, immI op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12798 match(Set cr (CmpU op1 op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12799
a61af66fc99e Initial load
duke
parents:
diff changeset
12800 format %{ "CMPu $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12801 opcode(0x81,0x07); /* Opcode 81 /7 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12802 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12803 ins_pipe( ialu_cr_reg_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
12804 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12805
a61af66fc99e Initial load
duke
parents:
diff changeset
12806 // // Cisc-spilled version of cmpU_eReg
a61af66fc99e Initial load
duke
parents:
diff changeset
12807 instruct compU_eReg_mem(eFlagsRegU cr, eRegI op1, memory op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12808 match(Set cr (CmpU op1 (LoadI op2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
12809
a61af66fc99e Initial load
duke
parents:
diff changeset
12810 format %{ "CMPu $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12811 ins_cost(500);
a61af66fc99e Initial load
duke
parents:
diff changeset
12812 opcode(0x3B); /* Opcode 3B /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12813 ins_encode( OpcP, RegMem( op1, op2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12814 ins_pipe( ialu_cr_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12815 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12816
a61af66fc99e Initial load
duke
parents:
diff changeset
12817 // // Cisc-spilled version of cmpU_eReg
a61af66fc99e Initial load
duke
parents:
diff changeset
12818 //instruct compU_mem_eReg(eFlagsRegU cr, memory op1, eRegI op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12819 // match(Set cr (CmpU (LoadI op1) op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12820 //
a61af66fc99e Initial load
duke
parents:
diff changeset
12821 // format %{ "CMPu $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12822 // ins_cost(500);
a61af66fc99e Initial load
duke
parents:
diff changeset
12823 // opcode(0x39); /* Opcode 39 /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12824 // ins_encode( OpcP, RegMem( op1, op2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12825 //%}
a61af66fc99e Initial load
duke
parents:
diff changeset
12826
a61af66fc99e Initial load
duke
parents:
diff changeset
12827 instruct testU_reg( eFlagsRegU cr, eRegI src, immI0 zero ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12828 match(Set cr (CmpU src zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12829
a61af66fc99e Initial load
duke
parents:
diff changeset
12830 format %{ "TESTu $src,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12831 opcode(0x85);
a61af66fc99e Initial load
duke
parents:
diff changeset
12832 ins_encode( OpcP, RegReg( src, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12833 ins_pipe( ialu_cr_reg_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
12834 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12835
a61af66fc99e Initial load
duke
parents:
diff changeset
12836 // Unsigned pointer compare Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
12837 instruct compP_eReg(eFlagsRegU cr, eRegP op1, eRegP op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12838 match(Set cr (CmpP op1 op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12839
a61af66fc99e Initial load
duke
parents:
diff changeset
12840 format %{ "CMPu $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12841 opcode(0x3B); /* Opcode 3B /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12842 ins_encode( OpcP, RegReg( op1, op2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12843 ins_pipe( ialu_cr_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12844 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12845
a61af66fc99e Initial load
duke
parents:
diff changeset
12846 instruct compP_eReg_imm(eFlagsRegU cr, eRegP op1, immP op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12847 match(Set cr (CmpP op1 op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12848
a61af66fc99e Initial load
duke
parents:
diff changeset
12849 format %{ "CMPu $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12850 opcode(0x81,0x07); /* Opcode 81 /7 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12851 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12852 ins_pipe( ialu_cr_reg_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
12853 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12854
a61af66fc99e Initial load
duke
parents:
diff changeset
12855 // // Cisc-spilled version of cmpP_eReg
a61af66fc99e Initial load
duke
parents:
diff changeset
12856 instruct compP_eReg_mem(eFlagsRegU cr, eRegP op1, memory op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12857 match(Set cr (CmpP op1 (LoadP op2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
12858
a61af66fc99e Initial load
duke
parents:
diff changeset
12859 format %{ "CMPu $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12860 ins_cost(500);
a61af66fc99e Initial load
duke
parents:
diff changeset
12861 opcode(0x3B); /* Opcode 3B /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12862 ins_encode( OpcP, RegMem( op1, op2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12863 ins_pipe( ialu_cr_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12864 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12865
a61af66fc99e Initial load
duke
parents:
diff changeset
12866 // // Cisc-spilled version of cmpP_eReg
a61af66fc99e Initial load
duke
parents:
diff changeset
12867 //instruct compP_mem_eReg(eFlagsRegU cr, memory op1, eRegP op2) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12868 // match(Set cr (CmpP (LoadP op1) op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12869 //
a61af66fc99e Initial load
duke
parents:
diff changeset
12870 // format %{ "CMPu $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12871 // ins_cost(500);
a61af66fc99e Initial load
duke
parents:
diff changeset
12872 // opcode(0x39); /* Opcode 39 /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12873 // ins_encode( OpcP, RegMem( op1, op2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12874 //%}
a61af66fc99e Initial load
duke
parents:
diff changeset
12875
a61af66fc99e Initial load
duke
parents:
diff changeset
12876 // Compare raw pointer (used in out-of-heap check).
a61af66fc99e Initial load
duke
parents:
diff changeset
12877 // Only works because non-oop pointers must be raw pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
12878 // and raw pointers have no anti-dependencies.
a61af66fc99e Initial load
duke
parents:
diff changeset
12879 instruct compP_mem_eReg( eFlagsRegU cr, eRegP op1, memory op2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12880 predicate( !n->in(2)->in(2)->bottom_type()->isa_oop_ptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
12881 match(Set cr (CmpP op1 (LoadP op2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
12882
a61af66fc99e Initial load
duke
parents:
diff changeset
12883 format %{ "CMPu $op1,$op2" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12884 opcode(0x3B); /* Opcode 3B /r */
a61af66fc99e Initial load
duke
parents:
diff changeset
12885 ins_encode( OpcP, RegMem( op1, op2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12886 ins_pipe( ialu_cr_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
12887 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12888
a61af66fc99e Initial load
duke
parents:
diff changeset
12889 //
a61af66fc99e Initial load
duke
parents:
diff changeset
12890 // This will generate a signed flags result. This should be ok
a61af66fc99e Initial load
duke
parents:
diff changeset
12891 // since any compare to a zero should be eq/neq.
a61af66fc99e Initial load
duke
parents:
diff changeset
12892 instruct testP_reg( eFlagsReg cr, eRegP src, immP0 zero ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12893 match(Set cr (CmpP src zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12894
a61af66fc99e Initial load
duke
parents:
diff changeset
12895 format %{ "TEST $src,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12896 opcode(0x85);
a61af66fc99e Initial load
duke
parents:
diff changeset
12897 ins_encode( OpcP, RegReg( src, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12898 ins_pipe( ialu_cr_reg_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
12899 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12900
a61af66fc99e Initial load
duke
parents:
diff changeset
12901 // Cisc-spilled version of testP_reg
a61af66fc99e Initial load
duke
parents:
diff changeset
12902 // This will generate a signed flags result. This should be ok
a61af66fc99e Initial load
duke
parents:
diff changeset
12903 // since any compare to a zero should be eq/neq.
a61af66fc99e Initial load
duke
parents:
diff changeset
12904 instruct testP_Reg_mem( eFlagsReg cr, memory op, immI0 zero ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12905 match(Set cr (CmpP (LoadP op) zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
12906
a61af66fc99e Initial load
duke
parents:
diff changeset
12907 format %{ "TEST $op,0xFFFFFFFF" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12908 ins_cost(500);
a61af66fc99e Initial load
duke
parents:
diff changeset
12909 opcode(0xF7); /* Opcode F7 /0 */
a61af66fc99e Initial load
duke
parents:
diff changeset
12910 ins_encode( OpcP, RMopc_Mem(0x00,op), Con_d32(0xFFFFFFFF) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12911 ins_pipe( ialu_cr_reg_imm );
a61af66fc99e Initial load
duke
parents:
diff changeset
12912 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12913
a61af66fc99e Initial load
duke
parents:
diff changeset
12914 // Yanked all unsigned pointer compare operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
12915 // Pointer compares are done with CmpP which is already unsigned.
a61af66fc99e Initial load
duke
parents:
diff changeset
12916
a61af66fc99e Initial load
duke
parents:
diff changeset
12917 //----------Max and Min--------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
12918 // Min Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
12919 ////
a61af66fc99e Initial load
duke
parents:
diff changeset
12920 // *** Min and Max using the conditional move are slower than the
a61af66fc99e Initial load
duke
parents:
diff changeset
12921 // *** branch version on a Pentium III.
a61af66fc99e Initial load
duke
parents:
diff changeset
12922 // // Conditional move for min
a61af66fc99e Initial load
duke
parents:
diff changeset
12923 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12924 // effect( USE_DEF op2, USE op1, USE cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
12925 // format %{ "CMOVlt $op2,$op1\t! min" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12926 // opcode(0x4C,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
12927 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12928 // ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12929 //%}
a61af66fc99e Initial load
duke
parents:
diff changeset
12930 //
a61af66fc99e Initial load
duke
parents:
diff changeset
12931 //// Min Register with Register (P6 version)
a61af66fc99e Initial load
duke
parents:
diff changeset
12932 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12933 // predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
12934 // match(Set op2 (MinI op1 op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12935 // ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
12936 // expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12937 // eFlagsReg cr;
a61af66fc99e Initial load
duke
parents:
diff changeset
12938 // compI_eReg(cr,op1,op2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12939 // cmovI_reg_lt(op2,op1,cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
12940 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12941 //%}
a61af66fc99e Initial load
duke
parents:
diff changeset
12942
a61af66fc99e Initial load
duke
parents:
diff changeset
12943 // Min Register with Register (generic version)
a61af66fc99e Initial load
duke
parents:
diff changeset
12944 instruct minI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12945 match(Set dst (MinI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12946 effect(KILL flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
12947 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
12948
a61af66fc99e Initial load
duke
parents:
diff changeset
12949 format %{ "MIN $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12950 opcode(0xCC);
a61af66fc99e Initial load
duke
parents:
diff changeset
12951 ins_encode( min_enc(dst,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12952 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12953 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12954
a61af66fc99e Initial load
duke
parents:
diff changeset
12955 // Max Register with Register
a61af66fc99e Initial load
duke
parents:
diff changeset
12956 // *** Min and Max using the conditional move are slower than the
a61af66fc99e Initial load
duke
parents:
diff changeset
12957 // *** branch version on a Pentium III.
a61af66fc99e Initial load
duke
parents:
diff changeset
12958 // // Conditional move for max
a61af66fc99e Initial load
duke
parents:
diff changeset
12959 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12960 // effect( USE_DEF op2, USE op1, USE cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
12961 // format %{ "CMOVgt $op2,$op1\t! max" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12962 // opcode(0x4F,0x0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
12963 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12964 // ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
12965 //%}
a61af66fc99e Initial load
duke
parents:
diff changeset
12966 //
a61af66fc99e Initial load
duke
parents:
diff changeset
12967 // // Max Register with Register (P6 version)
a61af66fc99e Initial load
duke
parents:
diff changeset
12968 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12969 // predicate(VM_Version::supports_cmov() );
a61af66fc99e Initial load
duke
parents:
diff changeset
12970 // match(Set op2 (MaxI op1 op2));
a61af66fc99e Initial load
duke
parents:
diff changeset
12971 // ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
12972 // expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12973 // eFlagsReg cr;
a61af66fc99e Initial load
duke
parents:
diff changeset
12974 // compI_eReg(cr,op1,op2);
a61af66fc99e Initial load
duke
parents:
diff changeset
12975 // cmovI_reg_gt(op2,op1,cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
12976 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12977 //%}
a61af66fc99e Initial load
duke
parents:
diff changeset
12978
a61af66fc99e Initial load
duke
parents:
diff changeset
12979 // Max Register with Register (generic version)
a61af66fc99e Initial load
duke
parents:
diff changeset
12980 instruct maxI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12981 match(Set dst (MaxI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
12982 effect(KILL flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
12983 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
12984
a61af66fc99e Initial load
duke
parents:
diff changeset
12985 format %{ "MAX $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12986 opcode(0xCC);
a61af66fc99e Initial load
duke
parents:
diff changeset
12987 ins_encode( max_enc(dst,src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
12988 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
12989 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
12990
a61af66fc99e Initial load
duke
parents:
diff changeset
12991 // ============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
12992 // Branch Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
12993 // Jump Table
a61af66fc99e Initial load
duke
parents:
diff changeset
12994 instruct jumpXtnd(eRegI switch_val) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
12995 match(Jump switch_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
12996 ins_cost(350);
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
12997 format %{ "JMP [$constantaddress](,$switch_val,1)\n\t" %}
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
12998 ins_encode %{
0
a61af66fc99e Initial load
duke
parents:
diff changeset
12999 // Jump to Address(table_base + switch_reg)
a61af66fc99e Initial load
duke
parents:
diff changeset
13000 Address index(noreg, $switch_val$$Register, Address::times_1);
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1920
diff changeset
13001 __ jump(ArrayAddress($constantaddress, index));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13002 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13003 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13004 ins_pipe(pipe_jmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
13005 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13006
a61af66fc99e Initial load
duke
parents:
diff changeset
13007 // Jump Direct - Label defines a relative address from JMP+1
a61af66fc99e Initial load
duke
parents:
diff changeset
13008 instruct jmpDir(label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13009 match(Goto);
a61af66fc99e Initial load
duke
parents:
diff changeset
13010 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13011
a61af66fc99e Initial load
duke
parents:
diff changeset
13012 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13013 format %{ "JMP $labl" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13014 size(5);
a61af66fc99e Initial load
duke
parents:
diff changeset
13015 opcode(0xE9);
a61af66fc99e Initial load
duke
parents:
diff changeset
13016 ins_encode( OpcP, Lbl( labl ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13017 ins_pipe( pipe_jmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13018 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13019 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13020
a61af66fc99e Initial load
duke
parents:
diff changeset
13021 // Jump Direct Conditional - Label defines a relative address from Jcc+1
a61af66fc99e Initial load
duke
parents:
diff changeset
13022 instruct jmpCon(cmpOp cop, eFlagsReg cr, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13023 match(If cop cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
13024 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13025
a61af66fc99e Initial load
duke
parents:
diff changeset
13026 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13027 format %{ "J$cop $labl" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13028 size(6);
a61af66fc99e Initial load
duke
parents:
diff changeset
13029 opcode(0x0F, 0x80);
a61af66fc99e Initial load
duke
parents:
diff changeset
13030 ins_encode( Jcc( cop, labl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13031 ins_pipe( pipe_jcc );
a61af66fc99e Initial load
duke
parents:
diff changeset
13032 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13033 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13034
a61af66fc99e Initial load
duke
parents:
diff changeset
13035 // Jump Direct Conditional - Label defines a relative address from Jcc+1
a61af66fc99e Initial load
duke
parents:
diff changeset
13036 instruct jmpLoopEnd(cmpOp cop, eFlagsReg cr, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13037 match(CountedLoopEnd cop cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
13038 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13039
a61af66fc99e Initial load
duke
parents:
diff changeset
13040 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13041 format %{ "J$cop $labl\t# Loop end" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13042 size(6);
a61af66fc99e Initial load
duke
parents:
diff changeset
13043 opcode(0x0F, 0x80);
a61af66fc99e Initial load
duke
parents:
diff changeset
13044 ins_encode( Jcc( cop, labl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13045 ins_pipe( pipe_jcc );
a61af66fc99e Initial load
duke
parents:
diff changeset
13046 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13047 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13048
a61af66fc99e Initial load
duke
parents:
diff changeset
13049 // Jump Direct Conditional - Label defines a relative address from Jcc+1
a61af66fc99e Initial load
duke
parents:
diff changeset
13050 instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13051 match(CountedLoopEnd cop cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
13052 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13053
a61af66fc99e Initial load
duke
parents:
diff changeset
13054 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13055 format %{ "J$cop,u $labl\t# Loop end" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13056 size(6);
a61af66fc99e Initial load
duke
parents:
diff changeset
13057 opcode(0x0F, 0x80);
a61af66fc99e Initial load
duke
parents:
diff changeset
13058 ins_encode( Jcc( cop, labl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13059 ins_pipe( pipe_jcc );
a61af66fc99e Initial load
duke
parents:
diff changeset
13060 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13061 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13062
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13063 instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13064 match(CountedLoopEnd cop cmp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13065 effect(USE labl);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13066
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13067 ins_cost(200);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13068 format %{ "J$cop,u $labl\t# Loop end" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13069 size(6);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13070 opcode(0x0F, 0x80);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13071 ins_encode( Jcc( cop, labl) );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13072 ins_pipe( pipe_jcc );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13073 ins_pc_relative(1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13074 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13075
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13076 // Jump Direct Conditional - using unsigned comparison
a61af66fc99e Initial load
duke
parents:
diff changeset
13077 instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13078 match(If cop cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
13079 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13080
a61af66fc99e Initial load
duke
parents:
diff changeset
13081 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13082 format %{ "J$cop,u $labl" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13083 size(6);
a61af66fc99e Initial load
duke
parents:
diff changeset
13084 opcode(0x0F, 0x80);
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13085 ins_encode(Jcc(cop, labl));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13086 ins_pipe(pipe_jcc);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13087 ins_pc_relative(1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13088 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13089
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13090 instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13091 match(If cop cmp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13092 effect(USE labl);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13093
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13094 ins_cost(200);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13095 format %{ "J$cop,u $labl" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13096 size(6);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13097 opcode(0x0F, 0x80);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13098 ins_encode(Jcc(cop, labl));
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13099 ins_pipe(pipe_jcc);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13100 ins_pc_relative(1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13101 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13102
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13103 instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13104 match(If cop cmp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13105 effect(USE labl);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13106
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13107 ins_cost(200);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13108 format %{ $$template
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13109 if ($cop$$cmpcode == Assembler::notEqual) {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13110 $$emit$$"JP,u $labl\n\t"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13111 $$emit$$"J$cop,u $labl"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13112 } else {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13113 $$emit$$"JP,u done\n\t"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13114 $$emit$$"J$cop,u $labl\n\t"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13115 $$emit$$"done:"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13116 }
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13117 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13118 size(12);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13119 opcode(0x0F, 0x80);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13120 ins_encode %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13121 Label* l = $labl$$label;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13122 $$$emit8$primary;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13123 emit_cc(cbuf, $secondary, Assembler::parity);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13124 int parity_disp = -1;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13125 bool ok = false;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13126 if ($cop$$cmpcode == Assembler::notEqual) {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13127 // the two jumps 6 bytes apart so the jump distances are too
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
13128 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13129 } else if ($cop$$cmpcode == Assembler::equal) {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13130 parity_disp = 6;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13131 ok = true;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13132 } else {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13133 ShouldNotReachHere();
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13134 }
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13135 emit_d32(cbuf, parity_disp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13136 $$$emit8$primary;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13137 emit_cc(cbuf, $secondary, $cop$$cmpcode);
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
13138 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13139 emit_d32(cbuf, disp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13140 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13141 ins_pipe(pipe_jcc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13142 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13143 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13144
a61af66fc99e Initial load
duke
parents:
diff changeset
13145 // ============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
13146 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
a61af66fc99e Initial load
duke
parents:
diff changeset
13147 // array for an instance of the superklass. Set a hidden internal cache on a
a61af66fc99e Initial load
duke
parents:
diff changeset
13148 // hit (cache is checked with exposed code in gen_subtype_check()). Return
a61af66fc99e Initial load
duke
parents:
diff changeset
13149 // NZ for a miss or zero for a hit. The encoding ALSO sets flags.
a61af66fc99e Initial load
duke
parents:
diff changeset
13150 instruct partialSubtypeCheck( eDIRegP result, eSIRegP sub, eAXRegP super, eCXRegI rcx, eFlagsReg cr ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13151 match(Set result (PartialSubtypeCheck sub super));
a61af66fc99e Initial load
duke
parents:
diff changeset
13152 effect( KILL rcx, KILL cr );
a61af66fc99e Initial load
duke
parents:
diff changeset
13153
a61af66fc99e Initial load
duke
parents:
diff changeset
13154 ins_cost(1100); // slightly larger than the next version
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 643
diff changeset
13155 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13156 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13157 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13158 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13159 "JNE,s miss\t\t# Missed: EDI not-zero\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13160 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13161 "XOR $result,$result\t\t Hit: EDI zero\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13162 "miss:\t" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13163
a61af66fc99e Initial load
duke
parents:
diff changeset
13164 opcode(0x1); // Force a XOR of EDI
a61af66fc99e Initial load
duke
parents:
diff changeset
13165 ins_encode( enc_PartialSubtypeCheck() );
a61af66fc99e Initial load
duke
parents:
diff changeset
13166 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13167 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13168
a61af66fc99e Initial load
duke
parents:
diff changeset
13169 instruct partialSubtypeCheck_vs_Zero( eFlagsReg cr, eSIRegP sub, eAXRegP super, eCXRegI rcx, eDIRegP result, immP0 zero ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13170 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
a61af66fc99e Initial load
duke
parents:
diff changeset
13171 effect( KILL rcx, KILL result );
a61af66fc99e Initial load
duke
parents:
diff changeset
13172
a61af66fc99e Initial load
duke
parents:
diff changeset
13173 ins_cost(1000);
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 643
diff changeset
13174 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13175 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13176 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13177 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13178 "JNE,s miss\t\t# Missed: flags NZ\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13179 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache, flags Z\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13180 "miss:\t" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13181
a61af66fc99e Initial load
duke
parents:
diff changeset
13182 opcode(0x0); // No need to XOR EDI
a61af66fc99e Initial load
duke
parents:
diff changeset
13183 ins_encode( enc_PartialSubtypeCheck() );
a61af66fc99e Initial load
duke
parents:
diff changeset
13184 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13185 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13186
a61af66fc99e Initial load
duke
parents:
diff changeset
13187 // ============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
13188 // Branch Instructions -- short offset versions
a61af66fc99e Initial load
duke
parents:
diff changeset
13189 //
a61af66fc99e Initial load
duke
parents:
diff changeset
13190 // These instructions are used to replace jumps of a long offset (the default
a61af66fc99e Initial load
duke
parents:
diff changeset
13191 // match) with jumps of a shorter offset. These instructions are all tagged
a61af66fc99e Initial load
duke
parents:
diff changeset
13192 // with the ins_short_branch attribute, which causes the ADLC to suppress the
a61af66fc99e Initial load
duke
parents:
diff changeset
13193 // match rules in general matching. Instead, the ADLC generates a conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
13194 // method in the MachNode which can be used to do in-place replacement of the
a61af66fc99e Initial load
duke
parents:
diff changeset
13195 // long variant with the shorter variant. The compiler will determine if a
a61af66fc99e Initial load
duke
parents:
diff changeset
13196 // branch can be taken by the is_short_branch_offset() predicate in the machine
a61af66fc99e Initial load
duke
parents:
diff changeset
13197 // specific code section of the file.
a61af66fc99e Initial load
duke
parents:
diff changeset
13198
a61af66fc99e Initial load
duke
parents:
diff changeset
13199 // Jump Direct - Label defines a relative address from JMP+1
a61af66fc99e Initial load
duke
parents:
diff changeset
13200 instruct jmpDir_short(label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13201 match(Goto);
a61af66fc99e Initial load
duke
parents:
diff changeset
13202 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13203
a61af66fc99e Initial load
duke
parents:
diff changeset
13204 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13205 format %{ "JMP,s $labl" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13206 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
13207 opcode(0xEB);
a61af66fc99e Initial load
duke
parents:
diff changeset
13208 ins_encode( OpcP, LblShort( labl ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13209 ins_pipe( pipe_jmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13210 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13211 ins_short_branch(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13212 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13213
a61af66fc99e Initial load
duke
parents:
diff changeset
13214 // Jump Direct Conditional - Label defines a relative address from Jcc+1
a61af66fc99e Initial load
duke
parents:
diff changeset
13215 instruct jmpCon_short(cmpOp cop, eFlagsReg cr, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13216 match(If cop cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
13217 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13218
a61af66fc99e Initial load
duke
parents:
diff changeset
13219 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13220 format %{ "J$cop,s $labl" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13221 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
13222 opcode(0x70);
a61af66fc99e Initial load
duke
parents:
diff changeset
13223 ins_encode( JccShort( cop, labl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13224 ins_pipe( pipe_jcc );
a61af66fc99e Initial load
duke
parents:
diff changeset
13225 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13226 ins_short_branch(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13227 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13228
a61af66fc99e Initial load
duke
parents:
diff changeset
13229 // Jump Direct Conditional - Label defines a relative address from Jcc+1
a61af66fc99e Initial load
duke
parents:
diff changeset
13230 instruct jmpLoopEnd_short(cmpOp cop, eFlagsReg cr, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13231 match(CountedLoopEnd cop cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
13232 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13233
a61af66fc99e Initial load
duke
parents:
diff changeset
13234 ins_cost(300);
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13235 format %{ "J$cop,s $labl\t# Loop end" %}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13236 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
13237 opcode(0x70);
a61af66fc99e Initial load
duke
parents:
diff changeset
13238 ins_encode( JccShort( cop, labl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13239 ins_pipe( pipe_jcc );
a61af66fc99e Initial load
duke
parents:
diff changeset
13240 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13241 ins_short_branch(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13242 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13243
a61af66fc99e Initial load
duke
parents:
diff changeset
13244 // Jump Direct Conditional - Label defines a relative address from Jcc+1
a61af66fc99e Initial load
duke
parents:
diff changeset
13245 instruct jmpLoopEndU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13246 match(CountedLoopEnd cop cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
13247 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13248
a61af66fc99e Initial load
duke
parents:
diff changeset
13249 ins_cost(300);
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13250 format %{ "J$cop,us $labl\t# Loop end" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13251 size(2);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13252 opcode(0x70);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13253 ins_encode( JccShort( cop, labl) );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13254 ins_pipe( pipe_jcc );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13255 ins_pc_relative(1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13256 ins_short_branch(1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13257 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13258
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13259 instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13260 match(CountedLoopEnd cop cmp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13261 effect(USE labl);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13262
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13263 ins_cost(300);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13264 format %{ "J$cop,us $labl\t# Loop end" %}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13265 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
13266 opcode(0x70);
a61af66fc99e Initial load
duke
parents:
diff changeset
13267 ins_encode( JccShort( cop, labl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13268 ins_pipe( pipe_jcc );
a61af66fc99e Initial load
duke
parents:
diff changeset
13269 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13270 ins_short_branch(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13271 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13272
a61af66fc99e Initial load
duke
parents:
diff changeset
13273 // Jump Direct Conditional - using unsigned comparison
a61af66fc99e Initial load
duke
parents:
diff changeset
13274 instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13275 match(If cop cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
13276 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13277
a61af66fc99e Initial load
duke
parents:
diff changeset
13278 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13279 format %{ "J$cop,us $labl" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13280 size(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
13281 opcode(0x70);
a61af66fc99e Initial load
duke
parents:
diff changeset
13282 ins_encode( JccShort( cop, labl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13283 ins_pipe( pipe_jcc );
a61af66fc99e Initial load
duke
parents:
diff changeset
13284 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13285 ins_short_branch(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13286 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13287
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13288 instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13289 match(If cop cmp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13290 effect(USE labl);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13291
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13292 ins_cost(300);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13293 format %{ "J$cop,us $labl" %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13294 size(2);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13295 opcode(0x70);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13296 ins_encode( JccShort( cop, labl) );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13297 ins_pipe( pipe_jcc );
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13298 ins_pc_relative(1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13299 ins_short_branch(1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13300 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13301
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13302 instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13303 match(If cop cmp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13304 effect(USE labl);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13305
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13306 ins_cost(300);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13307 format %{ $$template
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13308 if ($cop$$cmpcode == Assembler::notEqual) {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13309 $$emit$$"JP,u,s $labl\n\t"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13310 $$emit$$"J$cop,u,s $labl"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13311 } else {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13312 $$emit$$"JP,u,s done\n\t"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13313 $$emit$$"J$cop,u,s $labl\n\t"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13314 $$emit$$"done:"
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13315 }
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13316 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13317 size(4);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13318 opcode(0x70);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13319 ins_encode %{
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13320 Label* l = $labl$$label;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13321 emit_cc(cbuf, $primary, Assembler::parity);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13322 int parity_disp = -1;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13323 if ($cop$$cmpcode == Assembler::notEqual) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
13324 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13325 } else if ($cop$$cmpcode == Assembler::equal) {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13326 parity_disp = 2;
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13327 } else {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13328 ShouldNotReachHere();
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13329 }
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13330 emit_d8(cbuf, parity_disp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13331 emit_cc(cbuf, $primary, $cop$$cmpcode);
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1730
diff changeset
13332 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13333 emit_d8(cbuf, disp);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13334 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13335 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13336 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13337 ins_pipe(pipe_jcc);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13338 ins_pc_relative(1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13339 ins_short_branch(1);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13340 %}
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 403
diff changeset
13341
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13342 // ============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
13343 // Long Compare
a61af66fc99e Initial load
duke
parents:
diff changeset
13344 //
a61af66fc99e Initial load
duke
parents:
diff changeset
13345 // Currently we hold longs in 2 registers. Comparing such values efficiently
a61af66fc99e Initial load
duke
parents:
diff changeset
13346 // is tricky. The flavor of compare used depends on whether we are testing
a61af66fc99e Initial load
duke
parents:
diff changeset
13347 // for LT, LE, or EQ. For a simple LT test we can check just the sign bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
13348 // The GE test is the negated LT test. The LE test can be had by commuting
a61af66fc99e Initial load
duke
parents:
diff changeset
13349 // the operands (yielding a GE test) and then negating; negate again for the
a61af66fc99e Initial load
duke
parents:
diff changeset
13350 // GT test. The EQ test is done by ORcc'ing the high and low halves, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
13351 // NE test is negated from that.
a61af66fc99e Initial load
duke
parents:
diff changeset
13352
a61af66fc99e Initial load
duke
parents:
diff changeset
13353 // Due to a shortcoming in the ADLC, it mixes up expressions like:
a61af66fc99e Initial load
duke
parents:
diff changeset
13354 // (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)). Note the
a61af66fc99e Initial load
duke
parents:
diff changeset
13355 // difference between 'Y' and '0L'. The tree-matches for the CmpI sections
a61af66fc99e Initial load
duke
parents:
diff changeset
13356 // are collapsed internally in the ADLC's dfa-gen code. The match for
a61af66fc99e Initial load
duke
parents:
diff changeset
13357 // (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the
a61af66fc99e Initial load
duke
parents:
diff changeset
13358 // foo match ends up with the wrong leaf. One fix is to not match both
a61af66fc99e Initial load
duke
parents:
diff changeset
13359 // reg-reg and reg-zero forms of long-compare. This is unfortunate because
a61af66fc99e Initial load
duke
parents:
diff changeset
13360 // both forms beat the trinary form of long-compare and both are very useful
a61af66fc99e Initial load
duke
parents:
diff changeset
13361 // on Intel which has so few registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
13362
a61af66fc99e Initial load
duke
parents:
diff changeset
13363 // Manifest a CmpL result in an integer register. Very painful.
a61af66fc99e Initial load
duke
parents:
diff changeset
13364 // This is the test to avoid.
a61af66fc99e Initial load
duke
parents:
diff changeset
13365 instruct cmpL3_reg_reg(eSIRegI dst, eRegL src1, eRegL src2, eFlagsReg flags ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13366 match(Set dst (CmpL3 src1 src2));
a61af66fc99e Initial load
duke
parents:
diff changeset
13367 effect( KILL flags );
a61af66fc99e Initial load
duke
parents:
diff changeset
13368 ins_cost(1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
13369 format %{ "XOR $dst,$dst\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13370 "CMP $src1.hi,$src2.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13371 "JLT,s m_one\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13372 "JGT,s p_one\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13373 "CMP $src1.lo,$src2.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13374 "JB,s m_one\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13375 "JEQ,s done\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
13376 "p_one:\tINC $dst\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13377 "JMP,s done\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
13378 "m_one:\tDEC $dst\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
13379 "done:" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13380 ins_encode %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13381 Label p_one, m_one, done;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
13382 __ xorptr($dst$$Register, $dst$$Register);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13383 __ cmpl(HIGH_FROM_LOW($src1$$Register), HIGH_FROM_LOW($src2$$Register));
a61af66fc99e Initial load
duke
parents:
diff changeset
13384 __ jccb(Assembler::less, m_one);
a61af66fc99e Initial load
duke
parents:
diff changeset
13385 __ jccb(Assembler::greater, p_one);
a61af66fc99e Initial load
duke
parents:
diff changeset
13386 __ cmpl($src1$$Register, $src2$$Register);
a61af66fc99e Initial load
duke
parents:
diff changeset
13387 __ jccb(Assembler::below, m_one);
a61af66fc99e Initial load
duke
parents:
diff changeset
13388 __ jccb(Assembler::equal, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
13389 __ bind(p_one);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
13390 __ incrementl($dst$$Register);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13391 __ jmpb(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
13392 __ bind(m_one);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 235
diff changeset
13393 __ decrementl($dst$$Register);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13394 __ bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
13395 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13396 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13397 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13398
a61af66fc99e Initial load
duke
parents:
diff changeset
13399 //======
a61af66fc99e Initial load
duke
parents:
diff changeset
13400 // Manifest a CmpL result in the normal flags. Only good for LT or GE
a61af66fc99e Initial load
duke
parents:
diff changeset
13401 // compares. Can be used for LE or GT compares by reversing arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
13402 // NOT GOOD FOR EQ/NE tests.
a61af66fc99e Initial load
duke
parents:
diff changeset
13403 instruct cmpL_zero_flags_LTGE( flagsReg_long_LTGE flags, eRegL src, immL0 zero ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13404 match( Set flags (CmpL src zero ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13405 ins_cost(100);
a61af66fc99e Initial load
duke
parents:
diff changeset
13406 format %{ "TEST $src.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13407 opcode(0x85);
a61af66fc99e Initial load
duke
parents:
diff changeset
13408 ins_encode( OpcP, RegReg_Hi2( src, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13409 ins_pipe( ialu_cr_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13410 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13411
a61af66fc99e Initial load
duke
parents:
diff changeset
13412 // Manifest a CmpL result in the normal flags. Only good for LT or GE
a61af66fc99e Initial load
duke
parents:
diff changeset
13413 // compares. Can be used for LE or GT compares by reversing arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
13414 // NOT GOOD FOR EQ/NE tests.
a61af66fc99e Initial load
duke
parents:
diff changeset
13415 instruct cmpL_reg_flags_LTGE( flagsReg_long_LTGE flags, eRegL src1, eRegL src2, eRegI tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13416 match( Set flags (CmpL src1 src2 ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13417 effect( TEMP tmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13418 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13419 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13420 "MOV $tmp,$src1.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13421 "SBB $tmp,$src2.hi\t! Compute flags for long compare" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13422 ins_encode( long_cmp_flags2( src1, src2, tmp ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13423 ins_pipe( ialu_cr_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13424 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13425
a61af66fc99e Initial load
duke
parents:
diff changeset
13426 // Long compares reg < zero/req OR reg >= zero/req.
a61af66fc99e Initial load
duke
parents:
diff changeset
13427 // Just a wrapper for a normal branch, plus the predicate test.
a61af66fc99e Initial load
duke
parents:
diff changeset
13428 instruct cmpL_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13429 match(If cmp flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
13430 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13431 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
a61af66fc99e Initial load
duke
parents:
diff changeset
13432 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13433 jmpCon(cmp,flags,labl); // JLT or JGE...
a61af66fc99e Initial load
duke
parents:
diff changeset
13434 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13435 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13436
a61af66fc99e Initial load
duke
parents:
diff changeset
13437 // Compare 2 longs and CMOVE longs.
a61af66fc99e Initial load
duke
parents:
diff changeset
13438 instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13439 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13440 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13441 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
13442 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13443 "CMOV$cmp $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13444 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13445 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13446 ins_pipe( pipe_cmov_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
13447 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13448
a61af66fc99e Initial load
duke
parents:
diff changeset
13449 instruct cmovLL_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, load_long_memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13450 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
13451 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13452 ins_cost(500);
a61af66fc99e Initial load
duke
parents:
diff changeset
13453 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13454 "CMOV$cmp $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13455 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13456 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13457 ins_pipe( pipe_cmov_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
13458 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13459
a61af66fc99e Initial load
duke
parents:
diff changeset
13460 // Compare 2 longs and CMOVE ints.
a61af66fc99e Initial load
duke
parents:
diff changeset
13461 instruct cmovII_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegI dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13462 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13463 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13464 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13465 format %{ "CMOV$cmp $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13466 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13467 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13468 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13469 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13470
a61af66fc99e Initial load
duke
parents:
diff changeset
13471 instruct cmovII_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegI dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13472 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13473 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
13474 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
13475 format %{ "CMOV$cmp $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13476 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13477 ins_encode( enc_cmov(cmp), RegMem( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13478 ins_pipe( pipe_cmov_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
13479 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13480
a61af66fc99e Initial load
duke
parents:
diff changeset
13481 // Compare 2 longs and CMOVE ints.
a61af66fc99e Initial load
duke
parents:
diff changeset
13482 instruct cmovPP_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegP dst, eRegP src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13483 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13484 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13485 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13486 format %{ "CMOV$cmp $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13487 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13488 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13489 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13490 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13491
a61af66fc99e Initial load
duke
parents:
diff changeset
13492 // Compare 2 longs and CMOVE doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
13493 instruct cmovDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13494 predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
a61af66fc99e Initial load
duke
parents:
diff changeset
13495 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13496 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13497 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13498 fcmovD_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13499 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13500 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13501
a61af66fc99e Initial load
duke
parents:
diff changeset
13502 // Compare 2 longs and CMOVE doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
13503 instruct cmovXDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13504 predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
a61af66fc99e Initial load
duke
parents:
diff changeset
13505 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13506 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13507 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13508 fcmovXD_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13509 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13510 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13511
a61af66fc99e Initial load
duke
parents:
diff changeset
13512 instruct cmovFF_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regF dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13513 predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
a61af66fc99e Initial load
duke
parents:
diff changeset
13514 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13515 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13516 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13517 fcmovF_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13518 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13519 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13520
a61af66fc99e Initial load
duke
parents:
diff changeset
13521 instruct cmovXX_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13522 predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
a61af66fc99e Initial load
duke
parents:
diff changeset
13523 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13524 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13525 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13526 fcmovX_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13527 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13528 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13529
a61af66fc99e Initial load
duke
parents:
diff changeset
13530 //======
a61af66fc99e Initial load
duke
parents:
diff changeset
13531 // Manifest a CmpL result in the normal flags. Only good for EQ/NE compares.
a61af66fc99e Initial load
duke
parents:
diff changeset
13532 instruct cmpL_zero_flags_EQNE( flagsReg_long_EQNE flags, eRegL src, immL0 zero, eRegI tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13533 match( Set flags (CmpL src zero ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13534 effect(TEMP tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
13535 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13536 format %{ "MOV $tmp,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13537 "OR $tmp,$src.hi\t! Long is EQ/NE 0?" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13538 ins_encode( long_cmp_flags0( src, tmp ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13539 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
13540 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13541
a61af66fc99e Initial load
duke
parents:
diff changeset
13542 // Manifest a CmpL result in the normal flags. Only good for EQ/NE compares.
a61af66fc99e Initial load
duke
parents:
diff changeset
13543 instruct cmpL_reg_flags_EQNE( flagsReg_long_EQNE flags, eRegL src1, eRegL src2 ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13544 match( Set flags (CmpL src1 src2 ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13545 ins_cost(200+300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13546 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13547 "JNE,s skip\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13548 "CMP $src1.hi,$src2.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13549 "skip:\t" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13550 ins_encode( long_cmp_flags1( src1, src2 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13551 ins_pipe( ialu_cr_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13552 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13553
a61af66fc99e Initial load
duke
parents:
diff changeset
13554 // Long compare reg == zero/reg OR reg != zero/reg
a61af66fc99e Initial load
duke
parents:
diff changeset
13555 // Just a wrapper for a normal branch, plus the predicate test.
a61af66fc99e Initial load
duke
parents:
diff changeset
13556 instruct cmpL_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13557 match(If cmp flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
13558 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13559 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
a61af66fc99e Initial load
duke
parents:
diff changeset
13560 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13561 jmpCon(cmp,flags,labl); // JEQ or JNE...
a61af66fc99e Initial load
duke
parents:
diff changeset
13562 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13563 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13564
a61af66fc99e Initial load
duke
parents:
diff changeset
13565 // Compare 2 longs and CMOVE longs.
a61af66fc99e Initial load
duke
parents:
diff changeset
13566 instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13567 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13568 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13569 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
13570 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13571 "CMOV$cmp $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13572 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13573 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13574 ins_pipe( pipe_cmov_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
13575 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13576
a61af66fc99e Initial load
duke
parents:
diff changeset
13577 instruct cmovLL_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, load_long_memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13578 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
13579 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13580 ins_cost(500);
a61af66fc99e Initial load
duke
parents:
diff changeset
13581 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13582 "CMOV$cmp $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13583 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13584 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13585 ins_pipe( pipe_cmov_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
13586 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13587
a61af66fc99e Initial load
duke
parents:
diff changeset
13588 // Compare 2 longs and CMOVE ints.
a61af66fc99e Initial load
duke
parents:
diff changeset
13589 instruct cmovII_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegI dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13590 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13591 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13592 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13593 format %{ "CMOV$cmp $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13594 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13595 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13596 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13597 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13598
a61af66fc99e Initial load
duke
parents:
diff changeset
13599 instruct cmovII_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegI dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13600 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13601 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
13602 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
13603 format %{ "CMOV$cmp $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13604 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13605 ins_encode( enc_cmov(cmp), RegMem( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13606 ins_pipe( pipe_cmov_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
13607 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13608
a61af66fc99e Initial load
duke
parents:
diff changeset
13609 // Compare 2 longs and CMOVE ints.
a61af66fc99e Initial load
duke
parents:
diff changeset
13610 instruct cmovPP_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegP dst, eRegP src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13611 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13612 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13613 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13614 format %{ "CMOV$cmp $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13615 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13616 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13617 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13618 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13619
a61af66fc99e Initial load
duke
parents:
diff changeset
13620 // Compare 2 longs and CMOVE doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
13621 instruct cmovDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13622 predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
a61af66fc99e Initial load
duke
parents:
diff changeset
13623 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13624 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13625 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13626 fcmovD_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13627 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13628 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13629
a61af66fc99e Initial load
duke
parents:
diff changeset
13630 // Compare 2 longs and CMOVE doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
13631 instruct cmovXDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13632 predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
a61af66fc99e Initial load
duke
parents:
diff changeset
13633 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13634 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13635 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13636 fcmovXD_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13637 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13638 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13639
a61af66fc99e Initial load
duke
parents:
diff changeset
13640 instruct cmovFF_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regF dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13641 predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
a61af66fc99e Initial load
duke
parents:
diff changeset
13642 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13643 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13644 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13645 fcmovF_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13646 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13647 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13648
a61af66fc99e Initial load
duke
parents:
diff changeset
13649 instruct cmovXX_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13650 predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
a61af66fc99e Initial load
duke
parents:
diff changeset
13651 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13652 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13653 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13654 fcmovX_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13655 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13656 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13657
a61af66fc99e Initial load
duke
parents:
diff changeset
13658 //======
a61af66fc99e Initial load
duke
parents:
diff changeset
13659 // Manifest a CmpL result in the normal flags. Only good for LE or GT compares.
a61af66fc99e Initial load
duke
parents:
diff changeset
13660 // Same as cmpL_reg_flags_LEGT except must negate src
a61af66fc99e Initial load
duke
parents:
diff changeset
13661 instruct cmpL_zero_flags_LEGT( flagsReg_long_LEGT flags, eRegL src, immL0 zero, eRegI tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13662 match( Set flags (CmpL src zero ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13663 effect( TEMP tmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13664 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13665 format %{ "XOR $tmp,$tmp\t# Long compare for -$src < 0, use commuted test\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13666 "CMP $tmp,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13667 "SBB $tmp,$src.hi\n\t" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13668 ins_encode( long_cmp_flags3(src, tmp) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13669 ins_pipe( ialu_reg_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
13670 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13671
a61af66fc99e Initial load
duke
parents:
diff changeset
13672 // Manifest a CmpL result in the normal flags. Only good for LE or GT compares.
a61af66fc99e Initial load
duke
parents:
diff changeset
13673 // Same as cmpL_reg_flags_LTGE except operands swapped. Swapping operands
a61af66fc99e Initial load
duke
parents:
diff changeset
13674 // requires a commuted test to get the same result.
a61af66fc99e Initial load
duke
parents:
diff changeset
13675 instruct cmpL_reg_flags_LEGT( flagsReg_long_LEGT flags, eRegL src1, eRegL src2, eRegI tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13676 match( Set flags (CmpL src1 src2 ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13677 effect( TEMP tmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13678 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13679 format %{ "CMP $src2.lo,$src1.lo\t! Long compare, swapped operands, use with commuted test\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13680 "MOV $tmp,$src2.hi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13681 "SBB $tmp,$src1.hi\t! Compute flags for long compare" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13682 ins_encode( long_cmp_flags2( src2, src1, tmp ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13683 ins_pipe( ialu_cr_reg_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13684 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13685
a61af66fc99e Initial load
duke
parents:
diff changeset
13686 // Long compares reg < zero/req OR reg >= zero/req.
a61af66fc99e Initial load
duke
parents:
diff changeset
13687 // Just a wrapper for a normal branch, plus the predicate test
a61af66fc99e Initial load
duke
parents:
diff changeset
13688 instruct cmpL_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, label labl) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13689 match(If cmp flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
13690 effect(USE labl);
a61af66fc99e Initial load
duke
parents:
diff changeset
13691 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
a61af66fc99e Initial load
duke
parents:
diff changeset
13692 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13693 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13694 jmpCon(cmp,flags,labl); // JGT or JLE...
a61af66fc99e Initial load
duke
parents:
diff changeset
13695 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13696 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13697
a61af66fc99e Initial load
duke
parents:
diff changeset
13698 // Compare 2 longs and CMOVE longs.
a61af66fc99e Initial load
duke
parents:
diff changeset
13699 instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13700 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13701 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13702 ins_cost(400);
a61af66fc99e Initial load
duke
parents:
diff changeset
13703 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13704 "CMOV$cmp $dst.hi,$src.hi" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13705 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13706 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13707 ins_pipe( pipe_cmov_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
13708 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13709
a61af66fc99e Initial load
duke
parents:
diff changeset
13710 instruct cmovLL_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, load_long_memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13711 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
13712 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13713 ins_cost(500);
a61af66fc99e Initial load
duke
parents:
diff changeset
13714 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13715 "CMOV$cmp $dst.hi,$src.hi+4" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13716 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13717 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13718 ins_pipe( pipe_cmov_reg_long );
a61af66fc99e Initial load
duke
parents:
diff changeset
13719 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13720
a61af66fc99e Initial load
duke
parents:
diff changeset
13721 // Compare 2 longs and CMOVE ints.
a61af66fc99e Initial load
duke
parents:
diff changeset
13722 instruct cmovII_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegI dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13723 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13724 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13725 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13726 format %{ "CMOV$cmp $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13727 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13728 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13729 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13730 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13731
a61af66fc99e Initial load
duke
parents:
diff changeset
13732 instruct cmovII_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegI dst, memory src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13733 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13734 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
a61af66fc99e Initial load
duke
parents:
diff changeset
13735 ins_cost(250);
a61af66fc99e Initial load
duke
parents:
diff changeset
13736 format %{ "CMOV$cmp $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13737 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13738 ins_encode( enc_cmov(cmp), RegMem( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13739 ins_pipe( pipe_cmov_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
13740 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13741
a61af66fc99e Initial load
duke
parents:
diff changeset
13742 // Compare 2 longs and CMOVE ptrs.
a61af66fc99e Initial load
duke
parents:
diff changeset
13743 instruct cmovPP_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegP dst, eRegP src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13744 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
a61af66fc99e Initial load
duke
parents:
diff changeset
13745 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13746 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13747 format %{ "CMOV$cmp $dst,$src" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13748 opcode(0x0F,0x40);
a61af66fc99e Initial load
duke
parents:
diff changeset
13749 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13750 ins_pipe( pipe_cmov_reg );
a61af66fc99e Initial load
duke
parents:
diff changeset
13751 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13752
a61af66fc99e Initial load
duke
parents:
diff changeset
13753 // Compare 2 longs and CMOVE doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
13754 instruct cmovDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regD dst, regD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13755 predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
a61af66fc99e Initial load
duke
parents:
diff changeset
13756 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13757 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13758 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13759 fcmovD_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13760 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13761 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13762
a61af66fc99e Initial load
duke
parents:
diff changeset
13763 // Compare 2 longs and CMOVE doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
13764 instruct cmovXDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regXD dst, regXD src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13765 predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
a61af66fc99e Initial load
duke
parents:
diff changeset
13766 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13767 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13768 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13769 fcmovXD_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13770 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13771 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13772
a61af66fc99e Initial load
duke
parents:
diff changeset
13773 instruct cmovFF_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regF dst, regF src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13774 predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
a61af66fc99e Initial load
duke
parents:
diff changeset
13775 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13776 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13777 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13778 fcmovF_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13779 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13780 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13781
a61af66fc99e Initial load
duke
parents:
diff changeset
13782
a61af66fc99e Initial load
duke
parents:
diff changeset
13783 instruct cmovXX_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regX dst, regX src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13784 predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
a61af66fc99e Initial load
duke
parents:
diff changeset
13785 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
a61af66fc99e Initial load
duke
parents:
diff changeset
13786 ins_cost(200);
a61af66fc99e Initial load
duke
parents:
diff changeset
13787 expand %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13788 fcmovX_regS(cmp,flags,dst,src);
a61af66fc99e Initial load
duke
parents:
diff changeset
13789 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13790 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13791
a61af66fc99e Initial load
duke
parents:
diff changeset
13792
a61af66fc99e Initial load
duke
parents:
diff changeset
13793 // ============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
13794 // Procedure Call/Return Instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
13795 // Call Java Static Instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
13796 // Note: If this code changes, the corresponding ret_addr_offset() and
a61af66fc99e Initial load
duke
parents:
diff changeset
13797 // compute_padding() functions will have to be adjusted.
a61af66fc99e Initial load
duke
parents:
diff changeset
13798 instruct CallStaticJavaDirect(method meth) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13799 match(CallStaticJava);
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13800 predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13801 effect(USE meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
13802
a61af66fc99e Initial load
duke
parents:
diff changeset
13803 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13804 format %{ "CALL,static " %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13805 opcode(0xE8); /* E8 cd */
a61af66fc99e Initial load
duke
parents:
diff changeset
13806 ins_encode( pre_call_FPU,
a61af66fc99e Initial load
duke
parents:
diff changeset
13807 Java_Static_Call( meth ),
a61af66fc99e Initial load
duke
parents:
diff changeset
13808 call_epilog,
a61af66fc99e Initial load
duke
parents:
diff changeset
13809 post_call_FPU );
a61af66fc99e Initial load
duke
parents:
diff changeset
13810 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13811 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13812 ins_alignment(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
13813 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13814
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13815 // Call Java Static Instruction (method handle version)
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13816 // Note: If this code changes, the corresponding ret_addr_offset() and
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13817 // compute_padding() functions will have to be adjusted.
1567
110501f54a99 6934104: JSR 292 needs to support SPARC C2
twisti
parents: 1396
diff changeset
13818 instruct CallStaticJavaHandle(method meth, eBPRegP ebp_mh_SP_save) %{
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13819 match(CallStaticJava);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13820 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13821 effect(USE meth);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13822 // EBP is saved by all callees (for interpreter stack correction).
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13823 // We use it here for a similar purpose, in {preserve,restore}_SP.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13824
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13825 ins_cost(300);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13826 format %{ "CALL,static/MethodHandle " %}
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13827 opcode(0xE8); /* E8 cd */
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13828 ins_encode( pre_call_FPU,
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13829 preserve_SP,
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13830 Java_Static_Call( meth ),
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13831 restore_SP,
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13832 call_epilog,
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13833 post_call_FPU );
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13834 ins_pipe( pipe_slow );
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13835 ins_pc_relative(1);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13836 ins_alignment(4);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13837 %}
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 989
diff changeset
13838
0
a61af66fc99e Initial load
duke
parents:
diff changeset
13839 // Call Java Dynamic Instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
13840 // Note: If this code changes, the corresponding ret_addr_offset() and
a61af66fc99e Initial load
duke
parents:
diff changeset
13841 // compute_padding() functions will have to be adjusted.
a61af66fc99e Initial load
duke
parents:
diff changeset
13842 instruct CallDynamicJavaDirect(method meth) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13843 match(CallDynamicJava);
a61af66fc99e Initial load
duke
parents:
diff changeset
13844 effect(USE meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
13845
a61af66fc99e Initial load
duke
parents:
diff changeset
13846 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13847 format %{ "MOV EAX,(oop)-1\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13848 "CALL,dynamic" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13849 opcode(0xE8); /* E8 cd */
a61af66fc99e Initial load
duke
parents:
diff changeset
13850 ins_encode( pre_call_FPU,
a61af66fc99e Initial load
duke
parents:
diff changeset
13851 Java_Dynamic_Call( meth ),
a61af66fc99e Initial load
duke
parents:
diff changeset
13852 call_epilog,
a61af66fc99e Initial load
duke
parents:
diff changeset
13853 post_call_FPU );
a61af66fc99e Initial load
duke
parents:
diff changeset
13854 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13855 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13856 ins_alignment(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
13857 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13858
a61af66fc99e Initial load
duke
parents:
diff changeset
13859 // Call Runtime Instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
13860 instruct CallRuntimeDirect(method meth) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13861 match(CallRuntime );
a61af66fc99e Initial load
duke
parents:
diff changeset
13862 effect(USE meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
13863
a61af66fc99e Initial load
duke
parents:
diff changeset
13864 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13865 format %{ "CALL,runtime " %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13866 opcode(0xE8); /* E8 cd */
a61af66fc99e Initial load
duke
parents:
diff changeset
13867 // Use FFREEs to clear entries in float stack
a61af66fc99e Initial load
duke
parents:
diff changeset
13868 ins_encode( pre_call_FPU,
a61af66fc99e Initial load
duke
parents:
diff changeset
13869 FFree_Float_Stack_All,
a61af66fc99e Initial load
duke
parents:
diff changeset
13870 Java_To_Runtime( meth ),
a61af66fc99e Initial load
duke
parents:
diff changeset
13871 post_call_FPU );
a61af66fc99e Initial load
duke
parents:
diff changeset
13872 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13873 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13874 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13875
a61af66fc99e Initial load
duke
parents:
diff changeset
13876 // Call runtime without safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
13877 instruct CallLeafDirect(method meth) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13878 match(CallLeaf);
a61af66fc99e Initial load
duke
parents:
diff changeset
13879 effect(USE meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
13880
a61af66fc99e Initial load
duke
parents:
diff changeset
13881 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13882 format %{ "CALL_LEAF,runtime " %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13883 opcode(0xE8); /* E8 cd */
a61af66fc99e Initial load
duke
parents:
diff changeset
13884 ins_encode( pre_call_FPU,
a61af66fc99e Initial load
duke
parents:
diff changeset
13885 FFree_Float_Stack_All,
a61af66fc99e Initial load
duke
parents:
diff changeset
13886 Java_To_Runtime( meth ),
a61af66fc99e Initial load
duke
parents:
diff changeset
13887 Verify_FPU_For_Leaf, post_call_FPU );
a61af66fc99e Initial load
duke
parents:
diff changeset
13888 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13889 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13890 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13891
a61af66fc99e Initial load
duke
parents:
diff changeset
13892 instruct CallLeafNoFPDirect(method meth) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13893 match(CallLeafNoFP);
a61af66fc99e Initial load
duke
parents:
diff changeset
13894 effect(USE meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
13895
a61af66fc99e Initial load
duke
parents:
diff changeset
13896 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13897 format %{ "CALL_LEAF_NOFP,runtime " %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13898 opcode(0xE8); /* E8 cd */
a61af66fc99e Initial load
duke
parents:
diff changeset
13899 ins_encode(Java_To_Runtime(meth));
a61af66fc99e Initial load
duke
parents:
diff changeset
13900 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13901 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13902 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13903
a61af66fc99e Initial load
duke
parents:
diff changeset
13904
a61af66fc99e Initial load
duke
parents:
diff changeset
13905 // Return Instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
13906 // Remove the return address & jump to it.
a61af66fc99e Initial load
duke
parents:
diff changeset
13907 instruct Ret() %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13908 match(Return);
a61af66fc99e Initial load
duke
parents:
diff changeset
13909 format %{ "RET" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13910 opcode(0xC3);
a61af66fc99e Initial load
duke
parents:
diff changeset
13911 ins_encode(OpcP);
a61af66fc99e Initial load
duke
parents:
diff changeset
13912 ins_pipe( pipe_jmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13913 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13914
a61af66fc99e Initial load
duke
parents:
diff changeset
13915 // Tail Call; Jump from runtime stub to Java code.
a61af66fc99e Initial load
duke
parents:
diff changeset
13916 // Also known as an 'interprocedural jump'.
a61af66fc99e Initial load
duke
parents:
diff changeset
13917 // Target of jump will eventually return to caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
13918 // TailJump below removes the return address.
a61af66fc99e Initial load
duke
parents:
diff changeset
13919 instruct TailCalljmpInd(eRegP_no_EBP jump_target, eBXRegP method_oop) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13920 match(TailCall jump_target method_oop );
a61af66fc99e Initial load
duke
parents:
diff changeset
13921 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13922 format %{ "JMP $jump_target \t# EBX holds method oop" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13923 opcode(0xFF, 0x4); /* Opcode FF /4 */
a61af66fc99e Initial load
duke
parents:
diff changeset
13924 ins_encode( OpcP, RegOpc(jump_target) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13925 ins_pipe( pipe_jmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13926 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13927
a61af66fc99e Initial load
duke
parents:
diff changeset
13928
a61af66fc99e Initial load
duke
parents:
diff changeset
13929 // Tail Jump; remove the return address; jump to target.
a61af66fc99e Initial load
duke
parents:
diff changeset
13930 // TailCall above leaves the return address around.
a61af66fc99e Initial load
duke
parents:
diff changeset
13931 instruct tailjmpInd(eRegP_no_EBP jump_target, eAXRegP ex_oop) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13932 match( TailJump jump_target ex_oop );
a61af66fc99e Initial load
duke
parents:
diff changeset
13933 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13934 format %{ "POP EDX\t# pop return address into dummy\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
13935 "JMP $jump_target " %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13936 opcode(0xFF, 0x4); /* Opcode FF /4 */
a61af66fc99e Initial load
duke
parents:
diff changeset
13937 ins_encode( enc_pop_rdx,
a61af66fc99e Initial load
duke
parents:
diff changeset
13938 OpcP, RegOpc(jump_target) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13939 ins_pipe( pipe_jmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13940 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13941
a61af66fc99e Initial load
duke
parents:
diff changeset
13942 // Create exception oop: created by stack-crawling runtime code.
a61af66fc99e Initial load
duke
parents:
diff changeset
13943 // Created exception is now available to this handler, and is setup
a61af66fc99e Initial load
duke
parents:
diff changeset
13944 // just prior to jumping to this handler. No code emitted.
a61af66fc99e Initial load
duke
parents:
diff changeset
13945 instruct CreateException( eAXRegP ex_oop )
a61af66fc99e Initial load
duke
parents:
diff changeset
13946 %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13947 match(Set ex_oop (CreateEx));
a61af66fc99e Initial load
duke
parents:
diff changeset
13948
a61af66fc99e Initial load
duke
parents:
diff changeset
13949 size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
13950 // use the following format syntax
a61af66fc99e Initial load
duke
parents:
diff changeset
13951 format %{ "# exception oop is in EAX; no code emitted" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13952 ins_encode();
a61af66fc99e Initial load
duke
parents:
diff changeset
13953 ins_pipe( empty );
a61af66fc99e Initial load
duke
parents:
diff changeset
13954 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13955
a61af66fc99e Initial load
duke
parents:
diff changeset
13956
a61af66fc99e Initial load
duke
parents:
diff changeset
13957 // Rethrow exception:
a61af66fc99e Initial load
duke
parents:
diff changeset
13958 // The exception oop will come in the first argument position.
a61af66fc99e Initial load
duke
parents:
diff changeset
13959 // Then JUMP (not call) to the rethrow stub code.
a61af66fc99e Initial load
duke
parents:
diff changeset
13960 instruct RethrowException()
a61af66fc99e Initial load
duke
parents:
diff changeset
13961 %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13962 match(Rethrow);
a61af66fc99e Initial load
duke
parents:
diff changeset
13963
a61af66fc99e Initial load
duke
parents:
diff changeset
13964 // use the following format syntax
a61af66fc99e Initial load
duke
parents:
diff changeset
13965 format %{ "JMP rethrow_stub" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13966 ins_encode(enc_rethrow);
a61af66fc99e Initial load
duke
parents:
diff changeset
13967 ins_pipe( pipe_jmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13968 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13969
a61af66fc99e Initial load
duke
parents:
diff changeset
13970 // inlined locking and unlocking
a61af66fc99e Initial load
duke
parents:
diff changeset
13971
a61af66fc99e Initial load
duke
parents:
diff changeset
13972
a61af66fc99e Initial load
duke
parents:
diff changeset
13973 instruct cmpFastLock( eFlagsReg cr, eRegP object, eRegP box, eAXRegI tmp, eRegP scr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13974 match( Set cr (FastLock object box) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13975 effect( TEMP tmp, TEMP scr );
a61af66fc99e Initial load
duke
parents:
diff changeset
13976 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13977 format %{ "FASTLOCK $object, $box KILLS $tmp,$scr" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13978 ins_encode( Fast_Lock(object,box,tmp,scr) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13979 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13980 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13981 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13982
a61af66fc99e Initial load
duke
parents:
diff changeset
13983 instruct cmpFastUnlock( eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13984 match( Set cr (FastUnlock object box) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13985 effect( TEMP tmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
13986 ins_cost(300);
a61af66fc99e Initial load
duke
parents:
diff changeset
13987 format %{ "FASTUNLOCK $object, $box, $tmp" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13988 ins_encode( Fast_Unlock(object,box,tmp) );
a61af66fc99e Initial load
duke
parents:
diff changeset
13989 ins_pipe( pipe_slow );
a61af66fc99e Initial load
duke
parents:
diff changeset
13990 ins_pc_relative(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
13991 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
13992
a61af66fc99e Initial load
duke
parents:
diff changeset
13993
a61af66fc99e Initial load
duke
parents:
diff changeset
13994
a61af66fc99e Initial load
duke
parents:
diff changeset
13995 // ============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
13996 // Safepoint Instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
13997 instruct safePoint_poll(eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
13998 match(SafePoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
13999 effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
14000
a61af66fc99e Initial load
duke
parents:
diff changeset
14001 // TODO-FIXME: we currently poll at offset 0 of the safepoint polling page.
a61af66fc99e Initial load
duke
parents:
diff changeset
14002 // On SPARC that might be acceptable as we can generate the address with
a61af66fc99e Initial load
duke
parents:
diff changeset
14003 // just a sethi, saving an or. By polling at offset 0 we can end up
a61af66fc99e Initial load
duke
parents:
diff changeset
14004 // putting additional pressure on the index-0 in the D$. Because of
a61af66fc99e Initial load
duke
parents:
diff changeset
14005 // alignment (just like the situation at hand) the lower indices tend
a61af66fc99e Initial load
duke
parents:
diff changeset
14006 // to see more traffic. It'd be better to change the polling address
a61af66fc99e Initial load
duke
parents:
diff changeset
14007 // to offset 0 of the last $line in the polling page.
a61af66fc99e Initial load
duke
parents:
diff changeset
14008
a61af66fc99e Initial load
duke
parents:
diff changeset
14009 format %{ "TSTL #polladdr,EAX\t! Safepoint: poll for GC" %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14010 ins_cost(125);
a61af66fc99e Initial load
duke
parents:
diff changeset
14011 size(6) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
14012 ins_encode( Safepoint_Poll() );
a61af66fc99e Initial load
duke
parents:
diff changeset
14013 ins_pipe( ialu_reg_mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
14014 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14015
a61af66fc99e Initial load
duke
parents:
diff changeset
14016 //----------PEEPHOLE RULES-----------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
14017 // These must follow all instruction definitions as they use the names
a61af66fc99e Initial load
duke
parents:
diff changeset
14018 // defined in the instructions definitions.
a61af66fc99e Initial load
duke
parents:
diff changeset
14019 //
605
98cb887364d3 6810672: Comment typos
twisti
parents: 570
diff changeset
14020 // peepmatch ( root_instr_name [preceding_instruction]* );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
14021 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14022 // peepconstraint %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14023 // (instruction_number.operand_name relational_op instruction_number.operand_name
a61af66fc99e Initial load
duke
parents:
diff changeset
14024 // [, ...] );
a61af66fc99e Initial load
duke
parents:
diff changeset
14025 // // instruction numbers are zero-based using left to right order in peepmatch
a61af66fc99e Initial load
duke
parents:
diff changeset
14026 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14027 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
14028 // // provide an instruction_number.operand_name for each operand that appears
a61af66fc99e Initial load
duke
parents:
diff changeset
14029 // // in the replacement instruction's match rule
a61af66fc99e Initial load
duke
parents:
diff changeset
14030 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14031 // ---------VM FLAGS---------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
14032 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14033 // All peephole optimizations can be turned off using -XX:-OptoPeephole
a61af66fc99e Initial load
duke
parents:
diff changeset
14034 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14035 // Each peephole rule is given an identifying number starting with zero and
a61af66fc99e Initial load
duke
parents:
diff changeset
14036 // increasing by one in the order seen by the parser. An individual peephole
a61af66fc99e Initial load
duke
parents:
diff changeset
14037 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
a61af66fc99e Initial load
duke
parents:
diff changeset
14038 // on the command-line.
a61af66fc99e Initial load
duke
parents:
diff changeset
14039 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14040 // ---------CURRENT LIMITATIONS----------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
14041 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14042 // Only match adjacent instructions in same basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
14043 // Only equality constraints
a61af66fc99e Initial load
duke
parents:
diff changeset
14044 // Only constraints between operands, not (0.dest_reg == EAX_enc)
a61af66fc99e Initial load
duke
parents:
diff changeset
14045 // Only one replacement instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
14046 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14047 // ---------EXAMPLE----------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
14048 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14049 // // pertinent parts of existing instructions in architecture description
a61af66fc99e Initial load
duke
parents:
diff changeset
14050 // instruct movI(eRegI dst, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14051 // match(Set dst (CopyI src));
a61af66fc99e Initial load
duke
parents:
diff changeset
14052 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14053 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14054 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14055 // match(Set dst (AddI dst src));
a61af66fc99e Initial load
duke
parents:
diff changeset
14056 // effect(KILL cr);
a61af66fc99e Initial load
duke
parents:
diff changeset
14057 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14058 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14059 // // Change (inc mov) to lea
a61af66fc99e Initial load
duke
parents:
diff changeset
14060 // peephole %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14061 // // increment preceeded by register-register move
a61af66fc99e Initial load
duke
parents:
diff changeset
14062 // peepmatch ( incI_eReg movI );
a61af66fc99e Initial load
duke
parents:
diff changeset
14063 // // require that the destination register of the increment
a61af66fc99e Initial load
duke
parents:
diff changeset
14064 // // match the destination register of the move
a61af66fc99e Initial load
duke
parents:
diff changeset
14065 // peepconstraint ( 0.dst == 1.dst );
a61af66fc99e Initial load
duke
parents:
diff changeset
14066 // // construct a replacement instruction that sets
a61af66fc99e Initial load
duke
parents:
diff changeset
14067 // // the destination to ( move's source register + one )
a61af66fc99e Initial load
duke
parents:
diff changeset
14068 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
14069 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14070 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14071 // Implementation no longer uses movX instructions since
a61af66fc99e Initial load
duke
parents:
diff changeset
14072 // machine-independent system no longer uses CopyX nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
14073 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14074 // peephole %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14075 // peepmatch ( incI_eReg movI );
a61af66fc99e Initial load
duke
parents:
diff changeset
14076 // peepconstraint ( 0.dst == 1.dst );
a61af66fc99e Initial load
duke
parents:
diff changeset
14077 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
14078 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14079 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14080 // peephole %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14081 // peepmatch ( decI_eReg movI );
a61af66fc99e Initial load
duke
parents:
diff changeset
14082 // peepconstraint ( 0.dst == 1.dst );
a61af66fc99e Initial load
duke
parents:
diff changeset
14083 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
14084 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14085 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14086 // peephole %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14087 // peepmatch ( addI_eReg_imm movI );
a61af66fc99e Initial load
duke
parents:
diff changeset
14088 // peepconstraint ( 0.dst == 1.dst );
a61af66fc99e Initial load
duke
parents:
diff changeset
14089 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
14090 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14091 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14092 // peephole %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14093 // peepmatch ( addP_eReg_imm movP );
a61af66fc99e Initial load
duke
parents:
diff changeset
14094 // peepconstraint ( 0.dst == 1.dst );
a61af66fc99e Initial load
duke
parents:
diff changeset
14095 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
14096 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14097
a61af66fc99e Initial load
duke
parents:
diff changeset
14098 // // Change load of spilled value to only a spill
a61af66fc99e Initial load
duke
parents:
diff changeset
14099 // instruct storeI(memory mem, eRegI src) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14100 // match(Set mem (StoreI mem src));
a61af66fc99e Initial load
duke
parents:
diff changeset
14101 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14102 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14103 // instruct loadI(eRegI dst, memory mem) %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14104 // match(Set dst (LoadI mem));
a61af66fc99e Initial load
duke
parents:
diff changeset
14105 // %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14106 //
a61af66fc99e Initial load
duke
parents:
diff changeset
14107 peephole %{
a61af66fc99e Initial load
duke
parents:
diff changeset
14108 peepmatch ( loadI storeI );
a61af66fc99e Initial load
duke
parents:
diff changeset
14109 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
14110 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
14111 %}
a61af66fc99e Initial load
duke
parents:
diff changeset
14112
a61af66fc99e Initial load
duke
parents:
diff changeset
14113 //----------SMARTSPILL RULES---------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
14114 // These must follow all instruction definitions as they use the names
a61af66fc99e Initial load
duke
parents:
diff changeset
14115 // defined in the instructions definitions.