OLD | NEW |
---|---|
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
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 // This file implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
368 Str << " + " << LastFixup->value()->getOffset(); | 368 Str << " + " << LastFixup->value()->getOffset(); |
369 } | 369 } |
370 Str << "\n"; | 370 Str << "\n"; |
371 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) { | 371 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) { |
372 Str << "\t.byte 0x"; | 372 Str << "\t.byte 0x"; |
373 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); | 373 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); |
374 Str << "\n"; | 374 Str << "\n"; |
375 } | 375 } |
376 } | 376 } |
377 | 377 |
378 void emitIASBytesBranch(const Cfg *Func, const x86::AssemblerX86 *Asm, | |
379 intptr_t StartPosition, const x86::Label *Label, | |
380 const IceString &LabelName, bool Near) { | |
381 // If this is a backward branch (label is bound), we're good and know | |
382 // the offset. If this is a forward branch, then we can't actually emit | |
383 // the thing as text in a streaming manner, because the fixup hasn't | |
384 // happened yet. Instead, emit .long ($BranchLabel) - (. + 4), in that | |
385 // case and let the external assembler take care of that fixup. | |
386 if (Label->IsBound()) { | |
387 emitIASBytes(Func, Asm, StartPosition); | |
388 return; | |
389 } | |
390 const intptr_t FwdBranchSize = Near ? 1 : 4; | |
Jim Stichnoth
2014/10/22 18:01:14
Should this be size_t or ptrdiff_t or something si
jvoung (off chromium)
2014/10/22 20:43:58
Hmm, it could be a ptrdiff_t too, but I had it as
| |
391 const IceString FwdBranchDirective = Near ? ".byte" : ".long"; | |
392 Ostream &Str = Func->getContext()->getStrEmit(); | |
393 intptr_t EndPosition = Asm->GetPosition(); | |
394 assert(EndPosition - StartPosition > FwdBranchSize); | |
395 for (intptr_t i = StartPosition; i < EndPosition - FwdBranchSize; ++i) { | |
396 Str << "\t.byte 0x"; | |
397 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); | |
398 Str << "\n"; | |
399 } | |
400 Str << "\t" << FwdBranchDirective << " " << LabelName << " - (. + " | |
401 << FwdBranchSize << ")\n"; | |
402 return; | |
403 } | |
404 | |
378 } // end of anonymous namespace | 405 } // end of anonymous namespace |
379 | 406 |
380 void InstX8632::dump(const Cfg *Func) const { | 407 void InstX8632::dump(const Cfg *Func) const { |
381 Ostream &Str = Func->getContext()->getStrDump(); | 408 Ostream &Str = Func->getContext()->getStrDump(); |
382 Str << "[X8632] "; | 409 Str << "[X8632] "; |
383 Inst::dump(Func); | 410 Inst::dump(Func); |
384 } | 411 } |
385 | 412 |
386 void InstX8632Label::emit(const Cfg *Func) const { | 413 void InstX8632Label::emit(const Cfg *Func) const { |
387 Ostream &Str = Func->getContext()->getStrEmit(); | 414 Ostream &Str = Func->getContext()->getStrEmit(); |
388 Str << getName(Func) << ":\n"; | 415 Str << getName(Func) << ":\n"; |
389 } | 416 } |
390 | 417 |
418 void InstX8632Label::emitIAS(const Cfg *Func) const { | |
419 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | |
420 Asm->Bind(&AsmLabel); | |
421 // TODO(jvoung): remove the the textual label once forward branch | |
422 // fixups are used (and text assembler is not used). | |
423 Ostream &Str = Func->getContext()->getStrEmit(); | |
424 Str << getName(Func) << ":\n"; | |
425 } | |
426 | |
391 void InstX8632Label::dump(const Cfg *Func) const { | 427 void InstX8632Label::dump(const Cfg *Func) const { |
392 Ostream &Str = Func->getContext()->getStrDump(); | 428 Ostream &Str = Func->getContext()->getStrDump(); |
393 Str << getName(Func) << ":"; | 429 Str << getName(Func) << ":"; |
394 } | 430 } |
395 | 431 |
396 void InstX8632Br::emit(const Cfg *Func) const { | 432 void InstX8632Br::emit(const Cfg *Func) const { |
397 Ostream &Str = Func->getContext()->getStrEmit(); | 433 Ostream &Str = Func->getContext()->getStrEmit(); |
398 Str << "\t"; | 434 Str << "\t"; |
399 | 435 |
400 if (Condition == CondX86::Br_None) { | 436 if (Condition == CondX86::Br_None) { |
401 Str << "jmp"; | 437 Str << "jmp"; |
402 } else { | 438 } else { |
403 Str << InstX8632BrAttributes[Condition].EmitString; | 439 Str << InstX8632BrAttributes[Condition].EmitString; |
404 } | 440 } |
405 | 441 |
406 if (Label) { | 442 if (Label) { |
407 Str << "\t" << Label->getName(Func) << "\n"; | 443 Str << "\t" << Label->getName(Func) << "\n"; |
408 } else { | 444 } else { |
409 if (Condition == CondX86::Br_None) { | 445 if (Condition == CondX86::Br_None) { |
410 Str << "\t" << getTargetFalse()->getAsmName() << "\n"; | 446 Str << "\t" << getTargetFalse()->getAsmName() << "\n"; |
411 } else { | 447 } else { |
412 Str << "\t" << getTargetTrue()->getAsmName() << "\n"; | 448 Str << "\t" << getTargetTrue()->getAsmName() << "\n"; |
413 if (getTargetFalse()) { | 449 if (getTargetFalse()) { |
414 Str << "\tjmp\t" << getTargetFalse()->getAsmName() << "\n"; | 450 Str << "\tjmp\t" << getTargetFalse()->getAsmName() << "\n"; |
415 } | 451 } |
416 } | 452 } |
417 } | 453 } |
418 } | 454 } |
419 | 455 |
456 void InstX8632Br::emitIAS(const Cfg *Func) const { | |
457 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | |
458 intptr_t StartPosition = Asm->GetPosition(); | |
459 if (Label) { | |
460 x86::Label *L = Label->getAsmLabel(); | |
461 // In all these cases, local Labels should only be used for Near. | |
Jim Stichnoth
2014/10/22 18:01:14
Is there any validation of this assumption? Stric
jvoung (off chromium)
2014/10/22 20:43:58
Yes, it's a bit roundabout, but when the forward-r
jvoung (off chromium)
2014/10/23 18:19:51
As far as stats, so far on GCC, eon, perlbmk, and
| |
462 const bool Near = true; | |
463 if (Condition == CondX86::Br_None) { | |
464 Asm->jmp(L, Near); | |
465 } else { | |
466 Asm->j(Condition, L, Near); | |
467 } | |
468 emitIASBytesBranch(Func, Asm, StartPosition, L, Label->getName(Func), Near); | |
469 } else { | |
470 // Pessimistically assume it's far. This only affects Labels that | |
471 // are not Bound. | |
472 const bool Near = false; | |
473 if (Condition == CondX86::Br_None) { | |
474 x86::Label *L = | |
475 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | |
476 assert(!getTargetTrue()); | |
477 Asm->jmp(L, Near); | |
478 emitIASBytesBranch(Func, Asm, StartPosition, L, | |
479 getTargetFalse()->getAsmName(), Near); | |
480 } else { | |
481 x86::Label *L = Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); | |
482 Asm->j(Condition, L, Near); | |
483 emitIASBytesBranch(Func, Asm, StartPosition, L, | |
484 getTargetTrue()->getAsmName(), Near); | |
485 StartPosition = Asm->GetPosition(); | |
486 if (getTargetFalse()) { | |
487 x86::Label *L2 = | |
488 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | |
489 Asm->jmp(L2, Near); | |
490 emitIASBytesBranch(Func, Asm, StartPosition, L2, | |
491 getTargetFalse()->getAsmName(), Near); | |
492 } | |
493 } | |
494 } | |
495 } | |
496 | |
420 void InstX8632Br::dump(const Cfg *Func) const { | 497 void InstX8632Br::dump(const Cfg *Func) const { |
421 Ostream &Str = Func->getContext()->getStrDump(); | 498 Ostream &Str = Func->getContext()->getStrDump(); |
422 Str << "br "; | 499 Str << "br "; |
423 | 500 |
424 if (Condition == CondX86::Br_None) { | 501 if (Condition == CondX86::Br_None) { |
425 Str << "label %" | 502 Str << "label %" |
426 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); | 503 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); |
427 return; | 504 return; |
428 } | 505 } |
429 | 506 |
(...skipping 2446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2876 } | 2953 } |
2877 Str << "("; | 2954 Str << "("; |
2878 if (Func) | 2955 if (Func) |
2879 Var->dump(Func); | 2956 Var->dump(Func); |
2880 else | 2957 else |
2881 Var->dump(Str); | 2958 Var->dump(Str); |
2882 Str << ")"; | 2959 Str << ")"; |
2883 } | 2960 } |
2884 | 2961 |
2885 } // end of namespace Ice | 2962 } // end of namespace Ice |
OLD | NEW |