Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Side by Side Diff: src/IceTargetLoweringX8664.cpp

Issue 1616103002: Subzero. X8664. Enables RIP-based addressing mode. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: make presubmit happy. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===// 1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } else { 287 } else {
288 _push_rbp(); 288 _push_rbp();
289 } 289 }
290 } 290 }
291 291
292 void TargetX8664::emitGetIP(CfgNode *Node) { 292 void TargetX8664::emitGetIP(CfgNode *Node) {
293 // No IP base register is needed on X86-64. 293 // No IP base register is needed on X86-64.
294 (void)Node; 294 (void)Node;
295 } 295 }
296 296
297 namespace {
298 bool isAssignedToRspOrRbp(const Variable *Var) {
299 if (Var == nullptr) {
300 return false;
301 }
302
303 if (Var->isRematerializable()) {
304 return true;
305 }
306
307 if (!Var->hasReg()) {
Jim Stichnoth 2016/01/23 01:57:47 Optional: You could skip this condition if you wan
John 2016/01/26 19:44:25 I did not know that. I will leave this as is -- ex
308 return false;
309 }
310
311 int32_t RegNum = Var->getRegNum();
Jim Stichnoth 2016/01/23 01:57:47 const
John 2016/01/26 19:44:25 Done.
312 if ((RegNum == Traits::RegisterSet::Reg_rsp) ||
313 (RegNum == Traits::RegisterSet::Reg_rbp)) {
314 return true;
315 }
316
317 return false;
318 }
319 } // end of anonymous namespace
320
297 Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) { 321 Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) {
298 // In x86_64-nacl, all memory references are relative to %r15 (i.e., %rzp.)
299 // NaCl sandboxing also requires that any registers that are not %rsp and
300 // %rbp to be 'truncated' to 32-bit before memory access.
301 if (SandboxingType == ST_None) { 322 if (SandboxingType == ST_None) {
302 return Mem; 323 return Mem;
303 } 324 }
304 325
305 if (SandboxingType == ST_Nonsfi) { 326 if (SandboxingType == ST_Nonsfi) {
306 llvm::report_fatal_error( 327 llvm::report_fatal_error(
307 "_sandbox_mem_reference not implemented for nonsfi"); 328 "_sandbox_mem_reference not implemented for nonsfi");
308 } 329 }
309 330
331 // In x86_64-nacl, all memory references are relative to a base register
332 // (%r15, %rsp, %rbp, or %rip).
333
310 Variable *Base = Mem->getBase(); 334 Variable *Base = Mem->getBase();
311 Variable *Index = Mem->getIndex(); 335 Variable *Index = Mem->getIndex();
312 uint16_t Shift = 0; 336 uint16_t Shift = 0;
313 Variable *ZeroReg = 337 Variable *ZeroReg = RebasePtr;
314 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
315 Constant *Offset = Mem->getOffset(); 338 Constant *Offset = Mem->getOffset();
316 Variable *T = nullptr; 339 Variable *T = nullptr;
317 340
341 if (Base == nullptr && Index == nullptr) {
342 // Mem is RIP-relative. There's no need to rebase it.
343 return Mem;
344 }
345
318 if (Mem->getIsRebased()) { 346 if (Mem->getIsRebased()) {
319 // If Mem.IsRebased, then we don't need to update Mem to contain a reference 347 // If Mem.IsRebased, then we don't need to update Mem, as it's already been
320 // to a valid base register (%r15, %rsp, or %rbp), but we still need to 348 // updated to contain a reference to one of %rsp, %rbp, or %r15.
321 // truncate Mem.Index (if any) to 32-bit. 349 // We don't return early because we still need to zero extend Index.
Jim Stichnoth 2016/01/23 01:57:47 Is the "don't return early" comment because of my
John 2016/01/26 19:44:25 no, it is not. The previous comment said "but we s
322 assert(ZeroReg == Base || Base->isRematerializable()); 350 assert(ZeroReg == Base || isAssignedToRspOrRbp(Base));
323 T = makeReg(IceType_i32); 351 ZeroReg = Base;
324 _mov(T, Index); 352 if (Index != nullptr) {
325 Shift = Mem->getShift(); 353 T = makeReg(IceType_i32);
354 _mov(T, Index);
355 Shift = Mem->getShift();
356 }
326 } else { 357 } else {
327 if (Base != nullptr) { 358 if (Base != nullptr) {
328 if (Base->isRematerializable()) { 359 // If Base is a valid base pointer we don't need to use the RebasePtr. By
360 // doing this we might save us the need to zero extend the memory operand.
361 if (isAssignedToRspOrRbp(Base)) {
329 ZeroReg = Base; 362 ZeroReg = Base;
330 } else { 363 } else {
331 T = Base; 364 T = Base;
332 } 365 }
333 } 366 }
334 367
335 if (Index != nullptr) { 368 if (Index != nullptr) {
336 assert(!Index->isRematerializable()); 369 assert(!Index->isRematerializable());
370 // If Index is not nullptr, it is mandatory that T is a nullptr.
371 // Otherwise, the lowering generated an memory operand with two registers.
Jim Stichnoth 2016/01/23 01:57:47 s/an/a/
John 2016/01/26 19:44:25 Done.
372 // Note that Base might still be non-nullptr, but it must be a valid
373 // base register.
337 if (T != nullptr) { 374 if (T != nullptr) {
338 llvm::report_fatal_error("memory reference contains base and index."); 375 llvm::report_fatal_error("memory reference contains base and index.");
339 } 376 }
340 T = Index; 377 // If the Index is not shifted, and it is a Valid Base, and the ZeroReg is
341 Shift = Mem->getShift(); 378 // still RebasePtr, then we do ZeroReg = Index, and hopefully prevent the
379 // need to zero-extend the memory operand (which may still happen -- see
380 // NeedLea below.)
381 if (Shift == 0 && isAssignedToRspOrRbp(Index) && ZeroReg == RebasePtr) {
382 ZeroReg = Index;
383 } else {
384 T = Index;
385 Shift = Mem->getShift();
386 }
342 } 387 }
343 } 388 }
344 389
345 // NeedsLea is a flags indicating whether Mem needs to be materialized to a 390 // NeedsLea is a flags indicating whether Mem needs to be materialized to a
346 // GPR prior to being used. A LEA is needed if Mem.Offset is a constant 391 // GPR prior to being used. A LEA is needed if Mem.Offset is a constant
347 // relocatable, or if Mem.Offset is negative. In both these cases, the LEA is 392 // relocatable, or if Mem.Offset is negative. In both these cases, the LEA is
348 // needed to ensure the sandboxed memory operand will only use the lower 393 // needed to ensure the sandboxed memory operand will only use the lower
349 // 32-bits of T+Offset. 394 // 32-bits of T+Offset.
350 bool NeedsLea = false; 395 bool NeedsLea = false;
351 if (const auto *Offset = Mem->getOffset()) { 396 if (const auto *Offset = Mem->getOffset()) {
352 if (llvm::isa<ConstantRelocatable>(Offset)) { 397 if (llvm::isa<ConstantRelocatable>(Offset)) {
353 NeedsLea = true; 398 NeedsLea = true;
354 } else if (const auto *Imm = llvm::cast<ConstantInteger32>(Offset)) { 399 } else if (const auto *Imm = llvm::cast<ConstantInteger32>(Offset)) {
355 NeedsLea = Imm->getValue() < 0; 400 NeedsLea = Imm->getValue() < 0;
356 } 401 }
357 } 402 }
358 403
359 int32_t RegNum = Variable::NoRegister; 404 int32_t RegNum = Variable::NoRegister;
360 int32_t RegNum32 = Variable::NoRegister; 405 int32_t RegNum32 = Variable::NoRegister;
361 if (T != nullptr) { 406 if (T != nullptr) {
362 if (T->hasReg()) { 407 if (T->hasReg()) {
363 RegNum = Traits::getGprForType(IceType_i64, T->getRegNum()); 408 RegNum = Traits::getGprForType(IceType_i64, T->getRegNum());
364 RegNum32 = Traits::getGprForType(IceType_i32, RegNum); 409 RegNum32 = Traits::getGprForType(IceType_i32, RegNum);
365 switch (RegNum) { 410 // At this point, if T was assigned to rsp/rbp, then we would have already
366 case Traits::RegisterSet::Reg_rsp: 411 // made this the ZeroReg.
367 case Traits::RegisterSet::Reg_rbp: 412 assert(RegNum != Traits::RegisterSet::Reg_rsp);
368 // Memory operands referencing rsp/rbp do not need to be sandboxed. 413 assert(RegNum != Traits::RegisterSet::Reg_rbp);
369 return Mem;
370 }
371 } 414 }
372 415
373 switch (T->getType()) { 416 switch (T->getType()) {
374 default: 417 default:
418 llvm::report_fatal_error("Mem pointer should be a 32-bit integer.");
Jim Stichnoth 2016/01/23 01:57:47 Here and below, would it make more sense to say "G
John 2016/01/26 19:44:25 I tend to think about GPRs/Regs in the assembler.
375 case IceType_i64: 419 case IceType_i64:
376 // Even though "default:" would also catch T.Type == IceType_i64, an 420 // Even though "default:" would also catch T.Type == IceType_i64, an
377 // explicit 'case IceType_i64' shows that memory operands are always 421 // explicit 'case IceType_i64' shows that memory operands are always
378 // supposed to be 32-bits. 422 // supposed to be 32-bits.
379 llvm::report_fatal_error("Mem pointer should be 32-bit."); 423 llvm::report_fatal_error("Mem pointer should not be a 64-bit integer.");
380 case IceType_i32: { 424 case IceType_i32: {
381 Variable *T64 = makeReg(IceType_i64, RegNum); 425 Variable *T64 = makeReg(IceType_i64, RegNum);
382 auto *Movzx = _movzx(T64, T); 426 auto *Movzx = _movzx(T64, T);
383 if (!NeedsLea) { 427 if (!NeedsLea) {
384 // This movzx is only needed when Mem does not need to be lea'd into a 428 // This movzx is only needed when Mem does not need to be lea'd into a
385 // temporary. If an lea is going to be emitted, then eliding this movzx 429 // temporary. If an lea is going to be emitted, then eliding this movzx
386 // is safe because the emitted lea will write a 32-bit result -- 430 // is safe because the emitted lea will write a 32-bit result --
387 // implicitly zero-extended to 64-bit. 431 // implicitly zero-extended to 64-bit.
388 Movzx->setMustKeep(); 432 Movzx->setMustKeep();
389 } 433 }
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 #define X(tag, sizeLog2, align, elts, elty, str) \ 760 #define X(tag, sizeLog2, align, elts, elty, str) \
717 static_assert(_table1_##tag == _table2_##tag, \ 761 static_assert(_table1_##tag == _table2_##tag, \
718 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); 762 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE");
719 ICETYPE_TABLE 763 ICETYPE_TABLE
720 #undef X 764 #undef X
721 } // end of namespace dummy3 765 } // end of namespace dummy3
722 } // end of anonymous namespace 766 } // end of anonymous namespace
723 767
724 } // end of namespace X8664 768 } // end of namespace X8664
725 } // end of namespace Ice 769 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698