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

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: Add opcode suffix to xchg. Use .L$ prefix for constant pool entries. 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
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceInstX8632.def » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 429 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
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);
2050 // The llvm-mc assembler using Intel syntax has a bug in which "mov 2067 Type SrcTy = Src->getType();
2051 // reg, RelocatableConstant" does not generate the right instruction 2068 Type DestTy = getDest()->getType();
2052 // with a relocation. To work around, we emit "lea reg, 2069 Str << "\tmov" << (!isScalarFloatingType(DestTy)
2053 // RelocatableConstant". Also, the lowering and legalization is 2070 ? getWidthString(SrcTy)
2054 // changed to allow relocatable constants only in Assign and Call 2071 : TypeX8632Attributes[DestTy].SdSsString) << "\t";
2055 // instructions or in Mem operands. TODO(stichnot): remove LEAHACK
2056 // once a proper emitter is used.
2057 //
2058 // In addition, llvm-mc doesn't like "lea eax, bp" or "lea eax, Sp"
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. 2072 // For an integer truncation operation, src is wider than dest.
2071 // Ideally, we use a mov instruction whose data width matches the 2073 // 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 2074 // 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 2075 // 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 2076 // safe, we instead widen the dest to match src. This works even
2075 // for stack-allocated dest variables because typeWidthOnStack() 2077 // for stack-allocated dest variables because typeWidthOnStack()
2076 // pads to a 4-byte boundary even if only a lower portion is used. 2078 // 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 2079 // TODO: This assert disallows usages such as copying a floating point
2078 // value between a vector and a scalar (which movss is used for). 2080 // value between a vector and a scalar (which movss is used for).
2079 // Clean this up. 2081 // Clean this up.
2080 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == 2082 assert(Func->getTarget()->typeWidthInBytesOnStack(DestTy) ==
2081 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); 2083 Func->getTarget()->typeWidthInBytesOnStack(SrcTy));
2082 if (UseLeaHack) { 2084 Src->emit(Func);
2083 Src->emit(Func); 2085 Str << ", ";
2084 Str << ", %"; 2086 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 } 2087 }
2094 2088
2095 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const { 2089 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const {
2096 assert(getSrcSize() == 1); 2090 assert(getSrcSize() == 1);
2097 const Variable *Dest = getDest(); 2091 const Variable *Dest = getDest();
2098 const Operand *Src = getSrc(0); 2092 const Operand *Src = getSrc(0);
2099 Type DestTy = Dest->getType(); 2093 Type DestTy = Dest->getType();
2100 Type SrcTy = Src->getType(); 2094 Type SrcTy = Src->getType();
2101 // Mov can be used for GPRs or XMM registers. Also, the type does not 2095 // 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 2096 // necessarily match (Mov can be used for bitcasts). However, when
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2199 } 2193 }
2200 2194
2201 template <> void InstX8632Movp::emit(const Cfg *Func) const { 2195 template <> void InstX8632Movp::emit(const Cfg *Func) const {
2202 // TODO(wala,stichnot): movups works with all vector operands, but 2196 // TODO(wala,stichnot): movups works with all vector operands, but
2203 // there exist other instructions (movaps, movdqa, movdqu) that may 2197 // there exist other instructions (movaps, movdqa, movdqu) that may
2204 // perform better, depending on the data type and alignment of the 2198 // perform better, depending on the data type and alignment of the
2205 // operands. 2199 // operands.
2206 Ostream &Str = Func->getContext()->getStrEmit(); 2200 Ostream &Str = Func->getContext()->getStrEmit();
2207 assert(getSrcSize() == 1); 2201 assert(getSrcSize() == 1);
2208 Str << "\tmovups\t"; 2202 Str << "\tmovups\t";
2203 getSrc(0)->emit(Func);
2204 Str << ", ";
2209 getDest()->emit(Func); 2205 getDest()->emit(Func);
2210 Str << ", ";
2211 getSrc(0)->emit(Func);
2212 } 2206 }
2213 2207
2214 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { 2208 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const {
2215 assert(getSrcSize() == 1); 2209 assert(getSrcSize() == 1);
2216 assert(isVectorType(getDest()->getType())); 2210 assert(isVectorType(getDest()->getType()));
2217 const Variable *Dest = getDest(); 2211 const Variable *Dest = getDest();
2218 const Operand *Src = getSrc(0); 2212 const Operand *Src = getSrc(0);
2219 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { 2213 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = {
2220 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, 2214 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups,
2221 &x86::AssemblerX86::movups 2215 &x86::AssemblerX86::movups
2222 }; 2216 };
2223 emitIASMovlikeXMM(Func, Dest, Src, Emitter); 2217 emitIASMovlikeXMM(Func, Dest, Src, Emitter);
2224 } 2218 }
2225 2219
2226 template <> void InstX8632Movq::emit(const Cfg *Func) const { 2220 template <> void InstX8632Movq::emit(const Cfg *Func) const {
2227 Ostream &Str = Func->getContext()->getStrEmit(); 2221 Ostream &Str = Func->getContext()->getStrEmit();
2228 assert(getSrcSize() == 1); 2222 assert(getSrcSize() == 1);
2229 assert(getDest()->getType() == IceType_i64 || 2223 assert(getDest()->getType() == IceType_i64 ||
2230 getDest()->getType() == IceType_f64); 2224 getDest()->getType() == IceType_f64);
2231 Str << "\tmovq\t"; 2225 Str << "\tmovq\t";
2226 getSrc(0)->emit(Func);
2227 Str << ", ";
2232 getDest()->emit(Func); 2228 getDest()->emit(Func);
2233 Str << ", ";
2234 getSrc(0)->emit(Func);
2235 } 2229 }
2236 2230
2237 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { 2231 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const {
2238 assert(getSrcSize() == 1); 2232 assert(getSrcSize() == 1);
2239 assert(getDest()->getType() == IceType_i64 || 2233 assert(getDest()->getType() == IceType_i64 ||
2240 getDest()->getType() == IceType_f64); 2234 getDest()->getType() == IceType_f64);
2241 const Variable *Dest = getDest(); 2235 const Variable *Dest = getDest();
2242 const Operand *Src = getSrc(0); 2236 const Operand *Src = getSrc(0);
2243 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { 2237 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = {
2244 &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, &x86::AssemblerX86::movq 2238 &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, &x86::AssemblerX86::movq
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2300 2294
2301 void InstX8632Nop::dump(const Cfg *Func) const { 2295 void InstX8632Nop::dump(const Cfg *Func) const {
2302 Ostream &Str = Func->getContext()->getStrDump(); 2296 Ostream &Str = Func->getContext()->getStrDump();
2303 Str << "nop (variant = " << Variant << ")"; 2297 Str << "nop (variant = " << Variant << ")";
2304 } 2298 }
2305 2299
2306 void InstX8632Fld::emit(const Cfg *Func) const { 2300 void InstX8632Fld::emit(const Cfg *Func) const {
2307 Ostream &Str = Func->getContext()->getStrEmit(); 2301 Ostream &Str = Func->getContext()->getStrEmit();
2308 assert(getSrcSize() == 1); 2302 assert(getSrcSize() == 1);
2309 Type Ty = getSrc(0)->getType(); 2303 Type Ty = getSrc(0)->getType();
2304 SizeT Width = typeWidthInBytes(Ty);
2310 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); 2305 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0));
2311 if (Var && Var->hasReg()) { 2306 if (Var && Var->hasReg()) {
2312 // This is a physical xmm register, so we need to spill it to a 2307 // This is a physical xmm register, so we need to spill it to a
2313 // temporary stack slot. 2308 // temporary stack slot.
2314 SizeT Width = typeWidthInBytes(Ty); 2309 Str << "\tsubl\t$" << Width << ", %esp"
2315 Str << "\tsub\tesp, " << Width << "\n"; 2310 << "\n";
2316 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" 2311 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t";
2317 << TypeX8632Attributes[Ty].WidthString << " [esp], ";
2318 Var->emit(Func); 2312 Var->emit(Func);
2319 Str << "\n"; 2313 Str << ", (%esp)\n";
2320 Str << "\tfld\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 2314 Str << "\tfld" << getFldString(Ty) << "\t"
2321 Str << "\tadd\tesp, " << Width; 2315 << "(%esp)\n";
2316 Str << "\taddl\t$" << Width << ", %esp";
2322 return; 2317 return;
2323 } 2318 }
2324 Str << "\tfld\t"; 2319 Str << "\tfld" << getFldString(Ty) << "\t";
2325 getSrc(0)->emit(Func); 2320 getSrc(0)->emit(Func);
2326 } 2321 }
2327 2322
2328 void InstX8632Fld::emitIAS(const Cfg *Func) const { 2323 void InstX8632Fld::emitIAS(const Cfg *Func) const {
2329 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2324 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2330 intptr_t StartPosition = Asm->GetPosition(); 2325 intptr_t StartPosition = Asm->GetPosition();
2331 assert(getSrcSize() == 1); 2326 assert(getSrcSize() == 1);
2332 const Operand *Src = getSrc(0); 2327 const Operand *Src = getSrc(0);
2333 Type Ty = Src->getType(); 2328 Type Ty = Src->getType();
2334 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { 2329 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(); 2362 Ostream &Str = Func->getContext()->getStrEmit();
2368 assert(getSrcSize() == 0); 2363 assert(getSrcSize() == 0);
2369 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to 2364 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to
2370 // "partially" delete the fstp if the Dest is unused. 2365 // "partially" delete the fstp if the Dest is unused.
2371 // Even if Dest is unused, the fstp should be kept for the SideEffects 2366 // Even if Dest is unused, the fstp should be kept for the SideEffects
2372 // of popping the stack. 2367 // of popping the stack.
2373 if (getDest() == NULL) { 2368 if (getDest() == NULL) {
2374 Str << "\tfstp\tst(0)"; 2369 Str << "\tfstp\tst(0)";
2375 return; 2370 return;
2376 } 2371 }
2372 Type Ty = getDest()->getType();
2373 size_t Width = typeWidthInBytes(Ty);
2377 if (!getDest()->hasReg()) { 2374 if (!getDest()->hasReg()) {
2378 Str << "\tfstp\t"; 2375 Str << "\tfstp" << getFldString(Ty) << "\t";
2379 getDest()->emit(Func); 2376 getDest()->emit(Func);
2380 return; 2377 return;
2381 } 2378 }
2382 // Dest is a physical (xmm) register, so st(0) needs to go through 2379 // Dest is a physical (xmm) register, so st(0) needs to go through
2383 // memory. Hack this by creating a temporary stack slot, spilling 2380 // memory. Hack this by creating a temporary stack slot, spilling
2384 // st(0) there, loading it into the xmm register, and deallocating 2381 // st(0) there, loading it into the xmm register, and deallocating
2385 // the stack slot. 2382 // the stack slot.
2386 Type Ty = getDest()->getType(); 2383 Str << "\tsubl\t$" << Width << ", %esp\n";
2387 size_t Width = typeWidthInBytes(Ty); 2384 Str << "\tfstp" << getFldString(Ty) << "\t"
2388 Str << "\tsub\tesp, " << Width << "\n"; 2385 << "(%esp)\n";
2389 Str << "\tfstp\t" << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 2386 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"
2390 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"; 2387 << "(%esp), ";
2391 getDest()->emit(Func); 2388 getDest()->emit(Func);
2392 Str << ", " << TypeX8632Attributes[Ty].WidthString << " [esp]\n"; 2389 Str << "\n";
2393 Str << "\tadd\tesp, " << Width; 2390 Str << "\taddl\t$" << Width << ", %esp";
2394 } 2391 }
2395 2392
2396 void InstX8632Fstp::emitIAS(const Cfg *Func) const { 2393 void InstX8632Fstp::emitIAS(const Cfg *Func) const {
2397 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2394 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2398 intptr_t StartPosition = Asm->GetPosition(); 2395 intptr_t StartPosition = Asm->GetPosition();
2399 assert(getSrcSize() == 0); 2396 assert(getSrcSize() == 0);
2400 const Variable *Dest = getDest(); 2397 const Variable *Dest = getDest();
2401 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to 2398 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to
2402 // "partially" delete the fstp if the Dest is unused. 2399 // "partially" delete the fstp if the Dest is unused.
2403 // Even if Dest is unused, the fstp should be kept for the SideEffects 2400 // 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 { 2448 template <> void InstX8632Pextr::emit(const Cfg *Func) const {
2452 Ostream &Str = Func->getContext()->getStrEmit(); 2449 Ostream &Str = Func->getContext()->getStrEmit();
2453 assert(getSrcSize() == 2); 2450 assert(getSrcSize() == 2);
2454 // pextrb and pextrd are SSE4.1 instructions. 2451 // pextrb and pextrd are SSE4.1 instructions.
2455 assert(getSrc(0)->getType() == IceType_v8i16 || 2452 assert(getSrc(0)->getType() == IceType_v8i16 ||
2456 getSrc(0)->getType() == IceType_v8i1 || 2453 getSrc(0)->getType() == IceType_v8i1 ||
2457 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() 2454 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet()
2458 >= TargetX8632::SSE4_1); 2455 >= TargetX8632::SSE4_1);
2459 Str << "\t" << Opcode 2456 Str << "\t" << Opcode
2460 << TypeX8632Attributes[getSrc(0)->getType()].PackString << "\t"; 2457 << TypeX8632Attributes[getSrc(0)->getType()].PackString << "\t";
2458 getSrc(1)->emit(Func);
2459 Str << ", ";
2460 getSrc(0)->emit(Func);
2461 Str << ", ";
2461 Variable *Dest = getDest(); 2462 Variable *Dest = getDest();
2462 // pextrw must take a register dest. There is an SSE4.1 version that takes 2463 // 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 2464 // a memory dest, but we aren't using it. For uniformity, just restrict
2464 // them all to have a register dest for now. 2465 // them all to have a register dest for now.
2465 assert(Dest->hasReg()); 2466 assert(Dest->hasReg());
2466 Dest->asType(IceType_i32).emit(Func); 2467 Dest->asType(IceType_i32).emit(Func);
2467 Str << ", ";
2468 getSrc(0)->emit(Func);
2469 Str << ", ";
2470 getSrc(1)->emit(Func);
2471 } 2468 }
2472 2469
2473 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const { 2470 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const {
2474 assert(getSrcSize() == 2); 2471 assert(getSrcSize() == 2);
2475 // pextrb and pextrd are SSE4.1 instructions. 2472 // pextrb and pextrd are SSE4.1 instructions.
2476 const Variable *Dest = getDest(); 2473 const Variable *Dest = getDest();
2477 Type DispatchTy = Dest->getType(); 2474 Type DispatchTy = Dest->getType();
2478 assert(DispatchTy == IceType_i16 || 2475 assert(DispatchTy == IceType_i16 ||
2479 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 2476 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
2480 TargetX8632::SSE4_1); 2477 TargetX8632::SSE4_1);
(...skipping 14 matching lines...) Expand all
2495 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { 2492 template <> void InstX8632Pinsr::emit(const Cfg *Func) const {
2496 Ostream &Str = Func->getContext()->getStrEmit(); 2493 Ostream &Str = Func->getContext()->getStrEmit();
2497 assert(getSrcSize() == 3); 2494 assert(getSrcSize() == 3);
2498 // pinsrb and pinsrd are SSE4.1 instructions. 2495 // pinsrb and pinsrd are SSE4.1 instructions.
2499 assert(getDest()->getType() == IceType_v8i16 || 2496 assert(getDest()->getType() == IceType_v8i16 ||
2500 getDest()->getType() == IceType_v8i1 || 2497 getDest()->getType() == IceType_v8i1 ||
2501 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() 2498 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet()
2502 >= TargetX8632::SSE4_1); 2499 >= TargetX8632::SSE4_1);
2503 Str << "\t" << Opcode 2500 Str << "\t" << Opcode
2504 << TypeX8632Attributes[getDest()->getType()].PackString << "\t"; 2501 << TypeX8632Attributes[getDest()->getType()].PackString << "\t";
2505 getDest()->emit(Func); 2502 getSrc(2)->emit(Func);
2506 Str << ", "; 2503 Str << ", ";
2507 Operand *Src1 = getSrc(1); 2504 Operand *Src1 = getSrc(1);
2508 if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) { 2505 if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) {
2509 // If src1 is a register, it should always be r32. 2506 // If src1 is a register, it should always be r32.
2510 if (VSrc1->hasReg()) { 2507 if (VSrc1->hasReg()) {
2511 VSrc1->asType(IceType_i32).emit(Func); 2508 VSrc1->asType(IceType_i32).emit(Func);
2512 } else { 2509 } else {
2513 VSrc1->emit(Func); 2510 VSrc1->emit(Func);
2514 } 2511 }
2515 } else { 2512 } else {
2516 Src1->emit(Func); 2513 Src1->emit(Func);
2517 } 2514 }
2518 Str << ", "; 2515 Str << ", ";
2519 getSrc(2)->emit(Func); 2516 getDest()->emit(Func);
2520 } 2517 }
2521 2518
2522 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { 2519 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const {
2523 assert(getSrcSize() == 3); 2520 assert(getSrcSize() == 3);
2524 assert(getDest() == getSrc(0)); 2521 assert(getDest() == getSrc(0));
2525 // pinsrb and pinsrd are SSE4.1 instructions. 2522 // pinsrb and pinsrd are SSE4.1 instructions.
2526 const Operand *Src0 = getSrc(1); 2523 const Operand *Src0 = getSrc(1);
2527 Type DispatchTy = Src0->getType(); 2524 Type DispatchTy = Src0->getType();
2528 assert(DispatchTy == IceType_i16 || 2525 assert(DispatchTy == IceType_i16 ||
2529 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 2526 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2586 } 2583 }
2587 2584
2588 void InstX8632Pop::dump(const Cfg *Func) const { 2585 void InstX8632Pop::dump(const Cfg *Func) const {
2589 Ostream &Str = Func->getContext()->getStrDump(); 2586 Ostream &Str = Func->getContext()->getStrDump();
2590 dumpDest(Func); 2587 dumpDest(Func);
2591 Str << " = pop." << getDest()->getType() << " "; 2588 Str << " = pop." << getDest()->getType() << " ";
2592 } 2589 }
2593 2590
2594 void InstX8632AdjustStack::emit(const Cfg *Func) const { 2591 void InstX8632AdjustStack::emit(const Cfg *Func) const {
2595 Ostream &Str = Func->getContext()->getStrEmit(); 2592 Ostream &Str = Func->getContext()->getStrEmit();
2596 Str << "\tsub\tesp, " << Amount; 2593 Str << "\tsubl\t$" << Amount << ", %esp";
2597 Func->getTarget()->updateStackAdjustment(Amount); 2594 Func->getTarget()->updateStackAdjustment(Amount);
2598 } 2595 }
2599 2596
2600 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { 2597 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
2601 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2598 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2602 intptr_t StartPosition = Asm->GetPosition(); 2599 intptr_t StartPosition = Asm->GetPosition();
2603 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); 2600 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount));
2604 emitIASBytes(Func, Asm, StartPosition); 2601 emitIASBytes(Func, Asm, StartPosition);
2605 Func->getTarget()->updateStackAdjustment(Amount); 2602 Func->getTarget()->updateStackAdjustment(Amount);
2606 } 2603 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); 2673 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
2677 Str << "ret." << Ty << " "; 2674 Str << "ret." << Ty << " ";
2678 dumpSources(Func); 2675 dumpSources(Func);
2679 } 2676 }
2680 2677
2681 void InstX8632Xadd::emit(const Cfg *Func) const { 2678 void InstX8632Xadd::emit(const Cfg *Func) const {
2682 Ostream &Str = Func->getContext()->getStrEmit(); 2679 Ostream &Str = Func->getContext()->getStrEmit();
2683 if (Locked) { 2680 if (Locked) {
2684 Str << "\tlock"; 2681 Str << "\tlock";
2685 } 2682 }
2686 Str << "\txadd\t"; 2683 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t";
2684 getSrc(1)->emit(Func);
2685 Str << ", ";
2687 getSrc(0)->emit(Func); 2686 getSrc(0)->emit(Func);
2688 Str << ", ";
2689 getSrc(1)->emit(Func);
2690 } 2687 }
2691 2688
2692 void InstX8632Xadd::emitIAS(const Cfg *Func) const { 2689 void InstX8632Xadd::emitIAS(const Cfg *Func) const {
2693 assert(getSrcSize() == 2); 2690 assert(getSrcSize() == 2);
2694 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2691 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2695 intptr_t StartPosition = Asm->GetPosition(); 2692 intptr_t StartPosition = Asm->GetPosition();
2696 Type Ty = getSrc(0)->getType(); 2693 Type Ty = getSrc(0)->getType();
2697 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2694 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2698 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2695 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2699 const x86::Address Addr = Mem->toAsmAddress(Asm); 2696 const x86::Address Addr = Mem->toAsmAddress(Asm);
(...skipping 13 matching lines...) Expand all
2713 if (Locked) { 2710 if (Locked) {
2714 Str << "lock "; 2711 Str << "lock ";
2715 } 2712 }
2716 Type Ty = getSrc(0)->getType(); 2713 Type Ty = getSrc(0)->getType();
2717 Str << "xadd." << Ty << " "; 2714 Str << "xadd." << Ty << " ";
2718 dumpSources(Func); 2715 dumpSources(Func);
2719 } 2716 }
2720 2717
2721 void InstX8632Xchg::emit(const Cfg *Func) const { 2718 void InstX8632Xchg::emit(const Cfg *Func) const {
2722 Ostream &Str = Func->getContext()->getStrEmit(); 2719 Ostream &Str = Func->getContext()->getStrEmit();
2723 Str << "\txchg\t"; 2720 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t";
2721 getSrc(1)->emit(Func);
2722 Str << ", ";
2724 getSrc(0)->emit(Func); 2723 getSrc(0)->emit(Func);
2725 Str << ", ";
2726 getSrc(1)->emit(Func);
2727 } 2724 }
2728 2725
2729 void InstX8632Xchg::emitIAS(const Cfg *Func) const { 2726 void InstX8632Xchg::emitIAS(const Cfg *Func) const {
2730 assert(getSrcSize() == 2); 2727 assert(getSrcSize() == 2);
2731 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2728 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2732 intptr_t StartPosition = Asm->GetPosition(); 2729 intptr_t StartPosition = Asm->GetPosition();
2733 Type Ty = getSrc(0)->getType(); 2730 Type Ty = getSrc(0)->getType();
2734 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2731 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2735 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2732 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2736 const x86::Address Addr = Mem->toAsmAddress(Asm); 2733 const x86::Address Addr = Mem->toAsmAddress(Asm);
2737 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); 2734 const Variable *VarReg = llvm::cast<Variable>(getSrc(1));
2738 assert(VarReg->hasReg()); 2735 assert(VarReg->hasReg());
2739 const RegX8632::GPRRegister Reg = 2736 const RegX8632::GPRRegister Reg =
2740 RegX8632::getEncodedGPR(VarReg->getRegNum()); 2737 RegX8632::getEncodedGPR(VarReg->getRegNum());
2741 Asm->xchg(Ty, Addr, Reg); 2738 Asm->xchg(Ty, Addr, Reg);
2742 emitIASBytes(Func, Asm, StartPosition); 2739 emitIASBytes(Func, Asm, StartPosition);
2743 } 2740 }
2744 2741
2745 void InstX8632Xchg::dump(const Cfg *Func) const { 2742 void InstX8632Xchg::dump(const Cfg *Func) const {
2746 Ostream &Str = Func->getContext()->getStrDump(); 2743 Ostream &Str = Func->getContext()->getStrDump();
2747 Type Ty = getSrc(0)->getType(); 2744 Type Ty = getSrc(0)->getType();
2748 Str << "xchg." << Ty << " "; 2745 Str << "xchg." << Ty << " ";
2749 dumpSources(Func); 2746 dumpSources(Func);
2750 } 2747 }
2751 2748
2752 void OperandX8632Mem::emit(const Cfg *Func) const { 2749 void OperandX8632Mem::emit(const Cfg *Func) const {
2753 Ostream &Str = Func->getContext()->getStrEmit(); 2750 Ostream &Str = Func->getContext()->getStrEmit();
2754 Str << TypeX8632Attributes[getType()].WidthString << " ";
2755 if (SegmentReg != DefaultSegment) { 2751 if (SegmentReg != DefaultSegment) {
2756 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); 2752 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
2757 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; 2753 Str << InstX8632SegmentRegNames[SegmentReg] << ":";
2758 } 2754 }
2759 // TODO: The following is an almost verbatim paste of dump(). 2755 // Emit as Offset(Base,Index,1<<Shift).
2760 bool Dumped = false; 2756 // Offset is emitted without the leading '$'.
2761 Str << "["; 2757 // Omit the (Base,Index,1<<Shift) part if Base==NULL.
2758 if (Offset == NULL) {
2759 // No offset, emit nothing.
2760 } else if (auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
2761 if (CI->getValue())
2762 // Emit a non-zero offset without a leading '$'.
2763 Str << CI->getValue();
2764 } else if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
2765 CR->emitWithoutDollar(Func->getContext());
2766 } else {
2767 llvm_unreachable("Invalid offset type for x86 mem operand");
2768 }
2769
2762 if (Base) { 2770 if (Base) {
2771 Str << "(";
2763 Base->emit(Func); 2772 Base->emit(Func);
2764 Dumped = true; 2773 if (Index) {
2774 Str << ",";
2775 Index->emit(Func);
2776 if (Shift)
2777 Str << "," << (1u << Shift);
2778 }
2779 Str << ")";
2765 } 2780 }
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 } 2781 }
2798 2782
2799 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const { 2783 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const {
2800 if (SegmentReg != DefaultSegment) { 2784 if (SegmentReg != DefaultSegment) {
2801 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); 2785 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
2802 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; 2786 Str << InstX8632SegmentRegNames[SegmentReg] << ":";
2803 } 2787 }
2804 bool Dumped = false; 2788 bool Dumped = false;
2805 Str << "["; 2789 Str << "[";
2806 if (Base) { 2790 if (Base) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2896 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), 2880 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()),
2897 Offset); 2881 Offset);
2898 } 2882 }
2899 2883
2900 void VariableSplit::emit(const Cfg *Func) const { 2884 void VariableSplit::emit(const Cfg *Func) const {
2901 Ostream &Str = Func->getContext()->getStrEmit(); 2885 Ostream &Str = Func->getContext()->getStrEmit();
2902 assert(!Var->hasReg()); 2886 assert(!Var->hasReg());
2903 // The following is copied/adapted from TargetX8632::emitVariable(). 2887 // The following is copied/adapted from TargetX8632::emitVariable().
2904 const TargetLowering *Target = Func->getTarget(); 2888 const TargetLowering *Target = Func->getTarget();
2905 const Type Ty = IceType_i32; 2889 const Type Ty = IceType_i32;
2906 Str << TypeX8632Attributes[Ty].WidthString << " ["
2907 << Target->getRegName(Target->getFrameOrStackReg(), Ty);
2908 int32_t Offset = 2890 int32_t Offset =
2909 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); 2891 Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
2910 if (Offset) { 2892 if (Offset)
2911 if (Offset > 0)
2912 Str << "+";
2913 Str << Offset; 2893 Str << Offset;
2914 } 2894 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")";
2915 Str << "]";
2916 } 2895 }
2917 2896
2918 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { 2897 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const {
2919 switch (Part) { 2898 switch (Part) {
2920 case Low: 2899 case Low:
2921 Str << "low"; 2900 Str << "low";
2922 break; 2901 break;
2923 case High: 2902 case High:
2924 Str << "high"; 2903 Str << "high";
2925 break; 2904 break;
2926 default: 2905 default:
2927 Str << "???"; 2906 Str << "???";
2928 break; 2907 break;
2929 } 2908 }
2930 Str << "("; 2909 Str << "(";
2931 if (Func) 2910 if (Func)
2932 Var->dump(Func); 2911 Var->dump(Func);
2933 else 2912 else
2934 Var->dump(Str); 2913 Var->dump(Str);
2935 Str << ")"; 2914 Str << ")";
2936 } 2915 }
2937 2916
2938 } // end of namespace Ice 2917 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceInstX8632.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698