| 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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 | 364 |
| 365 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) | 365 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) |
| 366 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { | 366 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { |
| 367 addSource(Dest); | 367 addSource(Dest); |
| 368 addSource(Source); | 368 addSource(Source); |
| 369 } | 369 } |
| 370 | 370 |
| 371 // ======================== Dump routines ======================== // | 371 // ======================== Dump routines ======================== // |
| 372 | 372 |
| 373 void InstX8632::dump(const Cfg *Func) const { | 373 void InstX8632::dump(const Cfg *Func) const { |
| 374 if (!ALLOW_DUMP) | 374 if (!buildAllowsDump()) |
| 375 return; | 375 return; |
| 376 Ostream &Str = Func->getContext()->getStrDump(); | 376 Ostream &Str = Func->getContext()->getStrDump(); |
| 377 Str << "[X8632] "; | 377 Str << "[X8632] "; |
| 378 Inst::dump(Func); | 378 Inst::dump(Func); |
| 379 } | 379 } |
| 380 | 380 |
| 381 void InstX8632FakeRMW::dump(const Cfg *Func) const { | 381 void InstX8632FakeRMW::dump(const Cfg *Func) const { |
| 382 if (!ALLOW_DUMP) | 382 if (!buildAllowsDump()) |
| 383 return; | 383 return; |
| 384 Ostream &Str = Func->getContext()->getStrDump(); | 384 Ostream &Str = Func->getContext()->getStrDump(); |
| 385 Type Ty = getData()->getType(); | 385 Type Ty = getData()->getType(); |
| 386 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; | 386 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; |
| 387 getAddr()->dump(Func); | 387 getAddr()->dump(Func); |
| 388 Str << ", "; | 388 Str << ", "; |
| 389 getData()->dump(Func); | 389 getData()->dump(Func); |
| 390 Str << ", beacon="; | 390 Str << ", beacon="; |
| 391 getBeacon()->dump(Func); | 391 getBeacon()->dump(Func); |
| 392 } | 392 } |
| 393 | 393 |
| 394 void InstX8632Label::emit(const Cfg *Func) const { | 394 void InstX8632Label::emit(const Cfg *Func) const { |
| 395 if (!ALLOW_DUMP) | 395 if (!buildAllowsDump()) |
| 396 return; | 396 return; |
| 397 Ostream &Str = Func->getContext()->getStrEmit(); | 397 Ostream &Str = Func->getContext()->getStrEmit(); |
| 398 Str << getName(Func) << ":"; | 398 Str << getName(Func) << ":"; |
| 399 } | 399 } |
| 400 | 400 |
| 401 void InstX8632Label::emitIAS(const Cfg *Func) const { | 401 void InstX8632Label::emitIAS(const Cfg *Func) const { |
| 402 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 402 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 403 Asm->BindLocalLabel(Number); | 403 Asm->BindLocalLabel(Number); |
| 404 } | 404 } |
| 405 | 405 |
| 406 void InstX8632Label::dump(const Cfg *Func) const { | 406 void InstX8632Label::dump(const Cfg *Func) const { |
| 407 if (!ALLOW_DUMP) | 407 if (!buildAllowsDump()) |
| 408 return; | 408 return; |
| 409 Ostream &Str = Func->getContext()->getStrDump(); | 409 Ostream &Str = Func->getContext()->getStrDump(); |
| 410 Str << getName(Func) << ":"; | 410 Str << getName(Func) << ":"; |
| 411 } | 411 } |
| 412 | 412 |
| 413 void InstX8632Br::emit(const Cfg *Func) const { | 413 void InstX8632Br::emit(const Cfg *Func) const { |
| 414 if (!ALLOW_DUMP) | 414 if (!buildAllowsDump()) |
| 415 return; | 415 return; |
| 416 Ostream &Str = Func->getContext()->getStrEmit(); | 416 Ostream &Str = Func->getContext()->getStrEmit(); |
| 417 Str << "\t"; | 417 Str << "\t"; |
| 418 | 418 |
| 419 if (Condition == CondX86::Br_None) { | 419 if (Condition == CondX86::Br_None) { |
| 420 Str << "jmp"; | 420 Str << "jmp"; |
| 421 } else { | 421 } else { |
| 422 Str << InstX8632BrAttributes[Condition].EmitString; | 422 Str << InstX8632BrAttributes[Condition].EmitString; |
| 423 } | 423 } |
| 424 | 424 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 if (getTargetFalse()) { | 463 if (getTargetFalse()) { |
| 464 X8632::Label *L2 = | 464 X8632::Label *L2 = |
| 465 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 465 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
| 466 Asm->jmp(L2, Near); | 466 Asm->jmp(L2, Near); |
| 467 } | 467 } |
| 468 } | 468 } |
| 469 } | 469 } |
| 470 } | 470 } |
| 471 | 471 |
| 472 void InstX8632Br::dump(const Cfg *Func) const { | 472 void InstX8632Br::dump(const Cfg *Func) const { |
| 473 if (!ALLOW_DUMP) | 473 if (!buildAllowsDump()) |
| 474 return; | 474 return; |
| 475 Ostream &Str = Func->getContext()->getStrDump(); | 475 Ostream &Str = Func->getContext()->getStrDump(); |
| 476 Str << "br "; | 476 Str << "br "; |
| 477 | 477 |
| 478 if (Condition == CondX86::Br_None) { | 478 if (Condition == CondX86::Br_None) { |
| 479 Str << "label %" | 479 Str << "label %" |
| 480 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); | 480 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); |
| 481 return; | 481 return; |
| 482 } | 482 } |
| 483 | 483 |
| 484 Str << InstX8632BrAttributes[Condition].DisplayString; | 484 Str << InstX8632BrAttributes[Condition].DisplayString; |
| 485 if (Label) { | 485 if (Label) { |
| 486 Str << ", label %" << Label->getName(Func); | 486 Str << ", label %" << Label->getName(Func); |
| 487 } else { | 487 } else { |
| 488 Str << ", label %" << getTargetTrue()->getName(); | 488 Str << ", label %" << getTargetTrue()->getName(); |
| 489 if (getTargetFalse()) { | 489 if (getTargetFalse()) { |
| 490 Str << ", label %" << getTargetFalse()->getName(); | 490 Str << ", label %" << getTargetFalse()->getName(); |
| 491 } | 491 } |
| 492 } | 492 } |
| 493 } | 493 } |
| 494 | 494 |
| 495 void InstX8632Jmp::emit(const Cfg *Func) const { | 495 void InstX8632Jmp::emit(const Cfg *Func) const { |
| 496 if (!ALLOW_DUMP) | 496 if (!buildAllowsDump()) |
| 497 return; | 497 return; |
| 498 Ostream &Str = Func->getContext()->getStrEmit(); | 498 Ostream &Str = Func->getContext()->getStrEmit(); |
| 499 assert(getSrcSize() == 1); | 499 assert(getSrcSize() == 1); |
| 500 Str << "\tjmp\t*"; | 500 Str << "\tjmp\t*"; |
| 501 getJmpTarget()->emit(Func); | 501 getJmpTarget()->emit(Func); |
| 502 } | 502 } |
| 503 | 503 |
| 504 void InstX8632Jmp::emitIAS(const Cfg *Func) const { | 504 void InstX8632Jmp::emitIAS(const Cfg *Func) const { |
| 505 // Note: Adapted (mostly copied) from InstX8632Call::emitIAS(). | 505 // Note: Adapted (mostly copied) from InstX8632Call::emitIAS(). |
| 506 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 506 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 531 // TODO(jvoung): Support this when there is a lowering that | 531 // TODO(jvoung): Support this when there is a lowering that |
| 532 // actually triggers this case. | 532 // actually triggers this case. |
| 533 (void)Imm; | 533 (void)Imm; |
| 534 llvm::report_fatal_error("Unexpected jmp to absolute address"); | 534 llvm::report_fatal_error("Unexpected jmp to absolute address"); |
| 535 } else { | 535 } else { |
| 536 llvm::report_fatal_error("Unexpected operand type"); | 536 llvm::report_fatal_error("Unexpected operand type"); |
| 537 } | 537 } |
| 538 } | 538 } |
| 539 | 539 |
| 540 void InstX8632Jmp::dump(const Cfg *Func) const { | 540 void InstX8632Jmp::dump(const Cfg *Func) const { |
| 541 if (!ALLOW_DUMP) | 541 if (!buildAllowsDump()) |
| 542 return; | 542 return; |
| 543 Ostream &Str = Func->getContext()->getStrDump(); | 543 Ostream &Str = Func->getContext()->getStrDump(); |
| 544 Str << "jmp "; | 544 Str << "jmp "; |
| 545 getJmpTarget()->dump(Func); | 545 getJmpTarget()->dump(Func); |
| 546 } | 546 } |
| 547 | 547 |
| 548 void InstX8632Call::emit(const Cfg *Func) const { | 548 void InstX8632Call::emit(const Cfg *Func) const { |
| 549 if (!ALLOW_DUMP) | 549 if (!buildAllowsDump()) |
| 550 return; | 550 return; |
| 551 Ostream &Str = Func->getContext()->getStrEmit(); | 551 Ostream &Str = Func->getContext()->getStrEmit(); |
| 552 assert(getSrcSize() == 1); | 552 assert(getSrcSize() == 1); |
| 553 Str << "\tcall\t"; | 553 Str << "\tcall\t"; |
| 554 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) { | 554 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) { |
| 555 // Emit without a leading '$'. | 555 // Emit without a leading '$'. |
| 556 Str << CI->getValue(); | 556 Str << CI->getValue(); |
| 557 } else if (const auto CallTarget = | 557 } else if (const auto CallTarget = |
| 558 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { | 558 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { |
| 559 CallTarget->emitWithoutPrefix(Func->getTarget()); | 559 CallTarget->emitWithoutPrefix(Func->getTarget()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 582 Asm->call(CR); | 582 Asm->call(CR); |
| 583 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { | 583 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { |
| 584 Asm->call(X8632::Immediate(Imm->getValue())); | 584 Asm->call(X8632::Immediate(Imm->getValue())); |
| 585 } else { | 585 } else { |
| 586 llvm_unreachable("Unexpected operand type"); | 586 llvm_unreachable("Unexpected operand type"); |
| 587 } | 587 } |
| 588 Func->getTarget()->resetStackAdjustment(); | 588 Func->getTarget()->resetStackAdjustment(); |
| 589 } | 589 } |
| 590 | 590 |
| 591 void InstX8632Call::dump(const Cfg *Func) const { | 591 void InstX8632Call::dump(const Cfg *Func) const { |
| 592 if (!ALLOW_DUMP) | 592 if (!buildAllowsDump()) |
| 593 return; | 593 return; |
| 594 Ostream &Str = Func->getContext()->getStrDump(); | 594 Ostream &Str = Func->getContext()->getStrDump(); |
| 595 if (getDest()) { | 595 if (getDest()) { |
| 596 dumpDest(Func); | 596 dumpDest(Func); |
| 597 Str << " = "; | 597 Str << " = "; |
| 598 } | 598 } |
| 599 Str << "call "; | 599 Str << "call "; |
| 600 getCallTarget()->dump(Func); | 600 getCallTarget()->dump(Func); |
| 601 } | 601 } |
| 602 | 602 |
| 603 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for | 603 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for |
| 604 // shift instructions, in order to be syntactically valid. The | 604 // shift instructions, in order to be syntactically valid. The |
| 605 // Opcode parameter needs to be char* and not IceString because of | 605 // Opcode parameter needs to be char* and not IceString because of |
| 606 // template issues. | 606 // template issues. |
| 607 void InstX8632::emitTwoAddress(const char *Opcode, const Inst *Inst, | 607 void InstX8632::emitTwoAddress(const char *Opcode, const Inst *Inst, |
| 608 const Cfg *Func, bool ShiftHack) { | 608 const Cfg *Func, bool ShiftHack) { |
| 609 if (!ALLOW_DUMP) | 609 if (!buildAllowsDump()) |
| 610 return; | 610 return; |
| 611 Ostream &Str = Func->getContext()->getStrEmit(); | 611 Ostream &Str = Func->getContext()->getStrEmit(); |
| 612 assert(Inst->getSrcSize() == 2); | 612 assert(Inst->getSrcSize() == 2); |
| 613 Operand *Dest = Inst->getDest(); | 613 Operand *Dest = Inst->getDest(); |
| 614 if (Dest == nullptr) | 614 if (Dest == nullptr) |
| 615 Dest = Inst->getSrc(0); | 615 Dest = Inst->getSrc(0); |
| 616 assert(Dest == Inst->getSrc(0)); | 616 assert(Dest == Inst->getSrc(0)); |
| 617 Operand *Src1 = Inst->getSrc(1); | 617 Operand *Src1 = Inst->getSrc(1); |
| 618 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t"; | 618 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t"; |
| 619 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); | 619 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 template <> | 1147 template <> |
| 1148 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psra::Emitter = { | 1148 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psra::Emitter = { |
| 1149 &X8632::AssemblerX8632::psra, &X8632::AssemblerX8632::psra, | 1149 &X8632::AssemblerX8632::psra, &X8632::AssemblerX8632::psra, |
| 1150 &X8632::AssemblerX8632::psra}; | 1150 &X8632::AssemblerX8632::psra}; |
| 1151 template <> | 1151 template <> |
| 1152 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psrl::Emitter = { | 1152 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psrl::Emitter = { |
| 1153 &X8632::AssemblerX8632::psrl, &X8632::AssemblerX8632::psrl, | 1153 &X8632::AssemblerX8632::psrl, &X8632::AssemblerX8632::psrl, |
| 1154 &X8632::AssemblerX8632::psrl}; | 1154 &X8632::AssemblerX8632::psrl}; |
| 1155 | 1155 |
| 1156 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { | 1156 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { |
| 1157 if (!ALLOW_DUMP) | 1157 if (!buildAllowsDump()) |
| 1158 return; | 1158 return; |
| 1159 Ostream &Str = Func->getContext()->getStrEmit(); | 1159 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1160 assert(getSrcSize() == 1); | 1160 assert(getSrcSize() == 1); |
| 1161 Type Ty = getSrc(0)->getType(); | 1161 Type Ty = getSrc(0)->getType(); |
| 1162 assert(isScalarFloatingType(Ty)); | 1162 assert(isScalarFloatingType(Ty)); |
| 1163 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 1163 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
| 1164 getSrc(0)->emit(Func); | 1164 getSrc(0)->emit(Func); |
| 1165 Str << ", "; | 1165 Str << ", "; |
| 1166 getDest()->emit(Func); | 1166 getDest()->emit(Func); |
| 1167 } | 1167 } |
| 1168 | 1168 |
| 1169 template <> void InstX8632Addss::emit(const Cfg *Func) const { | 1169 template <> void InstX8632Addss::emit(const Cfg *Func) const { |
| 1170 if (!ALLOW_DUMP) | 1170 if (!buildAllowsDump()) |
| 1171 return; | 1171 return; |
| 1172 char buf[30]; | 1172 char buf[30]; |
| 1173 snprintf(buf, llvm::array_lengthof(buf), "add%s", | 1173 snprintf(buf, llvm::array_lengthof(buf), "add%s", |
| 1174 TypeX8632Attributes[getDest()->getType()].SdSsString); | 1174 TypeX8632Attributes[getDest()->getType()].SdSsString); |
| 1175 emitTwoAddress(buf, this, Func); | 1175 emitTwoAddress(buf, this, Func); |
| 1176 } | 1176 } |
| 1177 | 1177 |
| 1178 template <> void InstX8632Padd::emit(const Cfg *Func) const { | 1178 template <> void InstX8632Padd::emit(const Cfg *Func) const { |
| 1179 if (!ALLOW_DUMP) | 1179 if (!buildAllowsDump()) |
| 1180 return; | 1180 return; |
| 1181 char buf[30]; | 1181 char buf[30]; |
| 1182 snprintf(buf, llvm::array_lengthof(buf), "padd%s", | 1182 snprintf(buf, llvm::array_lengthof(buf), "padd%s", |
| 1183 TypeX8632Attributes[getDest()->getType()].PackString); | 1183 TypeX8632Attributes[getDest()->getType()].PackString); |
| 1184 emitTwoAddress(buf, this, Func); | 1184 emitTwoAddress(buf, this, Func); |
| 1185 } | 1185 } |
| 1186 | 1186 |
| 1187 template <> void InstX8632Pmull::emit(const Cfg *Func) const { | 1187 template <> void InstX8632Pmull::emit(const Cfg *Func) const { |
| 1188 if (!ALLOW_DUMP) | 1188 if (!buildAllowsDump()) |
| 1189 return; | 1189 return; |
| 1190 char buf[30]; | 1190 char buf[30]; |
| 1191 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || | 1191 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || |
| 1192 getDest()->getType() == IceType_v8i16; | 1192 getDest()->getType() == IceType_v8i16; |
| 1193 bool InstructionSetIsValid = | 1193 bool InstructionSetIsValid = |
| 1194 getDest()->getType() == IceType_v8i16 || | 1194 getDest()->getType() == IceType_v8i16 || |
| 1195 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1195 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1196 TargetX8632::SSE4_1; | 1196 TargetX8632::SSE4_1; |
| 1197 (void)TypesAreValid; | 1197 (void)TypesAreValid; |
| 1198 (void)InstructionSetIsValid; | 1198 (void)InstructionSetIsValid; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1213 (void)TypesAreValid; | 1213 (void)TypesAreValid; |
| 1214 (void)InstructionSetIsValid; | 1214 (void)InstructionSetIsValid; |
| 1215 assert(TypesAreValid); | 1215 assert(TypesAreValid); |
| 1216 assert(InstructionSetIsValid); | 1216 assert(InstructionSetIsValid); |
| 1217 assert(getSrcSize() == 2); | 1217 assert(getSrcSize() == 2); |
| 1218 Type ElementTy = typeElementType(Ty); | 1218 Type ElementTy = typeElementType(Ty); |
| 1219 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); | 1219 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); |
| 1220 } | 1220 } |
| 1221 | 1221 |
| 1222 template <> void InstX8632Subss::emit(const Cfg *Func) const { | 1222 template <> void InstX8632Subss::emit(const Cfg *Func) const { |
| 1223 if (!ALLOW_DUMP) | 1223 if (!buildAllowsDump()) |
| 1224 return; | 1224 return; |
| 1225 char buf[30]; | 1225 char buf[30]; |
| 1226 snprintf(buf, llvm::array_lengthof(buf), "sub%s", | 1226 snprintf(buf, llvm::array_lengthof(buf), "sub%s", |
| 1227 TypeX8632Attributes[getDest()->getType()].SdSsString); | 1227 TypeX8632Attributes[getDest()->getType()].SdSsString); |
| 1228 emitTwoAddress(buf, this, Func); | 1228 emitTwoAddress(buf, this, Func); |
| 1229 } | 1229 } |
| 1230 | 1230 |
| 1231 template <> void InstX8632Psub::emit(const Cfg *Func) const { | 1231 template <> void InstX8632Psub::emit(const Cfg *Func) const { |
| 1232 if (!ALLOW_DUMP) | 1232 if (!buildAllowsDump()) |
| 1233 return; | 1233 return; |
| 1234 char buf[30]; | 1234 char buf[30]; |
| 1235 snprintf(buf, llvm::array_lengthof(buf), "psub%s", | 1235 snprintf(buf, llvm::array_lengthof(buf), "psub%s", |
| 1236 TypeX8632Attributes[getDest()->getType()].PackString); | 1236 TypeX8632Attributes[getDest()->getType()].PackString); |
| 1237 emitTwoAddress(buf, this, Func); | 1237 emitTwoAddress(buf, this, Func); |
| 1238 } | 1238 } |
| 1239 | 1239 |
| 1240 template <> void InstX8632Mulss::emit(const Cfg *Func) const { | 1240 template <> void InstX8632Mulss::emit(const Cfg *Func) const { |
| 1241 if (!ALLOW_DUMP) | 1241 if (!buildAllowsDump()) |
| 1242 return; | 1242 return; |
| 1243 char buf[30]; | 1243 char buf[30]; |
| 1244 snprintf(buf, llvm::array_lengthof(buf), "mul%s", | 1244 snprintf(buf, llvm::array_lengthof(buf), "mul%s", |
| 1245 TypeX8632Attributes[getDest()->getType()].SdSsString); | 1245 TypeX8632Attributes[getDest()->getType()].SdSsString); |
| 1246 emitTwoAddress(buf, this, Func); | 1246 emitTwoAddress(buf, this, Func); |
| 1247 } | 1247 } |
| 1248 | 1248 |
| 1249 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { | 1249 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { |
| 1250 if (!ALLOW_DUMP) | 1250 if (!buildAllowsDump()) |
| 1251 return; | 1251 return; |
| 1252 assert(getSrc(0)->getType() == IceType_v4i32 && | 1252 assert(getSrc(0)->getType() == IceType_v4i32 && |
| 1253 getSrc(1)->getType() == IceType_v4i32); | 1253 getSrc(1)->getType() == IceType_v4i32); |
| 1254 emitTwoAddress(Opcode, this, Func); | 1254 emitTwoAddress(Opcode, this, Func); |
| 1255 } | 1255 } |
| 1256 | 1256 |
| 1257 template <> void InstX8632Divss::emit(const Cfg *Func) const { | 1257 template <> void InstX8632Divss::emit(const Cfg *Func) const { |
| 1258 if (!ALLOW_DUMP) | 1258 if (!buildAllowsDump()) |
| 1259 return; | 1259 return; |
| 1260 char buf[30]; | 1260 char buf[30]; |
| 1261 snprintf(buf, llvm::array_lengthof(buf), "div%s", | 1261 snprintf(buf, llvm::array_lengthof(buf), "div%s", |
| 1262 TypeX8632Attributes[getDest()->getType()].SdSsString); | 1262 TypeX8632Attributes[getDest()->getType()].SdSsString); |
| 1263 emitTwoAddress(buf, this, Func); | 1263 emitTwoAddress(buf, this, Func); |
| 1264 } | 1264 } |
| 1265 | 1265 |
| 1266 template <> void InstX8632Div::emit(const Cfg *Func) const { | 1266 template <> void InstX8632Div::emit(const Cfg *Func) const { |
| 1267 if (!ALLOW_DUMP) | 1267 if (!buildAllowsDump()) |
| 1268 return; | 1268 return; |
| 1269 Ostream &Str = Func->getContext()->getStrEmit(); | 1269 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1270 assert(getSrcSize() == 3); | 1270 assert(getSrcSize() == 3); |
| 1271 Operand *Src1 = getSrc(1); | 1271 Operand *Src1 = getSrc(1); |
| 1272 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; | 1272 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; |
| 1273 Src1->emit(Func); | 1273 Src1->emit(Func); |
| 1274 } | 1274 } |
| 1275 | 1275 |
| 1276 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { | 1276 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { |
| 1277 assert(getSrcSize() == 3); | 1277 assert(getSrcSize() == 3); |
| 1278 const Operand *Src = getSrc(1); | 1278 const Operand *Src = getSrc(1); |
| 1279 Type Ty = Src->getType(); | 1279 Type Ty = Src->getType(); |
| 1280 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { | 1280 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
| 1281 &X8632::AssemblerX8632::div, &X8632::AssemblerX8632::div}; | 1281 &X8632::AssemblerX8632::div, &X8632::AssemblerX8632::div}; |
| 1282 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1282 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
| 1283 } | 1283 } |
| 1284 | 1284 |
| 1285 template <> void InstX8632Idiv::emit(const Cfg *Func) const { | 1285 template <> void InstX8632Idiv::emit(const Cfg *Func) const { |
| 1286 if (!ALLOW_DUMP) | 1286 if (!buildAllowsDump()) |
| 1287 return; | 1287 return; |
| 1288 Ostream &Str = Func->getContext()->getStrEmit(); | 1288 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1289 assert(getSrcSize() == 3); | 1289 assert(getSrcSize() == 3); |
| 1290 Operand *Src1 = getSrc(1); | 1290 Operand *Src1 = getSrc(1); |
| 1291 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; | 1291 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; |
| 1292 Src1->emit(Func); | 1292 Src1->emit(Func); |
| 1293 } | 1293 } |
| 1294 | 1294 |
| 1295 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { | 1295 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { |
| 1296 assert(getSrcSize() == 3); | 1296 assert(getSrcSize() == 3); |
| 1297 const Operand *Src = getSrc(1); | 1297 const Operand *Src = getSrc(1); |
| 1298 Type Ty = Src->getType(); | 1298 Type Ty = Src->getType(); |
| 1299 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { | 1299 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
| 1300 &X8632::AssemblerX8632::idiv, &X8632::AssemblerX8632::idiv}; | 1300 &X8632::AssemblerX8632::idiv, &X8632::AssemblerX8632::idiv}; |
| 1301 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1301 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
| 1302 } | 1302 } |
| 1303 | 1303 |
| 1304 namespace { | 1304 namespace { |
| 1305 | 1305 |
| 1306 // pblendvb and blendvps take xmm0 as a final implicit argument. | 1306 // pblendvb and blendvps take xmm0 as a final implicit argument. |
| 1307 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, | 1307 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, |
| 1308 const Cfg *Func) { | 1308 const Cfg *Func) { |
| 1309 if (!ALLOW_DUMP) | 1309 if (!buildAllowsDump()) |
| 1310 return; | 1310 return; |
| 1311 Ostream &Str = Func->getContext()->getStrEmit(); | 1311 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1312 assert(Inst->getSrcSize() == 3); | 1312 assert(Inst->getSrcSize() == 3); |
| 1313 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1313 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == |
| 1314 RegX8632::Reg_xmm0); | 1314 RegX8632::Reg_xmm0); |
| 1315 Str << "\t" << Opcode << "\t"; | 1315 Str << "\t" << Opcode << "\t"; |
| 1316 Inst->getSrc(1)->emit(Func); | 1316 Inst->getSrc(1)->emit(Func); |
| 1317 Str << ", "; | 1317 Str << ", "; |
| 1318 Inst->getDest()->emit(Func); | 1318 Inst->getDest()->emit(Func); |
| 1319 } | 1319 } |
| 1320 | 1320 |
| 1321 void emitIASVariableBlendInst( | 1321 void emitIASVariableBlendInst( |
| 1322 const Inst *Inst, const Cfg *Func, | 1322 const Inst *Inst, const Cfg *Func, |
| 1323 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { | 1323 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { |
| 1324 assert(Inst->getSrcSize() == 3); | 1324 assert(Inst->getSrcSize() == 3); |
| 1325 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1325 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == |
| 1326 RegX8632::Reg_xmm0); | 1326 RegX8632::Reg_xmm0); |
| 1327 const Variable *Dest = Inst->getDest(); | 1327 const Variable *Dest = Inst->getDest(); |
| 1328 const Operand *Src = Inst->getSrc(1); | 1328 const Operand *Src = Inst->getSrc(1); |
| 1329 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); | 1329 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); |
| 1330 } | 1330 } |
| 1331 | 1331 |
| 1332 } // end anonymous namespace | 1332 } // end anonymous namespace |
| 1333 | 1333 |
| 1334 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { | 1334 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { |
| 1335 if (!ALLOW_DUMP) | 1335 if (!buildAllowsDump()) |
| 1336 return; | 1336 return; |
| 1337 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1337 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1338 TargetX8632::SSE4_1); | 1338 TargetX8632::SSE4_1); |
| 1339 emitVariableBlendInst(Opcode, this, Func); | 1339 emitVariableBlendInst(Opcode, this, Func); |
| 1340 } | 1340 } |
| 1341 | 1341 |
| 1342 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { | 1342 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { |
| 1343 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1343 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1344 TargetX8632::SSE4_1); | 1344 TargetX8632::SSE4_1); |
| 1345 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1345 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1346 &X8632::AssemblerX8632::blendvps, &X8632::AssemblerX8632::blendvps}; | 1346 &X8632::AssemblerX8632::blendvps, &X8632::AssemblerX8632::blendvps}; |
| 1347 emitIASVariableBlendInst(this, Func, Emitter); | 1347 emitIASVariableBlendInst(this, Func, Emitter); |
| 1348 } | 1348 } |
| 1349 | 1349 |
| 1350 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { | 1350 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { |
| 1351 if (!ALLOW_DUMP) | 1351 if (!buildAllowsDump()) |
| 1352 return; | 1352 return; |
| 1353 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1353 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1354 TargetX8632::SSE4_1); | 1354 TargetX8632::SSE4_1); |
| 1355 emitVariableBlendInst(Opcode, this, Func); | 1355 emitVariableBlendInst(Opcode, this, Func); |
| 1356 } | 1356 } |
| 1357 | 1357 |
| 1358 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { | 1358 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { |
| 1359 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1359 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1360 TargetX8632::SSE4_1); | 1360 TargetX8632::SSE4_1); |
| 1361 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1361 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1362 &X8632::AssemblerX8632::pblendvb, &X8632::AssemblerX8632::pblendvb}; | 1362 &X8632::AssemblerX8632::pblendvb, &X8632::AssemblerX8632::pblendvb}; |
| 1363 emitIASVariableBlendInst(this, Func, Emitter); | 1363 emitIASVariableBlendInst(this, Func, Emitter); |
| 1364 } | 1364 } |
| 1365 | 1365 |
| 1366 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 1366 template <> void InstX8632Imul::emit(const Cfg *Func) const { |
| 1367 if (!ALLOW_DUMP) | 1367 if (!buildAllowsDump()) |
| 1368 return; | 1368 return; |
| 1369 Ostream &Str = Func->getContext()->getStrEmit(); | 1369 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1370 assert(getSrcSize() == 2); | 1370 assert(getSrcSize() == 2); |
| 1371 Variable *Dest = getDest(); | 1371 Variable *Dest = getDest(); |
| 1372 if (isByteSizedArithType(Dest->getType())) { | 1372 if (isByteSizedArithType(Dest->getType())) { |
| 1373 // The 8-bit version of imul only allows the form "imul r/m8". | 1373 // The 8-bit version of imul only allows the form "imul r/m8". |
| 1374 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); | 1374 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); |
| 1375 (void)Src0Var; | 1375 (void)Src0Var; |
| 1376 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); | 1376 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); |
| 1377 Str << "\timulb\t"; | 1377 Str << "\timulb\t"; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 Type Ty = Dest->getType(); | 1421 Type Ty = Dest->getType(); |
| 1422 static const X8632::AssemblerX8632::ThreeOpImmEmitter< | 1422 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 1423 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 1423 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
| 1424 &X8632::AssemblerX8632::insertps, &X8632::AssemblerX8632::insertps}; | 1424 &X8632::AssemblerX8632::insertps, &X8632::AssemblerX8632::insertps}; |
| 1425 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 1425 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
| 1426 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 1426 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
| 1427 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 1427 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); |
| 1428 } | 1428 } |
| 1429 | 1429 |
| 1430 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { | 1430 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { |
| 1431 if (!ALLOW_DUMP) | 1431 if (!buildAllowsDump()) |
| 1432 return; | 1432 return; |
| 1433 Ostream &Str = Func->getContext()->getStrEmit(); | 1433 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1434 assert(getSrcSize() == 1); | 1434 assert(getSrcSize() == 1); |
| 1435 Operand *Src0 = getSrc(0); | 1435 Operand *Src0 = getSrc(0); |
| 1436 assert(llvm::isa<Variable>(Src0)); | 1436 assert(llvm::isa<Variable>(Src0)); |
| 1437 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 1437 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
| 1438 switch (Src0->getType()) { | 1438 switch (Src0->getType()) { |
| 1439 default: | 1439 default: |
| 1440 llvm_unreachable("unexpected source type!"); | 1440 llvm_unreachable("unexpected source type!"); |
| 1441 break; | 1441 break; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1473 Asm->cwd(); | 1473 Asm->cwd(); |
| 1474 break; | 1474 break; |
| 1475 case IceType_i32: | 1475 case IceType_i32: |
| 1476 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1476 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
| 1477 Asm->cdq(); | 1477 Asm->cdq(); |
| 1478 break; | 1478 break; |
| 1479 } | 1479 } |
| 1480 } | 1480 } |
| 1481 | 1481 |
| 1482 void InstX8632Mul::emit(const Cfg *Func) const { | 1482 void InstX8632Mul::emit(const Cfg *Func) const { |
| 1483 if (!ALLOW_DUMP) | 1483 if (!buildAllowsDump()) |
| 1484 return; | 1484 return; |
| 1485 Ostream &Str = Func->getContext()->getStrEmit(); | 1485 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1486 assert(getSrcSize() == 2); | 1486 assert(getSrcSize() == 2); |
| 1487 assert(llvm::isa<Variable>(getSrc(0))); | 1487 assert(llvm::isa<Variable>(getSrc(0))); |
| 1488 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1488 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
| 1489 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1489 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
| 1490 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; | 1490 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; |
| 1491 getSrc(1)->emit(Func); | 1491 getSrc(1)->emit(Func); |
| 1492 } | 1492 } |
| 1493 | 1493 |
| 1494 void InstX8632Mul::emitIAS(const Cfg *Func) const { | 1494 void InstX8632Mul::emitIAS(const Cfg *Func) const { |
| 1495 assert(getSrcSize() == 2); | 1495 assert(getSrcSize() == 2); |
| 1496 assert(llvm::isa<Variable>(getSrc(0))); | 1496 assert(llvm::isa<Variable>(getSrc(0))); |
| 1497 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1497 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
| 1498 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1498 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
| 1499 const Operand *Src = getSrc(1); | 1499 const Operand *Src = getSrc(1); |
| 1500 Type Ty = Src->getType(); | 1500 Type Ty = Src->getType(); |
| 1501 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { | 1501 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
| 1502 &X8632::AssemblerX8632::mul, &X8632::AssemblerX8632::mul}; | 1502 &X8632::AssemblerX8632::mul, &X8632::AssemblerX8632::mul}; |
| 1503 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1503 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
| 1504 } | 1504 } |
| 1505 | 1505 |
| 1506 void InstX8632Mul::dump(const Cfg *Func) const { | 1506 void InstX8632Mul::dump(const Cfg *Func) const { |
| 1507 if (!ALLOW_DUMP) | 1507 if (!buildAllowsDump()) |
| 1508 return; | 1508 return; |
| 1509 Ostream &Str = Func->getContext()->getStrDump(); | 1509 Ostream &Str = Func->getContext()->getStrDump(); |
| 1510 dumpDest(Func); | 1510 dumpDest(Func); |
| 1511 Str << " = mul." << getDest()->getType() << " "; | 1511 Str << " = mul." << getDest()->getType() << " "; |
| 1512 dumpSources(Func); | 1512 dumpSources(Func); |
| 1513 } | 1513 } |
| 1514 | 1514 |
| 1515 void InstX8632Shld::emit(const Cfg *Func) const { | 1515 void InstX8632Shld::emit(const Cfg *Func) const { |
| 1516 if (!ALLOW_DUMP) | 1516 if (!buildAllowsDump()) |
| 1517 return; | 1517 return; |
| 1518 Ostream &Str = Func->getContext()->getStrEmit(); | 1518 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1519 Variable *Dest = getDest(); | 1519 Variable *Dest = getDest(); |
| 1520 assert(getSrcSize() == 3); | 1520 assert(getSrcSize() == 3); |
| 1521 assert(Dest == getSrc(0)); | 1521 assert(Dest == getSrc(0)); |
| 1522 Str << "\tshld" << getWidthString(Dest->getType()) << "\t"; | 1522 Str << "\tshld" << getWidthString(Dest->getType()) << "\t"; |
| 1523 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1523 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
| 1524 (void)ShiftReg; | 1524 (void)ShiftReg; |
| 1525 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1525 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
| 1526 Str << "%cl"; | 1526 Str << "%cl"; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1538 assert(getDest() == getSrc(0)); | 1538 assert(getDest() == getSrc(0)); |
| 1539 const Variable *Dest = getDest(); | 1539 const Variable *Dest = getDest(); |
| 1540 const Operand *Src1 = getSrc(1); | 1540 const Operand *Src1 = getSrc(1); |
| 1541 const Operand *Src2 = getSrc(2); | 1541 const Operand *Src2 = getSrc(2); |
| 1542 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { | 1542 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { |
| 1543 &X8632::AssemblerX8632::shld, &X8632::AssemblerX8632::shld}; | 1543 &X8632::AssemblerX8632::shld, &X8632::AssemblerX8632::shld}; |
| 1544 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 1544 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); |
| 1545 } | 1545 } |
| 1546 | 1546 |
| 1547 void InstX8632Shld::dump(const Cfg *Func) const { | 1547 void InstX8632Shld::dump(const Cfg *Func) const { |
| 1548 if (!ALLOW_DUMP) | 1548 if (!buildAllowsDump()) |
| 1549 return; | 1549 return; |
| 1550 Ostream &Str = Func->getContext()->getStrDump(); | 1550 Ostream &Str = Func->getContext()->getStrDump(); |
| 1551 dumpDest(Func); | 1551 dumpDest(Func); |
| 1552 Str << " = shld." << getDest()->getType() << " "; | 1552 Str << " = shld." << getDest()->getType() << " "; |
| 1553 dumpSources(Func); | 1553 dumpSources(Func); |
| 1554 } | 1554 } |
| 1555 | 1555 |
| 1556 void InstX8632Shrd::emit(const Cfg *Func) const { | 1556 void InstX8632Shrd::emit(const Cfg *Func) const { |
| 1557 if (!ALLOW_DUMP) | 1557 if (!buildAllowsDump()) |
| 1558 return; | 1558 return; |
| 1559 Ostream &Str = Func->getContext()->getStrEmit(); | 1559 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1560 Variable *Dest = getDest(); | 1560 Variable *Dest = getDest(); |
| 1561 assert(getSrcSize() == 3); | 1561 assert(getSrcSize() == 3); |
| 1562 assert(Dest == getSrc(0)); | 1562 assert(Dest == getSrc(0)); |
| 1563 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t"; | 1563 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t"; |
| 1564 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1564 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
| 1565 (void)ShiftReg; | 1565 (void)ShiftReg; |
| 1566 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1566 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
| 1567 Str << "%cl"; | 1567 Str << "%cl"; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1579 assert(getDest() == getSrc(0)); | 1579 assert(getDest() == getSrc(0)); |
| 1580 const Variable *Dest = getDest(); | 1580 const Variable *Dest = getDest(); |
| 1581 const Operand *Src1 = getSrc(1); | 1581 const Operand *Src1 = getSrc(1); |
| 1582 const Operand *Src2 = getSrc(2); | 1582 const Operand *Src2 = getSrc(2); |
| 1583 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { | 1583 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { |
| 1584 &X8632::AssemblerX8632::shrd, &X8632::AssemblerX8632::shrd}; | 1584 &X8632::AssemblerX8632::shrd, &X8632::AssemblerX8632::shrd}; |
| 1585 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 1585 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); |
| 1586 } | 1586 } |
| 1587 | 1587 |
| 1588 void InstX8632Shrd::dump(const Cfg *Func) const { | 1588 void InstX8632Shrd::dump(const Cfg *Func) const { |
| 1589 if (!ALLOW_DUMP) | 1589 if (!buildAllowsDump()) |
| 1590 return; | 1590 return; |
| 1591 Ostream &Str = Func->getContext()->getStrDump(); | 1591 Ostream &Str = Func->getContext()->getStrDump(); |
| 1592 dumpDest(Func); | 1592 dumpDest(Func); |
| 1593 Str << " = shrd." << getDest()->getType() << " "; | 1593 Str << " = shrd." << getDest()->getType() << " "; |
| 1594 dumpSources(Func); | 1594 dumpSources(Func); |
| 1595 } | 1595 } |
| 1596 | 1596 |
| 1597 void InstX8632Cmov::emit(const Cfg *Func) const { | 1597 void InstX8632Cmov::emit(const Cfg *Func) const { |
| 1598 if (!ALLOW_DUMP) | 1598 if (!buildAllowsDump()) |
| 1599 return; | 1599 return; |
| 1600 Ostream &Str = Func->getContext()->getStrEmit(); | 1600 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1601 Variable *Dest = getDest(); | 1601 Variable *Dest = getDest(); |
| 1602 Str << "\t"; | 1602 Str << "\t"; |
| 1603 assert(Condition != CondX86::Br_None); | 1603 assert(Condition != CondX86::Br_None); |
| 1604 assert(getDest()->hasReg()); | 1604 assert(getDest()->hasReg()); |
| 1605 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString | 1605 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString |
| 1606 << getWidthString(Dest->getType()) << "\t"; | 1606 << getWidthString(Dest->getType()) << "\t"; |
| 1607 getSrc(1)->emit(Func); | 1607 getSrc(1)->emit(Func); |
| 1608 Str << ", "; | 1608 Str << ", "; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1631 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 1631 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 1632 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1632 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1633 Asm->cmov(SrcTy, Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), | 1633 Asm->cmov(SrcTy, Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), |
| 1634 Mem->toAsmAddress(Asm)); | 1634 Mem->toAsmAddress(Asm)); |
| 1635 } else { | 1635 } else { |
| 1636 llvm_unreachable("Unexpected operand type"); | 1636 llvm_unreachable("Unexpected operand type"); |
| 1637 } | 1637 } |
| 1638 } | 1638 } |
| 1639 | 1639 |
| 1640 void InstX8632Cmov::dump(const Cfg *Func) const { | 1640 void InstX8632Cmov::dump(const Cfg *Func) const { |
| 1641 if (!ALLOW_DUMP) | 1641 if (!buildAllowsDump()) |
| 1642 return; | 1642 return; |
| 1643 Ostream &Str = Func->getContext()->getStrDump(); | 1643 Ostream &Str = Func->getContext()->getStrDump(); |
| 1644 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 1644 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
| 1645 Str << getDest()->getType() << " "; | 1645 Str << getDest()->getType() << " "; |
| 1646 dumpDest(Func); | 1646 dumpDest(Func); |
| 1647 Str << ", "; | 1647 Str << ", "; |
| 1648 dumpSources(Func); | 1648 dumpSources(Func); |
| 1649 } | 1649 } |
| 1650 | 1650 |
| 1651 void InstX8632Cmpps::emit(const Cfg *Func) const { | 1651 void InstX8632Cmpps::emit(const Cfg *Func) const { |
| 1652 if (!ALLOW_DUMP) | 1652 if (!buildAllowsDump()) |
| 1653 return; | 1653 return; |
| 1654 Ostream &Str = Func->getContext()->getStrEmit(); | 1654 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1655 assert(getSrcSize() == 2); | 1655 assert(getSrcSize() == 2); |
| 1656 assert(Condition < CondX86::Cmpps_Invalid); | 1656 assert(Condition < CondX86::Cmpps_Invalid); |
| 1657 Str << "\t"; | 1657 Str << "\t"; |
| 1658 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1658 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
| 1659 << "\t"; | 1659 << "\t"; |
| 1660 getSrc(1)->emit(Func); | 1660 getSrc(1)->emit(Func); |
| 1661 Str << ", "; | 1661 Str << ", "; |
| 1662 getDest()->emit(Func); | 1662 getDest()->emit(Func); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1675 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); | 1675 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
| 1676 } else { | 1676 } else { |
| 1677 X8632::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 1677 X8632::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 1678 ->stackVarToAsmOperand(SrcVar); | 1678 ->stackVarToAsmOperand(SrcVar); |
| 1679 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, | 1679 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
| 1680 Condition); | 1680 Condition); |
| 1681 } | 1681 } |
| 1682 } | 1682 } |
| 1683 | 1683 |
| 1684 void InstX8632Cmpps::dump(const Cfg *Func) const { | 1684 void InstX8632Cmpps::dump(const Cfg *Func) const { |
| 1685 if (!ALLOW_DUMP) | 1685 if (!buildAllowsDump()) |
| 1686 return; | 1686 return; |
| 1687 Ostream &Str = Func->getContext()->getStrDump(); | 1687 Ostream &Str = Func->getContext()->getStrDump(); |
| 1688 assert(Condition < CondX86::Cmpps_Invalid); | 1688 assert(Condition < CondX86::Cmpps_Invalid); |
| 1689 dumpDest(Func); | 1689 dumpDest(Func); |
| 1690 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1690 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
| 1691 << "\t"; | 1691 << "\t"; |
| 1692 dumpSources(Func); | 1692 dumpSources(Func); |
| 1693 } | 1693 } |
| 1694 | 1694 |
| 1695 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 1695 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
| 1696 if (!ALLOW_DUMP) | 1696 if (!buildAllowsDump()) |
| 1697 return; | 1697 return; |
| 1698 Ostream &Str = Func->getContext()->getStrEmit(); | 1698 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1699 assert(getSrcSize() == 3); | 1699 assert(getSrcSize() == 3); |
| 1700 if (Locked) { | 1700 if (Locked) { |
| 1701 Str << "\tlock"; | 1701 Str << "\tlock"; |
| 1702 } | 1702 } |
| 1703 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; | 1703 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 1704 getSrc(2)->emit(Func); | 1704 getSrc(2)->emit(Func); |
| 1705 Str << ", "; | 1705 Str << ", "; |
| 1706 getSrc(0)->emit(Func); | 1706 getSrc(0)->emit(Func); |
| 1707 } | 1707 } |
| 1708 | 1708 |
| 1709 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1709 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
| 1710 assert(getSrcSize() == 3); | 1710 assert(getSrcSize() == 3); |
| 1711 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1711 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1712 Type Ty = getSrc(0)->getType(); | 1712 Type Ty = getSrc(0)->getType(); |
| 1713 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1713 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1714 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1714 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1715 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 1715 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
| 1716 const auto VarReg = llvm::cast<Variable>(getSrc(2)); | 1716 const auto VarReg = llvm::cast<Variable>(getSrc(2)); |
| 1717 assert(VarReg->hasReg()); | 1717 assert(VarReg->hasReg()); |
| 1718 const RegX8632::GPRRegister Reg = | 1718 const RegX8632::GPRRegister Reg = |
| 1719 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 1719 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 1720 Asm->cmpxchg(Ty, Addr, Reg, Locked); | 1720 Asm->cmpxchg(Ty, Addr, Reg, Locked); |
| 1721 } | 1721 } |
| 1722 | 1722 |
| 1723 void InstX8632Cmpxchg::dump(const Cfg *Func) const { | 1723 void InstX8632Cmpxchg::dump(const Cfg *Func) const { |
| 1724 if (!ALLOW_DUMP) | 1724 if (!buildAllowsDump()) |
| 1725 return; | 1725 return; |
| 1726 Ostream &Str = Func->getContext()->getStrDump(); | 1726 Ostream &Str = Func->getContext()->getStrDump(); |
| 1727 if (Locked) { | 1727 if (Locked) { |
| 1728 Str << "lock "; | 1728 Str << "lock "; |
| 1729 } | 1729 } |
| 1730 Str << "cmpxchg." << getSrc(0)->getType() << " "; | 1730 Str << "cmpxchg." << getSrc(0)->getType() << " "; |
| 1731 dumpSources(Func); | 1731 dumpSources(Func); |
| 1732 } | 1732 } |
| 1733 | 1733 |
| 1734 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { | 1734 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { |
| 1735 if (!ALLOW_DUMP) | 1735 if (!buildAllowsDump()) |
| 1736 return; | 1736 return; |
| 1737 Ostream &Str = Func->getContext()->getStrEmit(); | 1737 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1738 assert(getSrcSize() == 5); | 1738 assert(getSrcSize() == 5); |
| 1739 if (Locked) { | 1739 if (Locked) { |
| 1740 Str << "\tlock"; | 1740 Str << "\tlock"; |
| 1741 } | 1741 } |
| 1742 Str << "\tcmpxchg8b\t"; | 1742 Str << "\tcmpxchg8b\t"; |
| 1743 getSrc(0)->emit(Func); | 1743 getSrc(0)->emit(Func); |
| 1744 } | 1744 } |
| 1745 | 1745 |
| 1746 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1746 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
| 1747 assert(getSrcSize() == 5); | 1747 assert(getSrcSize() == 5); |
| 1748 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1748 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1749 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1749 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1750 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1750 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1751 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 1751 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
| 1752 Asm->cmpxchg8b(Addr, Locked); | 1752 Asm->cmpxchg8b(Addr, Locked); |
| 1753 } | 1753 } |
| 1754 | 1754 |
| 1755 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1755 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
| 1756 if (!ALLOW_DUMP) | 1756 if (!buildAllowsDump()) |
| 1757 return; | 1757 return; |
| 1758 Ostream &Str = Func->getContext()->getStrDump(); | 1758 Ostream &Str = Func->getContext()->getStrDump(); |
| 1759 if (Locked) { | 1759 if (Locked) { |
| 1760 Str << "lock "; | 1760 Str << "lock "; |
| 1761 } | 1761 } |
| 1762 Str << "cmpxchg8b "; | 1762 Str << "cmpxchg8b "; |
| 1763 dumpSources(Func); | 1763 dumpSources(Func); |
| 1764 } | 1764 } |
| 1765 | 1765 |
| 1766 void InstX8632Cvt::emit(const Cfg *Func) const { | 1766 void InstX8632Cvt::emit(const Cfg *Func) const { |
| 1767 if (!ALLOW_DUMP) | 1767 if (!buildAllowsDump()) |
| 1768 return; | 1768 return; |
| 1769 Ostream &Str = Func->getContext()->getStrEmit(); | 1769 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1770 assert(getSrcSize() == 1); | 1770 assert(getSrcSize() == 1); |
| 1771 Str << "\tcvt"; | 1771 Str << "\tcvt"; |
| 1772 if (isTruncating()) | 1772 if (isTruncating()) |
| 1773 Str << "t"; | 1773 Str << "t"; |
| 1774 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" | 1774 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" |
| 1775 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; | 1775 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; |
| 1776 getSrc(0)->emit(Func); | 1776 getSrc(0)->emit(Func); |
| 1777 Str << ", "; | 1777 Str << ", "; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1832 assert(isVectorIntegerType(DestTy)); | 1832 assert(isVectorIntegerType(DestTy)); |
| 1833 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1833 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1834 &X8632::AssemblerX8632::cvttps2dq, &X8632::AssemblerX8632::cvttps2dq}; | 1834 &X8632::AssemblerX8632::cvttps2dq, &X8632::AssemblerX8632::cvttps2dq}; |
| 1835 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); | 1835 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); |
| 1836 return; | 1836 return; |
| 1837 } | 1837 } |
| 1838 } | 1838 } |
| 1839 } | 1839 } |
| 1840 | 1840 |
| 1841 void InstX8632Cvt::dump(const Cfg *Func) const { | 1841 void InstX8632Cvt::dump(const Cfg *Func) const { |
| 1842 if (!ALLOW_DUMP) | 1842 if (!buildAllowsDump()) |
| 1843 return; | 1843 return; |
| 1844 Ostream &Str = Func->getContext()->getStrDump(); | 1844 Ostream &Str = Func->getContext()->getStrDump(); |
| 1845 dumpDest(Func); | 1845 dumpDest(Func); |
| 1846 Str << " = cvt"; | 1846 Str << " = cvt"; |
| 1847 if (isTruncating()) | 1847 if (isTruncating()) |
| 1848 Str << "t"; | 1848 Str << "t"; |
| 1849 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" | 1849 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" |
| 1850 << TypeX8632Attributes[getDest()->getType()].CvtString << " "; | 1850 << TypeX8632Attributes[getDest()->getType()].CvtString << " "; |
| 1851 dumpSources(Func); | 1851 dumpSources(Func); |
| 1852 } | 1852 } |
| 1853 | 1853 |
| 1854 void InstX8632Icmp::emit(const Cfg *Func) const { | 1854 void InstX8632Icmp::emit(const Cfg *Func) const { |
| 1855 if (!ALLOW_DUMP) | 1855 if (!buildAllowsDump()) |
| 1856 return; | 1856 return; |
| 1857 Ostream &Str = Func->getContext()->getStrEmit(); | 1857 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1858 assert(getSrcSize() == 2); | 1858 assert(getSrcSize() == 2); |
| 1859 Str << "\tcmp" << getWidthString(getSrc(0)->getType()) << "\t"; | 1859 Str << "\tcmp" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 1860 getSrc(1)->emit(Func); | 1860 getSrc(1)->emit(Func); |
| 1861 Str << ", "; | 1861 Str << ", "; |
| 1862 getSrc(0)->emit(Func); | 1862 getSrc(0)->emit(Func); |
| 1863 } | 1863 } |
| 1864 | 1864 |
| 1865 void InstX8632Icmp::emitIAS(const Cfg *Func) const { | 1865 void InstX8632Icmp::emitIAS(const Cfg *Func) const { |
| 1866 assert(getSrcSize() == 2); | 1866 assert(getSrcSize() == 2); |
| 1867 const Operand *Src0 = getSrc(0); | 1867 const Operand *Src0 = getSrc(0); |
| 1868 const Operand *Src1 = getSrc(1); | 1868 const Operand *Src1 = getSrc(1); |
| 1869 Type Ty = Src0->getType(); | 1869 Type Ty = Src0->getType(); |
| 1870 static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = { | 1870 static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = { |
| 1871 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp, | 1871 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp, |
| 1872 &X8632::AssemblerX8632::cmp}; | 1872 &X8632::AssemblerX8632::cmp}; |
| 1873 static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = { | 1873 static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = { |
| 1874 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp}; | 1874 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp}; |
| 1875 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { | 1875 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
| 1876 if (SrcVar0->hasReg()) { | 1876 if (SrcVar0->hasReg()) { |
| 1877 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1877 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1878 return; | 1878 return; |
| 1879 } | 1879 } |
| 1880 } | 1880 } |
| 1881 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); | 1881 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); |
| 1882 } | 1882 } |
| 1883 | 1883 |
| 1884 void InstX8632Icmp::dump(const Cfg *Func) const { | 1884 void InstX8632Icmp::dump(const Cfg *Func) const { |
| 1885 if (!ALLOW_DUMP) | 1885 if (!buildAllowsDump()) |
| 1886 return; | 1886 return; |
| 1887 Ostream &Str = Func->getContext()->getStrDump(); | 1887 Ostream &Str = Func->getContext()->getStrDump(); |
| 1888 Str << "cmp." << getSrc(0)->getType() << " "; | 1888 Str << "cmp." << getSrc(0)->getType() << " "; |
| 1889 dumpSources(Func); | 1889 dumpSources(Func); |
| 1890 } | 1890 } |
| 1891 | 1891 |
| 1892 void InstX8632Ucomiss::emit(const Cfg *Func) const { | 1892 void InstX8632Ucomiss::emit(const Cfg *Func) const { |
| 1893 if (!ALLOW_DUMP) | 1893 if (!buildAllowsDump()) |
| 1894 return; | 1894 return; |
| 1895 Ostream &Str = Func->getContext()->getStrEmit(); | 1895 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1896 assert(getSrcSize() == 2); | 1896 assert(getSrcSize() == 2); |
| 1897 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 1897 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString |
| 1898 << "\t"; | 1898 << "\t"; |
| 1899 getSrc(1)->emit(Func); | 1899 getSrc(1)->emit(Func); |
| 1900 Str << ", "; | 1900 Str << ", "; |
| 1901 getSrc(0)->emit(Func); | 1901 getSrc(0)->emit(Func); |
| 1902 } | 1902 } |
| 1903 | 1903 |
| 1904 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { | 1904 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { |
| 1905 assert(getSrcSize() == 2); | 1905 assert(getSrcSize() == 2); |
| 1906 // Currently src0 is always a variable by convention, to avoid having | 1906 // Currently src0 is always a variable by convention, to avoid having |
| 1907 // two memory operands. | 1907 // two memory operands. |
| 1908 assert(llvm::isa<Variable>(getSrc(0))); | 1908 assert(llvm::isa<Variable>(getSrc(0))); |
| 1909 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); | 1909 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); |
| 1910 Type Ty = Src0Var->getType(); | 1910 Type Ty = Src0Var->getType(); |
| 1911 const static X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1911 const static X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1912 &X8632::AssemblerX8632::ucomiss, &X8632::AssemblerX8632::ucomiss}; | 1912 &X8632::AssemblerX8632::ucomiss, &X8632::AssemblerX8632::ucomiss}; |
| 1913 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); | 1913 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); |
| 1914 } | 1914 } |
| 1915 | 1915 |
| 1916 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 1916 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
| 1917 if (!ALLOW_DUMP) | 1917 if (!buildAllowsDump()) |
| 1918 return; | 1918 return; |
| 1919 Ostream &Str = Func->getContext()->getStrDump(); | 1919 Ostream &Str = Func->getContext()->getStrDump(); |
| 1920 Str << "ucomiss." << getSrc(0)->getType() << " "; | 1920 Str << "ucomiss." << getSrc(0)->getType() << " "; |
| 1921 dumpSources(Func); | 1921 dumpSources(Func); |
| 1922 } | 1922 } |
| 1923 | 1923 |
| 1924 void InstX8632UD2::emit(const Cfg *Func) const { | 1924 void InstX8632UD2::emit(const Cfg *Func) const { |
| 1925 if (!ALLOW_DUMP) | 1925 if (!buildAllowsDump()) |
| 1926 return; | 1926 return; |
| 1927 Ostream &Str = Func->getContext()->getStrEmit(); | 1927 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1928 assert(getSrcSize() == 0); | 1928 assert(getSrcSize() == 0); |
| 1929 Str << "\tud2"; | 1929 Str << "\tud2"; |
| 1930 } | 1930 } |
| 1931 | 1931 |
| 1932 void InstX8632UD2::emitIAS(const Cfg *Func) const { | 1932 void InstX8632UD2::emitIAS(const Cfg *Func) const { |
| 1933 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1933 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1934 Asm->ud2(); | 1934 Asm->ud2(); |
| 1935 } | 1935 } |
| 1936 | 1936 |
| 1937 void InstX8632UD2::dump(const Cfg *Func) const { | 1937 void InstX8632UD2::dump(const Cfg *Func) const { |
| 1938 if (!ALLOW_DUMP) | 1938 if (!buildAllowsDump()) |
| 1939 return; | 1939 return; |
| 1940 Ostream &Str = Func->getContext()->getStrDump(); | 1940 Ostream &Str = Func->getContext()->getStrDump(); |
| 1941 Str << "ud2\n"; | 1941 Str << "ud2\n"; |
| 1942 } | 1942 } |
| 1943 | 1943 |
| 1944 void InstX8632Test::emit(const Cfg *Func) const { | 1944 void InstX8632Test::emit(const Cfg *Func) const { |
| 1945 if (!ALLOW_DUMP) | 1945 if (!buildAllowsDump()) |
| 1946 return; | 1946 return; |
| 1947 Ostream &Str = Func->getContext()->getStrEmit(); | 1947 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1948 assert(getSrcSize() == 2); | 1948 assert(getSrcSize() == 2); |
| 1949 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t"; | 1949 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 1950 getSrc(1)->emit(Func); | 1950 getSrc(1)->emit(Func); |
| 1951 Str << ", "; | 1951 Str << ", "; |
| 1952 getSrc(0)->emit(Func); | 1952 getSrc(0)->emit(Func); |
| 1953 } | 1953 } |
| 1954 | 1954 |
| 1955 void InstX8632Test::emitIAS(const Cfg *Func) const { | 1955 void InstX8632Test::emitIAS(const Cfg *Func) const { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1966 if (SrcVar0->hasReg()) { | 1966 if (SrcVar0->hasReg()) { |
| 1967 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1967 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1968 return; | 1968 return; |
| 1969 } | 1969 } |
| 1970 } | 1970 } |
| 1971 llvm_unreachable("Nothing actually generates this so it's untested"); | 1971 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1972 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); | 1972 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); |
| 1973 } | 1973 } |
| 1974 | 1974 |
| 1975 void InstX8632Test::dump(const Cfg *Func) const { | 1975 void InstX8632Test::dump(const Cfg *Func) const { |
| 1976 if (!ALLOW_DUMP) | 1976 if (!buildAllowsDump()) |
| 1977 return; | 1977 return; |
| 1978 Ostream &Str = Func->getContext()->getStrDump(); | 1978 Ostream &Str = Func->getContext()->getStrDump(); |
| 1979 Str << "test." << getSrc(0)->getType() << " "; | 1979 Str << "test." << getSrc(0)->getType() << " "; |
| 1980 dumpSources(Func); | 1980 dumpSources(Func); |
| 1981 } | 1981 } |
| 1982 | 1982 |
| 1983 void InstX8632Mfence::emit(const Cfg *Func) const { | 1983 void InstX8632Mfence::emit(const Cfg *Func) const { |
| 1984 if (!ALLOW_DUMP) | 1984 if (!buildAllowsDump()) |
| 1985 return; | 1985 return; |
| 1986 Ostream &Str = Func->getContext()->getStrEmit(); | 1986 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1987 assert(getSrcSize() == 0); | 1987 assert(getSrcSize() == 0); |
| 1988 Str << "\tmfence"; | 1988 Str << "\tmfence"; |
| 1989 } | 1989 } |
| 1990 | 1990 |
| 1991 void InstX8632Mfence::emitIAS(const Cfg *Func) const { | 1991 void InstX8632Mfence::emitIAS(const Cfg *Func) const { |
| 1992 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1992 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1993 Asm->mfence(); | 1993 Asm->mfence(); |
| 1994 } | 1994 } |
| 1995 | 1995 |
| 1996 void InstX8632Mfence::dump(const Cfg *Func) const { | 1996 void InstX8632Mfence::dump(const Cfg *Func) const { |
| 1997 if (!ALLOW_DUMP) | 1997 if (!buildAllowsDump()) |
| 1998 return; | 1998 return; |
| 1999 Ostream &Str = Func->getContext()->getStrDump(); | 1999 Ostream &Str = Func->getContext()->getStrDump(); |
| 2000 Str << "mfence\n"; | 2000 Str << "mfence\n"; |
| 2001 } | 2001 } |
| 2002 | 2002 |
| 2003 void InstX8632Store::emit(const Cfg *Func) const { | 2003 void InstX8632Store::emit(const Cfg *Func) const { |
| 2004 if (!ALLOW_DUMP) | 2004 if (!buildAllowsDump()) |
| 2005 return; | 2005 return; |
| 2006 Ostream &Str = Func->getContext()->getStrEmit(); | 2006 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2007 assert(getSrcSize() == 2); | 2007 assert(getSrcSize() == 2); |
| 2008 Type Ty = getSrc(0)->getType(); | 2008 Type Ty = getSrc(0)->getType(); |
| 2009 Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString | 2009 Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString |
| 2010 << "\t"; | 2010 << "\t"; |
| 2011 getSrc(0)->emit(Func); | 2011 getSrc(0)->emit(Func); |
| 2012 Str << ", "; | 2012 Str << ", "; |
| 2013 getSrc(1)->emit(Func); | 2013 getSrc(1)->emit(Func); |
| 2014 } | 2014 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2037 return; | 2037 return; |
| 2038 } else { | 2038 } else { |
| 2039 assert(isScalarIntegerType(DestTy)); | 2039 assert(isScalarIntegerType(DestTy)); |
| 2040 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { | 2040 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { |
| 2041 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov}; | 2041 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov}; |
| 2042 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); | 2042 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); |
| 2043 } | 2043 } |
| 2044 } | 2044 } |
| 2045 | 2045 |
| 2046 void InstX8632Store::dump(const Cfg *Func) const { | 2046 void InstX8632Store::dump(const Cfg *Func) const { |
| 2047 if (!ALLOW_DUMP) | 2047 if (!buildAllowsDump()) |
| 2048 return; | 2048 return; |
| 2049 Ostream &Str = Func->getContext()->getStrDump(); | 2049 Ostream &Str = Func->getContext()->getStrDump(); |
| 2050 Str << "mov." << getSrc(0)->getType() << " "; | 2050 Str << "mov." << getSrc(0)->getType() << " "; |
| 2051 getSrc(1)->dump(Func); | 2051 getSrc(1)->dump(Func); |
| 2052 Str << ", "; | 2052 Str << ", "; |
| 2053 getSrc(0)->dump(Func); | 2053 getSrc(0)->dump(Func); |
| 2054 } | 2054 } |
| 2055 | 2055 |
| 2056 void InstX8632StoreP::emit(const Cfg *Func) const { | 2056 void InstX8632StoreP::emit(const Cfg *Func) const { |
| 2057 if (!ALLOW_DUMP) | 2057 if (!buildAllowsDump()) |
| 2058 return; | 2058 return; |
| 2059 Ostream &Str = Func->getContext()->getStrEmit(); | 2059 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2060 assert(getSrcSize() == 2); | 2060 assert(getSrcSize() == 2); |
| 2061 Str << "\tmovups\t"; | 2061 Str << "\tmovups\t"; |
| 2062 getSrc(0)->emit(Func); | 2062 getSrc(0)->emit(Func); |
| 2063 Str << ", "; | 2063 Str << ", "; |
| 2064 getSrc(1)->emit(Func); | 2064 getSrc(1)->emit(Func); |
| 2065 } | 2065 } |
| 2066 | 2066 |
| 2067 void InstX8632StoreP::emitIAS(const Cfg *Func) const { | 2067 void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
| 2068 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2068 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2069 assert(getSrcSize() == 2); | 2069 assert(getSrcSize() == 2); |
| 2070 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2070 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
| 2071 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 2071 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 2072 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2072 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2073 assert(SrcVar->hasReg()); | 2073 assert(SrcVar->hasReg()); |
| 2074 Asm->movups(DestMem->toAsmAddress(Asm), | 2074 Asm->movups(DestMem->toAsmAddress(Asm), |
| 2075 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2075 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 2076 } | 2076 } |
| 2077 | 2077 |
| 2078 void InstX8632StoreP::dump(const Cfg *Func) const { | 2078 void InstX8632StoreP::dump(const Cfg *Func) const { |
| 2079 if (!ALLOW_DUMP) | 2079 if (!buildAllowsDump()) |
| 2080 return; | 2080 return; |
| 2081 Ostream &Str = Func->getContext()->getStrDump(); | 2081 Ostream &Str = Func->getContext()->getStrDump(); |
| 2082 Str << "storep." << getSrc(0)->getType() << " "; | 2082 Str << "storep." << getSrc(0)->getType() << " "; |
| 2083 getSrc(1)->dump(Func); | 2083 getSrc(1)->dump(Func); |
| 2084 Str << ", "; | 2084 Str << ", "; |
| 2085 getSrc(0)->dump(Func); | 2085 getSrc(0)->dump(Func); |
| 2086 } | 2086 } |
| 2087 | 2087 |
| 2088 void InstX8632StoreQ::emit(const Cfg *Func) const { | 2088 void InstX8632StoreQ::emit(const Cfg *Func) const { |
| 2089 if (!ALLOW_DUMP) | 2089 if (!buildAllowsDump()) |
| 2090 return; | 2090 return; |
| 2091 Ostream &Str = Func->getContext()->getStrEmit(); | 2091 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2092 assert(getSrcSize() == 2); | 2092 assert(getSrcSize() == 2); |
| 2093 assert(getSrc(1)->getType() == IceType_i64 || | 2093 assert(getSrc(1)->getType() == IceType_i64 || |
| 2094 getSrc(1)->getType() == IceType_f64); | 2094 getSrc(1)->getType() == IceType_f64); |
| 2095 Str << "\tmovq\t"; | 2095 Str << "\tmovq\t"; |
| 2096 getSrc(0)->emit(Func); | 2096 getSrc(0)->emit(Func); |
| 2097 Str << ", "; | 2097 Str << ", "; |
| 2098 getSrc(1)->emit(Func); | 2098 getSrc(1)->emit(Func); |
| 2099 } | 2099 } |
| 2100 | 2100 |
| 2101 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { | 2101 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
| 2102 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2102 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2103 assert(getSrcSize() == 2); | 2103 assert(getSrcSize() == 2); |
| 2104 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2104 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
| 2105 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 2105 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 2106 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2106 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2107 assert(SrcVar->hasReg()); | 2107 assert(SrcVar->hasReg()); |
| 2108 Asm->movq(DestMem->toAsmAddress(Asm), | 2108 Asm->movq(DestMem->toAsmAddress(Asm), |
| 2109 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2109 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 2110 } | 2110 } |
| 2111 | 2111 |
| 2112 void InstX8632StoreQ::dump(const Cfg *Func) const { | 2112 void InstX8632StoreQ::dump(const Cfg *Func) const { |
| 2113 if (!ALLOW_DUMP) | 2113 if (!buildAllowsDump()) |
| 2114 return; | 2114 return; |
| 2115 Ostream &Str = Func->getContext()->getStrDump(); | 2115 Ostream &Str = Func->getContext()->getStrDump(); |
| 2116 Str << "storeq." << getSrc(0)->getType() << " "; | 2116 Str << "storeq." << getSrc(0)->getType() << " "; |
| 2117 getSrc(1)->dump(Func); | 2117 getSrc(1)->dump(Func); |
| 2118 Str << ", "; | 2118 Str << ", "; |
| 2119 getSrc(0)->dump(Func); | 2119 getSrc(0)->dump(Func); |
| 2120 } | 2120 } |
| 2121 | 2121 |
| 2122 template <> void InstX8632Lea::emit(const Cfg *Func) const { | 2122 template <> void InstX8632Lea::emit(const Cfg *Func) const { |
| 2123 if (!ALLOW_DUMP) | 2123 if (!buildAllowsDump()) |
| 2124 return; | 2124 return; |
| 2125 Ostream &Str = Func->getContext()->getStrEmit(); | 2125 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2126 assert(getSrcSize() == 1); | 2126 assert(getSrcSize() == 1); |
| 2127 assert(getDest()->hasReg()); | 2127 assert(getDest()->hasReg()); |
| 2128 Str << "\tleal\t"; | 2128 Str << "\tleal\t"; |
| 2129 Operand *Src0 = getSrc(0); | 2129 Operand *Src0 = getSrc(0); |
| 2130 if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) { | 2130 if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) { |
| 2131 Type Ty = Src0Var->getType(); | 2131 Type Ty = Src0Var->getType(); |
| 2132 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 2132 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
| 2133 // acceptable type. | 2133 // acceptable type. |
| 2134 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func); | 2134 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func); |
| 2135 } else { | 2135 } else { |
| 2136 Src0->emit(Func); | 2136 Src0->emit(Func); |
| 2137 } | 2137 } |
| 2138 Str << ", "; | 2138 Str << ", "; |
| 2139 getDest()->emit(Func); | 2139 getDest()->emit(Func); |
| 2140 } | 2140 } |
| 2141 | 2141 |
| 2142 template <> void InstX8632Mov::emit(const Cfg *Func) const { | 2142 template <> void InstX8632Mov::emit(const Cfg *Func) const { |
| 2143 if (!ALLOW_DUMP) | 2143 if (!buildAllowsDump()) |
| 2144 return; | 2144 return; |
| 2145 Ostream &Str = Func->getContext()->getStrEmit(); | 2145 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2146 assert(getSrcSize() == 1); | 2146 assert(getSrcSize() == 1); |
| 2147 Operand *Src = getSrc(0); | 2147 Operand *Src = getSrc(0); |
| 2148 Type SrcTy = Src->getType(); | 2148 Type SrcTy = Src->getType(); |
| 2149 Type DestTy = getDest()->getType(); | 2149 Type DestTy = getDest()->getType(); |
| 2150 Str << "\tmov" << (!isScalarFloatingType(DestTy) | 2150 Str << "\tmov" << (!isScalarFloatingType(DestTy) |
| 2151 ? getWidthString(SrcTy) | 2151 ? getWidthString(SrcTy) |
| 2152 : TypeX8632Attributes[DestTy].SdSsString) << "\t"; | 2152 : TypeX8632Attributes[DestTy].SdSsString) << "\t"; |
| 2153 // For an integer truncation operation, src is wider than dest. | 2153 // For an integer truncation operation, src is wider than dest. |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2263 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); | 2263 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); |
| 2264 } else { | 2264 } else { |
| 2265 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2265 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2266 ->stackVarToAsmOperand(Dest)); | 2266 ->stackVarToAsmOperand(Dest)); |
| 2267 Asm->movd(StackAddr, SrcReg); | 2267 Asm->movd(StackAddr, SrcReg); |
| 2268 } | 2268 } |
| 2269 } | 2269 } |
| 2270 } | 2270 } |
| 2271 | 2271 |
| 2272 template <> void InstX8632Movp::emit(const Cfg *Func) const { | 2272 template <> void InstX8632Movp::emit(const Cfg *Func) const { |
| 2273 if (!ALLOW_DUMP) | 2273 if (!buildAllowsDump()) |
| 2274 return; | 2274 return; |
| 2275 // TODO(wala,stichnot): movups works with all vector operands, but | 2275 // TODO(wala,stichnot): movups works with all vector operands, but |
| 2276 // there exist other instructions (movaps, movdqa, movdqu) that may | 2276 // there exist other instructions (movaps, movdqa, movdqu) that may |
| 2277 // perform better, depending on the data type and alignment of the | 2277 // perform better, depending on the data type and alignment of the |
| 2278 // operands. | 2278 // operands. |
| 2279 Ostream &Str = Func->getContext()->getStrEmit(); | 2279 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2280 assert(getSrcSize() == 1); | 2280 assert(getSrcSize() == 1); |
| 2281 Str << "\tmovups\t"; | 2281 Str << "\tmovups\t"; |
| 2282 getSrc(0)->emit(Func); | 2282 getSrc(0)->emit(Func); |
| 2283 Str << ", "; | 2283 Str << ", "; |
| 2284 getDest()->emit(Func); | 2284 getDest()->emit(Func); |
| 2285 } | 2285 } |
| 2286 | 2286 |
| 2287 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { | 2287 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { |
| 2288 assert(getSrcSize() == 1); | 2288 assert(getSrcSize() == 1); |
| 2289 assert(isVectorType(getDest()->getType())); | 2289 assert(isVectorType(getDest()->getType())); |
| 2290 const Variable *Dest = getDest(); | 2290 const Variable *Dest = getDest(); |
| 2291 const Operand *Src = getSrc(0); | 2291 const Operand *Src = getSrc(0); |
| 2292 const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = { | 2292 const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = { |
| 2293 &X8632::AssemblerX8632::movups, &X8632::AssemblerX8632::movups, | 2293 &X8632::AssemblerX8632::movups, &X8632::AssemblerX8632::movups, |
| 2294 &X8632::AssemblerX8632::movups}; | 2294 &X8632::AssemblerX8632::movups}; |
| 2295 emitIASMovlikeXMM(Func, Dest, Src, Emitter); | 2295 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
| 2296 } | 2296 } |
| 2297 | 2297 |
| 2298 template <> void InstX8632Movq::emit(const Cfg *Func) const { | 2298 template <> void InstX8632Movq::emit(const Cfg *Func) const { |
| 2299 if (!ALLOW_DUMP) | 2299 if (!buildAllowsDump()) |
| 2300 return; | 2300 return; |
| 2301 Ostream &Str = Func->getContext()->getStrEmit(); | 2301 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2302 assert(getSrcSize() == 1); | 2302 assert(getSrcSize() == 1); |
| 2303 assert(getDest()->getType() == IceType_i64 || | 2303 assert(getDest()->getType() == IceType_i64 || |
| 2304 getDest()->getType() == IceType_f64); | 2304 getDest()->getType() == IceType_f64); |
| 2305 Str << "\tmovq\t"; | 2305 Str << "\tmovq\t"; |
| 2306 getSrc(0)->emit(Func); | 2306 getSrc(0)->emit(Func); |
| 2307 Str << ", "; | 2307 Str << ", "; |
| 2308 getDest()->emit(Func); | 2308 getDest()->emit(Func); |
| 2309 } | 2309 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2350 assert(getSrcSize() == 1); | 2350 assert(getSrcSize() == 1); |
| 2351 const Variable *Dest = getDest(); | 2351 const Variable *Dest = getDest(); |
| 2352 const Operand *Src = getSrc(0); | 2352 const Operand *Src = getSrc(0); |
| 2353 Type SrcTy = Src->getType(); | 2353 Type SrcTy = Src->getType(); |
| 2354 assert(typeWidthInBytes(Dest->getType()) > 1); | 2354 assert(typeWidthInBytes(Dest->getType()) > 1); |
| 2355 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); | 2355 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); |
| 2356 emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter); | 2356 emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter); |
| 2357 } | 2357 } |
| 2358 | 2358 |
| 2359 void InstX8632Nop::emit(const Cfg *Func) const { | 2359 void InstX8632Nop::emit(const Cfg *Func) const { |
| 2360 if (!ALLOW_DUMP) | 2360 if (!buildAllowsDump()) |
| 2361 return; | 2361 return; |
| 2362 Ostream &Str = Func->getContext()->getStrEmit(); | 2362 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2363 // TODO: Emit the right code for each variant. | 2363 // TODO: Emit the right code for each variant. |
| 2364 Str << "\tnop\t# variant = " << Variant; | 2364 Str << "\tnop\t# variant = " << Variant; |
| 2365 } | 2365 } |
| 2366 | 2366 |
| 2367 void InstX8632Nop::emitIAS(const Cfg *Func) const { | 2367 void InstX8632Nop::emitIAS(const Cfg *Func) const { |
| 2368 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2368 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2369 // TODO: Emit the right code for the variant. | 2369 // TODO: Emit the right code for the variant. |
| 2370 Asm->nop(); | 2370 Asm->nop(); |
| 2371 } | 2371 } |
| 2372 | 2372 |
| 2373 void InstX8632Nop::dump(const Cfg *Func) const { | 2373 void InstX8632Nop::dump(const Cfg *Func) const { |
| 2374 if (!ALLOW_DUMP) | 2374 if (!buildAllowsDump()) |
| 2375 return; | 2375 return; |
| 2376 Ostream &Str = Func->getContext()->getStrDump(); | 2376 Ostream &Str = Func->getContext()->getStrDump(); |
| 2377 Str << "nop (variant = " << Variant << ")"; | 2377 Str << "nop (variant = " << Variant << ")"; |
| 2378 } | 2378 } |
| 2379 | 2379 |
| 2380 void InstX8632Fld::emit(const Cfg *Func) const { | 2380 void InstX8632Fld::emit(const Cfg *Func) const { |
| 2381 if (!ALLOW_DUMP) | 2381 if (!buildAllowsDump()) |
| 2382 return; | 2382 return; |
| 2383 Ostream &Str = Func->getContext()->getStrEmit(); | 2383 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2384 assert(getSrcSize() == 1); | 2384 assert(getSrcSize() == 1); |
| 2385 Type Ty = getSrc(0)->getType(); | 2385 Type Ty = getSrc(0)->getType(); |
| 2386 SizeT Width = typeWidthInBytes(Ty); | 2386 SizeT Width = typeWidthInBytes(Ty); |
| 2387 const auto Var = llvm::dyn_cast<Variable>(getSrc(0)); | 2387 const auto Var = llvm::dyn_cast<Variable>(getSrc(0)); |
| 2388 if (Var && Var->hasReg()) { | 2388 if (Var && Var->hasReg()) { |
| 2389 // This is a physical xmm register, so we need to spill it to a | 2389 // This is a physical xmm register, so we need to spill it to a |
| 2390 // temporary stack slot. | 2390 // temporary stack slot. |
| 2391 Str << "\tsubl\t$" << Width << ", %esp" | 2391 Str << "\tsubl\t$" << Width << ", %esp" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2426 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2426 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2427 Asm->fld(Ty, Mem->toAsmAddress(Asm)); | 2427 Asm->fld(Ty, Mem->toAsmAddress(Asm)); |
| 2428 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 2428 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
| 2429 Asm->fld(Ty, X8632::Address::ofConstPool(Asm, Imm)); | 2429 Asm->fld(Ty, X8632::Address::ofConstPool(Asm, Imm)); |
| 2430 } else { | 2430 } else { |
| 2431 llvm_unreachable("Unexpected operand type"); | 2431 llvm_unreachable("Unexpected operand type"); |
| 2432 } | 2432 } |
| 2433 } | 2433 } |
| 2434 | 2434 |
| 2435 void InstX8632Fld::dump(const Cfg *Func) const { | 2435 void InstX8632Fld::dump(const Cfg *Func) const { |
| 2436 if (!ALLOW_DUMP) | 2436 if (!buildAllowsDump()) |
| 2437 return; | 2437 return; |
| 2438 Ostream &Str = Func->getContext()->getStrDump(); | 2438 Ostream &Str = Func->getContext()->getStrDump(); |
| 2439 Str << "fld." << getSrc(0)->getType() << " "; | 2439 Str << "fld." << getSrc(0)->getType() << " "; |
| 2440 dumpSources(Func); | 2440 dumpSources(Func); |
| 2441 } | 2441 } |
| 2442 | 2442 |
| 2443 void InstX8632Fstp::emit(const Cfg *Func) const { | 2443 void InstX8632Fstp::emit(const Cfg *Func) const { |
| 2444 if (!ALLOW_DUMP) | 2444 if (!buildAllowsDump()) |
| 2445 return; | 2445 return; |
| 2446 Ostream &Str = Func->getContext()->getStrEmit(); | 2446 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2447 assert(getSrcSize() == 0); | 2447 assert(getSrcSize() == 0); |
| 2448 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to | 2448 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
| 2449 // "partially" delete the fstp if the Dest is unused. | 2449 // "partially" delete the fstp if the Dest is unused. |
| 2450 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2450 // Even if Dest is unused, the fstp should be kept for the SideEffects |
| 2451 // of popping the stack. | 2451 // of popping the stack. |
| 2452 if (!getDest()) { | 2452 if (!getDest()) { |
| 2453 Str << "\tfstp\tst(0)"; | 2453 Str << "\tfstp\tst(0)"; |
| 2454 return; | 2454 return; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2499 X8632::Immediate Width(typeWidthInBytes(Ty)); | 2499 X8632::Immediate Width(typeWidthInBytes(Ty)); |
| 2500 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2500 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2501 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); | 2501 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); |
| 2502 Asm->fstp(Ty, StackSlot); | 2502 Asm->fstp(Ty, StackSlot); |
| 2503 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); | 2503 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); |
| 2504 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2504 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2505 } | 2505 } |
| 2506 } | 2506 } |
| 2507 | 2507 |
| 2508 void InstX8632Fstp::dump(const Cfg *Func) const { | 2508 void InstX8632Fstp::dump(const Cfg *Func) const { |
| 2509 if (!ALLOW_DUMP) | 2509 if (!buildAllowsDump()) |
| 2510 return; | 2510 return; |
| 2511 Ostream &Str = Func->getContext()->getStrDump(); | 2511 Ostream &Str = Func->getContext()->getStrDump(); |
| 2512 dumpDest(Func); | 2512 dumpDest(Func); |
| 2513 Str << " = fstp." << getDest()->getType() << ", st(0)"; | 2513 Str << " = fstp." << getDest()->getType() << ", st(0)"; |
| 2514 Str << "\n"; | 2514 Str << "\n"; |
| 2515 } | 2515 } |
| 2516 | 2516 |
| 2517 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { | 2517 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { |
| 2518 if (!ALLOW_DUMP) | 2518 if (!buildAllowsDump()) |
| 2519 return; | 2519 return; |
| 2520 char buf[30]; | 2520 char buf[30]; |
| 2521 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s", | 2521 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s", |
| 2522 TypeX8632Attributes[getDest()->getType()].PackString); | 2522 TypeX8632Attributes[getDest()->getType()].PackString); |
| 2523 emitTwoAddress(buf, this, Func); | 2523 emitTwoAddress(buf, this, Func); |
| 2524 } | 2524 } |
| 2525 | 2525 |
| 2526 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const { | 2526 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const { |
| 2527 if (!ALLOW_DUMP) | 2527 if (!buildAllowsDump()) |
| 2528 return; | 2528 return; |
| 2529 char buf[30]; | 2529 char buf[30]; |
| 2530 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s", | 2530 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s", |
| 2531 TypeX8632Attributes[getDest()->getType()].PackString); | 2531 TypeX8632Attributes[getDest()->getType()].PackString); |
| 2532 emitTwoAddress(buf, this, Func); | 2532 emitTwoAddress(buf, this, Func); |
| 2533 } | 2533 } |
| 2534 | 2534 |
| 2535 template <> void InstX8632Pextr::emit(const Cfg *Func) const { | 2535 template <> void InstX8632Pextr::emit(const Cfg *Func) const { |
| 2536 if (!ALLOW_DUMP) | 2536 if (!buildAllowsDump()) |
| 2537 return; | 2537 return; |
| 2538 Ostream &Str = Func->getContext()->getStrEmit(); | 2538 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2539 assert(getSrcSize() == 2); | 2539 assert(getSrcSize() == 2); |
| 2540 // pextrb and pextrd are SSE4.1 instructions. | 2540 // pextrb and pextrd are SSE4.1 instructions. |
| 2541 assert(getSrc(0)->getType() == IceType_v8i16 || | 2541 assert(getSrc(0)->getType() == IceType_v8i16 || |
| 2542 getSrc(0)->getType() == IceType_v8i1 || | 2542 getSrc(0)->getType() == IceType_v8i1 || |
| 2543 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2543 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 2544 TargetX8632::SSE4_1); | 2544 TargetX8632::SSE4_1); |
| 2545 Str << "\t" << Opcode << TypeX8632Attributes[getSrc(0)->getType()].PackString | 2545 Str << "\t" << Opcode << TypeX8632Attributes[getSrc(0)->getType()].PackString |
| 2546 << "\t"; | 2546 << "\t"; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2572 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); | 2572 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); |
| 2573 static const X8632::AssemblerX8632::ThreeOpImmEmitter< | 2573 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 2574 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { | 2574 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { |
| 2575 &X8632::AssemblerX8632::pextr, nullptr}; | 2575 &X8632::AssemblerX8632::pextr, nullptr}; |
| 2576 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, | 2576 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, |
| 2577 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( | 2577 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( |
| 2578 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); | 2578 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); |
| 2579 } | 2579 } |
| 2580 | 2580 |
| 2581 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { | 2581 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { |
| 2582 if (!ALLOW_DUMP) | 2582 if (!buildAllowsDump()) |
| 2583 return; | 2583 return; |
| 2584 Ostream &Str = Func->getContext()->getStrEmit(); | 2584 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2585 assert(getSrcSize() == 3); | 2585 assert(getSrcSize() == 3); |
| 2586 // pinsrb and pinsrd are SSE4.1 instructions. | 2586 // pinsrb and pinsrd are SSE4.1 instructions. |
| 2587 assert(getDest()->getType() == IceType_v8i16 || | 2587 assert(getDest()->getType() == IceType_v8i16 || |
| 2588 getDest()->getType() == IceType_v8i1 || | 2588 getDest()->getType() == IceType_v8i1 || |
| 2589 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2589 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 2590 TargetX8632::SSE4_1); | 2590 TargetX8632::SSE4_1); |
| 2591 Str << "\t" << Opcode << TypeX8632Attributes[getDest()->getType()].PackString | 2591 Str << "\t" << Opcode << TypeX8632Attributes[getDest()->getType()].PackString |
| 2592 << "\t"; | 2592 << "\t"; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2647 Type Ty = Dest->getType(); | 2647 Type Ty = Dest->getType(); |
| 2648 static const X8632::AssemblerX8632::ThreeOpImmEmitter< | 2648 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 2649 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 2649 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
| 2650 &X8632::AssemblerX8632::shufps, &X8632::AssemblerX8632::shufps}; | 2650 &X8632::AssemblerX8632::shufps, &X8632::AssemblerX8632::shufps}; |
| 2651 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 2651 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
| 2652 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 2652 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
| 2653 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 2653 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); |
| 2654 } | 2654 } |
| 2655 | 2655 |
| 2656 void InstX8632Pop::emit(const Cfg *Func) const { | 2656 void InstX8632Pop::emit(const Cfg *Func) const { |
| 2657 if (!ALLOW_DUMP) | 2657 if (!buildAllowsDump()) |
| 2658 return; | 2658 return; |
| 2659 Ostream &Str = Func->getContext()->getStrEmit(); | 2659 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2660 assert(getSrcSize() == 0); | 2660 assert(getSrcSize() == 0); |
| 2661 Str << "\tpop\t"; | 2661 Str << "\tpop\t"; |
| 2662 getDest()->emit(Func); | 2662 getDest()->emit(Func); |
| 2663 } | 2663 } |
| 2664 | 2664 |
| 2665 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 2665 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
| 2666 assert(getSrcSize() == 0); | 2666 assert(getSrcSize() == 0); |
| 2667 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2667 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2668 if (getDest()->hasReg()) { | 2668 if (getDest()->hasReg()) { |
| 2669 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); | 2669 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); |
| 2670 } else { | 2670 } else { |
| 2671 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) | 2671 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) |
| 2672 ->stackVarToAsmOperand(getDest())); | 2672 ->stackVarToAsmOperand(getDest())); |
| 2673 } | 2673 } |
| 2674 } | 2674 } |
| 2675 | 2675 |
| 2676 void InstX8632Pop::dump(const Cfg *Func) const { | 2676 void InstX8632Pop::dump(const Cfg *Func) const { |
| 2677 if (!ALLOW_DUMP) | 2677 if (!buildAllowsDump()) |
| 2678 return; | 2678 return; |
| 2679 Ostream &Str = Func->getContext()->getStrDump(); | 2679 Ostream &Str = Func->getContext()->getStrDump(); |
| 2680 dumpDest(Func); | 2680 dumpDest(Func); |
| 2681 Str << " = pop." << getDest()->getType() << " "; | 2681 Str << " = pop." << getDest()->getType() << " "; |
| 2682 } | 2682 } |
| 2683 | 2683 |
| 2684 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 2684 void InstX8632AdjustStack::emit(const Cfg *Func) const { |
| 2685 if (!ALLOW_DUMP) | 2685 if (!buildAllowsDump()) |
| 2686 return; | 2686 return; |
| 2687 Ostream &Str = Func->getContext()->getStrEmit(); | 2687 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2688 Str << "\tsubl\t$" << Amount << ", %esp"; | 2688 Str << "\tsubl\t$" << Amount << ", %esp"; |
| 2689 Func->getTarget()->updateStackAdjustment(Amount); | 2689 Func->getTarget()->updateStackAdjustment(Amount); |
| 2690 } | 2690 } |
| 2691 | 2691 |
| 2692 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { | 2692 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { |
| 2693 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2693 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2694 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, X8632::Immediate(Amount)); | 2694 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, X8632::Immediate(Amount)); |
| 2695 Func->getTarget()->updateStackAdjustment(Amount); | 2695 Func->getTarget()->updateStackAdjustment(Amount); |
| 2696 } | 2696 } |
| 2697 | 2697 |
| 2698 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 2698 void InstX8632AdjustStack::dump(const Cfg *Func) const { |
| 2699 if (!ALLOW_DUMP) | 2699 if (!buildAllowsDump()) |
| 2700 return; | 2700 return; |
| 2701 Ostream &Str = Func->getContext()->getStrDump(); | 2701 Ostream &Str = Func->getContext()->getStrDump(); |
| 2702 Str << "esp = sub.i32 esp, " << Amount; | 2702 Str << "esp = sub.i32 esp, " << Amount; |
| 2703 } | 2703 } |
| 2704 | 2704 |
| 2705 void InstX8632Push::emit(const Cfg *Func) const { | 2705 void InstX8632Push::emit(const Cfg *Func) const { |
| 2706 if (!ALLOW_DUMP) | 2706 if (!buildAllowsDump()) |
| 2707 return; | 2707 return; |
| 2708 Ostream &Str = Func->getContext()->getStrEmit(); | 2708 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2709 assert(getSrcSize() == 1); | 2709 assert(getSrcSize() == 1); |
| 2710 // Push is currently only used for saving GPRs. | 2710 // Push is currently only used for saving GPRs. |
| 2711 const auto Var = llvm::cast<Variable>(getSrc(0)); | 2711 const auto Var = llvm::cast<Variable>(getSrc(0)); |
| 2712 assert(Var->hasReg()); | 2712 assert(Var->hasReg()); |
| 2713 Str << "\tpush\t"; | 2713 Str << "\tpush\t"; |
| 2714 Var->emit(Func); | 2714 Var->emit(Func); |
| 2715 } | 2715 } |
| 2716 | 2716 |
| 2717 void InstX8632Push::emitIAS(const Cfg *Func) const { | 2717 void InstX8632Push::emitIAS(const Cfg *Func) const { |
| 2718 assert(getSrcSize() == 1); | 2718 assert(getSrcSize() == 1); |
| 2719 // Push is currently only used for saving GPRs. | 2719 // Push is currently only used for saving GPRs. |
| 2720 const auto Var = llvm::cast<Variable>(getSrc(0)); | 2720 const auto Var = llvm::cast<Variable>(getSrc(0)); |
| 2721 assert(Var->hasReg()); | 2721 assert(Var->hasReg()); |
| 2722 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2722 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2723 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); | 2723 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); |
| 2724 } | 2724 } |
| 2725 | 2725 |
| 2726 void InstX8632Push::dump(const Cfg *Func) const { | 2726 void InstX8632Push::dump(const Cfg *Func) const { |
| 2727 if (!ALLOW_DUMP) | 2727 if (!buildAllowsDump()) |
| 2728 return; | 2728 return; |
| 2729 Ostream &Str = Func->getContext()->getStrDump(); | 2729 Ostream &Str = Func->getContext()->getStrDump(); |
| 2730 Str << "push." << getSrc(0)->getType() << " "; | 2730 Str << "push." << getSrc(0)->getType() << " "; |
| 2731 dumpSources(Func); | 2731 dumpSources(Func); |
| 2732 } | 2732 } |
| 2733 | 2733 |
| 2734 template <> void InstX8632Psll::emit(const Cfg *Func) const { | 2734 template <> void InstX8632Psll::emit(const Cfg *Func) const { |
| 2735 if (!ALLOW_DUMP) | 2735 if (!buildAllowsDump()) |
| 2736 return; | 2736 return; |
| 2737 assert(getDest()->getType() == IceType_v8i16 || | 2737 assert(getDest()->getType() == IceType_v8i16 || |
| 2738 getDest()->getType() == IceType_v8i1 || | 2738 getDest()->getType() == IceType_v8i1 || |
| 2739 getDest()->getType() == IceType_v4i32 || | 2739 getDest()->getType() == IceType_v4i32 || |
| 2740 getDest()->getType() == IceType_v4i1); | 2740 getDest()->getType() == IceType_v4i1); |
| 2741 char buf[30]; | 2741 char buf[30]; |
| 2742 snprintf(buf, llvm::array_lengthof(buf), "psll%s", | 2742 snprintf(buf, llvm::array_lengthof(buf), "psll%s", |
| 2743 TypeX8632Attributes[getDest()->getType()].PackString); | 2743 TypeX8632Attributes[getDest()->getType()].PackString); |
| 2744 emitTwoAddress(buf, this, Func); | 2744 emitTwoAddress(buf, this, Func); |
| 2745 } | 2745 } |
| 2746 | 2746 |
| 2747 template <> void InstX8632Psra::emit(const Cfg *Func) const { | 2747 template <> void InstX8632Psra::emit(const Cfg *Func) const { |
| 2748 if (!ALLOW_DUMP) | 2748 if (!buildAllowsDump()) |
| 2749 return; | 2749 return; |
| 2750 assert(getDest()->getType() == IceType_v8i16 || | 2750 assert(getDest()->getType() == IceType_v8i16 || |
| 2751 getDest()->getType() == IceType_v8i1 || | 2751 getDest()->getType() == IceType_v8i1 || |
| 2752 getDest()->getType() == IceType_v4i32 || | 2752 getDest()->getType() == IceType_v4i32 || |
| 2753 getDest()->getType() == IceType_v4i1); | 2753 getDest()->getType() == IceType_v4i1); |
| 2754 char buf[30]; | 2754 char buf[30]; |
| 2755 snprintf(buf, llvm::array_lengthof(buf), "psra%s", | 2755 snprintf(buf, llvm::array_lengthof(buf), "psra%s", |
| 2756 TypeX8632Attributes[getDest()->getType()].PackString); | 2756 TypeX8632Attributes[getDest()->getType()].PackString); |
| 2757 emitTwoAddress(buf, this, Func); | 2757 emitTwoAddress(buf, this, Func); |
| 2758 } | 2758 } |
| 2759 | 2759 |
| 2760 template <> void InstX8632Psrl::emit(const Cfg *Func) const { | 2760 template <> void InstX8632Psrl::emit(const Cfg *Func) const { |
| 2761 if (!ALLOW_DUMP) | 2761 if (!buildAllowsDump()) |
| 2762 return; | 2762 return; |
| 2763 char buf[30]; | 2763 char buf[30]; |
| 2764 snprintf(buf, llvm::array_lengthof(buf), "psrl%s", | 2764 snprintf(buf, llvm::array_lengthof(buf), "psrl%s", |
| 2765 TypeX8632Attributes[getDest()->getType()].PackString); | 2765 TypeX8632Attributes[getDest()->getType()].PackString); |
| 2766 emitTwoAddress(buf, this, Func); | 2766 emitTwoAddress(buf, this, Func); |
| 2767 } | 2767 } |
| 2768 | 2768 |
| 2769 void InstX8632Ret::emit(const Cfg *Func) const { | 2769 void InstX8632Ret::emit(const Cfg *Func) const { |
| 2770 if (!ALLOW_DUMP) | 2770 if (!buildAllowsDump()) |
| 2771 return; | 2771 return; |
| 2772 Ostream &Str = Func->getContext()->getStrEmit(); | 2772 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2773 Str << "\tret"; | 2773 Str << "\tret"; |
| 2774 } | 2774 } |
| 2775 | 2775 |
| 2776 void InstX8632Ret::emitIAS(const Cfg *Func) const { | 2776 void InstX8632Ret::emitIAS(const Cfg *Func) const { |
| 2777 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2777 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2778 Asm->ret(); | 2778 Asm->ret(); |
| 2779 } | 2779 } |
| 2780 | 2780 |
| 2781 void InstX8632Ret::dump(const Cfg *Func) const { | 2781 void InstX8632Ret::dump(const Cfg *Func) const { |
| 2782 if (!ALLOW_DUMP) | 2782 if (!buildAllowsDump()) |
| 2783 return; | 2783 return; |
| 2784 Ostream &Str = Func->getContext()->getStrDump(); | 2784 Ostream &Str = Func->getContext()->getStrDump(); |
| 2785 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 2785 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
| 2786 Str << "ret." << Ty << " "; | 2786 Str << "ret." << Ty << " "; |
| 2787 dumpSources(Func); | 2787 dumpSources(Func); |
| 2788 } | 2788 } |
| 2789 | 2789 |
| 2790 void InstX8632Setcc::emit(const Cfg *Func) const { | 2790 void InstX8632Setcc::emit(const Cfg *Func) const { |
| 2791 if (!ALLOW_DUMP) | 2791 if (!buildAllowsDump()) |
| 2792 return; | 2792 return; |
| 2793 Ostream &Str = Func->getContext()->getStrEmit(); | 2793 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2794 Str << "\tset" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 2794 Str << "\tset" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
| 2795 Dest->emit(Func); | 2795 Dest->emit(Func); |
| 2796 } | 2796 } |
| 2797 | 2797 |
| 2798 void InstX8632Setcc::emitIAS(const Cfg *Func) const { | 2798 void InstX8632Setcc::emitIAS(const Cfg *Func) const { |
| 2799 assert(Condition != CondX86::Br_None); | 2799 assert(Condition != CondX86::Br_None); |
| 2800 assert(getDest()->getType() == IceType_i1); | 2800 assert(getDest()->getType() == IceType_i1); |
| 2801 assert(getSrcSize() == 0); | 2801 assert(getSrcSize() == 0); |
| 2802 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2802 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2803 if (getDest()->hasReg()) | 2803 if (getDest()->hasReg()) |
| 2804 Asm->setcc(Condition, RegX8632::getEncodedByteReg(getDest()->getRegNum())); | 2804 Asm->setcc(Condition, RegX8632::getEncodedByteReg(getDest()->getRegNum())); |
| 2805 else | 2805 else |
| 2806 Asm->setcc(Condition, static_cast<TargetX8632 *>(Func->getTarget()) | 2806 Asm->setcc(Condition, static_cast<TargetX8632 *>(Func->getTarget()) |
| 2807 ->stackVarToAsmOperand(getDest())); | 2807 ->stackVarToAsmOperand(getDest())); |
| 2808 return; | 2808 return; |
| 2809 } | 2809 } |
| 2810 | 2810 |
| 2811 void InstX8632Setcc::dump(const Cfg *Func) const { | 2811 void InstX8632Setcc::dump(const Cfg *Func) const { |
| 2812 if (!ALLOW_DUMP) | 2812 if (!buildAllowsDump()) |
| 2813 return; | 2813 return; |
| 2814 Ostream &Str = Func->getContext()->getStrDump(); | 2814 Ostream &Str = Func->getContext()->getStrDump(); |
| 2815 Str << "setcc." << InstX8632BrAttributes[Condition].DisplayString << " "; | 2815 Str << "setcc." << InstX8632BrAttributes[Condition].DisplayString << " "; |
| 2816 dumpDest(Func); | 2816 dumpDest(Func); |
| 2817 } | 2817 } |
| 2818 | 2818 |
| 2819 void InstX8632Xadd::emit(const Cfg *Func) const { | 2819 void InstX8632Xadd::emit(const Cfg *Func) const { |
| 2820 if (!ALLOW_DUMP) | 2820 if (!buildAllowsDump()) |
| 2821 return; | 2821 return; |
| 2822 Ostream &Str = Func->getContext()->getStrEmit(); | 2822 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2823 if (Locked) { | 2823 if (Locked) { |
| 2824 Str << "\tlock"; | 2824 Str << "\tlock"; |
| 2825 } | 2825 } |
| 2826 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; | 2826 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 2827 getSrc(1)->emit(Func); | 2827 getSrc(1)->emit(Func); |
| 2828 Str << ", "; | 2828 Str << ", "; |
| 2829 getSrc(0)->emit(Func); | 2829 getSrc(0)->emit(Func); |
| 2830 } | 2830 } |
| 2831 | 2831 |
| 2832 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 2832 void InstX8632Xadd::emitIAS(const Cfg *Func) const { |
| 2833 assert(getSrcSize() == 2); | 2833 assert(getSrcSize() == 2); |
| 2834 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2834 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2835 Type Ty = getSrc(0)->getType(); | 2835 Type Ty = getSrc(0)->getType(); |
| 2836 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2836 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2837 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2837 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2838 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 2838 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
| 2839 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2839 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2840 assert(VarReg->hasReg()); | 2840 assert(VarReg->hasReg()); |
| 2841 const RegX8632::GPRRegister Reg = | 2841 const RegX8632::GPRRegister Reg = |
| 2842 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2842 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2843 Asm->xadd(Ty, Addr, Reg, Locked); | 2843 Asm->xadd(Ty, Addr, Reg, Locked); |
| 2844 } | 2844 } |
| 2845 | 2845 |
| 2846 void InstX8632Xadd::dump(const Cfg *Func) const { | 2846 void InstX8632Xadd::dump(const Cfg *Func) const { |
| 2847 if (!ALLOW_DUMP) | 2847 if (!buildAllowsDump()) |
| 2848 return; | 2848 return; |
| 2849 Ostream &Str = Func->getContext()->getStrDump(); | 2849 Ostream &Str = Func->getContext()->getStrDump(); |
| 2850 if (Locked) { | 2850 if (Locked) { |
| 2851 Str << "lock "; | 2851 Str << "lock "; |
| 2852 } | 2852 } |
| 2853 Type Ty = getSrc(0)->getType(); | 2853 Type Ty = getSrc(0)->getType(); |
| 2854 Str << "xadd." << Ty << " "; | 2854 Str << "xadd." << Ty << " "; |
| 2855 dumpSources(Func); | 2855 dumpSources(Func); |
| 2856 } | 2856 } |
| 2857 | 2857 |
| 2858 void InstX8632Xchg::emit(const Cfg *Func) const { | 2858 void InstX8632Xchg::emit(const Cfg *Func) const { |
| 2859 if (!ALLOW_DUMP) | 2859 if (!buildAllowsDump()) |
| 2860 return; | 2860 return; |
| 2861 Ostream &Str = Func->getContext()->getStrEmit(); | 2861 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2862 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; | 2862 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 2863 getSrc(1)->emit(Func); | 2863 getSrc(1)->emit(Func); |
| 2864 Str << ", "; | 2864 Str << ", "; |
| 2865 getSrc(0)->emit(Func); | 2865 getSrc(0)->emit(Func); |
| 2866 } | 2866 } |
| 2867 | 2867 |
| 2868 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 2868 void InstX8632Xchg::emitIAS(const Cfg *Func) const { |
| 2869 assert(getSrcSize() == 2); | 2869 assert(getSrcSize() == 2); |
| 2870 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2870 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2871 Type Ty = getSrc(0)->getType(); | 2871 Type Ty = getSrc(0)->getType(); |
| 2872 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2872 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2873 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2873 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2874 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 2874 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
| 2875 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2875 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2876 assert(VarReg->hasReg()); | 2876 assert(VarReg->hasReg()); |
| 2877 const RegX8632::GPRRegister Reg = | 2877 const RegX8632::GPRRegister Reg = |
| 2878 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2878 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2879 Asm->xchg(Ty, Addr, Reg); | 2879 Asm->xchg(Ty, Addr, Reg); |
| 2880 } | 2880 } |
| 2881 | 2881 |
| 2882 void InstX8632Xchg::dump(const Cfg *Func) const { | 2882 void InstX8632Xchg::dump(const Cfg *Func) const { |
| 2883 if (!ALLOW_DUMP) | 2883 if (!buildAllowsDump()) |
| 2884 return; | 2884 return; |
| 2885 Ostream &Str = Func->getContext()->getStrDump(); | 2885 Ostream &Str = Func->getContext()->getStrDump(); |
| 2886 Type Ty = getSrc(0)->getType(); | 2886 Type Ty = getSrc(0)->getType(); |
| 2887 Str << "xchg." << Ty << " "; | 2887 Str << "xchg." << Ty << " "; |
| 2888 dumpSources(Func); | 2888 dumpSources(Func); |
| 2889 } | 2889 } |
| 2890 | 2890 |
| 2891 void OperandX8632Mem::emit(const Cfg *Func) const { | 2891 void OperandX8632Mem::emit(const Cfg *Func) const { |
| 2892 if (!ALLOW_DUMP) | 2892 if (!buildAllowsDump()) |
| 2893 return; | 2893 return; |
| 2894 Ostream &Str = Func->getContext()->getStrEmit(); | 2894 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2895 if (SegmentReg != DefaultSegment) { | 2895 if (SegmentReg != DefaultSegment) { |
| 2896 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 2896 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
| 2897 Str << "%" << InstX8632SegmentRegNames[SegmentReg] << ":"; | 2897 Str << "%" << InstX8632SegmentRegNames[SegmentReg] << ":"; |
| 2898 } | 2898 } |
| 2899 // Emit as Offset(Base,Index,1<<Shift). | 2899 // Emit as Offset(Base,Index,1<<Shift). |
| 2900 // Offset is emitted without the leading '$'. | 2900 // Offset is emitted without the leading '$'. |
| 2901 // Omit the (Base,Index,1<<Shift) part if Base==nullptr. | 2901 // Omit the (Base,Index,1<<Shift) part if Base==nullptr. |
| 2902 if (!Offset) { | 2902 if (!Offset) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2918 Str << ","; | 2918 Str << ","; |
| 2919 Index->emit(Func); | 2919 Index->emit(Func); |
| 2920 if (Shift) | 2920 if (Shift) |
| 2921 Str << "," << (1u << Shift); | 2921 Str << "," << (1u << Shift); |
| 2922 } | 2922 } |
| 2923 Str << ")"; | 2923 Str << ")"; |
| 2924 } | 2924 } |
| 2925 } | 2925 } |
| 2926 | 2926 |
| 2927 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const { | 2927 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const { |
| 2928 if (!ALLOW_DUMP) | 2928 if (!buildAllowsDump()) |
| 2929 return; | 2929 return; |
| 2930 if (SegmentReg != DefaultSegment) { | 2930 if (SegmentReg != DefaultSegment) { |
| 2931 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 2931 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
| 2932 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; | 2932 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; |
| 2933 } | 2933 } |
| 2934 bool Dumped = false; | 2934 bool Dumped = false; |
| 2935 Str << "["; | 2935 Str << "["; |
| 2936 if (Base) { | 2936 if (Base) { |
| 2937 if (Func) | 2937 if (Func) |
| 2938 Base->dump(Func); | 2938 Base->dump(Func); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3019 X8632::Address VariableSplit::toAsmAddress(const Cfg *Func) const { | 3019 X8632::Address VariableSplit::toAsmAddress(const Cfg *Func) const { |
| 3020 assert(!Var->hasReg()); | 3020 assert(!Var->hasReg()); |
| 3021 const TargetLowering *Target = Func->getTarget(); | 3021 const TargetLowering *Target = Func->getTarget(); |
| 3022 int32_t Offset = | 3022 int32_t Offset = |
| 3023 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 3023 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
| 3024 return X8632::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), | 3024 return X8632::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), |
| 3025 Offset); | 3025 Offset); |
| 3026 } | 3026 } |
| 3027 | 3027 |
| 3028 void VariableSplit::emit(const Cfg *Func) const { | 3028 void VariableSplit::emit(const Cfg *Func) const { |
| 3029 if (!ALLOW_DUMP) | 3029 if (!buildAllowsDump()) |
| 3030 return; | 3030 return; |
| 3031 Ostream &Str = Func->getContext()->getStrEmit(); | 3031 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3032 assert(!Var->hasReg()); | 3032 assert(!Var->hasReg()); |
| 3033 // The following is copied/adapted from TargetX8632::emitVariable(). | 3033 // The following is copied/adapted from TargetX8632::emitVariable(). |
| 3034 const TargetLowering *Target = Func->getTarget(); | 3034 const TargetLowering *Target = Func->getTarget(); |
| 3035 const Type Ty = IceType_i32; | 3035 const Type Ty = IceType_i32; |
| 3036 int32_t Offset = | 3036 int32_t Offset = |
| 3037 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 3037 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
| 3038 if (Offset) | 3038 if (Offset) |
| 3039 Str << Offset; | 3039 Str << Offset; |
| 3040 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; | 3040 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; |
| 3041 } | 3041 } |
| 3042 | 3042 |
| 3043 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { | 3043 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { |
| 3044 if (!ALLOW_DUMP) | 3044 if (!buildAllowsDump()) |
| 3045 return; | 3045 return; |
| 3046 switch (Part) { | 3046 switch (Part) { |
| 3047 case Low: | 3047 case Low: |
| 3048 Str << "low"; | 3048 Str << "low"; |
| 3049 break; | 3049 break; |
| 3050 case High: | 3050 case High: |
| 3051 Str << "high"; | 3051 Str << "high"; |
| 3052 break; | 3052 break; |
| 3053 } | 3053 } |
| 3054 Str << "("; | 3054 Str << "("; |
| 3055 if (Func) | 3055 if (Func) |
| 3056 Var->dump(Func); | 3056 Var->dump(Func); |
| 3057 else | 3057 else |
| 3058 Var->dump(Str); | 3058 Var->dump(Str); |
| 3059 Str << ")"; | 3059 Str << ")"; |
| 3060 } | 3060 } |
| 3061 | 3061 |
| 3062 } // end of namespace Ice | 3062 } // end of namespace Ice |
| OLD | NEW |