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

Side by Side Diff: src/IceInstX8632.cpp

Issue 695993004: Subzero: Switch to AT&T asm syntax. I give up. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 { emit } \ 45 { emit } \
46 , 46 ,
47 ICEINSTX8632CMPPS_TABLE 47 ICEINSTX8632CMPPS_TABLE
48 #undef X 48 #undef X
49 }; 49 };
50 50
51 const struct TypeX8632Attributes_ { 51 const struct TypeX8632Attributes_ {
52 const char *CvtString; // i (integer), s (single FP), d (double FP) 52 const char *CvtString; // i (integer), s (single FP), d (double FP)
53 const char *SdSsString; // ss, sd, or <blank> 53 const char *SdSsString; // ss, sd, or <blank>
54 const char *PackString; // b, w, d, or <blank> 54 const char *PackString; // b, w, d, or <blank>
55 const char *WidthString; // {byte,word,dword,qword} ptr 55 const char *WidthString; // b, w, l, q, or <blank>
56 const char *FldString; // s, l, or <blank>
56 } TypeX8632Attributes[] = { 57 } TypeX8632Attributes[] = {
57 #define X(tag, elementty, cvt, sdss, pack, width) \ 58 #define X(tag, elementty, cvt, sdss, pack, width, fld) \
58 { cvt, "" sdss, pack, width } \ 59 { cvt, sdss, pack, width, fld } \
59 , 60 ,
60 ICETYPEX8632_TABLE 61 ICETYPEX8632_TABLE
61 #undef X 62 #undef X
62 }; 63 };
63 64
64 const char *InstX8632SegmentRegNames[] = { 65 const char *InstX8632SegmentRegNames[] = {
65 #define X(val, name, prefix) name, 66 #define X(val, name, prefix) name,
66 SEG_REGX8632_TABLE 67 SEG_REGX8632_TABLE
67 #undef X 68 #undef X
68 }; 69 };
69 70
70 uint8_t InstX8632SegmentPrefixes[] = { 71 uint8_t InstX8632SegmentPrefixes[] = {
71 #define X(val, name, prefix) prefix, 72 #define X(val, name, prefix) prefix,
72 SEG_REGX8632_TABLE 73 SEG_REGX8632_TABLE
73 #undef X 74 #undef X
74 }; 75 };
75 76
76 } // end of anonymous namespace 77 } // end of anonymous namespace
77 78
78 const char *InstX8632::getWidthString(Type Ty) { 79 const char *InstX8632::getWidthString(Type Ty) {
79 return TypeX8632Attributes[Ty].WidthString; 80 return TypeX8632Attributes[Ty].WidthString;
80 } 81 }
81 82
83 const char *InstX8632::getFldString(Type Ty) {
84 return TypeX8632Attributes[Ty].FldString;
85 }
86
82 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, 87 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base,
83 Constant *Offset, Variable *Index, 88 Constant *Offset, Variable *Index,
84 uint16_t Shift, SegmentRegisters SegmentReg) 89 uint16_t Shift, SegmentRegisters SegmentReg)
85 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), 90 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index),
86 Shift(Shift), SegmentReg(SegmentReg) { 91 Shift(Shift), SegmentReg(SegmentReg) {
87 assert(Shift <= 3); 92 assert(Shift <= 3);
88 Vars = NULL; 93 Vars = NULL;
89 NumVars = 0; 94 NumVars = 0;
90 if (Base) 95 if (Base)
91 ++NumVars; 96 ++NumVars;
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 // fixups are used (and text assembler is not used). 436 // fixups are used (and text assembler is not used).
432 Ostream &Str = Func->getContext()->getStrEmit(); 437 Ostream &Str = Func->getContext()->getStrEmit();
433 Str << getName(Func) << ":\n"; 438 Str << getName(Func) << ":\n";
434 } 439 }
435 440
436 void InstX8632Label::dump(const Cfg *Func) const { 441 void InstX8632Label::dump(const Cfg *Func) const {
437 Ostream &Str = Func->getContext()->getStrDump(); 442 Ostream &Str = Func->getContext()->getStrDump();
438 Str << getName(Func) << ":"; 443 Str << getName(Func) << ":";
439 } 444 }
440 445
441 void InstX8632Br::emit(const Cfg *Func) const { 446 void InstX8632Br::emit(const Cfg *Func) const {
Jim Stichnoth 2014/10/31 20:55:19 No change in branch syntax for AT&T.
442 Ostream &Str = Func->getContext()->getStrEmit(); 447 Ostream &Str = Func->getContext()->getStrEmit();
443 Str << "\t"; 448 Str << "\t";
444 449
445 if (Condition == CondX86::Br_None) { 450 if (Condition == CondX86::Br_None) {
446 Str << "jmp"; 451 Str << "jmp";
447 } else { 452 } else {
448 Str << InstX8632BrAttributes[Condition].EmitString; 453 Str << InstX8632BrAttributes[Condition].EmitString;
449 } 454 }
450 455
451 if (Label) { 456 if (Label) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 if (getTargetFalse()) { 526 if (getTargetFalse()) {
522 Str << ", label %" << getTargetFalse()->getName(); 527 Str << ", label %" << getTargetFalse()->getName();
523 } 528 }
524 } 529 }
525 } 530 }
526 531
527 void InstX8632Call::emit(const Cfg *Func) const { 532 void InstX8632Call::emit(const Cfg *Func) const {
528 Ostream &Str = Func->getContext()->getStrEmit(); 533 Ostream &Str = Func->getContext()->getStrEmit();
529 assert(getSrcSize() == 1); 534 assert(getSrcSize() == 1);
530 Str << "\tcall\t"; 535 Str << "\tcall\t";
531 getCallTarget()->emit(Func); 536 if (auto CallTarget = llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
537 // TODO(stichnot): All constant targets should suppress the '$',
538 // not just relocatables.
539 CallTarget->emitWithoutDollar(Func->getContext());
540 } else {
541 Str << "*";
542 getCallTarget()->emit(Func);
543 }
532 Func->getTarget()->resetStackAdjustment(); 544 Func->getTarget()->resetStackAdjustment();
533 } 545 }
534 546
535 void InstX8632Call::emitIAS(const Cfg *Func) const { 547 void InstX8632Call::emitIAS(const Cfg *Func) const {
536 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 548 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
537 intptr_t StartPosition = Asm->GetPosition(); 549 intptr_t StartPosition = Asm->GetPosition();
538 Operand *Target = getCallTarget(); 550 Operand *Target = getCallTarget();
539 bool NeedsFallback = false; 551 bool NeedsFallback = false;
540 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { 552 if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
541 if (Var->hasReg()) { 553 if (Var->hasReg()) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 } 602 }
591 603
592 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for 604 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for
593 // shift instructions, in order to be syntactically valid. The 605 // shift instructions, in order to be syntactically valid. The
594 // Opcode parameter needs to be char* and not IceString because of 606 // Opcode parameter needs to be char* and not IceString because of
595 // template issues. 607 // template issues.
596 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, 608 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
597 bool ShiftHack) { 609 bool ShiftHack) {
598 Ostream &Str = Func->getContext()->getStrEmit(); 610 Ostream &Str = Func->getContext()->getStrEmit();
599 assert(Inst->getSrcSize() == 2); 611 assert(Inst->getSrcSize() == 2);
600 assert(Inst->getDest() == Inst->getSrc(0)); 612 Variable *Dest = Inst->getDest();
601 Str << "\t" << Opcode << "\t"; 613 assert(Dest == Inst->getSrc(0));
602 Inst->getDest()->emit(Func); 614 Operand *Src1 = Inst->getSrc(1);
615 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t";
616 Variable *ShiftReg = llvm::dyn_cast<Variable>(Src1);
617 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx)
618 Str << "%cl";
619 else
620 Src1->emit(Func);
603 Str << ", "; 621 Str << ", ";
604 bool EmittedSrc1 = false; 622 Dest->emit(Func);
605 if (ShiftHack) {
606 Variable *ShiftReg = llvm::dyn_cast<Variable>(Inst->getSrc(1));
607 if (ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) {
608 Str << "cl";
609 EmittedSrc1 = true;
610 }
611 }
612 if (!EmittedSrc1)
613 Inst->getSrc(1)->emit(Func);
614 } 623 }
615 624
616 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, 625 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
617 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { 626 const x86::AssemblerX86::GPREmitterOneOp &Emitter) {
618 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 627 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
619 intptr_t StartPosition = Asm->GetPosition(); 628 intptr_t StartPosition = Asm->GetPosition();
620 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { 629 if (const auto Var = llvm::dyn_cast<Variable>(Op)) {
621 if (Var->hasReg()) { 630 if (Var->hasReg()) {
622 // We cheat a little and use GPRRegister even for byte operations. 631 // We cheat a little and use GPRRegister even for byte operations.
623 RegX8632::GPRRegister VarReg = 632 RegX8632::GPRRegister VarReg =
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 } 944 }
936 945
937 // In-place ops 946 // In-place ops
938 template <> const char *InstX8632Bswap::Opcode = "bswap"; 947 template <> const char *InstX8632Bswap::Opcode = "bswap";
939 template <> const char *InstX8632Neg::Opcode = "neg"; 948 template <> const char *InstX8632Neg::Opcode = "neg";
940 // Unary ops 949 // Unary ops
941 template <> const char *InstX8632Bsf::Opcode = "bsf"; 950 template <> const char *InstX8632Bsf::Opcode = "bsf";
942 template <> const char *InstX8632Bsr::Opcode = "bsr"; 951 template <> const char *InstX8632Bsr::Opcode = "bsr";
943 template <> const char *InstX8632Lea::Opcode = "lea"; 952 template <> const char *InstX8632Lea::Opcode = "lea";
944 template <> const char *InstX8632Movd::Opcode = "movd"; 953 template <> const char *InstX8632Movd::Opcode = "movd";
945 template <> const char *InstX8632Movsx::Opcode = "movsx"; 954 template <> const char *InstX8632Movsx::Opcode = "movs";
946 template <> const char *InstX8632Movzx::Opcode = "movzx"; 955 template <> const char *InstX8632Movzx::Opcode = "movz";
947 template <> const char *InstX8632Sqrtss::Opcode = "sqrtss"; 956 template <> const char *InstX8632Sqrtss::Opcode = "sqrtss";
948 template <> const char *InstX8632Cbwdq::Opcode = "cbw/cwd/cdq"; 957 template <> const char *InstX8632Cbwdq::Opcode = "cbw/cwd/cdq";
949 // Mov-like ops 958 // Mov-like ops
950 template <> const char *InstX8632Mov::Opcode = "mov"; 959 template <> const char *InstX8632Mov::Opcode = "mov";
951 template <> const char *InstX8632Movp::Opcode = "movups"; 960 template <> const char *InstX8632Movp::Opcode = "movups";
952 template <> const char *InstX8632Movq::Opcode = "movq"; 961 template <> const char *InstX8632Movq::Opcode = "movq";
953 // Binary ops 962 // Binary ops
954 template <> const char *InstX8632Add::Opcode = "add"; 963 template <> const char *InstX8632Add::Opcode = "add";
955 template <> const char *InstX8632Addps::Opcode = "addps"; 964 template <> const char *InstX8632Addps::Opcode = "addps";
956 template <> const char *InstX8632Adc::Opcode = "adc"; 965 template <> const char *InstX8632Adc::Opcode = "adc";
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = { 1156 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = {
1148 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra, 1157 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra,
1149 &x86::AssemblerX86::psra}; 1158 &x86::AssemblerX86::psra};
1150 1159
1151 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { 1160 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
1152 Ostream &Str = Func->getContext()->getStrEmit(); 1161 Ostream &Str = Func->getContext()->getStrEmit();
1153 assert(getSrcSize() == 1); 1162 assert(getSrcSize() == 1);
1154 Type Ty = getSrc(0)->getType(); 1163 Type Ty = getSrc(0)->getType();
1155 assert(isScalarFloatingType(Ty)); 1164 assert(isScalarFloatingType(Ty));
1156 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; 1165 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t";
1166 getSrc(0)->emit(Func);
1167 Str << ", ";
1157 getDest()->emit(Func); 1168 getDest()->emit(Func);
1158 Str << ", ";
1159 getSrc(0)->emit(Func);
1160 } 1169 }
1161 1170
1162 template <> void InstX8632Addss::emit(const Cfg *Func) const { 1171 template <> void InstX8632Addss::emit(const Cfg *Func) const {
1163 char buf[30]; 1172 char buf[30];
1164 snprintf(buf, llvm::array_lengthof(buf), "add%s", 1173 snprintf(buf, llvm::array_lengthof(buf), "add%s",
1165 TypeX8632Attributes[getDest()->getType()].SdSsString); 1174 TypeX8632Attributes[getDest()->getType()].SdSsString);
1166 emitTwoAddress(buf, this, Func); 1175 emitTwoAddress(buf, this, Func);
1167 } 1176 }
1168 1177
1169 template <> void InstX8632Padd::emit(const Cfg *Func) const { 1178 template <> void InstX8632Padd::emit(const Cfg *Func) const {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 template <> void InstX8632Divss::emit(const Cfg *Func) const { 1245 template <> void InstX8632Divss::emit(const Cfg *Func) const {
1237 char buf[30]; 1246 char buf[30];
1238 snprintf(buf, llvm::array_lengthof(buf), "div%s", 1247 snprintf(buf, llvm::array_lengthof(buf), "div%s",
1239 TypeX8632Attributes[getDest()->getType()].SdSsString); 1248 TypeX8632Attributes[getDest()->getType()].SdSsString);
1240 emitTwoAddress(buf, this, Func); 1249 emitTwoAddress(buf, this, Func);
1241 } 1250 }
1242 1251
1243 template <> void InstX8632Div::emit(const Cfg *Func) const { 1252 template <> void InstX8632Div::emit(const Cfg *Func) const {
1244 Ostream &Str = Func->getContext()->getStrEmit(); 1253 Ostream &Str = Func->getContext()->getStrEmit();
1245 assert(getSrcSize() == 3); 1254 assert(getSrcSize() == 3);
1246 Str << "\t" << Opcode << "\t"; 1255 Operand *Src1 = getSrc(1);
1247 getSrc(1)->emit(Func); 1256 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t";
1257 Src1->emit(Func);
1248 } 1258 }
1249 1259
1250 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { 1260 template <> void InstX8632Div::emitIAS(const Cfg *Func) const {
1251 assert(getSrcSize() == 3); 1261 assert(getSrcSize() == 3);
1252 const Operand *Src = getSrc(1); 1262 const Operand *Src = getSrc(1);
1253 Type Ty = Src->getType(); 1263 Type Ty = Src->getType();
1254 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { 1264 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
1255 &x86::AssemblerX86::div, &x86::AssemblerX86::div}; 1265 &x86::AssemblerX86::div, &x86::AssemblerX86::div};
1256 emitIASOpTyGPR(Func, Ty, Src, Emitter); 1266 emitIASOpTyGPR(Func, Ty, Src, Emitter);
1257 } 1267 }
1258 1268
1259 template <> void InstX8632Idiv::emit(const Cfg *Func) const { 1269 template <> void InstX8632Idiv::emit(const Cfg *Func) const {
1260 Ostream &Str = Func->getContext()->getStrEmit(); 1270 Ostream &Str = Func->getContext()->getStrEmit();
1261 assert(getSrcSize() == 3); 1271 assert(getSrcSize() == 3);
1262 Str << "\t" << Opcode << "\t"; 1272 Operand *Src1 = getSrc(1);
1263 getSrc(1)->emit(Func); 1273 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t";
1274 Src1->emit(Func);
1264 } 1275 }
1265 1276
1266 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { 1277 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const {
1267 assert(getSrcSize() == 3); 1278 assert(getSrcSize() == 3);
1268 const Operand *Src = getSrc(1); 1279 const Operand *Src = getSrc(1);
1269 Type Ty = Src->getType(); 1280 Type Ty = Src->getType();
1270 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { 1281 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
1271 &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv}; 1282 &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv};
1272 emitIASOpTyGPR(Func, Ty, Src, Emitter); 1283 emitIASOpTyGPR(Func, Ty, Src, Emitter);
1273 } 1284 }
1274 1285
1275 namespace { 1286 namespace {
1276 1287
1277 // pblendvb and blendvps take xmm0 as a final implicit argument. 1288 // pblendvb and blendvps take xmm0 as a final implicit argument.
1278 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, 1289 void emitVariableBlendInst(const char *Opcode, const Inst *Inst,
1279 const Cfg *Func) { 1290 const Cfg *Func) {
1280 Ostream &Str = Func->getContext()->getStrEmit(); 1291 Ostream &Str = Func->getContext()->getStrEmit();
1281 assert(Inst->getSrcSize() == 3); 1292 assert(Inst->getSrcSize() == 3);
1282 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == 1293 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
1283 RegX8632::Reg_xmm0); 1294 RegX8632::Reg_xmm0);
1284 Str << "\t" << Opcode << "\t"; 1295 Str << "\t" << Opcode << "\t";
1296 Inst->getSrc(1)->emit(Func);
1297 Str << ", ";
1285 Inst->getDest()->emit(Func); 1298 Inst->getDest()->emit(Func);
1286 Str << ", ";
1287 Inst->getSrc(1)->emit(Func);
1288 } 1299 }
1289 1300
1290 void 1301 void
1291 emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func, 1302 emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func,
1292 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { 1303 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) {
1293 assert(Inst->getSrcSize() == 3); 1304 assert(Inst->getSrcSize() == 3);
1294 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == 1305 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
1295 RegX8632::Reg_xmm0); 1306 RegX8632::Reg_xmm0);
1296 const Variable *Dest = Inst->getDest(); 1307 const Variable *Dest = Inst->getDest();
1297 const Operand *Src = Inst->getSrc(1); 1308 const Operand *Src = Inst->getSrc(1);
(...skipping 26 matching lines...) Expand all
1324 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 1335 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
1325 TargetX8632::SSE4_1); 1336 TargetX8632::SSE4_1);
1326 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { 1337 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = {
1327 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb}; 1338 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb};
1328 emitIASVariableBlendInst(this, Func, Emitter); 1339 emitIASVariableBlendInst(this, Func, Emitter);
1329 } 1340 }
1330 1341
1331 template <> void InstX8632Imul::emit(const Cfg *Func) const { 1342 template <> void InstX8632Imul::emit(const Cfg *Func) const {
1332 Ostream &Str = Func->getContext()->getStrEmit(); 1343 Ostream &Str = Func->getContext()->getStrEmit();
1333 assert(getSrcSize() == 2); 1344 assert(getSrcSize() == 2);
1334 if (isByteSizedArithType(getDest()->getType())) { 1345 Variable *Dest = getDest();
1346 if (isByteSizedArithType(Dest->getType())) {
1335 // The 8-bit version of imul only allows the form "imul r/m8". 1347 // The 8-bit version of imul only allows the form "imul r/m8".
1336 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); 1348 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0));
1337 (void)Src0; 1349 (void)Src0;
1338 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); 1350 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax);
1339 Str << "\timul\t"; 1351 Str << "\timulb\t";
1340 getSrc(1)->emit(Func); 1352 getSrc(1)->emit(Func);
1341 } else if (llvm::isa<Constant>(getSrc(1))) { 1353 } else if (llvm::isa<Constant>(getSrc(1))) {
1342 Str << "\timul\t"; 1354 Str << "\timul" << getWidthString(Dest->getType()) << "\t";
1343 getDest()->emit(Func); 1355 getSrc(1)->emit(Func);
1344 Str << ", "; 1356 Str << ", ";
1345 getSrc(0)->emit(Func); 1357 getSrc(0)->emit(Func);
1346 Str << ", "; 1358 Str << ", ";
1347 getSrc(1)->emit(Func); 1359 Dest->emit(Func);
1348 } else { 1360 } else {
1349 emitTwoAddress("imul", this, Func); 1361 emitTwoAddress("imul", this, Func);
1350 } 1362 }
1351 } 1363 }
1352 1364
1353 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { 1365 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const {
1354 assert(getSrcSize() == 2); 1366 assert(getSrcSize() == 2);
1355 const Variable *Var = getDest(); 1367 const Variable *Var = getDest();
1356 Type Ty = Var->getType(); 1368 Type Ty = Var->getType();
1357 const Operand *Src = getSrc(1); 1369 const Operand *Src = getSrc(1);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 assert(getSrcSize() == 1); 1406 assert(getSrcSize() == 1);
1395 Operand *Src0 = getSrc(0); 1407 Operand *Src0 = getSrc(0);
1396 assert(llvm::isa<Variable>(Src0)); 1408 assert(llvm::isa<Variable>(Src0));
1397 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); 1409 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax);
1398 switch (Src0->getType()) { 1410 switch (Src0->getType()) {
1399 default: 1411 default:
1400 llvm_unreachable("unexpected source type!"); 1412 llvm_unreachable("unexpected source type!");
1401 break; 1413 break;
1402 case IceType_i8: 1414 case IceType_i8:
1403 assert(getDest()->getRegNum() == RegX8632::Reg_eax); 1415 assert(getDest()->getRegNum() == RegX8632::Reg_eax);
1404 Str << "\tcbw"; 1416 Str << "\tcbtw";
1405 break; 1417 break;
1406 case IceType_i16: 1418 case IceType_i16:
1407 assert(getDest()->getRegNum() == RegX8632::Reg_edx); 1419 assert(getDest()->getRegNum() == RegX8632::Reg_edx);
1408 Str << "\tcwd"; 1420 Str << "\tcwtd";
1409 break; 1421 break;
1410 case IceType_i32: 1422 case IceType_i32:
1411 assert(getDest()->getRegNum() == RegX8632::Reg_edx); 1423 assert(getDest()->getRegNum() == RegX8632::Reg_edx);
1412 Str << "\tcdq"; 1424 Str << "\tcltd";
1413 break; 1425 break;
1414 } 1426 }
1415 } 1427 }
1416 1428
1417 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { 1429 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const {
1418 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1430 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1419 intptr_t StartPosition = Asm->GetPosition(); 1431 intptr_t StartPosition = Asm->GetPosition();
1420 assert(getSrcSize() == 1); 1432 assert(getSrcSize() == 1);
1421 Operand *Src0 = getSrc(0); 1433 Operand *Src0 = getSrc(0);
1422 assert(llvm::isa<Variable>(Src0)); 1434 assert(llvm::isa<Variable>(Src0));
(...skipping 17 matching lines...) Expand all
1440 } 1452 }
1441 emitIASBytes(Func, Asm, StartPosition); 1453 emitIASBytes(Func, Asm, StartPosition);
1442 } 1454 }
1443 1455
1444 void InstX8632Mul::emit(const Cfg *Func) const { 1456 void InstX8632Mul::emit(const Cfg *Func) const {
1445 Ostream &Str = Func->getContext()->getStrEmit(); 1457 Ostream &Str = Func->getContext()->getStrEmit();
1446 assert(getSrcSize() == 2); 1458 assert(getSrcSize() == 2);
1447 assert(llvm::isa<Variable>(getSrc(0))); 1459 assert(llvm::isa<Variable>(getSrc(0)));
1448 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1460 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1449 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1461 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1450 Str << "\tmul\t"; 1462 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t";
1451 getSrc(1)->emit(Func); 1463 getSrc(1)->emit(Func);
1452 } 1464 }
1453 1465
1454 void InstX8632Mul::emitIAS(const Cfg *Func) const { 1466 void InstX8632Mul::emitIAS(const Cfg *Func) const {
1455 assert(getSrcSize() == 2); 1467 assert(getSrcSize() == 2);
1456 assert(llvm::isa<Variable>(getSrc(0))); 1468 assert(llvm::isa<Variable>(getSrc(0)));
1457 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1469 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1458 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1470 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1459 const Operand *Src = getSrc(1); 1471 const Operand *Src = getSrc(1);
1460 Type Ty = Src->getType(); 1472 Type Ty = Src->getType();
1461 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { 1473 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
1462 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul}; 1474 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul};
1463 emitIASOpTyGPR(Func, Ty, Src, Emitter); 1475 emitIASOpTyGPR(Func, Ty, Src, Emitter);
1464 } 1476 }
1465 1477
1466 void InstX8632Mul::dump(const Cfg *Func) const { 1478 void InstX8632Mul::dump(const Cfg *Func) const {
1467 Ostream &Str = Func->getContext()->getStrDump(); 1479 Ostream &Str = Func->getContext()->getStrDump();
1468 dumpDest(Func); 1480 dumpDest(Func);
1469 Str << " = mul." << getDest()->getType() << " "; 1481 Str << " = mul." << getDest()->getType() << " ";
1470 dumpSources(Func); 1482 dumpSources(Func);
1471 } 1483 }
1472 1484
1473 void InstX8632Shld::emit(const Cfg *Func) const { 1485 void InstX8632Shld::emit(const Cfg *Func) const {
1474 Ostream &Str = Func->getContext()->getStrEmit(); 1486 Ostream &Str = Func->getContext()->getStrEmit();
1487 Variable *Dest = getDest();
1475 assert(getSrcSize() == 3); 1488 assert(getSrcSize() == 3);
1476 assert(getDest() == getSrc(0)); 1489 assert(Dest == getSrc(0));
1477 Str << "\tshld\t"; 1490 Str << "\tshld" << getWidthString(Dest->getType()) << "\t";
1478 getDest()->emit(Func); 1491 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
1492 (void)ShiftReg;
1493 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1494 Str << "%cl";
1495 } else {
1496 getSrc(2)->emit(Func);
1497 }
1479 Str << ", "; 1498 Str << ", ";
1480 getSrc(1)->emit(Func); 1499 getSrc(1)->emit(Func);
1481 Str << ", "; 1500 Str << ", ";
1482 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { 1501 Dest->emit(Func);
1483 (void)ShiftReg;
1484 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1485 Str << "cl";
1486 } else {
1487 getSrc(2)->emit(Func);
1488 }
1489 } 1502 }
1490 1503
1491 void InstX8632Shld::emitIAS(const Cfg *Func) const { 1504 void InstX8632Shld::emitIAS(const Cfg *Func) const {
1492 assert(getSrcSize() == 3); 1505 assert(getSrcSize() == 3);
1493 assert(getDest() == getSrc(0)); 1506 assert(getDest() == getSrc(0));
1494 const Variable *Dest = getDest(); 1507 const Variable *Dest = getDest();
1495 const Operand *Src1 = getSrc(1); 1508 const Operand *Src1 = getSrc(1);
1496 const Operand *Src2 = getSrc(2); 1509 const Operand *Src2 = getSrc(2);
1497 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { 1510 static const x86::AssemblerX86::GPREmitterShiftD Emitter = {
1498 &x86::AssemblerX86::shld, &x86::AssemblerX86::shld}; 1511 &x86::AssemblerX86::shld, &x86::AssemblerX86::shld};
1499 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); 1512 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter);
1500 } 1513 }
1501 1514
1502 void InstX8632Shld::dump(const Cfg *Func) const { 1515 void InstX8632Shld::dump(const Cfg *Func) const {
1503 Ostream &Str = Func->getContext()->getStrDump(); 1516 Ostream &Str = Func->getContext()->getStrDump();
1504 dumpDest(Func); 1517 dumpDest(Func);
1505 Str << " = shld." << getDest()->getType() << " "; 1518 Str << " = shld." << getDest()->getType() << " ";
1506 dumpSources(Func); 1519 dumpSources(Func);
1507 } 1520 }
1508 1521
1509 void InstX8632Shrd::emit(const Cfg *Func) const { 1522 void InstX8632Shrd::emit(const Cfg *Func) const {
1510 Ostream &Str = Func->getContext()->getStrEmit(); 1523 Ostream &Str = Func->getContext()->getStrEmit();
1524 Variable *Dest = getDest();
1511 assert(getSrcSize() == 3); 1525 assert(getSrcSize() == 3);
1512 assert(getDest() == getSrc(0)); 1526 assert(Dest == getSrc(0));
1513 Str << "\tshrd\t"; 1527 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t";
1514 getDest()->emit(Func); 1528 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
1529 (void)ShiftReg;
1530 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1531 Str << "%cl";
1532 } else {
1533 getSrc(2)->emit(Func);
1534 }
1515 Str << ", "; 1535 Str << ", ";
1516 getSrc(1)->emit(Func); 1536 getSrc(1)->emit(Func);
1517 Str << ", "; 1537 Str << ", ";
1518 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { 1538 Dest->emit(Func);
1519 (void)ShiftReg;
1520 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1521 Str << "cl";
1522 } else {
1523 getSrc(2)->emit(Func);
1524 }
1525 } 1539 }
1526 1540
1527 void InstX8632Shrd::emitIAS(const Cfg *Func) const { 1541 void InstX8632Shrd::emitIAS(const Cfg *Func) const {
1528 assert(getSrcSize() == 3); 1542 assert(getSrcSize() == 3);
1529 assert(getDest() == getSrc(0)); 1543 assert(getDest() == getSrc(0));
1530 const Variable *Dest = getDest(); 1544 const Variable *Dest = getDest();
1531 const Operand *Src1 = getSrc(1); 1545 const Operand *Src1 = getSrc(1);
1532 const Operand *Src2 = getSrc(2); 1546 const Operand *Src2 = getSrc(2);
1533 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { 1547 static const x86::AssemblerX86::GPREmitterShiftD Emitter = {
1534 &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd}; 1548 &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd};
1535 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); 1549 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter);
1536 } 1550 }
1537 1551
1538 void InstX8632Shrd::dump(const Cfg *Func) const { 1552 void InstX8632Shrd::dump(const Cfg *Func) const {
1539 Ostream &Str = Func->getContext()->getStrDump(); 1553 Ostream &Str = Func->getContext()->getStrDump();
1540 dumpDest(Func); 1554 dumpDest(Func);
1541 Str << " = shrd." << getDest()->getType() << " "; 1555 Str << " = shrd." << getDest()->getType() << " ";
1542 dumpSources(Func); 1556 dumpSources(Func);
1543 } 1557 }
1544 1558
1545 void InstX8632Cmov::emit(const Cfg *Func) const { 1559 void InstX8632Cmov::emit(const Cfg *Func) const {
1546 Ostream &Str = Func->getContext()->getStrEmit(); 1560 Ostream &Str = Func->getContext()->getStrEmit();
1561 Variable *Dest = getDest();
1547 Str << "\t"; 1562 Str << "\t";
1548 assert(Condition != CondX86::Br_None); 1563 assert(Condition != CondX86::Br_None);
1549 assert(getDest()->hasReg()); 1564 assert(getDest()->hasReg());
1550 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; 1565 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString
1551 getDest()->emit(Func); 1566 << getWidthString(Dest->getType()) << "\t";
1567 getSrc(1)->emit(Func);
1552 Str << ", "; 1568 Str << ", ";
1553 getSrc(1)->emit(Func); 1569 Dest->emit(Func);
1554 } 1570 }
1555 1571
1556 void InstX8632Cmov::emitIAS(const Cfg *Func) const { 1572 void InstX8632Cmov::emitIAS(const Cfg *Func) const {
1557 assert(Condition != CondX86::Br_None); 1573 assert(Condition != CondX86::Br_None);
1558 assert(getDest()->hasReg()); 1574 assert(getDest()->hasReg());
1559 assert(getSrcSize() == 2); 1575 assert(getSrcSize() == 2);
1560 // Only need the reg/reg form now. 1576 // Only need the reg/reg form now.
1561 const Variable *Src = llvm::cast<Variable>(getSrc(1)); 1577 const Variable *Src = llvm::cast<Variable>(getSrc(1));
1562 assert(Src->hasReg()); 1578 assert(Src->hasReg());
1563 assert(Src->getType() == IceType_i32); 1579 assert(Src->getType() == IceType_i32);
(...skipping 13 matching lines...) Expand all
1577 dumpSources(Func); 1593 dumpSources(Func);
1578 } 1594 }
1579 1595
1580 void InstX8632Cmpps::emit(const Cfg *Func) const { 1596 void InstX8632Cmpps::emit(const Cfg *Func) const {
1581 Ostream &Str = Func->getContext()->getStrEmit(); 1597 Ostream &Str = Func->getContext()->getStrEmit();
1582 assert(getSrcSize() == 2); 1598 assert(getSrcSize() == 2);
1583 assert(Condition < CondX86::Cmpps_Invalid); 1599 assert(Condition < CondX86::Cmpps_Invalid);
1584 Str << "\t"; 1600 Str << "\t";
1585 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1601 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
1586 << "\t"; 1602 << "\t";
1603 getSrc(1)->emit(Func);
1604 Str << ", ";
1587 getDest()->emit(Func); 1605 getDest()->emit(Func);
1588 Str << ", ";
1589 getSrc(1)->emit(Func);
1590 } 1606 }
1591 1607
1592 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { 1608 void InstX8632Cmpps::emitIAS(const Cfg *Func) const {
1593 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1609 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1594 intptr_t StartPosition = Asm->GetPosition(); 1610 intptr_t StartPosition = Asm->GetPosition();
1595 assert(getSrcSize() == 2); 1611 assert(getSrcSize() == 2);
1596 assert(Condition < CondX86::Cmpps_Invalid); 1612 assert(Condition < CondX86::Cmpps_Invalid);
1597 // Assuming there isn't any load folding for cmpps, and vector constants 1613 // Assuming there isn't any load folding for cmpps, and vector constants
1598 // are not allowed in PNaCl. 1614 // are not allowed in PNaCl.
1599 assert(llvm::isa<Variable>(getSrc(1))); 1615 assert(llvm::isa<Variable>(getSrc(1)));
(...skipping 18 matching lines...) Expand all
1618 << "\t"; 1634 << "\t";
1619 dumpSources(Func); 1635 dumpSources(Func);
1620 } 1636 }
1621 1637
1622 void InstX8632Cmpxchg::emit(const Cfg *Func) const { 1638 void InstX8632Cmpxchg::emit(const Cfg *Func) const {
1623 Ostream &Str = Func->getContext()->getStrEmit(); 1639 Ostream &Str = Func->getContext()->getStrEmit();
1624 assert(getSrcSize() == 3); 1640 assert(getSrcSize() == 3);
1625 if (Locked) { 1641 if (Locked) {
1626 Str << "\tlock"; 1642 Str << "\tlock";
1627 } 1643 }
1628 Str << "\tcmpxchg\t"; 1644 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t";
1645 getSrc(2)->emit(Func);
1646 Str << ", ";
1629 getSrc(0)->emit(Func); 1647 getSrc(0)->emit(Func);
1630 Str << ", ";
1631 getSrc(2)->emit(Func);
1632 } 1648 }
1633 1649
1634 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { 1650 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const {
1635 assert(getSrcSize() == 3); 1651 assert(getSrcSize() == 3);
1636 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1652 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1637 intptr_t StartPosition = Asm->GetPosition(); 1653 intptr_t StartPosition = Asm->GetPosition();
1638 Type Ty = getSrc(0)->getType(); 1654 Type Ty = getSrc(0)->getType();
1639 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1655 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1640 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1656 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1641 const x86::Address Addr = Mem->toAsmAddress(Asm); 1657 const x86::Address Addr = Mem->toAsmAddress(Asm);
(...skipping 11 matching lines...) Expand all
1653 1669
1654 void InstX8632Cmpxchg::dump(const Cfg *Func) const { 1670 void InstX8632Cmpxchg::dump(const Cfg *Func) const {
1655 Ostream &Str = Func->getContext()->getStrDump(); 1671 Ostream &Str = Func->getContext()->getStrDump();
1656 if (Locked) { 1672 if (Locked) {
1657 Str << "lock "; 1673 Str << "lock ";
1658 } 1674 }
1659 Str << "cmpxchg." << getSrc(0)->getType() << " "; 1675 Str << "cmpxchg." << getSrc(0)->getType() << " ";
1660 dumpSources(Func); 1676 dumpSources(Func);
1661 } 1677 }
1662 1678
1663 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { 1679 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const {
Jim Stichnoth 2014/10/31 20:55:19 No syntax changes since only one operand is emitte
1664 Ostream &Str = Func->getContext()->getStrEmit(); 1680 Ostream &Str = Func->getContext()->getStrEmit();
1665 assert(getSrcSize() == 5); 1681 assert(getSrcSize() == 5);
1666 if (Locked) { 1682 if (Locked) {
1667 Str << "\tlock"; 1683 Str << "\tlock";
1668 } 1684 }
1669 Str << "\tcmpxchg8b\t"; 1685 Str << "\tcmpxchg8b\t";
1670 getSrc(0)->emit(Func); 1686 getSrc(0)->emit(Func);
1671 } 1687 }
1672 1688
1673 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { 1689 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const {
(...skipping 20 matching lines...) Expand all
1694 } 1710 }
1695 1711
1696 void InstX8632Cvt::emit(const Cfg *Func) const { 1712 void InstX8632Cvt::emit(const Cfg *Func) const {
1697 Ostream &Str = Func->getContext()->getStrEmit(); 1713 Ostream &Str = Func->getContext()->getStrEmit();
1698 assert(getSrcSize() == 1); 1714 assert(getSrcSize() == 1);
1699 Str << "\tcvt"; 1715 Str << "\tcvt";
1700 if (isTruncating()) 1716 if (isTruncating())
1701 Str << "t"; 1717 Str << "t";
1702 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" 1718 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2"
1703 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; 1719 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t";
1720 getSrc(0)->emit(Func);
1721 Str << ", ";
1704 getDest()->emit(Func); 1722 getDest()->emit(Func);
1705 Str << ", ";
1706 getSrc(0)->emit(Func);
1707 } 1723 }
1708 1724
1709 void InstX8632Cvt::emitIAS(const Cfg *Func) const { 1725 void InstX8632Cvt::emitIAS(const Cfg *Func) const {
1710 assert(getSrcSize() == 1); 1726 assert(getSrcSize() == 1);
1711 const Variable *Dest = getDest(); 1727 const Variable *Dest = getDest();
1712 const Operand *Src = getSrc(0); 1728 const Operand *Src = getSrc(0);
1713 Type DestTy = Dest->getType(); 1729 Type DestTy = Dest->getType();
1714 Type SrcTy = Src->getType(); 1730 Type SrcTy = Src->getType();
1715 switch (Variant) { 1731 switch (Variant) {
1716 case Si2ss: { 1732 case Si2ss: {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 if (isTruncating()) 1788 if (isTruncating())
1773 Str << "t"; 1789 Str << "t";
1774 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" 1790 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2"
1775 << TypeX8632Attributes[getDest()->getType()].CvtString << " "; 1791 << TypeX8632Attributes[getDest()->getType()].CvtString << " ";
1776 dumpSources(Func); 1792 dumpSources(Func);
1777 } 1793 }
1778 1794
1779 void InstX8632Icmp::emit(const Cfg *Func) const { 1795 void InstX8632Icmp::emit(const Cfg *Func) const {
1780 Ostream &Str = Func->getContext()->getStrEmit(); 1796 Ostream &Str = Func->getContext()->getStrEmit();
1781 assert(getSrcSize() == 2); 1797 assert(getSrcSize() == 2);
1782 Str << "\tcmp\t"; 1798 Str << "\tcmp" << getWidthString(getSrc(0)->getType()) << "\t";
1799 getSrc(1)->emit(Func);
1800 Str << ", ";
1783 getSrc(0)->emit(Func); 1801 getSrc(0)->emit(Func);
1784 Str << ", ";
1785 getSrc(1)->emit(Func);
1786 } 1802 }
1787 1803
1788 void InstX8632Icmp::emitIAS(const Cfg *Func) const { 1804 void InstX8632Icmp::emitIAS(const Cfg *Func) const {
1789 assert(getSrcSize() == 2); 1805 assert(getSrcSize() == 2);
1790 const Operand *Src0 = getSrc(0); 1806 const Operand *Src0 = getSrc(0);
1791 const Operand *Src1 = getSrc(1); 1807 const Operand *Src1 = getSrc(1);
1792 Type Ty = Src0->getType(); 1808 Type Ty = Src0->getType();
1793 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { 1809 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = {
1794 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp 1810 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp
1795 }; 1811 };
(...skipping 13 matching lines...) Expand all
1809 Ostream &Str = Func->getContext()->getStrDump(); 1825 Ostream &Str = Func->getContext()->getStrDump();
1810 Str << "cmp." << getSrc(0)->getType() << " "; 1826 Str << "cmp." << getSrc(0)->getType() << " ";
1811 dumpSources(Func); 1827 dumpSources(Func);
1812 } 1828 }
1813 1829
1814 void InstX8632Ucomiss::emit(const Cfg *Func) const { 1830 void InstX8632Ucomiss::emit(const Cfg *Func) const {
1815 Ostream &Str = Func->getContext()->getStrEmit(); 1831 Ostream &Str = Func->getContext()->getStrEmit();
1816 assert(getSrcSize() == 2); 1832 assert(getSrcSize() == 2);
1817 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString 1833 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString
1818 << "\t"; 1834 << "\t";
1835 getSrc(1)->emit(Func);
1836 Str << ", ";
1819 getSrc(0)->emit(Func); 1837 getSrc(0)->emit(Func);
1820 Str << ", ";
1821 getSrc(1)->emit(Func);
1822 } 1838 }
1823 1839
1824 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { 1840 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const {
1825 assert(getSrcSize() == 2); 1841 assert(getSrcSize() == 2);
1826 // Currently src0 is always a variable by convention, to avoid having 1842 // Currently src0 is always a variable by convention, to avoid having
1827 // two memory operands. 1843 // two memory operands.
1828 assert(llvm::isa<Variable>(getSrc(0))); 1844 assert(llvm::isa<Variable>(getSrc(0)));
1829 const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); 1845 const Variable *Src0 = llvm::cast<Variable>(getSrc(0));
1830 Type Ty = Src0->getType(); 1846 Type Ty = Src0->getType();
1831 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { 1847 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = {
(...skipping 22 matching lines...) Expand all
1854 } 1870 }
1855 1871
1856 void InstX8632UD2::dump(const Cfg *Func) const { 1872 void InstX8632UD2::dump(const Cfg *Func) const {
1857 Ostream &Str = Func->getContext()->getStrDump(); 1873 Ostream &Str = Func->getContext()->getStrDump();
1858 Str << "ud2\n"; 1874 Str << "ud2\n";
1859 } 1875 }
1860 1876
1861 void InstX8632Test::emit(const Cfg *Func) const { 1877 void InstX8632Test::emit(const Cfg *Func) const {
1862 Ostream &Str = Func->getContext()->getStrEmit(); 1878 Ostream &Str = Func->getContext()->getStrEmit();
1863 assert(getSrcSize() == 2); 1879 assert(getSrcSize() == 2);
1864 Str << "\ttest\t"; 1880 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t";
1881 getSrc(1)->emit(Func);
1882 Str << ", ";
1865 getSrc(0)->emit(Func); 1883 getSrc(0)->emit(Func);
1866 Str << ", ";
1867 getSrc(1)->emit(Func);
1868 } 1884 }
1869 1885
1870 void InstX8632Test::emitIAS(const Cfg *Func) const { 1886 void InstX8632Test::emitIAS(const Cfg *Func) const {
1871 assert(getSrcSize() == 2); 1887 assert(getSrcSize() == 2);
1872 const Operand *Src0 = getSrc(0); 1888 const Operand *Src0 = getSrc(0);
1873 const Operand *Src1 = getSrc(1); 1889 const Operand *Src1 = getSrc(1);
1874 Type Ty = Src0->getType(); 1890 Type Ty = Src0->getType();
1875 // The Reg/Addr form of test is not encodeable. 1891 // The Reg/Addr form of test is not encodeable.
1876 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { 1892 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = {
1877 &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test 1893 &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1909 } 1925 }
1910 1926
1911 void InstX8632Mfence::dump(const Cfg *Func) const { 1927 void InstX8632Mfence::dump(const Cfg *Func) const {
1912 Ostream &Str = Func->getContext()->getStrDump(); 1928 Ostream &Str = Func->getContext()->getStrDump();
1913 Str << "mfence\n"; 1929 Str << "mfence\n";
1914 } 1930 }
1915 1931
1916 void InstX8632Store::emit(const Cfg *Func) const { 1932 void InstX8632Store::emit(const Cfg *Func) const {
1917 Ostream &Str = Func->getContext()->getStrEmit(); 1933 Ostream &Str = Func->getContext()->getStrEmit();
1918 assert(getSrcSize() == 2); 1934 assert(getSrcSize() == 2);
1919 Str << "\tmov" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString 1935 Type Ty = getSrc(0)->getType();
1936 Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString
1920 << "\t"; 1937 << "\t";
1938 getSrc(0)->emit(Func);
1939 Str << ", ";
1921 getSrc(1)->emit(Func); 1940 getSrc(1)->emit(Func);
1922 Str << ", ";
1923 getSrc(0)->emit(Func);
1924 } 1941 }
1925 1942
1926 void InstX8632Store::emitIAS(const Cfg *Func) const { 1943 void InstX8632Store::emitIAS(const Cfg *Func) const {
1927 assert(getSrcSize() == 2); 1944 assert(getSrcSize() == 2);
1928 const Operand *Dest = getSrc(1); 1945 const Operand *Dest = getSrc(1);
1929 const Operand *Src = getSrc(0); 1946 const Operand *Src = getSrc(0);
1930 Type DestTy = Dest->getType(); 1947 Type DestTy = Dest->getType();
1931 if (isScalarFloatingType(DestTy)) { 1948 if (isScalarFloatingType(DestTy)) {
1932 // Src must be a register, since Dest is a Mem operand of some kind. 1949 // Src must be a register, since Dest is a Mem operand of some kind.
1933 const Variable *SrcVar = llvm::cast<Variable>(Src); 1950 const Variable *SrcVar = llvm::cast<Variable>(Src);
(...skipping 26 matching lines...) Expand all
1960 Str << "mov." << getSrc(0)->getType() << " "; 1977 Str << "mov." << getSrc(0)->getType() << " ";
1961 getSrc(1)->dump(Func); 1978 getSrc(1)->dump(Func);
1962 Str << ", "; 1979 Str << ", ";
1963 getSrc(0)->dump(Func); 1980 getSrc(0)->dump(Func);
1964 } 1981 }
1965 1982
1966 void InstX8632StoreP::emit(const Cfg *Func) const { 1983 void InstX8632StoreP::emit(const Cfg *Func) const {
1967 Ostream &Str = Func->getContext()->getStrEmit(); 1984 Ostream &Str = Func->getContext()->getStrEmit();
1968 assert(getSrcSize() == 2); 1985 assert(getSrcSize() == 2);
1969 Str << "\tmovups\t"; 1986 Str << "\tmovups\t";
1987 getSrc(0)->emit(Func);
1988 Str << ", ";
1970 getSrc(1)->emit(Func); 1989 getSrc(1)->emit(Func);
1971 Str << ", ";
1972 getSrc(0)->emit(Func);
1973 } 1990 }
1974 1991
1975 void InstX8632StoreP::emitIAS(const Cfg *Func) const { 1992 void InstX8632StoreP::emitIAS(const Cfg *Func) const {
1976 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1993 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1977 intptr_t StartPosition = Asm->GetPosition(); 1994 intptr_t StartPosition = Asm->GetPosition();
1978 assert(getSrcSize() == 2); 1995 assert(getSrcSize() == 2);
1979 const Variable *Src = llvm::cast<Variable>(getSrc(0)); 1996 const Variable *Src = llvm::cast<Variable>(getSrc(0));
1980 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 1997 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
1981 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1998 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1982 assert(Src->hasReg()); 1999 assert(Src->hasReg());
1983 Asm->movups(DestMem->toAsmAddress(Asm), 2000 Asm->movups(DestMem->toAsmAddress(Asm),
1984 RegX8632::getEncodedXmm(Src->getRegNum())); 2001 RegX8632::getEncodedXmm(Src->getRegNum()));
1985 emitIASBytes(Func, Asm, StartPosition); 2002 emitIASBytes(Func, Asm, StartPosition);
1986 } 2003 }
1987 2004
1988 void InstX8632StoreP::dump(const Cfg *Func) const { 2005 void InstX8632StoreP::dump(const Cfg *Func) const {
1989 Ostream &Str = Func->getContext()->getStrDump(); 2006 Ostream &Str = Func->getContext()->getStrDump();
1990 Str << "storep." << getSrc(0)->getType() << " "; 2007 Str << "storep." << getSrc(0)->getType() << " ";
1991 getSrc(1)->dump(Func); 2008 getSrc(1)->dump(Func);
1992 Str << ", "; 2009 Str << ", ";
1993 getSrc(0)->dump(Func); 2010 getSrc(0)->dump(Func);
1994 } 2011 }
1995 2012
1996 void InstX8632StoreQ::emit(const Cfg *Func) const { 2013 void InstX8632StoreQ::emit(const Cfg *Func) const {
1997 Ostream &Str = Func->getContext()->getStrEmit(); 2014 Ostream &Str = Func->getContext()->getStrEmit();
1998 assert(getSrcSize() == 2); 2015 assert(getSrcSize() == 2);
1999 assert(getSrc(1)->getType() == IceType_i64 || 2016 assert(getSrc(1)->getType() == IceType_i64 ||
2000 getSrc(1)->getType() == IceType_f64); 2017 getSrc(1)->getType() == IceType_f64);
2001 Str << "\tmovq\t"; 2018 Str << "\tmovq\t";
2019 getSrc(0)->emit(Func);
2020 Str << ", ";
2002 getSrc(1)->emit(Func); 2021 getSrc(1)->emit(Func);
2003 Str << ", ";
2004 getSrc(0)->emit(Func);
2005 } 2022 }
2006 2023
2007 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { 2024 void InstX8632StoreQ::emitIAS(const Cfg *Func) const {
2008 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2025 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2009 intptr_t StartPosition = Asm->GetPosition(); 2026 intptr_t StartPosition = Asm->GetPosition();
2010 assert(getSrcSize() == 2); 2027 assert(getSrcSize() == 2);
2011 const Variable *Src = llvm::cast<Variable>(getSrc(0)); 2028 const Variable *Src = llvm::cast<Variable>(getSrc(0));
2012 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 2029 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
2013 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2030 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2014 assert(Src->hasReg()); 2031 assert(Src->hasReg());
2015 Asm->movq(DestMem->toAsmAddress(Asm), 2032 Asm->movq(DestMem->toAsmAddress(Asm),
2016 RegX8632::getEncodedXmm(Src->getRegNum())); 2033 RegX8632::getEncodedXmm(Src->getRegNum()));
2017 emitIASBytes(Func, Asm, StartPosition); 2034 emitIASBytes(Func, Asm, StartPosition);
2018 } 2035 }
2019 2036
2020 void InstX8632StoreQ::dump(const Cfg *Func) const { 2037 void InstX8632StoreQ::dump(const Cfg *Func) const {
2021 Ostream &Str = Func->getContext()->getStrDump(); 2038 Ostream &Str = Func->getContext()->getStrDump();
2022 Str << "storeq." << getSrc(0)->getType() << " "; 2039 Str << "storeq." << getSrc(0)->getType() << " ";
2023 getSrc(1)->dump(Func); 2040 getSrc(1)->dump(Func);
2024 Str << ", "; 2041 Str << ", ";
2025 getSrc(0)->dump(Func); 2042 getSrc(0)->dump(Func);
2026 } 2043 }
2027 2044
2028 template <> void InstX8632Lea::emit(const Cfg *Func) const { 2045 template <> void InstX8632Lea::emit(const Cfg *Func) const {
2029 Ostream &Str = Func->getContext()->getStrEmit(); 2046 Ostream &Str = Func->getContext()->getStrEmit();
2030 assert(getSrcSize() == 1); 2047 assert(getSrcSize() == 1);
2031 assert(getDest()->hasReg()); 2048 assert(getDest()->hasReg());
2032 Str << "\tlea\t"; 2049 Str << "\tleal\t";
2033 getDest()->emit(Func);
2034 Str << ", ";
2035 Operand *Src0 = getSrc(0); 2050 Operand *Src0 = getSrc(0);
2036 if (Variable *VSrc0 = llvm::dyn_cast<Variable>(Src0)) { 2051 if (Variable *VSrc0 = llvm::dyn_cast<Variable>(Src0)) {
2037 Type Ty = VSrc0->getType(); 2052 Type Ty = VSrc0->getType();
2038 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an 2053 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
2039 // acceptable type. 2054 // acceptable type.
2040 VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func); 2055 VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func);
2041 } else { 2056 } else {
2042 Src0->emit(Func); 2057 Src0->emit(Func);
2043 } 2058 }
2059 Str << ", ";
2060 getDest()->emit(Func);
2044 } 2061 }
2045 2062
2046 template <> void InstX8632Mov::emit(const Cfg *Func) const { 2063 template <> void InstX8632Mov::emit(const Cfg *Func) const {
2047 Ostream &Str = Func->getContext()->getStrEmit(); 2064 Ostream &Str = Func->getContext()->getStrEmit();
2048 assert(getSrcSize() == 1); 2065 assert(getSrcSize() == 1);
2049 Operand *Src = getSrc(0); 2066 Operand *Src = getSrc(0);
2067 Type SrcTy = Src->getType();
2068 Type DestTy = getDest()->getType();
2050 // The llvm-mc assembler using Intel syntax has a bug in which "mov 2069 // The llvm-mc assembler using Intel syntax has a bug in which "mov
2051 // reg, RelocatableConstant" does not generate the right instruction 2070 // reg, RelocatableConstant" does not generate the right instruction
2052 // with a relocation. To work around, we emit "lea reg, 2071 // with a relocation. To work around, we emit "lea reg,
2053 // RelocatableConstant". Also, the lowering and legalization is 2072 // RelocatableConstant". Also, the lowering and legalization is
2054 // changed to allow relocatable constants only in Assign and Call 2073 // changed to allow relocatable constants only in Assign and Call
2055 // instructions or in Mem operands. TODO(stichnot): remove LEAHACK 2074 // instructions or in Mem operands.
2056 // once a proper emitter is used. 2075 Str << "\tmov" << (!isScalarFloatingType(DestTy)
2057 // 2076 ? getWidthString(SrcTy)
2058 // In addition, llvm-mc doesn't like "lea eax, bp" or "lea eax, Sp" 2077 : TypeX8632Attributes[DestTy].SdSsString) << "\t";
2059 // or "lea eax, flags" etc., when the relocatable constant name is a
2060 // reserved word. The hack-on-top-of-hack is to temporarily drop
2061 // into AT&T syntax for this lea instruction.
2062 bool UseLeaHack = llvm::isa<ConstantRelocatable>(Src);
2063 if (UseLeaHack) {
2064 Str << ".att_syntax\n";
2065 Str << "\tleal";
2066 } else {
2067 Str << "\tmov" << TypeX8632Attributes[getDest()->getType()].SdSsString;
2068 }
2069 Str << "\t";
2070 // For an integer truncation operation, src is wider than dest. 2078 // For an integer truncation operation, src is wider than dest.
2071 // Ideally, we use a mov instruction whose data width matches the 2079 // Ideally, we use a mov instruction whose data width matches the
2072 // narrower dest. This is a problem if e.g. src is a register like 2080 // narrower dest. This is a problem if e.g. src is a register like
2073 // esi or si where there is no 8-bit version of the register. To be 2081 // esi or si where there is no 8-bit version of the register. To be
2074 // safe, we instead widen the dest to match src. This works even 2082 // safe, we instead widen the dest to match src. This works even
2075 // for stack-allocated dest variables because typeWidthOnStack() 2083 // for stack-allocated dest variables because typeWidthOnStack()
2076 // pads to a 4-byte boundary even if only a lower portion is used. 2084 // pads to a 4-byte boundary even if only a lower portion is used.
2077 // TODO: This assert disallows usages such as copying a floating point 2085 // TODO: This assert disallows usages such as copying a floating point
2078 // value between a vector and a scalar (which movss is used for). 2086 // value between a vector and a scalar (which movss is used for).
2079 // Clean this up. 2087 // Clean this up.
2080 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == 2088 assert(Func->getTarget()->typeWidthInBytesOnStack(DestTy) ==
2081 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); 2089 Func->getTarget()->typeWidthInBytesOnStack(SrcTy));
2082 if (UseLeaHack) { 2090 Src->emit(Func);
2083 Src->emit(Func); 2091 Str << ", ";
2084 Str << ", %"; 2092 getDest()->asType(SrcTy).emit(Func);
2085 getDest()->emit(Func);
2086 Str << "\n";
2087 Str << ".intel_syntax";
2088 } else {
2089 getDest()->asType(Src->getType()).emit(Func);
2090 Str << ", ";
2091 Src->emit(Func);
2092 }
2093 } 2093 }
2094 2094
2095 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const { 2095 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const {
2096 assert(getSrcSize() == 1); 2096 assert(getSrcSize() == 1);
2097 const Variable *Dest = getDest(); 2097 const Variable *Dest = getDest();
2098 const Operand *Src = getSrc(0); 2098 const Operand *Src = getSrc(0);
2099 Type DestTy = Dest->getType(); 2099 Type DestTy = Dest->getType();
2100 Type SrcTy = Src->getType(); 2100 Type SrcTy = Src->getType();
2101 // Mov can be used for GPRs or XMM registers. Also, the type does not 2101 // Mov can be used for GPRs or XMM registers. Also, the type does not
2102 // necessarily match (Mov can be used for bitcasts). However, when 2102 // necessarily match (Mov can be used for bitcasts). However, when
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2199 } 2199 }
2200 2200
2201 template <> void InstX8632Movp::emit(const Cfg *Func) const { 2201 template <> void InstX8632Movp::emit(const Cfg *Func) const {
2202 // TODO(wala,stichnot): movups works with all vector operands, but 2202 // TODO(wala,stichnot): movups works with all vector operands, but
2203 // there exist other instructions (movaps, movdqa, movdqu) that may 2203 // there exist other instructions (movaps, movdqa, movdqu) that may
2204 // perform better, depending on the data type and alignment of the 2204 // perform better, depending on the data type and alignment of the
2205 // operands. 2205 // operands.
2206 Ostream &Str = Func->getContext()->getStrEmit(); 2206 Ostream &Str = Func->getContext()->getStrEmit();
2207 assert(getSrcSize() == 1); 2207 assert(getSrcSize() == 1);
2208 Str << "\tmovups\t"; 2208 Str << "\tmovups\t";
2209 getSrc(0)->emit(Func);
2210 Str << ", ";
2209 getDest()->emit(Func); 2211 getDest()->emit(Func);
2210 Str << ", ";
2211 getSrc(0)->emit(Func);
2212 } 2212 }
2213 2213
2214 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { 2214 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const {
2215 assert(getSrcSize() == 1); 2215 assert(getSrcSize() == 1);
2216 assert(isVectorType(getDest()->getType())); 2216 assert(isVectorType(getDest()->getType()));
2217 const Variable *Dest = getDest(); 2217 const Variable *Dest = getDest();
2218 const Operand *Src = getSrc(0); 2218 const Operand *Src = getSrc(0);
2219 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { 2219 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = {
2220 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, 2220 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups,
2221 &x86::AssemblerX86::movups 2221 &x86::AssemblerX86::movups
2222 }; 2222 };
2223 emitIASMovlikeXMM(Func, Dest, Src, Emitter); 2223 emitIASMovlikeXMM(Func, Dest, Src, Emitter);
2224 } 2224 }
2225 2225
2226 template <> void InstX8632Movq::emit(const Cfg *Func) const { 2226 template <> void InstX8632Movq::emit(const Cfg *Func) const {
2227 Ostream &Str = Func->getContext()->getStrEmit(); 2227 Ostream &Str = Func->getContext()->getStrEmit();
2228 assert(getSrcSize() == 1); 2228 assert(getSrcSize() == 1);
2229 assert(getDest()->getType() == IceType_i64 || 2229 assert(getDest()->getType() == IceType_i64 ||
2230 getDest()->getType() == IceType_f64); 2230 getDest()->getType() == IceType_f64);
2231 Str << "\tmovq\t"; 2231 Str << "\tmovq\t";
2232 getSrc(0)->emit(Func);
2233 Str << ", ";
2232 getDest()->emit(Func); 2234 getDest()->emit(Func);
2233 Str << ", ";
2234 getSrc(0)->emit(Func);
2235 } 2235 }
2236 2236
2237 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { 2237 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const {
2238 assert(getSrcSize() == 1); 2238 assert(getSrcSize() == 1);
2239 assert(getDest()->getType() == IceType_i64 || 2239 assert(getDest()->getType() == IceType_i64 ||
2240 getDest()->getType() == IceType_f64); 2240 getDest()->getType() == IceType_f64);
2241 const Variable *Dest = getDest(); 2241 const Variable *Dest = getDest();
2242 const Operand *Src = getSrc(0); 2242 const Operand *Src = getSrc(0);
2243 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { 2243 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = {
2244 &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, &x86::AssemblerX86::movq 2244 &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, &x86::AssemblerX86::movq
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2300 2300
2301 void InstX8632Nop::dump(const Cfg *Func) const { 2301 void InstX8632Nop::dump(const Cfg *Func) const {
2302 Ostream &Str = Func->getContext()->getStrDump(); 2302 Ostream &Str = Func->getContext()->getStrDump();
2303 Str << "nop (variant = " << Variant << ")"; 2303 Str << "nop (variant = " << Variant << ")";
2304 } 2304 }
2305 2305
2306 void InstX8632Fld::emit(const Cfg *Func) const { 2306 void InstX8632Fld::emit(const Cfg *Func) const {
2307 Ostream &Str = Func->getContext()->getStrEmit(); 2307 Ostream &Str = Func->getContext()->getStrEmit();
2308 assert(getSrcSize() == 1); 2308 assert(getSrcSize() == 1);
2309 Type Ty = getSrc(0)->getType(); 2309 Type Ty = getSrc(0)->getType();
2310 SizeT Width = typeWidthInBytes(Ty);
2310 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); 2311 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0));
2311 if (Var && Var->hasReg()) { 2312 if (Var && Var->hasReg()) {
2312 // This is a physical xmm register, so we need to spill it to a 2313 // This is a physical xmm register, so we need to spill it to a
2313 // temporary stack slot. 2314 // temporary stack slot.
2314 SizeT Width = typeWidthInBytes(Ty); 2315 Str << "\tsubl\t$" << Width << ", %esp"
2315 Str << "\tsub\tesp, " << Width << "\n"; 2316 << "\n";
2316 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" 2317 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t";
2317 << TypeX8632Attributes[Ty].WidthString << " [esp], ";
2318 Var->emit(Func); 2318 Var->emit(Func);
2319 Str << "\n"; 2319 Str << ", (%esp)\n";
2320 Str << "\tfld\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 2320 Str << "\tfld" << getFldString(Ty) << "\t"
2321 Str << "\tadd\tesp, " << Width; 2321 << "(%esp)\n";
2322 Str << "\taddl\t$" << Width << ", %esp";
2322 return; 2323 return;
2323 } 2324 }
2324 Str << "\tfld\t"; 2325 Str << "\tfld" << getFldString(Ty) << "\t";
2325 getSrc(0)->emit(Func); 2326 getSrc(0)->emit(Func);
2326 } 2327 }
2327 2328
2328 void InstX8632Fld::emitIAS(const Cfg *Func) const { 2329 void InstX8632Fld::emitIAS(const Cfg *Func) const {
2329 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2330 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2330 intptr_t StartPosition = Asm->GetPosition(); 2331 intptr_t StartPosition = Asm->GetPosition();
2331 assert(getSrcSize() == 1); 2332 assert(getSrcSize() == 1);
2332 const Operand *Src = getSrc(0); 2333 const Operand *Src = getSrc(0);
2333 Type Ty = Src->getType(); 2334 Type Ty = Src->getType();
2334 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { 2335 if (const auto Var = llvm::dyn_cast<Variable>(Src)) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2367 Ostream &Str = Func->getContext()->getStrEmit(); 2368 Ostream &Str = Func->getContext()->getStrEmit();
2368 assert(getSrcSize() == 0); 2369 assert(getSrcSize() == 0);
2369 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to 2370 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to
2370 // "partially" delete the fstp if the Dest is unused. 2371 // "partially" delete the fstp if the Dest is unused.
2371 // Even if Dest is unused, the fstp should be kept for the SideEffects 2372 // Even if Dest is unused, the fstp should be kept for the SideEffects
2372 // of popping the stack. 2373 // of popping the stack.
2373 if (getDest() == NULL) { 2374 if (getDest() == NULL) {
2374 Str << "\tfstp\tst(0)"; 2375 Str << "\tfstp\tst(0)";
2375 return; 2376 return;
2376 } 2377 }
2378 Type Ty = getDest()->getType();
2379 size_t Width = typeWidthInBytes(Ty);
2377 if (!getDest()->hasReg()) { 2380 if (!getDest()->hasReg()) {
2378 Str << "\tfstp\t"; 2381 Str << "\tfstp" << getFldString(Ty) << "\t";
2379 getDest()->emit(Func); 2382 getDest()->emit(Func);
2380 return; 2383 return;
2381 } 2384 }
2382 // Dest is a physical (xmm) register, so st(0) needs to go through 2385 // Dest is a physical (xmm) register, so st(0) needs to go through
2383 // memory. Hack this by creating a temporary stack slot, spilling 2386 // memory. Hack this by creating a temporary stack slot, spilling
2384 // st(0) there, loading it into the xmm register, and deallocating 2387 // st(0) there, loading it into the xmm register, and deallocating
2385 // the stack slot. 2388 // the stack slot.
2386 Type Ty = getDest()->getType(); 2389 Str << "\tsubl\t$" << Width << ", %esp\n";
2387 size_t Width = typeWidthInBytes(Ty); 2390 Str << "\tfstp" << getFldString(Ty) << "\t"
2388 Str << "\tsub\tesp, " << Width << "\n"; 2391 << "(%esp)\n";
2389 Str << "\tfstp\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 2392 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"
2390 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"; 2393 << "(%esp), ";
2391 getDest()->emit(Func); 2394 getDest()->emit(Func);
2392 Str << ", " << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 2395 Str << "\n";
2393 Str << "\tadd\tesp, " << Width; 2396 Str << "\taddl\t$" << Width << ", %esp";
2394 } 2397 }
2395 2398
2396 void InstX8632Fstp::emitIAS(const Cfg *Func) const { 2399 void InstX8632Fstp::emitIAS(const Cfg *Func) const {
2397 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2400 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2398 intptr_t StartPosition = Asm->GetPosition(); 2401 intptr_t StartPosition = Asm->GetPosition();
2399 assert(getSrcSize() == 0); 2402 assert(getSrcSize() == 0);
2400 const Variable *Dest = getDest(); 2403 const Variable *Dest = getDest();
2401 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to 2404 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to
2402 // "partially" delete the fstp if the Dest is unused. 2405 // "partially" delete the fstp if the Dest is unused.
2403 // Even if Dest is unused, the fstp should be kept for the SideEffects 2406 // Even if Dest is unused, the fstp should be kept for the SideEffects
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 template <> void InstX8632Pextr::emit(const Cfg *Func) const { 2454 template <> void InstX8632Pextr::emit(const Cfg *Func) const {
2452 Ostream &Str = Func->getContext()->getStrEmit(); 2455 Ostream &Str = Func->getContext()->getStrEmit();
2453 assert(getSrcSize() == 2); 2456 assert(getSrcSize() == 2);
2454 // pextrb and pextrd are SSE4.1 instructions. 2457 // pextrb and pextrd are SSE4.1 instructions.
2455 assert(getSrc(0)->getType() == IceType_v8i16 || 2458 assert(getSrc(0)->getType() == IceType_v8i16 ||
2456 getSrc(0)->getType() == IceType_v8i1 || 2459 getSrc(0)->getType() == IceType_v8i1 ||
2457 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() 2460 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet()
2458 >= TargetX8632::SSE4_1); 2461 >= TargetX8632::SSE4_1);
2459 Str << "\t" << Opcode 2462 Str << "\t" << Opcode
2460 << TypeX8632Attributes[getSrc(0)->getType()].PackString << "\t"; 2463 << TypeX8632Attributes[getSrc(0)->getType()].PackString << "\t";
2464 getSrc(1)->emit(Func);
2465 Str << ", ";
2466 getSrc(0)->emit(Func);
2467 Str << ", ";
2461 Variable *Dest = getDest(); 2468 Variable *Dest = getDest();
2462 // pextrw must take a register dest. There is an SSE4.1 version that takes 2469 // pextrw must take a register dest. There is an SSE4.1 version that takes
2463 // a memory dest, but we aren't using it. For uniformity, just restrict 2470 // a memory dest, but we aren't using it. For uniformity, just restrict
2464 // them all to have a register dest for now. 2471 // them all to have a register dest for now.
2465 assert(Dest->hasReg()); 2472 assert(Dest->hasReg());
2466 Dest->asType(IceType_i32).emit(Func); 2473 Dest->asType(IceType_i32).emit(Func);
2467 Str << ", ";
2468 getSrc(0)->emit(Func);
2469 Str << ", ";
2470 getSrc(1)->emit(Func);
2471 } 2474 }
2472 2475
2473 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const { 2476 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const {
2474 assert(getSrcSize() == 2); 2477 assert(getSrcSize() == 2);
2475 // pextrb and pextrd are SSE4.1 instructions. 2478 // pextrb and pextrd are SSE4.1 instructions.
2476 const Variable *Dest = getDest(); 2479 const Variable *Dest = getDest();
2477 Type DispatchTy = Dest->getType(); 2480 Type DispatchTy = Dest->getType();
2478 assert(DispatchTy == IceType_i16 || 2481 assert(DispatchTy == IceType_i16 ||
2479 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 2482 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
2480 TargetX8632::SSE4_1); 2483 TargetX8632::SSE4_1);
(...skipping 14 matching lines...) Expand all
2495 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { 2498 template <> void InstX8632Pinsr::emit(const Cfg *Func) const {
2496 Ostream &Str = Func->getContext()->getStrEmit(); 2499 Ostream &Str = Func->getContext()->getStrEmit();
2497 assert(getSrcSize() == 3); 2500 assert(getSrcSize() == 3);
2498 // pinsrb and pinsrd are SSE4.1 instructions. 2501 // pinsrb and pinsrd are SSE4.1 instructions.
2499 assert(getDest()->getType() == IceType_v8i16 || 2502 assert(getDest()->getType() == IceType_v8i16 ||
2500 getDest()->getType() == IceType_v8i1 || 2503 getDest()->getType() == IceType_v8i1 ||
2501 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() 2504 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet()
2502 >= TargetX8632::SSE4_1); 2505 >= TargetX8632::SSE4_1);
2503 Str << "\t" << Opcode 2506 Str << "\t" << Opcode
2504 << TypeX8632Attributes[getDest()->getType()].PackString << "\t"; 2507 << TypeX8632Attributes[getDest()->getType()].PackString << "\t";
2505 getDest()->emit(Func); 2508 getSrc(2)->emit(Func);
2506 Str << ", "; 2509 Str << ", ";
2507 Operand *Src1 = getSrc(1); 2510 Operand *Src1 = getSrc(1);
2508 if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) { 2511 if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) {
2509 // If src1 is a register, it should always be r32. 2512 // If src1 is a register, it should always be r32.
2510 if (VSrc1->hasReg()) { 2513 if (VSrc1->hasReg()) {
2511 VSrc1->asType(IceType_i32).emit(Func); 2514 VSrc1->asType(IceType_i32).emit(Func);
2512 } else { 2515 } else {
2513 VSrc1->emit(Func); 2516 VSrc1->emit(Func);
2514 } 2517 }
2515 } else { 2518 } else {
2516 Src1->emit(Func); 2519 Src1->emit(Func);
2517 } 2520 }
2518 Str << ", "; 2521 Str << ", ";
2519 getSrc(2)->emit(Func); 2522 getDest()->emit(Func);
2520 } 2523 }
2521 2524
2522 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { 2525 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const {
2523 assert(getSrcSize() == 3); 2526 assert(getSrcSize() == 3);
2524 assert(getDest() == getSrc(0)); 2527 assert(getDest() == getSrc(0));
2525 // pinsrb and pinsrd are SSE4.1 instructions. 2528 // pinsrb and pinsrd are SSE4.1 instructions.
2526 const Operand *Src0 = getSrc(1); 2529 const Operand *Src0 = getSrc(1);
2527 Type DispatchTy = Src0->getType(); 2530 Type DispatchTy = Src0->getType();
2528 assert(DispatchTy == IceType_i16 || 2531 assert(DispatchTy == IceType_i16 ||
2529 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 2532 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2586 } 2589 }
2587 2590
2588 void InstX8632Pop::dump(const Cfg *Func) const { 2591 void InstX8632Pop::dump(const Cfg *Func) const {
2589 Ostream &Str = Func->getContext()->getStrDump(); 2592 Ostream &Str = Func->getContext()->getStrDump();
2590 dumpDest(Func); 2593 dumpDest(Func);
2591 Str << " = pop." << getDest()->getType() << " "; 2594 Str << " = pop." << getDest()->getType() << " ";
2592 } 2595 }
2593 2596
2594 void InstX8632AdjustStack::emit(const Cfg *Func) const { 2597 void InstX8632AdjustStack::emit(const Cfg *Func) const {
2595 Ostream &Str = Func->getContext()->getStrEmit(); 2598 Ostream &Str = Func->getContext()->getStrEmit();
2596 Str << "\tsub\tesp, " << Amount; 2599 Str << "\tsubl\t$" << Amount << ", %esp";
2597 Func->getTarget()->updateStackAdjustment(Amount); 2600 Func->getTarget()->updateStackAdjustment(Amount);
2598 } 2601 }
2599 2602
2600 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { 2603 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
2601 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2604 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2602 intptr_t StartPosition = Asm->GetPosition(); 2605 intptr_t StartPosition = Asm->GetPosition();
2603 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); 2606 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount));
2604 emitIASBytes(Func, Asm, StartPosition); 2607 emitIASBytes(Func, Asm, StartPosition);
2605 Func->getTarget()->updateStackAdjustment(Amount); 2608 Func->getTarget()->updateStackAdjustment(Amount);
2606 } 2609 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); 2679 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
2677 Str << "ret." << Ty << " "; 2680 Str << "ret." << Ty << " ";
2678 dumpSources(Func); 2681 dumpSources(Func);
2679 } 2682 }
2680 2683
2681 void InstX8632Xadd::emit(const Cfg *Func) const { 2684 void InstX8632Xadd::emit(const Cfg *Func) const {
2682 Ostream &Str = Func->getContext()->getStrEmit(); 2685 Ostream &Str = Func->getContext()->getStrEmit();
2683 if (Locked) { 2686 if (Locked) {
2684 Str << "\tlock"; 2687 Str << "\tlock";
2685 } 2688 }
2686 Str << "\txadd\t"; 2689 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t";
2690 getSrc(1)->emit(Func);
2691 Str << ", ";
2687 getSrc(0)->emit(Func); 2692 getSrc(0)->emit(Func);
2688 Str << ", ";
2689 getSrc(1)->emit(Func);
2690 } 2693 }
2691 2694
2692 void InstX8632Xadd::emitIAS(const Cfg *Func) const { 2695 void InstX8632Xadd::emitIAS(const Cfg *Func) const {
2693 assert(getSrcSize() == 2); 2696 assert(getSrcSize() == 2);
2694 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2697 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2695 intptr_t StartPosition = Asm->GetPosition(); 2698 intptr_t StartPosition = Asm->GetPosition();
2696 Type Ty = getSrc(0)->getType(); 2699 Type Ty = getSrc(0)->getType();
2697 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2700 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2698 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2701 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2699 const x86::Address Addr = Mem->toAsmAddress(Asm); 2702 const x86::Address Addr = Mem->toAsmAddress(Asm);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2744 2747
2745 void InstX8632Xchg::dump(const Cfg *Func) const { 2748 void InstX8632Xchg::dump(const Cfg *Func) const {
2746 Ostream &Str = Func->getContext()->getStrDump(); 2749 Ostream &Str = Func->getContext()->getStrDump();
2747 Type Ty = getSrc(0)->getType(); 2750 Type Ty = getSrc(0)->getType();
2748 Str << "xchg." << Ty << " "; 2751 Str << "xchg." << Ty << " ";
2749 dumpSources(Func); 2752 dumpSources(Func);
2750 } 2753 }
2751 2754
2752 void OperandX8632Mem::emit(const Cfg *Func) const { 2755 void OperandX8632Mem::emit(const Cfg *Func) const {
2753 Ostream &Str = Func->getContext()->getStrEmit(); 2756 Ostream &Str = Func->getContext()->getStrEmit();
2754 Str << TypeX8632Attributes[getType()].WidthString << " ";
2755 if (SegmentReg != DefaultSegment) { 2757 if (SegmentReg != DefaultSegment) {
2756 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); 2758 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
2757 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; 2759 Str << InstX8632SegmentRegNames[SegmentReg] << ":";
2758 } 2760 }
2759 // TODO: The following is an almost verbatim paste of dump(). 2761 // Emit as Offset(Base,Index,1<<Shift).
2760 bool Dumped = false; 2762 // Offset is emitted without the leading '$'.
2761 Str << "["; 2763 // Omit the (Base,Index,1<<Shift) part if Base==NULL.
2764 if (Offset == NULL) {
2765 // No offset, emit nothing.
2766 } else if (auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
2767 if (CI->getValue())
2768 // Emit a non-zero offset without a leading '$'.
2769 Str << CI->getValue();
2770 } else if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
2771 CR->emitWithoutDollar(Func->getContext());
2772 } else {
2773 assert(0);
2774 }
2775
2762 if (Base) { 2776 if (Base) {
2777 Str << "(";
2763 Base->emit(Func); 2778 Base->emit(Func);
2764 Dumped = true; 2779 if (Index) {
2780 Str << ",";
2781 Index->emit(Func);
2782 if (Shift)
2783 Str << "," << (1u << Shift);
2784 }
2785 Str << ")";
2765 } 2786 }
2766 if (Index) {
2767 assert(Base);
2768 Str << "+";
2769 if (Shift > 0)
2770 Str << (1u << Shift) << "*";
2771 Index->emit(Func);
2772 Dumped = true;
2773 }
2774 // Pretty-print the Offset.
2775 bool OffsetIsZero = false;
2776 bool OffsetIsNegative = false;
2777 if (Offset == NULL) {
2778 OffsetIsZero = true;
2779 } else if (ConstantInteger32 *CI =
2780 llvm::dyn_cast<ConstantInteger32>(Offset)) {
2781 OffsetIsZero = (CI->getValue() == 0);
2782 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
2783 } else {
2784 assert(llvm::isa<ConstantRelocatable>(Offset));
2785 }
2786 if (Dumped) {
2787 if (!OffsetIsZero) { // Suppress if Offset is known to be 0
2788 if (!OffsetIsNegative) // Suppress if Offset is known to be negative
2789 Str << "+";
2790 Offset->emit(Func);
2791 }
2792 } else {
2793 // There is only the offset.
2794 Offset->emit(Func);
2795 }
2796 Str << "]";
2797 } 2787 }
2798 2788
2799 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const { 2789 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const {
2800 if (SegmentReg != DefaultSegment) { 2790 if (SegmentReg != DefaultSegment) {
2801 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); 2791 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
2802 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; 2792 Str << InstX8632SegmentRegNames[SegmentReg] << ":";
2803 } 2793 }
2804 bool Dumped = false; 2794 bool Dumped = false;
2805 Str << "["; 2795 Str << "[";
2806 if (Base) { 2796 if (Base) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2896 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), 2886 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()),
2897 Offset); 2887 Offset);
2898 } 2888 }
2899 2889
2900 void VariableSplit::emit(const Cfg *Func) const { 2890 void VariableSplit::emit(const Cfg *Func) const {
2901 Ostream &Str = Func->getContext()->getStrEmit(); 2891 Ostream &Str = Func->getContext()->getStrEmit();
2902 assert(!Var->hasReg()); 2892 assert(!Var->hasReg());
2903 // The following is copied/adapted from TargetX8632::emitVariable(). 2893 // The following is copied/adapted from TargetX8632::emitVariable().
2904 const TargetLowering *Target = Func->getTarget(); 2894 const TargetLowering *Target = Func->getTarget();
2905 const Type Ty = IceType_i32; 2895 const Type Ty = IceType_i32;
2906 Str << TypeX8632Attributes[Ty].WidthString << " ["
2907 << Target->getRegName(Target->getFrameOrStackReg(), Ty);
2908 int32_t Offset = 2896 int32_t Offset =
2909 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); 2897 Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
2910 if (Offset) { 2898 if (Offset)
2911 if (Offset > 0)
2912 Str << "+";
2913 Str << Offset; 2899 Str << Offset;
2914 } 2900 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")";
2915 Str << "]";
2916 } 2901 }
2917 2902
2918 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { 2903 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const {
2919 switch (Part) { 2904 switch (Part) {
2920 case Low: 2905 case Low:
2921 Str << "low"; 2906 Str << "low";
2922 break; 2907 break;
2923 case High: 2908 case High:
2924 Str << "high"; 2909 Str << "high";
2925 break; 2910 break;
2926 default: 2911 default:
2927 Str << "???"; 2912 Str << "???";
2928 break; 2913 break;
2929 } 2914 }
2930 Str << "("; 2915 Str << "(";
2931 if (Func) 2916 if (Func)
2932 Var->dump(Func); 2917 Var->dump(Func);
2933 else 2918 else
2934 Var->dump(Str); 2919 Var->dump(Str);
2935 Str << ")"; 2920 Str << ")";
2936 } 2921 }
2937 2922
2938 } // end of namespace Ice 2923 } // end of namespace Ice
OLDNEW
« src/IceInstX8632.h ('K') | « src/IceInstX8632.h ('k') | src/IceInstX8632.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698