| 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 |