blob: 00a455c23e1dba571fa3700a0736ded2aafbd777 [file] [log] [blame]
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001//===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Defines X8632 specific data related to X8632 Instructions and
12/// Instruction traits.
John Porto921856d2015-07-07 11:56:26 -070013///
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080014/// These are declared in the IceTargetLoweringX8632Traits.h header file. This
15/// file also defines X8632 operand specific methods (dump and emit.)
Andrew Scull9612d322015-07-06 14:53:25 -070016///
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070017//===----------------------------------------------------------------------===//
John Porto67f8de92015-06-25 10:14:17 -070018#include "IceInstX8632.h"
19
John Portoaff4ccf2015-06-10 16:35:06 -070020#include "IceAssemblerX8632.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070021#include "IceCfg.h"
22#include "IceCfgNode.h"
Jan Voungbd385e42014-09-18 18:18:10 -070023#include "IceConditionCodesX8632.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070024#include "IceInst.h"
Jan Voungbd385e42014-09-18 18:18:10 -070025#include "IceRegistersX8632.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070026#include "IceTargetLoweringX8632.h"
27#include "IceOperand.h"
28
29namespace Ice {
30
John Porto4a566862016-01-04 09:33:41 -080031namespace X8632 {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070032
John Porto4a566862016-01-04 09:33:41 -080033const TargetX8632Traits::InstBrAttributesType
34 TargetX8632Traits::InstBrAttributes[] = {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -070035#define X(val, encode, opp, dump, emit) \
John Porto5d0acff2015-06-30 15:29:21 -070036 { X8632::Traits::Cond::opp, dump, emit } \
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070037 ,
John Porto921856d2015-07-07 11:56:26 -070038 ICEINSTX8632BR_TABLE
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070039#undef X
Jim Stichnothdd842db2015-01-27 12:53:53 -080040};
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070041
John Porto4a566862016-01-04 09:33:41 -080042const TargetX8632Traits::InstCmppsAttributesType
43 TargetX8632Traits::InstCmppsAttributes[] = {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -070044#define X(val, emit) \
Matt Walace0ca8f2014-07-24 12:34:20 -070045 { emit } \
46 ,
John Porto921856d2015-07-07 11:56:26 -070047 ICEINSTX8632CMPPS_TABLE
Matt Walace0ca8f2014-07-24 12:34:20 -070048#undef X
Jim Stichnothdd842db2015-01-27 12:53:53 -080049};
Matt Walace0ca8f2014-07-24 12:34:20 -070050
John Porto4a566862016-01-04 09:33:41 -080051const TargetX8632Traits::TypeAttributesType
52 TargetX8632Traits::TypeAttributes[] = {
Nicolas Capens7638e272016-10-06 11:33:55 -040053#define X(tag, elty, cvt, sdss, pdps, spsd, int_, unpack, pack, width, fld) \
54 { cvt, sdss, pdps, spsd, int_, unpack, pack, width, fld } \
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070055 ,
John Porto921856d2015-07-07 11:56:26 -070056 ICETYPEX8632_TABLE
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070057#undef X
Jim Stichnothdd842db2015-01-27 12:53:53 -080058};
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070059
John Porto4a566862016-01-04 09:33:41 -080060const char *TargetX8632Traits::InstSegmentRegNames[] = {
Jan Voungfe14fb82014-10-13 15:56:32 -070061#define X(val, name, prefix) name,
62 SEG_REGX8632_TABLE
63#undef X
64};
65
John Porto4a566862016-01-04 09:33:41 -080066uint8_t TargetX8632Traits::InstSegmentPrefixes[] = {
Jan Voungfe14fb82014-10-13 15:56:32 -070067#define X(val, name, prefix) prefix,
68 SEG_REGX8632_TABLE
Jan Voung3bd9f1a2014-06-18 10:50:57 -070069#undef X
70};
Jan Voung3bd9f1a2014-06-18 10:50:57 -070071
John Porto4a566862016-01-04 09:33:41 -080072void TargetX8632Traits::X86Operand::dump(const Cfg *, Ostream &Str) const {
John Porto921856d2015-07-07 11:56:26 -070073 if (BuildDefs::dump())
74 Str << "<OperandX8632>";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070075}
76
Jim Stichnoth8ff4b282016-01-04 15:39:06 -080077TargetX8632Traits::X86OperandMem::X86OperandMem(
78 Cfg *Func, Type Ty, Variable *Base, Constant *Offset, Variable *Index,
John Porto56958cb2016-01-14 09:18:18 -080079 uint16_t Shift, SegmentRegisters SegmentReg, bool IsRebased)
John Porto921856d2015-07-07 11:56:26 -070080 : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index),
John Porto56958cb2016-01-14 09:18:18 -080081 Shift(Shift), SegmentReg(SegmentReg), IsRebased(IsRebased) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070082 assert(Shift <= 3);
Jim Stichnothae953202014-12-20 06:17:49 -080083 Vars = nullptr;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070084 NumVars = 0;
85 if (Base)
86 ++NumVars;
87 if (Index)
88 ++NumVars;
89 if (NumVars) {
90 Vars = Func->allocateArrayOf<Variable *>(NumVars);
91 SizeT I = 0;
92 if (Base)
93 Vars[I++] = Base;
94 if (Index)
95 Vars[I++] = Index;
96 assert(I == NumVars);
97 }
98}
99
David Sehr2f3b8ec2015-11-16 16:51:39 -0800100namespace {
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800101
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800102int32_t getRematerializableOffset(Variable *Var,
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800103 const Ice::X8632::TargetX8632 *Target) {
David Sehr26217e32015-11-26 13:03:50 -0800104 int32_t Disp = Var->getStackOffset();
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800105 const auto RegNum = Var->getRegNum();
David Sehr26217e32015-11-26 13:03:50 -0800106 if (RegNum == Target->getFrameReg()) {
David Sehr2f3b8ec2015-11-16 16:51:39 -0800107 Disp += Target->getFrameFixedAllocaOffset();
David Sehr26217e32015-11-26 13:03:50 -0800108 } else if (RegNum != Target->getStackReg()) {
David Sehr2f3b8ec2015-11-16 16:51:39 -0800109 llvm::report_fatal_error("Unexpected rematerializable register type");
110 }
111 return Disp;
112}
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800113
114void validateMemOperandPIC(const TargetX8632Traits::X86OperandMem *Mem,
115 bool UseNonsfi) {
116 if (!BuildDefs::asserts())
117 return;
118 const bool HasCR =
119 Mem->getOffset() && llvm::isa<ConstantRelocatable>(Mem->getOffset());
120 (void)HasCR;
John Porto56958cb2016-01-14 09:18:18 -0800121 const bool IsRebased = Mem->getIsRebased();
122 (void)IsRebased;
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800123 if (UseNonsfi)
John Porto56958cb2016-01-14 09:18:18 -0800124 assert(HasCR == IsRebased);
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800125 else
John Porto56958cb2016-01-14 09:18:18 -0800126 assert(!IsRebased);
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800127}
128
David Sehr2f3b8ec2015-11-16 16:51:39 -0800129} // end of anonymous namespace
130
John Porto4a566862016-01-04 09:33:41 -0800131void TargetX8632Traits::X86OperandMem::emit(const Cfg *Func) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700132 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800133 return;
Karl Schimpfd4699942016-04-02 09:55:31 -0700134 const bool UseNonsfi = getFlags().getUseNonsfi();
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800135 validateMemOperandPIC(this, UseNonsfi);
John Porto4a566862016-01-04 09:33:41 -0800136 const auto *Target =
137 static_cast<const ::Ice::X8632::TargetX8632 *>(Func->getTarget());
David Sehr4318a412015-11-11 15:01:55 -0800138 // If the base is rematerializable, we need to replace it with the correct
139 // physical register (esp or ebp), and update the Offset.
140 int32_t Disp = 0;
141 if (getBase() && getBase()->isRematerializable()) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800142 Disp += getRematerializableOffset(getBase(), Target);
David Sehr4318a412015-11-11 15:01:55 -0800143 }
144 // The index should never be rematerializable. But if we ever allow it, then
145 // we should make sure the rematerialization offset is shifted by the Shift
146 // value.
147 if (getIndex())
148 assert(!getIndex()->isRematerializable());
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700149 Ostream &Str = Func->getContext()->getStrEmit();
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700150 if (SegmentReg != DefaultSegment) {
Jim Stichnoth5acafbc2014-07-30 15:37:39 -0700151 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
John Porto921856d2015-07-07 11:56:26 -0700152 Str << "%" << X8632::Traits::InstSegmentRegNames[SegmentReg] << ":";
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700153 }
Andrew Scull57e12682015-09-16 11:30:19 -0700154 // Emit as Offset(Base,Index,1<<Shift). Offset is emitted without the leading
155 // '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr.
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800156 if (getOffset() == nullptr && Disp == 0) {
Jim Stichnothbca2f652014-11-01 10:13:54 -0700157 // No offset, emit nothing.
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800158 } else if (getOffset() == nullptr && Disp != 0) {
David Sehr4318a412015-11-11 15:01:55 -0800159 Str << Disp;
160 } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
161 if (getBase() == nullptr || CI->getValue() || Disp != 0)
Jim Stichnothbca2f652014-11-01 10:13:54 -0700162 // Emit a non-zero offset without a leading '$'.
David Sehr4318a412015-11-11 15:01:55 -0800163 Str << CI->getValue() + Disp;
164 } else if (const auto *CR =
165 llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
166 // TODO(sehr): ConstantRelocatable still needs updating for
167 // rematerializable base/index and Disp.
168 assert(Disp == 0);
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800169 CR->emitWithoutPrefix(Target, UseNonsfi ? "@GOTOFF" : "");
Jan Voungbc004632014-09-16 15:09:10 -0700170 } else {
Jim Stichnothbca2f652014-11-01 10:13:54 -0700171 llvm_unreachable("Invalid offset type for x86 mem operand");
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700172 }
Jim Stichnothbca2f652014-11-01 10:13:54 -0700173
David Sehr4318a412015-11-11 15:01:55 -0800174 if (getBase() || getIndex()) {
Jim Stichnothbca2f652014-11-01 10:13:54 -0700175 Str << "(";
David Sehr4318a412015-11-11 15:01:55 -0800176 if (getBase())
177 getBase()->emit(Func);
178 if (getIndex()) {
Jim Stichnothbca2f652014-11-01 10:13:54 -0700179 Str << ",";
David Sehr4318a412015-11-11 15:01:55 -0800180 getIndex()->emit(Func);
181 if (getShift())
182 Str << "," << (1u << getShift());
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700183 }
Jim Stichnothbca2f652014-11-01 10:13:54 -0700184 Str << ")";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700185 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700186}
187
John Porto4a566862016-01-04 09:33:41 -0800188void TargetX8632Traits::X86OperandMem::dump(const Cfg *Func,
189 Ostream &Str) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700190 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800191 return;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700192 if (SegmentReg != DefaultSegment) {
Jim Stichnoth5acafbc2014-07-30 15:37:39 -0700193 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
John Porto921856d2015-07-07 11:56:26 -0700194 Str << X8632::Traits::InstSegmentRegNames[SegmentReg] << ":";
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700195 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700196 bool Dumped = false;
197 Str << "[";
David Sehr4318a412015-11-11 15:01:55 -0800198 int32_t Disp = 0;
John Porto4a566862016-01-04 09:33:41 -0800199 const auto *Target =
200 static_cast<const ::Ice::X8632::TargetX8632 *>(Func->getTarget());
David Sehr4318a412015-11-11 15:01:55 -0800201 if (getBase() && getBase()->isRematerializable()) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800202 Disp += getRematerializableOffset(getBase(), Target);
David Sehr4318a412015-11-11 15:01:55 -0800203 }
204 if (getBase()) {
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -0700205 if (Func)
David Sehr4318a412015-11-11 15:01:55 -0800206 getBase()->dump(Func);
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -0700207 else
David Sehr4318a412015-11-11 15:01:55 -0800208 getBase()->dump(Str);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700209 Dumped = true;
210 }
David Sehr4318a412015-11-11 15:01:55 -0800211 if (getIndex()) {
212 assert(!getIndex()->isRematerializable());
213 if (getBase())
David Sehraa0b1a12015-10-27 16:55:40 -0700214 Str << "+";
David Sehr4318a412015-11-11 15:01:55 -0800215 if (getShift() > 0)
216 Str << (1u << getShift()) << "*";
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -0700217 if (Func)
David Sehr4318a412015-11-11 15:01:55 -0800218 getIndex()->dump(Func);
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -0700219 else
David Sehr4318a412015-11-11 15:01:55 -0800220 getIndex()->dump(Str);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700221 Dumped = true;
222 }
Jim Stichnoth8099e9a2015-11-12 10:26:34 -0800223 if (Disp) {
224 if (Disp > 0)
225 Str << "+";
226 Str << Disp;
227 Dumped = true;
228 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700229 // Pretty-print the Offset.
230 bool OffsetIsZero = false;
231 bool OffsetIsNegative = false;
Jim Stichnoth8099e9a2015-11-12 10:26:34 -0800232 if (getOffset() == nullptr) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700233 OffsetIsZero = true;
David Sehr4318a412015-11-11 15:01:55 -0800234 } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
Jim Stichnoth8099e9a2015-11-12 10:26:34 -0800235 OffsetIsZero = (CI->getValue() == 0);
236 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
Jan Voungbc004632014-09-16 15:09:10 -0700237 } else {
Jim Stichnoth8099e9a2015-11-12 10:26:34 -0800238 assert(llvm::isa<ConstantRelocatable>(getOffset()));
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700239 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700240 if (Dumped) {
241 if (!OffsetIsZero) { // Suppress if Offset is known to be 0
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700242 if (!OffsetIsNegative) // Suppress if Offset is known to be negative
243 Str << "+";
David Sehr4318a412015-11-11 15:01:55 -0800244 getOffset()->dump(Func, Str);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700245 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700246 } else {
247 // There is only the offset.
David Sehr4318a412015-11-11 15:01:55 -0800248 getOffset()->dump(Func, Str);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700249 }
250 Str << "]";
251}
252
John Porto4a566862016-01-04 09:33:41 -0800253void TargetX8632Traits::X86OperandMem::emitSegmentOverride(
254 TargetX8632Traits::Assembler *Asm) const {
Jan Voungfe14fb82014-10-13 15:56:32 -0700255 if (SegmentReg != DefaultSegment) {
256 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
John Porto921856d2015-07-07 11:56:26 -0700257 Asm->emitSegmentOverride(X8632::Traits::InstSegmentPrefixes[SegmentReg]);
Jan Voungfe14fb82014-10-13 15:56:32 -0700258 }
259}
260
John Porto4a566862016-01-04 09:33:41 -0800261TargetX8632Traits::Address TargetX8632Traits::X86OperandMem::toAsmAddress(
262 TargetX8632Traits::Assembler *Asm,
John Porto56958cb2016-01-14 09:18:18 -0800263 const Ice::TargetLowering *TargetLowering, bool /*IsLeaAddr*/) const {
John Porto4a566862016-01-04 09:33:41 -0800264 const auto *Target =
265 static_cast<const ::Ice::X8632::TargetX8632 *>(TargetLowering);
Karl Schimpfd4699942016-04-02 09:55:31 -0700266 const bool UseNonsfi = getFlags().getUseNonsfi();
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800267 validateMemOperandPIC(this, UseNonsfi);
268 int32_t Disp = 0;
David Sehr4318a412015-11-11 15:01:55 -0800269 if (getBase() && getBase()->isRematerializable()) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800270 Disp += getRematerializableOffset(getBase(), Target);
David Sehr4318a412015-11-11 15:01:55 -0800271 }
272 // The index should never be rematerializable. But if we ever allow it, then
273 // we should make sure the rematerialization offset is shifted by the Shift
274 // value.
275 if (getIndex())
276 assert(!getIndex()->isRematerializable());
Jan Voung359c0362014-11-04 10:40:03 -0800277 AssemblerFixup *Fixup = nullptr;
Jan Voung8acded02014-09-22 18:02:25 -0700278 // Determine the offset (is it relocatable?)
279 if (getOffset()) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700280 if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
David Sehr4318a412015-11-11 15:01:55 -0800281 Disp += static_cast<int32_t>(CI->getValue());
Jan Voung359c0362014-11-04 10:40:03 -0800282 } else if (const auto CR =
Jan Voung8acded02014-09-22 18:02:25 -0700283 llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
David Sehr4318a412015-11-11 15:01:55 -0800284 Disp += CR->getOffset();
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800285 Fixup = Asm->createFixup(Target->getAbsFixup(), CR);
Jan Voung8acded02014-09-22 18:02:25 -0700286 } else {
287 llvm_unreachable("Unexpected offset type");
288 }
289 }
290
291 // Now convert to the various possible forms.
292 if (getBase() && getIndex()) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700293 return X8632::Traits::Address(getEncodedGPR(getBase()->getRegNum()),
294 getEncodedGPR(getIndex()->getRegNum()),
295 X8632::Traits::ScaleFactor(getShift()), Disp,
296 Fixup);
Jan Voung8acded02014-09-22 18:02:25 -0700297 } else if (getBase()) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700298 return X8632::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp,
299 Fixup);
Jan Voung8acded02014-09-22 18:02:25 -0700300 } else if (getIndex()) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700301 return X8632::Traits::Address(getEncodedGPR(getIndex()->getRegNum()),
302 X8632::Traits::ScaleFactor(getShift()), Disp,
303 Fixup);
Jan Voung8acded02014-09-22 18:02:25 -0700304 } else {
David Sehraa0b1a12015-10-27 16:55:40 -0700305 return X8632::Traits::Address(Disp, Fixup);
Jan Voung8acded02014-09-22 18:02:25 -0700306 }
307}
308
John Porto4a566862016-01-04 09:33:41 -0800309TargetX8632Traits::Address
310TargetX8632Traits::VariableSplit::toAsmAddress(const Cfg *Func) const {
Jan Voungfe14fb82014-10-13 15:56:32 -0700311 assert(!Var->hasReg());
John Porto921856d2015-07-07 11:56:26 -0700312 const ::Ice::TargetLowering *Target = Func->getTarget();
David Sehr26217e32015-11-26 13:03:50 -0800313 int32_t Offset = Var->getStackOffset() + getOffset();
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700314 return X8632::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()),
315 Offset, AssemblerFixup::NoFixup);
Jan Voungfe14fb82014-10-13 15:56:32 -0700316}
317
John Porto4a566862016-01-04 09:33:41 -0800318void TargetX8632Traits::VariableSplit::emit(const Cfg *Func) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700319 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800320 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700321 Ostream &Str = Func->getContext()->getStrEmit();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700322 assert(!Var->hasReg());
323 // The following is copied/adapted from TargetX8632::emitVariable().
John Porto921856d2015-07-07 11:56:26 -0700324 const ::Ice::TargetLowering *Target = Func->getTarget();
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700325 constexpr Type Ty = IceType_i32;
David Sehr26217e32015-11-26 13:03:50 -0800326 int32_t Offset = Var->getStackOffset() + getOffset();
Jim Stichnothbca2f652014-11-01 10:13:54 -0700327 if (Offset)
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700328 Str << Offset;
Jim Stichnothbca2f652014-11-01 10:13:54 -0700329 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700330}
331
John Porto4a566862016-01-04 09:33:41 -0800332void TargetX8632Traits::VariableSplit::dump(const Cfg *Func,
333 Ostream &Str) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700334 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800335 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700336 switch (Part) {
337 case Low:
338 Str << "low";
339 break;
340 case High:
341 Str << "high";
342 break;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700343 }
344 Str << "(";
Jim Stichnoth2e8bfbb2014-09-16 10:16:00 -0700345 if (Func)
346 Var->dump(Func);
347 else
348 Var->dump(Str);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700349 Str << ")";
350}
351
John Porto4a566862016-01-04 09:33:41 -0800352} // namespace X8632
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700353} // end of namespace Ice
John Porto921856d2015-07-07 11:56:26 -0700354
John Porto4a566862016-01-04 09:33:41 -0800355X86INSTS_DEFINE_STATIC_DATA(X8632, X8632::Traits)