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; |
| 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->BindLocalLabel(Number); |
| 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 = Asm->GetOrCreateLocalLabel(Label->getNumber()); |
| 461 // In all these cases, local Labels should only be used for Near. |
| 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 |