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