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

Side by Side Diff: src/IceTargetLoweringX8664.cpp

Issue 1605103002: Subzero. X86. Refactors Address Mode formation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Minor changes. 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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 // to avoid leaking the upper 32-bits (i.e., the sandbox address.) 212 // to avoid leaking the upper 32-bits (i.e., the sandbox address.)
213 AutoBundle _(this); 213 AutoBundle _(this);
214 _push(_0); 214 _push(_0);
215 Context.insert<typename Traits::Insts::Store>(ebp, TopOfStack); 215 Context.insert<typename Traits::Insts::Store>(ebp, TopOfStack);
216 } 216 }
217 217
218 Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) { 218 Traits::X86OperandMem *TargetX8664::_sandbox_mem_reference(X86OperandMem *Mem) {
219 // In x86_64-nacl, all memory references are relative to %r15 (i.e., %rzp.) 219 // In x86_64-nacl, all memory references are relative to %r15 (i.e., %rzp.)
220 // NaCl sandboxing also requires that any registers that are not %rsp and 220 // NaCl sandboxing also requires that any registers that are not %rsp and
221 // %rbp to be 'truncated' to 32-bit before memory access. 221 // %rbp to be 'truncated' to 32-bit before memory access.
222 assert(NeedSandboxing); 222 if (SandboxingType == ST_None) {
223 return Mem;
224 }
225
226 if (SandboxingType == ST_Nonsfi) {
227 llvm::report_fatal_error(
228 "_sandbox_mem_reference not implemented for nonsfi");
229 }
230
223 Variable *Base = Mem->getBase(); 231 Variable *Base = Mem->getBase();
224 Variable *Index = Mem->getIndex(); 232 Variable *Index = Mem->getIndex();
225 uint16_t Shift = 0; 233 uint16_t Shift = 0;
226 Variable *r15 = 234 Variable *ZeroReg =
227 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); 235 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
228 Constant *Offset = Mem->getOffset(); 236 Constant *Offset = Mem->getOffset();
229 Variable *T = nullptr; 237 Variable *T = nullptr;
230 238
231 if (Mem->getIsRebased()) { 239 if (Mem->getIsRebased()) {
232 // If Mem.IsRebased, then we don't need to update Mem to contain a reference 240 // If Mem.IsRebased, then we don't need to update Mem to contain a reference
233 // to %r15, but we still need to truncate Mem.Index (if any) to 32-bit. 241 // to a valid base register (%r15, %rsp, or %rbp), but we still need to
234 assert(r15 == Base); 242 // truncate Mem.Index (if any) to 32-bit.
235 T = Index; 243 assert(ZeroReg == Base || Base->isRematerializable());
244 T = makeReg(IceType_i32);
245 _mov(T, Index);
236 Shift = Mem->getShift(); 246 Shift = Mem->getShift();
Jim Stichnoth 2016/01/22 02:44:10 Add an early return here, and pull the rest out of
John 2016/01/22 02:56:21 It's not possible. There's more code after the els
Jim Stichnoth 2016/01/22 03:08:55 Let me clarify (hopefully I'm not being stupid her
John 2016/01/22 04:18:07 That would not work: void TargetX8664::_sandbox_m
Jim Stichnoth 2016/01/22 04:29:40 OK, it turns out I was indeed stupid. I misread t
237 } else if (Base != nullptr && Index != nullptr) { 247 } else {
238 // Another approach could be to emit an 248 if (Base != nullptr) {
239 // 249 if (Base->isRematerializable()) {
240 // lea Mem, %T 250 ZeroReg = Base;
241 // 251 } else {
242 // And then update Mem.Base = r15, Mem.Index = T, Mem.Shift = 0 252 T = Base;
243 llvm::report_fatal_error("memory reference contains base and index."); 253 }
244 } else if (Base != nullptr) { 254 }
245 T = Base; 255
246 } else if (Index != nullptr) { 256 if (Index != nullptr) {
247 T = Index; 257 assert(!Index->isRematerializable());
248 Shift = Mem->getShift(); 258 if (T != nullptr) {
259 llvm::report_fatal_error("memory reference contains base and index.");
260 }
261 T = Index;
262 Shift = Mem->getShift();
263 }
249 } 264 }
250 265
251 // NeedsLea is a flags indicating whether Mem needs to be materialized to a 266 // NeedsLea is a flags indicating whether Mem needs to be materialized to a
252 // GPR prior to being used. A LEA is needed if Mem.Offset is a constant 267 // GPR prior to being used. A LEA is needed if Mem.Offset is a constant
253 // relocatable, or if Mem.Offset is negative. In both these cases, the LEA is 268 // relocatable, or if Mem.Offset is negative. In both these cases, the LEA is
254 // needed to ensure the sandboxed memory operand will only use the lower 269 // needed to ensure the sandboxed memory operand will only use the lower
255 // 32-bits of T+Offset. 270 // 32-bits of T+Offset.
256 bool NeedsLea = false; 271 bool NeedsLea = false;
257 if (const auto *Offset = Mem->getOffset()) { 272 if (const auto *Offset = Mem->getOffset()) {
258 if (llvm::isa<ConstantRelocatable>(Offset)) { 273 if (llvm::isa<ConstantRelocatable>(Offset)) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 Traits::X86OperandMem::DefaultSegment, NotRebased)); 328 Traits::X86OperandMem::DefaultSegment, NotRebased));
314 329
315 T = makeReg(IceType_i64, RegNum); 330 T = makeReg(IceType_i64, RegNum);
316 _movzx(T, NewT); 331 _movzx(T, NewT);
317 Shift = 0; 332 Shift = 0;
318 Offset = nullptr; 333 Offset = nullptr;
319 } 334 }
320 335
321 static constexpr bool IsRebased = true; 336 static constexpr bool IsRebased = true;
322 return Traits::X86OperandMem::create( 337 return Traits::X86OperandMem::create(
323 Func, Mem->getType(), r15, Offset, T, Shift, 338 Func, Mem->getType(), ZeroReg, Offset, T, Shift,
324 Traits::X86OperandMem::DefaultSegment, IsRebased); 339 Traits::X86OperandMem::DefaultSegment, IsRebased);
325 } 340 }
326 341
327 void TargetX8664::_sub_sp(Operand *Adjustment) { 342 void TargetX8664::_sub_sp(Operand *Adjustment) {
328 Variable *rsp = 343 Variable *rsp =
329 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64); 344 getPhysicalRegister(Traits::RegisterSet::Reg_rsp, IceType_i64);
330 if (!NeedSandboxing) { 345 if (!NeedSandboxing) {
331 _sub(rsp, Adjustment); 346 _sub(rsp, Adjustment);
332 return; 347 return;
333 } 348 }
334 349
335 Variable *esp = 350 Variable *esp =
336 getPhysicalRegister(Traits::RegisterSet::Reg_esp, IceType_i32); 351 getPhysicalRegister(Traits::RegisterSet::Reg_esp, IceType_i32);
337 Variable *r15 = 352 Variable *r15 =
338 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); 353 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
339 354
340 // .bundle_start 355 // .bundle_start
341 // sub Adjustment, %esp 356 // sub Adjustment, %esp
342 // add %r15, %rsp 357 // add %r15, %rsp
343 // .bundle_end 358 // .bundle_end
344 AutoBundle _(this); 359 AutoBundle _(this);
345 _redefined(Context.insert<InstFakeDef>(esp, rsp)); 360 _redefined(Context.insert<InstFakeDef>(esp, rsp));
346 _sub(esp, Adjustment); 361 _sub(esp, Adjustment);
347 _redefined(Context.insert<InstFakeDef>(rsp, esp)); 362 _redefined(Context.insert<InstFakeDef>(rsp, esp));
348 _add(rsp, r15); 363 _add(rsp, r15);
349 } 364 }
350 365
366 void TargetX8664::initSandboxPtr() {
367 switch (SandboxingType) {
368 case ST_Nonsfi:
369 // Probably no implementation is needed, but error to be safe for now.
370 llvm::report_fatal_error("Need to implement initSandboxPtr() for 64-bit.");
Jim Stichnoth 2016/01/22 02:44:10 I would add "nonsfi" to this error string.
John 2016/01/22 04:18:07 Done.
371 case ST_NaCl:
372 SandboxPtr = getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
373 break;
374 case ST_None:
375 // nothing.
376 break;
377 }
378 }
379
351 void TargetX8664::initSandbox() { 380 void TargetX8664::initSandbox() {
352 assert(NeedSandboxing); 381 assert(NeedSandboxing);
Jim Stichnoth 2016/01/22 02:44:10 This function should probably be checking Sandboxi
John 2016/01/22 04:18:07 It is: NeedSandboxing --> SandboxingType == ST_NaC
353 Context.init(Func->getEntryNode()); 382 Context.init(Func->getEntryNode());
354 Context.setInsertPoint(Context.getCur()); 383 Context.setInsertPoint(Context.getCur());
355 Variable *r15 = 384 Variable *r15 =
356 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64); 385 getPhysicalRegister(Traits::RegisterSet::Reg_r15, IceType_i64);
357 Context.insert<InstFakeDef>(r15); 386 Context.insert<InstFakeDef>(r15);
358 Context.insert<InstFakeUse>(r15); 387 Context.insert<InstFakeUse>(r15);
359 } 388 }
360 389
390 namespace {
391 bool isRematerializable(const Variable *Var) {
392 return Var != nullptr && Var->isRematerializable();
393 }
394 } // end of anonymous namespace
395
396 bool TargetX8664::legalizeOptAddrForSandbox(OptAddr *Addr) {
397 if (SandboxingType == ST_Nonsfi) {
398 llvm::report_fatal_error("Nonsfi not yet implemented for x8664.");
399 }
400
401 if (isRematerializable(Addr->Base)) {
402 if (Addr->Index == SandboxPtr) {
403 Addr->Index = nullptr;
404 Addr->Shift = 0;
405 }
406 return true;
407 }
408
409 if (isRematerializable(Addr->Index)) {
410 if (Addr->Base == SandboxPtr) {
411 Addr->Base = nullptr;
412 }
413 return true;
414 }
415
416 assert(Addr->Base != SandboxPtr && Addr->Index != SandboxPtr);
417
418 if (Addr->Base == nullptr) {
419 // Addr->Base = SandboxPtr;
Jim Stichnoth 2016/01/22 02:44:10 Remove the commented code, here and below?
John 2016/01/22 04:18:07 Done.
420 return true;
421 }
422
423 if (Addr->Index == nullptr) {
424 // Addr->Index = SandboxPtr;
425 // Addr->Shift = 0;
426 return true;
427 }
428
429 return false;
430 }
431
361 void TargetX8664::lowerIndirectJump(Variable *JumpTarget) { 432 void TargetX8664::lowerIndirectJump(Variable *JumpTarget) {
362 std::unique_ptr<AutoBundle> Bundler; 433 std::unique_ptr<AutoBundle> Bundler;
363 434
364 if (!NeedSandboxing) { 435 if (!NeedSandboxing) {
365 Variable *T = makeReg(IceType_i64); 436 Variable *T = makeReg(IceType_i64);
366 _movzx(T, JumpTarget); 437 _movzx(T, JumpTarget);
367 JumpTarget = T; 438 JumpTarget = T;
368 } else { 439 } else {
369 Variable *T = makeReg(IceType_i32); 440 Variable *T = makeReg(IceType_i32);
370 Variable *T64 = makeReg(IceType_i64); 441 Variable *T64 = makeReg(IceType_i64);
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 #define X(tag, sizeLog2, align, elts, elty, str) \ 1217 #define X(tag, sizeLog2, align, elts, elty, str) \
1147 static_assert(_table1_##tag == _table2_##tag, \ 1218 static_assert(_table1_##tag == _table2_##tag, \
1148 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE"); 1219 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE");
1149 ICETYPE_TABLE 1220 ICETYPE_TABLE
1150 #undef X 1221 #undef X
1151 } // end of namespace dummy3 1222 } // end of namespace dummy3
1152 } // end of anonymous namespace 1223 } // end of anonymous namespace
1153 1224
1154 } // end of namespace X8664 1225 } // end of namespace X8664
1155 } // end of namespace Ice 1226 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698