65 address start = __ pc(); |
65 address start = __ pc(); |
66 |
66 |
67 // |
67 // |
68 // void getPsrInfo(VM_Version::CpuidInfo* cpuid_info); |
68 // void getPsrInfo(VM_Version::CpuidInfo* cpuid_info); |
69 // |
69 // |
70 __ pushl(rbp); |
70 __ push(rbp); |
71 __ movl(rbp, Address(rsp, 8)); // cpuid_info address |
71 __ movptr(rbp, Address(rsp, 8)); // cpuid_info address |
72 __ pushl(rbx); |
72 __ push(rbx); |
73 __ pushl(rsi); |
73 __ push(rsi); |
74 __ pushfd(); // preserve rbx, and flags |
74 __ pushf(); // preserve rbx, and flags |
75 __ popl(rax); |
75 __ pop(rax); |
76 __ pushl(rax); |
76 __ push(rax); |
77 __ movl(rcx, rax); |
77 __ mov(rcx, rax); |
78 // |
78 // |
79 // if we are unable to change the AC flag, we have a 386 |
79 // if we are unable to change the AC flag, we have a 386 |
80 // |
80 // |
81 __ xorl(rax, EFL_AC); |
81 __ xorl(rax, EFL_AC); |
82 __ pushl(rax); |
82 __ push(rax); |
83 __ popfd(); |
83 __ popf(); |
84 __ pushfd(); |
84 __ pushf(); |
85 __ popl(rax); |
85 __ pop(rax); |
86 __ cmpl(rax, rcx); |
86 __ cmpptr(rax, rcx); |
87 __ jccb(Assembler::notEqual, detect_486); |
87 __ jccb(Assembler::notEqual, detect_486); |
88 |
88 |
89 __ movl(rax, CPU_FAMILY_386); |
89 __ movl(rax, CPU_FAMILY_386); |
90 __ movl(Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())), rax); |
90 __ movl(Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())), rax); |
91 __ jmp(done); |
91 __ jmp(done); |
93 // |
93 // |
94 // If we are unable to change the ID flag, we have a 486 which does |
94 // If we are unable to change the ID flag, we have a 486 which does |
95 // not support the "cpuid" instruction. |
95 // not support the "cpuid" instruction. |
96 // |
96 // |
97 __ bind(detect_486); |
97 __ bind(detect_486); |
98 __ movl(rax, rcx); |
98 __ mov(rax, rcx); |
99 __ xorl(rax, EFL_ID); |
99 __ xorl(rax, EFL_ID); |
100 __ pushl(rax); |
100 __ push(rax); |
101 __ popfd(); |
101 __ popf(); |
102 __ pushfd(); |
102 __ pushf(); |
103 __ popl(rax); |
103 __ pop(rax); |
104 __ cmpl(rcx, rax); |
104 __ cmpptr(rcx, rax); |
105 __ jccb(Assembler::notEqual, detect_586); |
105 __ jccb(Assembler::notEqual, detect_586); |
106 |
106 |
107 __ bind(cpu486); |
107 __ bind(cpu486); |
108 __ movl(rax, CPU_FAMILY_486); |
108 __ movl(rax, CPU_FAMILY_486); |
109 __ movl(Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())), rax); |
109 __ movl(Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())), rax); |
111 |
111 |
112 // |
112 // |
113 // at this point, we have a chip which supports the "cpuid" instruction |
113 // at this point, we have a chip which supports the "cpuid" instruction |
114 // |
114 // |
115 __ bind(detect_586); |
115 __ bind(detect_586); |
116 __ xorl(rax, rax); |
116 __ xorptr(rax, rax); |
117 __ cpuid(); |
117 __ cpuid(); |
118 __ orl(rax, rax); |
118 __ orptr(rax, rax); |
119 __ jcc(Assembler::equal, cpu486); // if cpuid doesn't support an input |
119 __ jcc(Assembler::equal, cpu486); // if cpuid doesn't support an input |
120 // value of at least 1, we give up and |
120 // value of at least 1, we give up and |
121 // assume a 486 |
121 // assume a 486 |
122 __ leal(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); |
122 __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); |
123 __ movl(Address(rsi, 0), rax); |
123 __ movl(Address(rsi, 0), rax); |
124 __ movl(Address(rsi, 4), rbx); |
124 __ movl(Address(rsi, 4), rbx); |
125 __ movl(Address(rsi, 8), rcx); |
125 __ movl(Address(rsi, 8), rcx); |
126 __ movl(Address(rsi,12), rdx); |
126 __ movl(Address(rsi,12), rdx); |
127 |
127 |
132 // cpuid(0x4) Deterministic cache params |
132 // cpuid(0x4) Deterministic cache params |
133 // |
133 // |
134 __ movl(rax, 4); // and rcx already set to 0x0 |
134 __ movl(rax, 4); // and rcx already set to 0x0 |
135 __ xorl(rcx, rcx); |
135 __ xorl(rcx, rcx); |
136 __ cpuid(); |
136 __ cpuid(); |
137 __ pushl(rax); |
137 __ push(rax); |
138 __ andl(rax, 0x1f); // Determine if valid cache parameters used |
138 __ andl(rax, 0x1f); // Determine if valid cache parameters used |
139 __ orl(rax, rax); // rax,[4:0] == 0 indicates invalid cache |
139 __ orl(rax, rax); // rax,[4:0] == 0 indicates invalid cache |
140 __ popl(rax); |
140 __ pop(rax); |
141 __ jccb(Assembler::equal, std_cpuid1); |
141 __ jccb(Assembler::equal, std_cpuid1); |
142 |
142 |
143 __ leal(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); |
143 __ lea(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset()))); |
144 __ movl(Address(rsi, 0), rax); |
144 __ movl(Address(rsi, 0), rax); |
145 __ movl(Address(rsi, 4), rbx); |
145 __ movl(Address(rsi, 4), rbx); |
146 __ movl(Address(rsi, 8), rcx); |
146 __ movl(Address(rsi, 8), rcx); |
147 __ movl(Address(rsi,12), rdx); |
147 __ movl(Address(rsi,12), rdx); |
148 |
148 |
150 // Standard cpuid(0x1) |
150 // Standard cpuid(0x1) |
151 // |
151 // |
152 __ bind(std_cpuid1); |
152 __ bind(std_cpuid1); |
153 __ movl(rax, 1); |
153 __ movl(rax, 1); |
154 __ cpuid(); |
154 __ cpuid(); |
155 __ leal(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); |
155 __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset()))); |
156 __ movl(Address(rsi, 0), rax); |
156 __ movl(Address(rsi, 0), rax); |
157 __ movl(Address(rsi, 4), rbx); |
157 __ movl(Address(rsi, 4), rbx); |
158 __ movl(Address(rsi, 8), rcx); |
158 __ movl(Address(rsi, 8), rcx); |
159 __ movl(Address(rsi,12), rdx); |
159 __ movl(Address(rsi,12), rdx); |
160 |
160 |
169 // |
169 // |
170 // Extended cpuid(0x80000008) |
170 // Extended cpuid(0x80000008) |
171 // |
171 // |
172 __ movl(rax, 0x80000008); |
172 __ movl(rax, 0x80000008); |
173 __ cpuid(); |
173 __ cpuid(); |
174 __ leal(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); |
174 __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset()))); |
175 __ movl(Address(rsi, 0), rax); |
175 __ movl(Address(rsi, 0), rax); |
176 __ movl(Address(rsi, 4), rbx); |
176 __ movl(Address(rsi, 4), rbx); |
177 __ movl(Address(rsi, 8), rcx); |
177 __ movl(Address(rsi, 8), rcx); |
178 __ movl(Address(rsi,12), rdx); |
178 __ movl(Address(rsi,12), rdx); |
179 |
179 |
181 // Extended cpuid(0x80000005) |
181 // Extended cpuid(0x80000005) |
182 // |
182 // |
183 __ bind(ext_cpuid5); |
183 __ bind(ext_cpuid5); |
184 __ movl(rax, 0x80000005); |
184 __ movl(rax, 0x80000005); |
185 __ cpuid(); |
185 __ cpuid(); |
186 __ leal(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); |
186 __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset()))); |
187 __ movl(Address(rsi, 0), rax); |
187 __ movl(Address(rsi, 0), rax); |
188 __ movl(Address(rsi, 4), rbx); |
188 __ movl(Address(rsi, 4), rbx); |
189 __ movl(Address(rsi, 8), rcx); |
189 __ movl(Address(rsi, 8), rcx); |
190 __ movl(Address(rsi,12), rdx); |
190 __ movl(Address(rsi,12), rdx); |
191 |
191 |
193 // Extended cpuid(0x80000001) |
193 // Extended cpuid(0x80000001) |
194 // |
194 // |
195 __ bind(ext_cpuid1); |
195 __ bind(ext_cpuid1); |
196 __ movl(rax, 0x80000001); |
196 __ movl(rax, 0x80000001); |
197 __ cpuid(); |
197 __ cpuid(); |
198 __ leal(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); |
198 __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset()))); |
199 __ movl(Address(rsi, 0), rax); |
199 __ movl(Address(rsi, 0), rax); |
200 __ movl(Address(rsi, 4), rbx); |
200 __ movl(Address(rsi, 4), rbx); |
201 __ movl(Address(rsi, 8), rcx); |
201 __ movl(Address(rsi, 8), rcx); |
202 __ movl(Address(rsi,12), rdx); |
202 __ movl(Address(rsi,12), rdx); |
203 |
203 |
204 // |
204 // |
205 // return |
205 // return |
206 // |
206 // |
207 __ bind(done); |
207 __ bind(done); |
208 __ popfd(); |
208 __ popf(); |
209 __ popl(rsi); |
209 __ pop(rsi); |
210 __ popl(rbx); |
210 __ pop(rbx); |
211 __ popl(rbp); |
211 __ pop(rbp); |
212 __ ret(0); |
212 __ ret(0); |
213 |
213 |
214 # undef __ |
214 # undef __ |
215 |
215 |
216 return start; |
216 return start; |