OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 printf("Expected %.17f (0x%016" PRIx64 ")\t " | 88 printf("Expected %.17f (0x%016" PRIx64 ")\t " |
89 "Found %.17f (0x%016" PRIx64 ")\n", | 89 "Found %.17f (0x%016" PRIx64 ")\n", |
90 expected, double_to_rawbits(expected), | 90 expected, double_to_rawbits(expected), |
91 result, double_to_rawbits(result)); | 91 result, double_to_rawbits(result)); |
92 } | 92 } |
93 return false; | 93 return false; |
94 } | 94 } |
95 | 95 |
96 | 96 |
97 bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) { | 97 bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) { |
98 ASSERT(reg.Is32Bits()); | 98 DCHECK(reg.Is32Bits()); |
99 // Retrieve the corresponding X register so we can check that the upper part | 99 // Retrieve the corresponding X register so we can check that the upper part |
100 // was properly cleared. | 100 // was properly cleared. |
101 int64_t result_x = core->xreg(reg.code()); | 101 int64_t result_x = core->xreg(reg.code()); |
102 if ((result_x & 0xffffffff00000000L) != 0) { | 102 if ((result_x & 0xffffffff00000000L) != 0) { |
103 printf("Expected 0x%08" PRIx32 "\t Found 0x%016" PRIx64 "\n", | 103 printf("Expected 0x%08" PRIx32 "\t Found 0x%016" PRIx64 "\n", |
104 expected, result_x); | 104 expected, result_x); |
105 return false; | 105 return false; |
106 } | 106 } |
107 uint32_t result_w = core->wreg(reg.code()); | 107 uint32_t result_w = core->wreg(reg.code()); |
108 return Equal32(expected, core, result_w); | 108 return Equal32(expected, core, result_w); |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 bool Equal64(uint64_t expected, | 112 bool Equal64(uint64_t expected, |
113 const RegisterDump* core, | 113 const RegisterDump* core, |
114 const Register& reg) { | 114 const Register& reg) { |
115 ASSERT(reg.Is64Bits()); | 115 DCHECK(reg.Is64Bits()); |
116 uint64_t result = core->xreg(reg.code()); | 116 uint64_t result = core->xreg(reg.code()); |
117 return Equal64(expected, core, result); | 117 return Equal64(expected, core, result); |
118 } | 118 } |
119 | 119 |
120 | 120 |
121 bool EqualFP32(float expected, | 121 bool EqualFP32(float expected, |
122 const RegisterDump* core, | 122 const RegisterDump* core, |
123 const FPRegister& fpreg) { | 123 const FPRegister& fpreg) { |
124 ASSERT(fpreg.Is32Bits()); | 124 DCHECK(fpreg.Is32Bits()); |
125 // Retrieve the corresponding D register so we can check that the upper part | 125 // Retrieve the corresponding D register so we can check that the upper part |
126 // was properly cleared. | 126 // was properly cleared. |
127 uint64_t result_64 = core->dreg_bits(fpreg.code()); | 127 uint64_t result_64 = core->dreg_bits(fpreg.code()); |
128 if ((result_64 & 0xffffffff00000000L) != 0) { | 128 if ((result_64 & 0xffffffff00000000L) != 0) { |
129 printf("Expected 0x%08" PRIx32 " (%f)\t Found 0x%016" PRIx64 "\n", | 129 printf("Expected 0x%08" PRIx32 " (%f)\t Found 0x%016" PRIx64 "\n", |
130 float_to_rawbits(expected), expected, result_64); | 130 float_to_rawbits(expected), expected, result_64); |
131 return false; | 131 return false; |
132 } | 132 } |
133 | 133 |
134 return EqualFP32(expected, core, core->sreg(fpreg.code())); | 134 return EqualFP32(expected, core, core->sreg(fpreg.code())); |
135 } | 135 } |
136 | 136 |
137 | 137 |
138 bool EqualFP64(double expected, | 138 bool EqualFP64(double expected, |
139 const RegisterDump* core, | 139 const RegisterDump* core, |
140 const FPRegister& fpreg) { | 140 const FPRegister& fpreg) { |
141 ASSERT(fpreg.Is64Bits()); | 141 DCHECK(fpreg.Is64Bits()); |
142 return EqualFP64(expected, core, core->dreg(fpreg.code())); | 142 return EqualFP64(expected, core, core->dreg(fpreg.code())); |
143 } | 143 } |
144 | 144 |
145 | 145 |
146 bool Equal64(const Register& reg0, | 146 bool Equal64(const Register& reg0, |
147 const RegisterDump* core, | 147 const RegisterDump* core, |
148 const Register& reg1) { | 148 const Register& reg1) { |
149 ASSERT(reg0.Is64Bits() && reg1.Is64Bits()); | 149 DCHECK(reg0.Is64Bits() && reg1.Is64Bits()); |
150 int64_t expected = core->xreg(reg0.code()); | 150 int64_t expected = core->xreg(reg0.code()); |
151 int64_t result = core->xreg(reg1.code()); | 151 int64_t result = core->xreg(reg1.code()); |
152 return Equal64(expected, core, result); | 152 return Equal64(expected, core, result); |
153 } | 153 } |
154 | 154 |
155 | 155 |
156 static char FlagN(uint32_t flags) { | 156 static char FlagN(uint32_t flags) { |
157 return (flags & NFlag) ? 'N' : 'n'; | 157 return (flags & NFlag) ? 'N' : 'n'; |
158 } | 158 } |
159 | 159 |
160 | 160 |
161 static char FlagZ(uint32_t flags) { | 161 static char FlagZ(uint32_t flags) { |
162 return (flags & ZFlag) ? 'Z' : 'z'; | 162 return (flags & ZFlag) ? 'Z' : 'z'; |
163 } | 163 } |
164 | 164 |
165 | 165 |
166 static char FlagC(uint32_t flags) { | 166 static char FlagC(uint32_t flags) { |
167 return (flags & CFlag) ? 'C' : 'c'; | 167 return (flags & CFlag) ? 'C' : 'c'; |
168 } | 168 } |
169 | 169 |
170 | 170 |
171 static char FlagV(uint32_t flags) { | 171 static char FlagV(uint32_t flags) { |
172 return (flags & VFlag) ? 'V' : 'v'; | 172 return (flags & VFlag) ? 'V' : 'v'; |
173 } | 173 } |
174 | 174 |
175 | 175 |
176 bool EqualNzcv(uint32_t expected, uint32_t result) { | 176 bool EqualNzcv(uint32_t expected, uint32_t result) { |
177 ASSERT((expected & ~NZCVFlag) == 0); | 177 DCHECK((expected & ~NZCVFlag) == 0); |
178 ASSERT((result & ~NZCVFlag) == 0); | 178 DCHECK((result & ~NZCVFlag) == 0); |
179 if (result != expected) { | 179 if (result != expected) { |
180 printf("Expected: %c%c%c%c\t Found: %c%c%c%c\n", | 180 printf("Expected: %c%c%c%c\t Found: %c%c%c%c\n", |
181 FlagN(expected), FlagZ(expected), FlagC(expected), FlagV(expected), | 181 FlagN(expected), FlagZ(expected), FlagC(expected), FlagV(expected), |
182 FlagN(result), FlagZ(result), FlagC(result), FlagV(result)); | 182 FlagN(result), FlagZ(result), FlagC(result), FlagV(result)); |
183 return false; | 183 return false; |
184 } | 184 } |
185 | 185 |
186 return true; | 186 return true; |
187 } | 187 } |
188 | 188 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 x[i] = Register::Create(n, kXRegSizeInBits); | 224 x[i] = Register::Create(n, kXRegSizeInBits); |
225 } | 225 } |
226 if (w) { | 226 if (w) { |
227 w[i] = Register::Create(n, kWRegSizeInBits); | 227 w[i] = Register::Create(n, kWRegSizeInBits); |
228 } | 228 } |
229 list |= (1UL << n); | 229 list |= (1UL << n); |
230 i++; | 230 i++; |
231 } | 231 } |
232 } | 232 } |
233 // Check that we got enough registers. | 233 // Check that we got enough registers. |
234 ASSERT(CountSetBits(list, kNumberOfRegisters) == reg_count); | 234 DCHECK(CountSetBits(list, kNumberOfRegisters) == reg_count); |
235 | 235 |
236 return list; | 236 return list; |
237 } | 237 } |
238 | 238 |
239 | 239 |
240 RegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, | 240 RegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, |
241 int reg_size, int reg_count, RegList allowed) { | 241 int reg_size, int reg_count, RegList allowed) { |
242 RegList list = 0; | 242 RegList list = 0; |
243 int i = 0; | 243 int i = 0; |
244 for (unsigned n = 0; (n < kNumberOfFPRegisters) && (i < reg_count); n++) { | 244 for (unsigned n = 0; (n < kNumberOfFPRegisters) && (i < reg_count); n++) { |
245 if (((1UL << n) & allowed) != 0) { | 245 if (((1UL << n) & allowed) != 0) { |
246 // Only assigned allowed registers. | 246 // Only assigned allowed registers. |
247 if (v) { | 247 if (v) { |
248 v[i] = FPRegister::Create(n, reg_size); | 248 v[i] = FPRegister::Create(n, reg_size); |
249 } | 249 } |
250 if (d) { | 250 if (d) { |
251 d[i] = FPRegister::Create(n, kDRegSizeInBits); | 251 d[i] = FPRegister::Create(n, kDRegSizeInBits); |
252 } | 252 } |
253 if (s) { | 253 if (s) { |
254 s[i] = FPRegister::Create(n, kSRegSizeInBits); | 254 s[i] = FPRegister::Create(n, kSRegSizeInBits); |
255 } | 255 } |
256 list |= (1UL << n); | 256 list |= (1UL << n); |
257 i++; | 257 i++; |
258 } | 258 } |
259 } | 259 } |
260 // Check that we got enough registers. | 260 // Check that we got enough registers. |
261 ASSERT(CountSetBits(list, kNumberOfFPRegisters) == reg_count); | 261 DCHECK(CountSetBits(list, kNumberOfFPRegisters) == reg_count); |
262 | 262 |
263 return list; | 263 return list; |
264 } | 264 } |
265 | 265 |
266 | 266 |
267 void Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) { | 267 void Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) { |
268 Register first = NoReg; | 268 Register first = NoReg; |
269 for (unsigned i = 0; i < kNumberOfRegisters; i++) { | 269 for (unsigned i = 0; i < kNumberOfRegisters; i++) { |
270 if (reg_list & (1UL << i)) { | 270 if (reg_list & (1UL << i)) { |
271 Register xn = Register::Create(i, kXRegSizeInBits); | 271 Register xn = Register::Create(i, kXRegSizeInBits); |
272 // We should never write into csp here. | 272 // We should never write into csp here. |
273 ASSERT(!xn.Is(csp)); | 273 DCHECK(!xn.Is(csp)); |
274 if (!xn.IsZero()) { | 274 if (!xn.IsZero()) { |
275 if (!first.IsValid()) { | 275 if (!first.IsValid()) { |
276 // This is the first register we've hit, so construct the literal. | 276 // This is the first register we've hit, so construct the literal. |
277 __ Mov(xn, value); | 277 __ Mov(xn, value); |
278 first = xn; | 278 first = xn; |
279 } else { | 279 } else { |
280 // We've already loaded the literal, so re-use the value already | 280 // We've already loaded the literal, so re-use the value already |
281 // loaded into the first register we hit. | 281 // loaded into the first register we hit. |
282 __ Mov(xn, first); | 282 __ Mov(xn, first); |
283 } | 283 } |
(...skipping 29 matching lines...) Expand all Loading... |
313 } else if (reg_list.type() == CPURegister::kFPRegister) { | 313 } else if (reg_list.type() == CPURegister::kFPRegister) { |
314 // This will always clobber D registers. | 314 // This will always clobber D registers. |
315 ClobberFP(masm, reg_list.list()); | 315 ClobberFP(masm, reg_list.list()); |
316 } else { | 316 } else { |
317 UNREACHABLE(); | 317 UNREACHABLE(); |
318 } | 318 } |
319 } | 319 } |
320 | 320 |
321 | 321 |
322 void RegisterDump::Dump(MacroAssembler* masm) { | 322 void RegisterDump::Dump(MacroAssembler* masm) { |
323 ASSERT(__ StackPointer().Is(csp)); | 323 DCHECK(__ StackPointer().Is(csp)); |
324 | 324 |
325 // Ensure that we don't unintentionally clobber any registers. | 325 // Ensure that we don't unintentionally clobber any registers. |
326 RegList old_tmp_list = masm->TmpList()->list(); | 326 RegList old_tmp_list = masm->TmpList()->list(); |
327 RegList old_fptmp_list = masm->FPTmpList()->list(); | 327 RegList old_fptmp_list = masm->FPTmpList()->list(); |
328 masm->TmpList()->set_list(0); | 328 masm->TmpList()->set_list(0); |
329 masm->FPTmpList()->set_list(0); | 329 masm->FPTmpList()->set_list(0); |
330 | 330 |
331 // Preserve some temporary registers. | 331 // Preserve some temporary registers. |
332 Register dump_base = x0; | 332 Register dump_base = x0; |
333 Register dump = x1; | 333 Register dump = x1; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 | 389 |
390 // Dump the flags. | 390 // Dump the flags. |
391 __ Mrs(tmp, NZCV); | 391 __ Mrs(tmp, NZCV); |
392 __ Str(tmp, MemOperand(dump_base, flags_offset)); | 392 __ Str(tmp, MemOperand(dump_base, flags_offset)); |
393 | 393 |
394 // To dump the values that were in tmp amd dump, we need a new scratch | 394 // To dump the values that were in tmp amd dump, we need a new scratch |
395 // register. We can use any of the already dumped registers since we can | 395 // register. We can use any of the already dumped registers since we can |
396 // easily restore them. | 396 // easily restore them. |
397 Register dump2_base = x10; | 397 Register dump2_base = x10; |
398 Register dump2 = x11; | 398 Register dump2 = x11; |
399 ASSERT(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); | 399 DCHECK(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); |
400 | 400 |
401 // Don't lose the dump_ address. | 401 // Don't lose the dump_ address. |
402 __ Mov(dump2_base, dump_base); | 402 __ Mov(dump2_base, dump_base); |
403 | 403 |
404 __ Pop(tmp, dump, dump_base, xzr); | 404 __ Pop(tmp, dump, dump_base, xzr); |
405 | 405 |
406 __ Add(dump2, dump2_base, w_offset); | 406 __ Add(dump2, dump2_base, w_offset); |
407 __ Str(dump_base_w, MemOperand(dump2, dump_base.code() * kWRegSize)); | 407 __ Str(dump_base_w, MemOperand(dump2, dump_base.code() * kWRegSize)); |
408 __ Str(dump_w, MemOperand(dump2, dump.code() * kWRegSize)); | 408 __ Str(dump_w, MemOperand(dump2, dump.code() * kWRegSize)); |
409 __ Str(tmp_w, MemOperand(dump2, tmp.code() * kWRegSize)); | 409 __ Str(tmp_w, MemOperand(dump2, tmp.code() * kWRegSize)); |
410 | 410 |
411 __ Add(dump2, dump2_base, x_offset); | 411 __ Add(dump2, dump2_base, x_offset); |
412 __ Str(dump_base, MemOperand(dump2, dump_base.code() * kXRegSize)); | 412 __ Str(dump_base, MemOperand(dump2, dump_base.code() * kXRegSize)); |
413 __ Str(dump, MemOperand(dump2, dump.code() * kXRegSize)); | 413 __ Str(dump, MemOperand(dump2, dump.code() * kXRegSize)); |
414 __ Str(tmp, MemOperand(dump2, tmp.code() * kXRegSize)); | 414 __ Str(tmp, MemOperand(dump2, tmp.code() * kXRegSize)); |
415 | 415 |
416 // Finally, restore dump2_base and dump2. | 416 // Finally, restore dump2_base and dump2. |
417 __ Ldr(dump2_base, MemOperand(dump2, dump2_base.code() * kXRegSize)); | 417 __ Ldr(dump2_base, MemOperand(dump2, dump2_base.code() * kXRegSize)); |
418 __ Ldr(dump2, MemOperand(dump2, dump2.code() * kXRegSize)); | 418 __ Ldr(dump2, MemOperand(dump2, dump2.code() * kXRegSize)); |
419 | 419 |
420 // Restore the MacroAssembler's scratch registers. | 420 // Restore the MacroAssembler's scratch registers. |
421 masm->TmpList()->set_list(old_tmp_list); | 421 masm->TmpList()->set_list(old_tmp_list); |
422 masm->FPTmpList()->set_list(old_fptmp_list); | 422 masm->FPTmpList()->set_list(old_fptmp_list); |
423 | 423 |
424 completed_ = true; | 424 completed_ = true; |
425 } | 425 } |
OLD | NEW |