Sets the stage for enabling the use of the 8-bit high registers, but doesn't yet turn it on because more work is needed for correctness.
In the lowering, typing is tightened up so that we don't specify e.g. eax when we really mean ax or al. This gets rid of the ShiftHack hack. The one exception is the pinsr instruction which always requires an r32 register even if the memory operand is m8 or m16.
The x86 assembler unit tests are fixed, by not passing a GlobalContext arg to the Assembler ctor.
Many constexpr and "auto *" upgrades are applied. Sorry for not putting this into a separate CL - a few local fixes got out of hand...
Tested in the following ways:
- "make check-lit" - some .ll CHECK line changes due to register randomization
- "make check-xtest"
- "make check-xtest" with forced filetype=asm (via local .py hack)
- spec2k with all -filetype options
- compare before-and-after spec2k filetype=asm output - a few differences where the correct narrow register is used instead of the full-width register
To do in the next CL:
1. Add new register classes:
(a) 32-bit GPR truncable to 8-bit (eax, ecx, edx, ebx)
(b) 16-bit GPR truncable to 8-bit (ax, cx, dx, bx)
(c) 8-bit truncable from 16/32-bit (al, bl, cl, dl)
(c) 8-bit "mov"able from ah/bh/ch/dh
2. Enable use of ah/bh/ch/dh for x86-32.
3. Enable use of ah (but skip bh/ch/dh) for x86-64.
4. Statically initialize register tables in the TargetLowering subclass.
BUG= none
R=jpp@chromium.org, kschimpf@google.com
Review URL: https://codereview.chromium.org/1419903002 .
diff --git a/src/IceAssembler.cpp b/src/IceAssembler.cpp
index 0228476..480eb30 100644
--- a/src/IceAssembler.cpp
+++ b/src/IceAssembler.cpp
@@ -132,7 +132,7 @@
Buffer.size());
}
-void Assembler::emitIASBytes() const {
+void Assembler::emitIASBytes(GlobalContext *Ctx) const {
Ostream &Str = Ctx->getStrEmit();
intptr_t EndPosition = Buffer.size();
intptr_t CurPosition = 0;
diff --git a/src/IceAssembler.h b/src/IceAssembler.h
index d05660f..599a0a0 100644
--- a/src/IceAssembler.h
+++ b/src/IceAssembler.h
@@ -310,7 +310,7 @@
bool needsTextFixup() const { return Buffer.needsTextFixup(); }
- void emitIASBytes() const;
+ void emitIASBytes(GlobalContext *Ctx) const;
bool getInternal() const { return IsInternal; }
void setInternal(bool Internal) { IsInternal = Internal; }
const IceString &getFunctionName() { return FunctionName; }
@@ -324,8 +324,8 @@
AssemblerKind getKind() const { return Kind; }
protected:
- explicit Assembler(AssemblerKind Kind, GlobalContext *Ctx)
- : Kind(Kind), Allocator(), Ctx(Ctx), Buffer(*this) {}
+ explicit Assembler(AssemblerKind Kind)
+ : Kind(Kind), Allocator(), Buffer(*this) {}
private:
const AssemblerKind Kind;
@@ -346,7 +346,6 @@
void installFixup(AssemblerFixup *F) { Buffer.installFixup(F); }
protected:
- GlobalContext *Ctx;
// Buffer's constructor uses the Allocator, so it needs to appear after it.
// TODO(jpp): dependencies on construction order are a nice way of shooting
// yourself in the foot. Fix this.
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index eb785ff..8fe8f43 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -223,6 +223,7 @@
namespace ARM32 {
void AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) {
+ GlobalContext *Ctx = Node->getCfg()->getContext();
if (BuildDefs::dump() && !Ctx->getFlags().getDisableHybridAssembly()) {
// Generate label name so that branches can find it.
constexpr SizeT InstSize = 0;
diff --git a/src/IceAssemblerARM32.h b/src/IceAssemblerARM32.h
index d4c58af..0b9c756 100644
--- a/src/IceAssemblerARM32.h
+++ b/src/IceAssemblerARM32.h
@@ -45,13 +45,12 @@
using IOffsetT = int32_t;
class AssemblerARM32 : public Assembler {
- AssemblerARM32() = delete;
AssemblerARM32(const AssemblerARM32 &) = delete;
AssemblerARM32 &operator=(const AssemblerARM32 &) = delete;
public:
- explicit AssemblerARM32(GlobalContext *Ctx, bool use_far_branches = false)
- : Assembler(Asm_ARM32, Ctx) {
+ explicit AssemblerARM32(bool use_far_branches = false)
+ : Assembler(Asm_ARM32) {
// TODO(kschimpf): Add mode if needed when branches are handled.
(void)use_far_branches;
}
diff --git a/src/IceAssemblerMIPS32.h b/src/IceAssemblerMIPS32.h
index 7cf3ee5..1d46b91 100644
--- a/src/IceAssemblerMIPS32.h
+++ b/src/IceAssemblerMIPS32.h
@@ -35,8 +35,8 @@
AssemblerMIPS32 &operator=(const AssemblerMIPS32 &) = delete;
public:
- explicit AssemblerMIPS32(GlobalContext *Ctx, bool use_far_branches = false)
- : Assembler(Asm_MIPS32, Ctx) {
+ explicit AssemblerMIPS32(bool use_far_branches = false)
+ : Assembler(Asm_MIPS32) {
// This mode is only needed and implemented for MIPS32 and ARM.
assert(!use_far_branches);
(void)use_far_branches;
diff --git a/src/IceAssemblerX8632.h b/src/IceAssemblerX8632.h
index 3672ecd..fb9eedf 100644
--- a/src/IceAssemblerX8632.h
+++ b/src/IceAssemblerX8632.h
@@ -45,8 +45,8 @@
AssemblerX8632 &operator=(const AssemblerX8632 &) = delete;
public:
- explicit AssemblerX8632(GlobalContext *Ctx, bool use_far_branches = false)
- : X86Internal::AssemblerX86Base<TargetX8632>(Asm_X8632, Ctx,
+ explicit AssemblerX8632(bool use_far_branches = false)
+ : X86Internal::AssemblerX86Base<TargetX8632>(Asm_X8632,
use_far_branches) {}
~AssemblerX8632() override = default;
diff --git a/src/IceAssemblerX8664.h b/src/IceAssemblerX8664.h
index 43b50be..5666810 100644
--- a/src/IceAssemblerX8664.h
+++ b/src/IceAssemblerX8664.h
@@ -45,8 +45,8 @@
AssemblerX8664 &operator=(const AssemblerX8664 &) = delete;
public:
- explicit AssemblerX8664(GlobalContext *Ctx, bool use_far_branches = false)
- : X86Internal::AssemblerX86Base<TargetX8664>(Asm_X8664, Ctx,
+ explicit AssemblerX8664(bool use_far_branches = false)
+ : X86Internal::AssemblerX86Base<TargetX8664>(Asm_X8664,
use_far_branches) {}
~AssemblerX8664() override = default;
diff --git a/src/IceAssemblerX86Base.h b/src/IceAssemblerX86Base.h
index a7db6ef..3823f0d 100644
--- a/src/IceAssemblerX86Base.h
+++ b/src/IceAssemblerX86Base.h
@@ -115,9 +115,8 @@
AssemblerX86Base &operator=(const AssemblerX86Base &) = delete;
protected:
- AssemblerX86Base(AssemblerKind Kind, GlobalContext *Ctx,
- bool use_far_branches)
- : Assembler(Kind, Ctx) {
+ AssemblerX86Base(AssemblerKind Kind, bool use_far_branches)
+ : Assembler(Kind) {
// This mode is only needed and implemented for MIPS and ARM.
assert(!use_far_branches);
(void)use_far_branches;
diff --git a/src/IceBrowserCompileServer.cpp b/src/IceBrowserCompileServer.cpp
index 4d5705f..94b991a 100644
--- a/src/IceBrowserCompileServer.cpp
+++ b/src/IceBrowserCompileServer.cpp
@@ -94,8 +94,8 @@
std::unique_ptr<llvm::raw_fd_ostream> getOutputStream(int FD) {
if (FD <= 0)
llvm::report_fatal_error("Invalid output FD");
- const bool CloseOnDtor = true;
- const bool Unbuffered = false;
+ constexpr bool CloseOnDtor = true;
+ constexpr bool Unbuffered = false;
return std::unique_ptr<llvm::raw_fd_ostream>(
new llvm::raw_fd_ostream(FD, CloseOnDtor, Unbuffered));
}
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index a1c4b5f..57b1e73 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -198,7 +198,7 @@
// Create the Hi and Lo variables where a split was needed
for (Variable *Var : Variables)
- if (auto Var64On32 = llvm::dyn_cast<Variable64On32>(Var))
+ if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Var))
Var64On32->initHiLo(this);
// Figure out which alloca instructions result in storage at known stack frame
@@ -607,7 +607,7 @@
if (Variable *Dest = Inst.getDest()) {
if (!Dest->getIgnoreLiveness()) {
bool Invalid = false;
- const bool IsDest = true;
+ constexpr bool IsDest = true;
if (!Dest->getLiveRange().containsValue(InstNumber, IsDest))
Invalid = true;
// Check that this instruction actually *begins* Dest's live range,
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
index 71a0384..f9fa29d 100644
--- a/src/IceCfgNode.cpp
+++ b/src/IceCfgNode.cpp
@@ -130,7 +130,7 @@
// transformation preserves SSA form.
void CfgNode::placePhiLoads() {
for (Inst &I : Phis) {
- auto Phi = llvm::dyn_cast<InstPhi>(&I);
+ auto *Phi = llvm::dyn_cast<InstPhi>(&I);
Insts.insert(Insts.begin(), Phi->lower(Func));
}
}
@@ -222,7 +222,7 @@
for (CfgNode *Succ : OutEdges) {
// Consider every Phi instruction at the out-edge.
for (Inst &I : Succ->Phis) {
- auto Phi = llvm::dyn_cast<InstPhi>(&I);
+ auto *Phi = llvm::dyn_cast<InstPhi>(&I);
Operand *Operand = Phi->getOperandForTarget(this);
assert(Operand);
Variable *Dest = I.getDest();
@@ -303,7 +303,7 @@
const Operand *Opnd) {
if (Var1 == Opnd)
return true;
- const auto Var2 = llvm::dyn_cast<Variable>(Opnd);
+ const auto *Var2 = llvm::dyn_cast<Variable>(Opnd);
if (Var2 == nullptr)
return false;
@@ -459,7 +459,7 @@
int32_t Weight = 0;
if (Desc[I].NumPred == 0)
Weight += WeightNoPreds;
- if (auto Var = llvm::dyn_cast<Variable>(Desc[I].Src))
+ if (auto *Var = llvm::dyn_cast<Variable>(Desc[I].Src))
if (Var->hasReg())
Weight += WeightSrcIsReg;
if (!Desc[I].Dest->hasReg())
@@ -517,7 +517,7 @@
Split->appendInst(InstAssign::create(Func, Dest, Src));
// Update NumPred for all Phi assignments using this Phi's Src as their
// Dest variable. Also update Weight if NumPred dropped from 1 to 0.
- if (auto Var = llvm::dyn_cast<Variable>(Src)) {
+ if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
for (size_t I = 0; I < NumPhis; ++I) {
if (Desc[I].Processed)
continue;
@@ -634,7 +634,7 @@
for (Inst &I : Succ->Phis) {
if (I.isDeleted())
continue;
- auto Phi = llvm::dyn_cast<InstPhi>(&I);
+ auto *Phi = llvm::dyn_cast<InstPhi>(&I);
Phi->livenessPhiOperand(Live, this, Liveness);
}
}
diff --git a/src/IceCfgNode.h b/src/IceCfgNode.h
index 14eafa9..dbc2cce 100644
--- a/src/IceCfgNode.h
+++ b/src/IceCfgNode.h
@@ -31,6 +31,8 @@
return new (Func->allocate<CfgNode>()) CfgNode(Func, LabelIndex);
}
+ Cfg *getCfg() const { return Func; }
+
/// Access the label number and name for this node.
SizeT getIndex() const { return Number; }
void resetIndex(SizeT NewNumber) { Number = NewNumber; }
diff --git a/src/IceCompiler.cpp b/src/IceCompiler.cpp
index b4b6c89..fdd9756 100644
--- a/src/IceCompiler.cpp
+++ b/src/IceCompiler.cpp
@@ -181,7 +181,7 @@
Ctx.dumpTimers();
if (Ctx.getFlags().getTimeEachFunction()) {
- const bool DumpCumulative = false;
+ constexpr bool DumpCumulative = false;
Ctx.dumpTimers(GlobalContext::TSK_Funcs, DumpCumulative);
}
constexpr bool FinalStats = true;
diff --git a/src/IceConditionCodesX8632.h b/src/IceConditionCodesX8632.h
index eb09687..e17bf69 100644
--- a/src/IceConditionCodesX8632.h
+++ b/src/IceConditionCodesX8632.h
@@ -29,7 +29,7 @@
/// An enum of condition codes used for branches and cmov. The enum value
/// should match the value used to encode operands in binary instructions.
enum BrCond {
-#define X(tag, encode, opp, dump, emit) tag encode,
+#define X(val, encode, opp, dump, emit) val = encode,
ICEINSTX8632BR_TABLE
#undef X
Br_None
@@ -39,7 +39,7 @@
/// value should match the value used to encode operands in binary
/// instructions.
enum CmppsCond {
-#define X(tag, emit) tag,
+#define X(val, emit) val,
ICEINSTX8632CMPPS_TABLE
#undef X
Cmpps_Invalid
diff --git a/src/IceConditionCodesX8664.h b/src/IceConditionCodesX8664.h
index d1d9dd8..1875beb 100644
--- a/src/IceConditionCodesX8664.h
+++ b/src/IceConditionCodesX8664.h
@@ -25,7 +25,7 @@
/// An enum of condition codes used for branches and cmov. The enum value
/// should match the value used to encode operands in binary instructions.
enum BrCond {
-#define X(tag, encode, opp, dump, emit) tag encode,
+#define X(val, encode, opp, dump, emit) val = encode,
ICEINSTX8664BR_TABLE
#undef X
Br_None
@@ -35,7 +35,7 @@
/// value should match the value used to encode operands in binary
/// instructions.
enum CmppsCond {
-#define X(tag, emit) tag,
+#define X(val, emit) val,
ICEINSTX8664CMPPS_TABLE
#undef X
Cmpps_Invalid
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp
index a84ae2c..89fa2e3 100644
--- a/src/IceConverter.cpp
+++ b/src/IceConverter.cpp
@@ -668,8 +668,8 @@
// declaration.
void addGlobalInitializer(Ice::VariableDeclaration &Global,
const Constant *Initializer) {
- const bool HasOffset = false;
- const Ice::RelocOffsetT Offset = 0;
+ constexpr bool HasOffset = false;
+ constexpr Ice::RelocOffsetT Offset = 0;
addGlobalInitializer(Global, Initializer, HasOffset, Offset);
}
diff --git a/src/IceELFObjectWriter.cpp b/src/IceELFObjectWriter.cpp
index 202ab0e..2ea97d7 100644
--- a/src/IceELFObjectWriter.cpp
+++ b/src/IceELFObjectWriter.cpp
@@ -115,7 +115,7 @@
const Elf64_Xword ShEntSize = ELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel);
static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8,
"Elf_Rel/Rela sizes cannot be derived from sizeof");
- const Elf64_Xword ShFlags = 0;
+ constexpr Elf64_Xword ShFlags = 0;
ELFRelocationSection *RelSection = createSection<ELFRelocationSection>(
RelSectionName, ShType, ShFlags, ShAlign, ShEntSize);
RelSection->setRelatedSection(RelatedSection);
@@ -218,7 +218,7 @@
IceString SectionName = ".text";
if (FunctionSections)
SectionName += "." + FuncName;
- const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR;
+ constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR;
const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes();
Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags,
ShAlign, 0);
@@ -322,12 +322,12 @@
Elf64_Xword Align = Var->getAlignment();
ShAddralign = std::max(ShAddralign, Align);
}
- const Elf64_Xword ShEntsize = 0; // non-uniform data element size.
+ constexpr Elf64_Xword ShEntsize = 0; // non-uniform data element size.
// Lift this out, so it can be re-used if we do fdata-sections?
switch (ST) {
case ROData: {
const IceString SectionName = MangleSectionName(".rodata", SectionSuffix);
- const Elf64_Xword ShFlags = SHF_ALLOC;
+ constexpr Elf64_Xword ShFlags = SHF_ALLOC;
Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags,
ShAddralign, ShEntsize);
Section->setFileOffset(alignFileOffset(ShAddralign));
@@ -338,7 +338,7 @@
}
case Data: {
const IceString SectionName = MangleSectionName(".data", SectionSuffix);
- const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE;
+ constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE;
Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags,
ShAddralign, ShEntsize);
Section->setFileOffset(alignFileOffset(ShAddralign));
@@ -349,7 +349,7 @@
}
case BSS: {
const IceString SectionName = MangleSectionName(".bss", SectionSuffix);
- const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE;
+ constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE;
Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags,
ShAddralign, ShEntsize);
Section->setFileOffset(alignFileOffset(ShAddralign));
@@ -361,14 +361,14 @@
break;
}
- const uint8_t SymbolType = STT_OBJECT;
+ constexpr uint8_t SymbolType = STT_OBJECT;
for (VariableDeclaration *Var : Vars) {
// If the variable declaration does not have an initializer, its symtab
// entry will be created separately.
if (!Var->hasInitializer())
continue;
Elf64_Xword Align = Var->getAlignment();
- const Elf64_Xword MinAlign = 1;
+ constexpr Elf64_Xword MinAlign = 1;
Align = std::max(Align, MinAlign);
Section->padToAlignment(Str, Align);
SizeT SymbolSize = Var->getNumBytes();
@@ -405,7 +405,7 @@
AssemblerFixup NewFixup;
NewFixup.set_position(Section->getCurrentSize());
NewFixup.set_kind(RelocationKind);
- const bool SuppressMangling = true;
+ constexpr bool SuppressMangling = true;
NewFixup.set_value(Ctx.getConstantSym(
Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx),
SuppressMangling));
@@ -422,9 +422,9 @@
void ELFObjectWriter::writeInitialELFHeader() {
assert(!SectionNumbersAssigned);
- const Elf64_Off DummySHOffset = 0;
- const SizeT DummySHStrIndex = 0;
- const SizeT DummyNumSections = 0;
+ constexpr Elf64_Off DummySHOffset = 0;
+ constexpr SizeT DummySHStrIndex = 0;
+ constexpr SizeT DummyNumSections = 0;
if (ELF64) {
writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex,
DummyNumSections);
@@ -445,7 +445,7 @@
Str.write8(ELFDATA2LSB);
Str.write8(EV_CURRENT);
Str.write8(ELFOSABI_NONE);
- const uint8_t ELF_ABIVersion = 0;
+ constexpr uint8_t ELF_ABIVersion = 0;
Str.write8(ELF_ABIVersion);
Str.writeZeroPadding(EI_NIDENT - EI_PAD);
@@ -495,7 +495,7 @@
// Assume that writing WriteAmt bytes at a time allows us to avoid aligning
// between entries.
assert(WriteAmt % Align == 0);
- const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE;
+ constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE;
std::string SecBuffer;
llvm::raw_string_ostream SecStrBuf(SecBuffer);
SecStrBuf << ".rodata.cst" << WriteAmt;
@@ -505,7 +505,7 @@
SizeT OffsetInSection = 0;
// The symbol table entry doesn't need to know the defined symbol's size
// since this is in a section with a fixed Entry Size.
- const SizeT SymbolSize = 0;
+ constexpr SizeT SymbolSize = 0;
Section->setFileOffset(alignFileOffset(Align));
// If the -reorder-pooled-constant option is set to true, we should shuffle
@@ -523,7 +523,7 @@
for (Constant *C : Pool) {
if (!C->getShouldBePooled())
continue;
- auto Const = llvm::cast<ConstType>(C);
+ auto *Const = llvm::cast<ConstType>(C);
std::string SymBuffer;
llvm::raw_string_ostream SymStrBuf(SymBuffer);
Const->emitPoolLabel(SymStrBuf, &Ctx);
@@ -572,7 +572,7 @@
RelSection = createRelocationSection(Section);
RelRODataSections.push_back(RelSection);
- const uint8_t SymbolType = STT_OBJECT;
+ constexpr uint8_t SymbolType = STT_OBJECT;
Section->padToAlignment(Str, PointerSize);
bool IsExternal = Ctx.getFlags().getDisableInternal();
const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL;
@@ -596,7 +596,7 @@
void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) {
for (const Constant *S : UndefSyms) {
- const auto Sym = llvm::cast<ConstantRelocatable>(S);
+ const auto *Sym = llvm::cast<ConstantRelocatable>(S);
const IceString &Name = Sym->getName();
bool BadIntrinsic;
const Intrinsics::FullIntrinsicInfo *Info =
diff --git a/src/IceFixups.cpp b/src/IceFixups.cpp
index ddc7979..305e695 100644
--- a/src/IceFixups.cpp
+++ b/src/IceFixups.cpp
@@ -24,7 +24,7 @@
RelocOffsetT AssemblerFixup::offset() const {
if (isNullSymbol())
return 0;
- if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(value_))
+ if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(value_))
return CR->getOffset();
return 0;
}
@@ -34,7 +34,7 @@
llvm::raw_string_ostream Str(Buffer);
const Constant *C = value_;
assert(!isNullSymbol());
- if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(C)) {
+ if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(C)) {
if (CR->getSuppressMangling())
Str << CR->getName();
else
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index 7b54feb..be3d443 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -110,8 +110,8 @@
ValueType, typename std::enable_if<
std::is_same<ValueType, ConstantRelocatable>::value>::type> {
bool operator()(const Constant *Const1, const Constant *Const2) const {
- auto V1 = llvm::cast<ValueType>(Const1);
- auto V2 = llvm::cast<ValueType>(Const2);
+ auto *V1 = llvm::cast<ValueType>(Const1);
+ auto *V2 = llvm::cast<ValueType>(Const2);
if (V1->getName() == V2->getName())
return V1->getOffset() < V2->getOffset();
return V1->getName() < V2->getName();
@@ -519,7 +519,7 @@
case FT_Iasm: {
OstreamLocker L(this);
Cfg::emitTextHeader(MangledName, this, Asm.get());
- Asm->emitIASBytes();
+ Asm->emitIASBytes(this);
} break;
case FT_Asm:
llvm::report_fatal_error("Unexpected FT_Asm");
@@ -783,8 +783,8 @@
}
Constant *GlobalContext::getConstantExternSym(const IceString &Name) {
- const RelocOffsetT Offset = 0;
- const bool SuppressMangling = true;
+ constexpr RelocOffsetT Offset = 0;
+ constexpr bool SuppressMangling = true;
return getConstPool()->ExternRelocatables.getOrAdd(
this, RelocatableTuple(Offset, Name, SuppressMangling));
}
diff --git a/src/IceInst.h b/src/IceInst.h
index abd8144..5e32904 100644
--- a/src/IceInst.h
+++ b/src/IceInst.h
@@ -382,8 +382,8 @@
/// Set HasSideEffects to true so that the call instruction can't be
/// dead-code eliminated. IntrinsicCalls can override this if the particular
/// intrinsic is deletable and has no side-effects.
- const bool HasSideEffects = true;
- const InstKind Kind = Inst::Call;
+ constexpr bool HasSideEffects = true;
+ constexpr InstKind Kind = Inst::Call;
return new (Func->allocate<InstCall>()) InstCall(
Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind);
}
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
index d2cd6ef..a3c7c1d 100644
--- a/src/IceInstARM32.cpp
+++ b/src/IceInstARM32.cpp
@@ -890,7 +890,7 @@
getDest()->emit(Func);
Str << ", ";
Constant *Src0 = llvm::cast<Constant>(getSrc(0));
- if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) {
+ if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) {
Str << "#:lower16:";
CR->emitWithoutPrefix(Func->getTarget());
} else {
@@ -908,7 +908,7 @@
Str << "\t" << Opcode << getPredicate() << "\t";
Dest->emit(Func);
Str << ", ";
- if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) {
+ if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) {
Str << "#:upper16:";
CR->emitWithoutPrefix(Func->getTarget());
} else {
diff --git a/src/IceInstARM32.def b/src/IceInstARM32.def
index 0ceb4a4..291a64a 100644
--- a/src/IceInstARM32.def
+++ b/src/IceInstARM32.def
@@ -14,6 +14,8 @@
#ifndef SUBZERO_SRC_ICEINSTARM32_DEF
#define SUBZERO_SRC_ICEINSTARM32_DEF
+#include "IceRegList.h"
+
// NOTE: PC and SP are not considered isInt, to avoid register allocating.
//
// For the NaCl sandbox we also need to r9 (and the r8-r9 pair) for TLS, so
@@ -27,58 +29,25 @@
// technically preserved, but save/restore is handled separately, based on
// whether or not the function MaybeLeafFunc.
-// ALIASESn is a family of macros that we use to define register aliasing in
-// ARM32. n indicates how many aliases are being provided to the macro. It
-// assumes the parameters are register names declared in a namespace/class
-// named RegARM32.
-#define ALIASES1(r0) \
- {RegARM32::r0}
-#define ALIASES2(r0, r1) \
- {RegARM32::r0, RegARM32::r1}
-#define ALIASES3(r0, r1, r2) \
- {RegARM32::r0, RegARM32::r1, RegARM32::r2}
-#define ALIASES4(r0, r1, r2, r3) \
- {RegARM32::r0, RegARM32::r1, RegARM32::r2, RegARM32::r3}
-#define ALIASES7(r0, r1, r2, r3, r4, r5, r6) \
- {RegARM32::r0, RegARM32::r1, RegARM32::r2, RegARM32::r3, RegARM32::r4, \
- RegARM32::r5,RegARM32::r6}
-
-
#define REGARM32_GPR_TABLE \
- /* val, encode, name, scratch, preserved, stackptr, frameptr, \
- isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init */ \
- X(Reg_r0, 0, "r0", 1, 0, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r0, Reg_r0r1)) \
- X(Reg_r1, 1, "r1", 1, 0, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r1, Reg_r0r1)) \
- X(Reg_r2, 2, "r2", 1, 0, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r2, Reg_r2r3)) \
- X(Reg_r3, 3, "r3", 1, 0, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r3, Reg_r2r3)) \
- X(Reg_r4, 4, "r4", 0, 1, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r4, Reg_r4r5)) \
- X(Reg_r5, 5, "r5", 0, 1, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r5, Reg_r4r5)) \
- X(Reg_r6, 6, "r6", 0, 1, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r6, Reg_r6r7)) \
- X(Reg_r7, 7, "r7", 0, 1, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r7, Reg_r6r7)) \
- X(Reg_r8, 8, "r8", 0, 1, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r8, Reg_r8r9)) \
- X(Reg_r9, 9, "r9", 0, 1, 0, 0, 0, 0, 0, 0, 0, \
- ALIASES2(Reg_r9, Reg_r8r9)) \
- X(Reg_r10, 10, "r10", 0, 1, 0, 0, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_r10, Reg_r10fp)) \
- X(Reg_fp, 11, "fp", 0, 1, 0, 1, 1, 0, 0, 0, 0, \
- ALIASES2(Reg_fp, Reg_r10fp)) \
- X(Reg_ip, 12, "ip", 1, 0, 0, 0, 0, 0, 0, 0, 0, \
- ALIASES1(Reg_ip)) \
- X(Reg_sp, 13, "sp", 0, 0, 1, 0, 0, 0, 0, 0, 0, \
- ALIASES1(Reg_sp)) \
- X(Reg_lr, 14, "lr", 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- ALIASES1(Reg_lr)) \
- X(Reg_pc, 15, "pc", 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- ALIASES1(Reg_pc))
+ /* val, encode, name, scratch,preserved,stackptr,frameptr, \
+ isInt,isI64Pair,isFP32,isFP64,isVec128, alias_init */ \
+ X(Reg_r0, 0, "r0", 1,0,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r0r1)) \
+ X(Reg_r1, 1, "r1", 1,0,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r0r1)) \
+ X(Reg_r2, 2, "r2", 1,0,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r2r3)) \
+ X(Reg_r3, 3, "r3", 1,0,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r2r3)) \
+ X(Reg_r4, 4, "r4", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r4r5)) \
+ X(Reg_r5, 5, "r5", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r4r5)) \
+ X(Reg_r6, 6, "r6", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r6r7)) \
+ X(Reg_r7, 7, "r7", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r6r7)) \
+ X(Reg_r8, 8, "r8", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r8r9)) \
+ X(Reg_r9, 9, "r9", 0,1,0,0, 0,0,0,0,0, REGLIST1(RegARM32, r8r9)) \
+ X(Reg_r10, 10, "r10", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r10fp)) \
+ X(Reg_fp, 11, "fp", 0,1,0,1, 1,0,0,0,0, REGLIST1(RegARM32, r10fp)) \
+ X(Reg_ip, 12, "ip", 1,0,0,0, 0,0,0,0,0, REGLIST1(RegARM32, ip)) \
+ X(Reg_sp, 13, "sp", 0,0,1,0, 0,0,0,0,0, REGLIST1(RegARM32, sp)) \
+ X(Reg_lr, 14, "lr", 0,0,0,0, 0,0,0,0,0, REGLIST1(RegARM32, lr)) \
+ X(Reg_pc, 15, "pc", 0,0,0,0, 0,0,0,0,0, REGLIST1(RegARM32, pc))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)
@@ -88,20 +57,14 @@
// is preserved, then we mark the whole pair as preserved to help the register
// allocator.
#define REGARM32_I64PAIR_TABLE \
- /* val, encode, name, scratch, preserved, stackptr, frameptr, \
- isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init */ \
- X(Reg_r0r1, 0, "r0, r1", 1, 0, 0, 0, 0, 1, 0, 0, 0, \
- ALIASES3(Reg_r0, Reg_r1, Reg_r0r1)) \
- X(Reg_r2r3, 2, "r2, r3", 1, 0, 0, 0, 0, 1, 0, 0, 0, \
- ALIASES3(Reg_r2, Reg_r3, Reg_r2r3)) \
- X(Reg_r4r5, 4, "r4, r5", 0, 1, 0, 0, 0, 1, 0, 0, 0, \
- ALIASES3(Reg_r4, Reg_r5, Reg_r4r5)) \
- X(Reg_r6r7, 6, "r6, r7", 0, 1, 0, 0, 0, 1, 0, 0, 0, \
- ALIASES3(Reg_r6, Reg_r7, Reg_r6r7)) \
- X(Reg_r8r9, 8, "r8, r9", 0, 1, 0, 0, 0, 0, 0, 0, 0, \
- ALIASES3(Reg_r8, Reg_r9, Reg_r8r9)) \
- X(Reg_r10fp, 10, "r10, fp", 0, 1, 0, 0, 0, 0, 0, 0, 0, \
- ALIASES3(Reg_r10, Reg_fp, Reg_r10fp)) \
+ /* val, encode, name, scratch,preserved,stackptr,frameptr, \
+ isInt,isI64Pair,isFP32,isFP64,isVec128, alias_init */ \
+ X(Reg_r0r1, 0, "r0, r1", 1,0,0,0, 0,1,0,0,0, REGLIST2(RegARM32, r0, r1)) \
+ X(Reg_r2r3, 2, "r2, r3", 1,0,0,0, 0,1,0,0,0, REGLIST2(RegARM32, r2, r3)) \
+ X(Reg_r4r5, 4, "r4, r5", 0,1,0,0, 0,1,0,0,0, REGLIST2(RegARM32, r4, r5)) \
+ X(Reg_r6r7, 6, "r6, r7", 0,1,0,0, 0,1,0,0,0, REGLIST2(RegARM32, r6, r7)) \
+ X(Reg_r8r9, 8, "r8, r9", 0,1,0,0, 0,0,0,0,0, REGLIST2(RegARM32, r8, r9)) \
+ X(Reg_r10fp, 10, "r10, fp", 0,1,0,0, 0,0,0,0,0, REGLIST2(RegARM32, r10, fp))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)
@@ -114,80 +77,48 @@
// is_preserved = 1 if i >= 16 else 0
// print (' X(Reg_s{regnum:<2}, {regnum:<2}, "s{regnum}", ' +
// '{scratch}, {preserved}, 0, 0, 0, 0, 1, 0, 0, ' +
-// 'ALIASES(Reg_s{regnum_s:<2}, Reg_d{regnum:<2}, ' +
-// 'Reg_q{regnum_q:<2})) \\').format(
+// 'REGLIST2(RegARM32, d{regnum:<2}, ' +
+// 'q{regnum_q:<2})) \\').format(
// regnum=i, regnum_d=i>>1,
// regnum_q=i>>2, scratch=is_scratch, preserved=is_preserved)
//
// print_sregs()
//
#define REGARM32_FP32_TABLE \
- /* val, encode, name, scratch, preserved, stackptr, frameptr, \
- isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init */ \
- X(Reg_s0 , 0 , "s0" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s0 , Reg_d0 , Reg_q0)) \
- X(Reg_s1 , 1 , "s1" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s1 , Reg_d0 , Reg_q0)) \
- X(Reg_s2 , 2 , "s2" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s2 , Reg_d1 , Reg_q0)) \
- X(Reg_s3 , 3 , "s3" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s3 , Reg_d1 , Reg_q0)) \
- X(Reg_s4 , 4 , "s4" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s4 , Reg_d2 , Reg_q1)) \
- X(Reg_s5 , 5 , "s5" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s5 , Reg_d2 , Reg_q1)) \
- X(Reg_s6 , 6 , "s6" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s6 , Reg_d3 , Reg_q1)) \
- X(Reg_s7 , 7 , "s7" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s7 , Reg_d3 , Reg_q1)) \
- X(Reg_s8 , 8 , "s8" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s8 , Reg_d4 , Reg_q2)) \
- X(Reg_s9 , 9 , "s9" , 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s9 , Reg_d4 , Reg_q2)) \
- X(Reg_s10, 10, "s10", 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s10, Reg_d5 , Reg_q2)) \
- X(Reg_s11, 11, "s11", 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s11, Reg_d5 , Reg_q2)) \
- X(Reg_s12, 12, "s12", 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s12, Reg_d6 , Reg_q3)) \
- X(Reg_s13, 13, "s13", 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s13, Reg_d6 , Reg_q3)) \
- X(Reg_s14, 14, "s14", 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s14, Reg_d7 , Reg_q3)) \
- X(Reg_s15, 15, "s15", 1, 0, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s15, Reg_d7 , Reg_q3)) \
- X(Reg_s16, 16, "s16", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s16, Reg_d8 , Reg_q4)) \
- X(Reg_s17, 17, "s17", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s17, Reg_d8 , Reg_q4)) \
- X(Reg_s18, 18, "s18", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s18, Reg_d9 , Reg_q4)) \
- X(Reg_s19, 19, "s19", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s19, Reg_d9 , Reg_q4)) \
- X(Reg_s20, 20, "s20", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s20, Reg_d10, Reg_q5)) \
- X(Reg_s21, 21, "s21", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s21, Reg_d10, Reg_q5)) \
- X(Reg_s22, 22, "s22", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s22, Reg_d11, Reg_q5)) \
- X(Reg_s23, 23, "s23", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s23, Reg_d11, Reg_q5)) \
- X(Reg_s24, 24, "s24", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s24, Reg_d12, Reg_q6)) \
- X(Reg_s25, 25, "s25", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s25, Reg_d12, Reg_q6)) \
- X(Reg_s26, 26, "s26", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s26, Reg_d13, Reg_q6)) \
- X(Reg_s27, 27, "s27", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s27, Reg_d13, Reg_q6)) \
- X(Reg_s28, 28, "s28", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s28, Reg_d14, Reg_q7)) \
- X(Reg_s29, 29, "s29", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s29, Reg_d14, Reg_q7)) \
- X(Reg_s30, 30, "s30", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s30, Reg_d15, Reg_q7)) \
- X(Reg_s31, 31, "s31", 0, 1, 0, 0, 0, 0, 1, 0, 0, \
- ALIASES3(Reg_s31, Reg_d15, Reg_q7))
+ /* val, encode, name, scratch,preserved,stackptr,frameptr, \
+ isInt,isI64Pair,isFP32,isFP64,isVec128, alias_init */ \
+ X(Reg_s0, 0, "s0", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d0, q0)) \
+ X(Reg_s1, 1, "s1", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d0, q0)) \
+ X(Reg_s2, 2, "s2", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d1, q0)) \
+ X(Reg_s3, 3, "s3", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d1, q0)) \
+ X(Reg_s4, 4, "s4", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d2, q1)) \
+ X(Reg_s5, 5, "s5", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d2, q1)) \
+ X(Reg_s6, 6, "s6", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d3, q1)) \
+ X(Reg_s7, 7, "s7", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d3, q1)) \
+ X(Reg_s8, 8, "s8", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d4, q2)) \
+ X(Reg_s9, 9, "s9", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d4, q2)) \
+ X(Reg_s10, 10, "s10", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d5, q2)) \
+ X(Reg_s11, 11, "s11", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d5, q2)) \
+ X(Reg_s12, 12, "s12", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d6, q3)) \
+ X(Reg_s13, 13, "s13", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d6, q3)) \
+ X(Reg_s14, 14, "s14", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d7, q3)) \
+ X(Reg_s15, 15, "s15", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d7, q3)) \
+ X(Reg_s16, 16, "s16", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d8, q4)) \
+ X(Reg_s17, 17, "s17", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d8, q4)) \
+ X(Reg_s18, 18, "s18", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d9, q4)) \
+ X(Reg_s19, 19, "s19", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d9, q4)) \
+ X(Reg_s20, 20, "s20", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d10, q5)) \
+ X(Reg_s21, 21, "s21", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d10, q5)) \
+ X(Reg_s22, 22, "s22", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d11, q5)) \
+ X(Reg_s23, 23, "s23", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d11, q5)) \
+ X(Reg_s24, 24, "s24", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d12, q6)) \
+ X(Reg_s25, 25, "s25", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d12, q6)) \
+ X(Reg_s26, 26, "s26", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d13, q6)) \
+ X(Reg_s27, 27, "s27", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d13, q6)) \
+ X(Reg_s28, 28, "s28", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d14, q7)) \
+ X(Reg_s29, 29, "s29", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d14, q7)) \
+ X(Reg_s30, 30, "s30", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d15, q7)) \
+ X(Reg_s31, 31, "s31", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d15, q7))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32,isFP64, isVec128, alias_init)
@@ -205,7 +136,7 @@
// is_preserved = 1 if (8 <= i and i < 16) else 0
// print (' X(Reg_d{regnum:<2}, {regnum:<2}, "d{regnum}", ' +
// '{scratch}, {preserved}, 0, 0, 0, 0, 0, 1, 0, ' +
-// 'ALIASES(Reg_d{regnum:<2}, Reg_q{regnum_q:<2}) \\').format(
+// 'REGLIST1(RegARM32, q{regnum_q:<2}) \\').format(
// regnum=i, regnum_q=i>>1, scratch=is_scratch,
// preserved=is_preserved)
// for i in xrange(15, -1, -1):
@@ -213,80 +144,48 @@
// is_preserved = 1 if (8 <= i and i < 16) else 0
// print (' X(Reg_d{regnum:<2}, {regnum:<2}, "d{regnum}", ' +
// '{scratch}, {preserved}, 0, 0, 0, 0, 0, 1, 0, ' +
-// 'ALIASES(Reg_s{regnum_s0:<2}, Reg_s{regnum_s1:<2}, ' +
-// 'Reg_d{regnum:<2}, Reg_q{regnum_q:<2})) \\').format(
+// 'REGLIST3(RegARM32, s{regnum_s0:<2}, s{regnum_s1:<2}, ' +
+// 'q{regnum_q:<2})) \\').format(
// regnum_s0 = (i<<1), regnum_s1 = (i<<1) + 1, regnum=i,
// regnum_q=i>>1, scratch=is_scratch, preserved=is_preserved)
//
// print_dregs()
//
#define REGARM32_FP64_TABLE \
- /* val, encode, name, scratch, preserved, stackptr, frameptr, \
- isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init */ \
- X(Reg_d31, 31, "d31", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d31, Reg_q15)) \
- X(Reg_d30, 30, "d30", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d30, Reg_q15)) \
- X(Reg_d29, 29, "d29", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d29, Reg_q14)) \
- X(Reg_d28, 28, "d28", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d28, Reg_q14)) \
- X(Reg_d27, 27, "d27", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d27, Reg_q13)) \
- X(Reg_d26, 26, "d26", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d26, Reg_q13)) \
- X(Reg_d25, 25, "d25", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d25, Reg_q12)) \
- X(Reg_d24, 24, "d24", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d24, Reg_q12)) \
- X(Reg_d23, 23, "d23", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d23, Reg_q11)) \
- X(Reg_d22, 22, "d22", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d22, Reg_q11)) \
- X(Reg_d21, 21, "d21", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d21, Reg_q10)) \
- X(Reg_d20, 20, "d20", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d20, Reg_q10)) \
- X(Reg_d19, 19, "d19", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d19, Reg_q9)) \
- X(Reg_d18, 18, "d18", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d18, Reg_q9)) \
- X(Reg_d17, 17, "d17", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d17, Reg_q8)) \
- X(Reg_d16, 16, "d16", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES2(Reg_d16, Reg_q8)) \
- X(Reg_d15, 15, "d15", 0, 1, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s30, Reg_s31, Reg_d15, Reg_q7)) \
- X(Reg_d14, 14, "d14", 0, 1, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s28, Reg_s29, Reg_d14, Reg_q7)) \
- X(Reg_d13, 13, "d13", 0, 1, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s26, Reg_s27, Reg_d13, Reg_q6)) \
- X(Reg_d12, 12, "d12", 0, 1, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s24, Reg_s25, Reg_d12, Reg_q6)) \
- X(Reg_d11, 11, "d11", 0, 1, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s22, Reg_s23, Reg_d11, Reg_q5)) \
- X(Reg_d10, 10, "d10", 0, 1, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s20, Reg_s21, Reg_d10, Reg_q5)) \
- X(Reg_d9 , 9 , "d9", 0, 1, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s18, Reg_s19, Reg_d9 , Reg_q4)) \
- X(Reg_d8 , 8 , "d8", 0, 1, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s16, Reg_s17, Reg_d8 , Reg_q4)) \
- X(Reg_d7 , 7 , "d7", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s14, Reg_s15, Reg_d7 , Reg_q3)) \
- X(Reg_d6 , 6 , "d6", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s12, Reg_s13, Reg_d6 , Reg_q3)) \
- X(Reg_d5 , 5 , "d5", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s10, Reg_s11, Reg_d5 , Reg_q2)) \
- X(Reg_d4 , 4 , "d4", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s8 , Reg_s9 , Reg_d4 , Reg_q2)) \
- X(Reg_d3 , 3 , "d3", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s6 , Reg_s7 , Reg_d3 , Reg_q1)) \
- X(Reg_d2 , 2 , "d2", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s4 , Reg_s5 , Reg_d2 , Reg_q1)) \
- X(Reg_d1 , 1 , "d1", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s2 , Reg_s3 , Reg_d1 , Reg_q0)) \
- X(Reg_d0 , 0 , "d0", 1, 0, 0, 0, 0, 0, 0, 1, 0, \
- ALIASES4(Reg_s0 , Reg_s1 , Reg_d0 , Reg_q0))
+ /* val, encode, name, scratch,preserved,stackptr,frameptr, \
+ isInt,isI64Pair,isFP32,isFP64,isVec128, alias_init */ \
+ X(Reg_d31, 31, "d31", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q15)) \
+ X(Reg_d30, 30, "d30", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q15)) \
+ X(Reg_d29, 29, "d29", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q14)) \
+ X(Reg_d28, 28, "d28", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q14)) \
+ X(Reg_d27, 27, "d27", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q13)) \
+ X(Reg_d26, 26, "d26", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q13)) \
+ X(Reg_d25, 25, "d25", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q12)) \
+ X(Reg_d24, 24, "d24", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q12)) \
+ X(Reg_d23, 23, "d23", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q11)) \
+ X(Reg_d22, 22, "d22", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q11)) \
+ X(Reg_d21, 21, "d21", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q10)) \
+ X(Reg_d20, 20, "d20", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q10)) \
+ X(Reg_d19, 19, "d19", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q9)) \
+ X(Reg_d18, 18, "d18", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q9)) \
+ X(Reg_d17, 17, "d17", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q8)) \
+ X(Reg_d16, 16, "d16", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q8)) \
+ X(Reg_d15, 15, "d15", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s30, s31, q7)) \
+ X(Reg_d14, 14, "d14", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s28, s29, q7)) \
+ X(Reg_d13, 13, "d13", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s26, s27, q6)) \
+ X(Reg_d12, 12, "d12", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s24, s25, q6)) \
+ X(Reg_d11, 11, "d11", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s22, s23, q5)) \
+ X(Reg_d10, 10, "d10", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s20, s21, q5)) \
+ X(Reg_d9, 9, "d9", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s18, s19, q4)) \
+ X(Reg_d8, 8, "d8", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s16, s17, q4)) \
+ X(Reg_d7, 7, "d7", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s14, s15, q3)) \
+ X(Reg_d6, 6, "d6", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s12, s13, q3)) \
+ X(Reg_d5, 5, "d5", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s10, s11, q2)) \
+ X(Reg_d4, 4, "d4", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s8, s9, q2)) \
+ X(Reg_d3, 3, "d3", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s6, s7, q1)) \
+ X(Reg_d2, 2, "d2", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s4, s5, q1)) \
+ X(Reg_d1, 1, "d1", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s2, s3, q0)) \
+ X(Reg_d0, 0, "d0", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s0, s1, q0))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)
@@ -300,20 +199,18 @@
// is_scratch = 1 if (i < 4 or i >= 8) else 0
// is_preserved = 1 if (4 <= i and i < 8) else 0
// print (' X(Reg_q{regnum:<2}, {regnum:<2}, "q{regnum}", ' +
-// '{scratch}, {preserved}, 0, 0, 0, 0, 0, 0, 1, ALIASES(' +
-// 'Reg_d{regnum_d0:<2}, Reg_d{regnum_d1:<2}, ' +
-// 'Reg_q{regnum:<2})) \\').format(
+// '{scratch}, {preserved}, 0, 0, 0, 0, 0, 0, 1, REGLIST2(' +
+// 'RegARM32, d{regnum_d0:<2}, d{regnum_d1:<2})) \\').format(
// regnum_d0=(i<<1), regnum_d1=(i<<1)+1, regnum=i,
// scratch=is_scratch, preserved=is_preserved)
// for i in xrange(7, -1, -1):
// is_scratch = 1 if (i < 4 or i >= 8) else 0
// is_preserved = 1 if (4 <= i and i < 8) else 0
// print (' X(Reg_q{regnum:<2}, {regnum:<2}, "q{regnum}", ' +
-// '{scratch}, {preserved}, 0, 0, 0, 0, 0, 0, 1, ALIASES(' +
-// 'Reg_s{regnum_s0:<2}, Reg_s{regnum_s1:<2}, ' +
-// 'Reg_s{regnum_s2:<2}, Reg_s{regnum_s3:<2}, ' +
-// 'Reg_d{regnum_d0:<2}, Reg_d{regnum_d1:<2}, ' +
-// 'Reg_q{regnum:<2})) \\').format(
+// '{scratch}, {preserved}, 0, 0, 0, 0, 0, 0, 1, REGLIST6(' +
+// 'RegARM32, s{regnum_s0:<2}, s{regnum_s1:<2}, ' +
+// 's{regnum_s2:<2}, s{regnum_s3:<2}, ' +
+// 'd{regnum_d0:<2}, d{regnum_d1:<2})) \\').format(
// regnum_s0=(i<<2), regnum_s1=(i<<2)+1, regnum_s2=(i<<2)+2,
// regnum_s3=(i<<2)+3, regnum_d0=(i<<1), regnum_d1=(i<<1)+1,
// regnum=i, scratch=is_scratch, preserved=is_preserved)
@@ -324,37 +221,37 @@
/* val, encode, name, scratch, preserved, stackptr, frameptr, \
isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init */ \
X(Reg_q15, 15, "q15", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES3(Reg_d30, Reg_d31, Reg_q15)) \
+ REGLIST2(RegARM32, d30, d31)) \
X(Reg_q14, 14, "q14", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES3(Reg_d28, Reg_d29, Reg_q14)) \
+ REGLIST2(RegARM32, d28, d29)) \
X(Reg_q13, 13, "q13", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES3(Reg_d26, Reg_d27, Reg_q13)) \
+ REGLIST2(RegARM32, d26, d27)) \
X(Reg_q12, 12, "q12", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES3(Reg_d24, Reg_d25, Reg_q12)) \
+ REGLIST2(RegARM32, d24, d25)) \
X(Reg_q11, 11, "q11", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES3(Reg_d22, Reg_d23, Reg_q11)) \
+ REGLIST2(RegARM32, d22, d23)) \
X(Reg_q10, 10, "q10", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES3(Reg_d20, Reg_d21, Reg_q10)) \
- X(Reg_q9 , 9 , "q9", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES3(Reg_d18, Reg_d19, Reg_q9)) \
- X(Reg_q8 , 8 , "q8", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES3(Reg_d16, Reg_d17, Reg_q8)) \
- X(Reg_q7 , 7 , "q7", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES7(Reg_s28, Reg_s29, Reg_s30, Reg_s31, Reg_d14, Reg_d15, Reg_q7)) \
- X(Reg_q6 , 6 , "q6", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES7(Reg_s24, Reg_s25, Reg_s26, Reg_s27, Reg_d12, Reg_d13, Reg_q6)) \
- X(Reg_q5 , 5 , "q5", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES7(Reg_s20, Reg_s21, Reg_s22, Reg_s23, Reg_d10, Reg_d11, Reg_q5)) \
- X(Reg_q4 , 4 , "q4", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES7(Reg_s16, Reg_s17, Reg_s18, Reg_s19, Reg_d8 , Reg_d9 , Reg_q4)) \
- X(Reg_q3 , 3 , "q3", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES7(Reg_s12, Reg_s13, Reg_s14, Reg_s15, Reg_d6 , Reg_d7 , Reg_q3)) \
- X(Reg_q2 , 2 , "q2", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES7(Reg_s8 , Reg_s9 , Reg_s10, Reg_s11, Reg_d4 , Reg_d5 , Reg_q2)) \
- X(Reg_q1 , 1 , "q1", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES7(Reg_s4 , Reg_s5 , Reg_s6 , Reg_s7 , Reg_d2 , Reg_d3 , Reg_q1)) \
- X(Reg_q0 , 0 , "q0", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
- ALIASES7(Reg_s0 , Reg_s1 , Reg_s2 , Reg_s3 , Reg_d0 , Reg_d1 , Reg_q0))
+ REGLIST2(RegARM32, d20, d21)) \
+ X(Reg_q9, 9, "q9", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST2(RegARM32, d18, d19)) \
+ X(Reg_q8, 8, "q8", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST2(RegARM32, d16, d17)) \
+ X(Reg_q7, 7, "q7", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST6(RegARM32, s28, s29, s30, s31, d14, d15)) \
+ X(Reg_q6, 6, "q6", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST6(RegARM32, s24, s25, s26, s27, d12, d13)) \
+ X(Reg_q5, 5, "q5", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST6(RegARM32, s20, s21, s22, s23, d10, d11)) \
+ X(Reg_q4, 4, "q4", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST6(RegARM32, s16, s17, s18, s19, d8, d9)) \
+ X(Reg_q3, 3, "q3", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST6(RegARM32, s12, s13, s14, s15, d6, d7)) \
+ X(Reg_q2, 2, "q2", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST6(RegARM32, s8, s9, s10, s11, d4, d5)) \
+ X(Reg_q1, 1, "q1", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST6(RegARM32, s4, s5, s6, s7, d2, d3)) \
+ X(Reg_q0, 0, "q0", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
+ REGLIST6(RegARM32, s0, s1, s2, s3, d0, d1))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)
@@ -425,21 +322,21 @@
// is 1, but corresponds to Z = 0.
#define ICEINSTARM32COND_TABLE \
/* enum value, encoding, opposite, emit */ \
- X(EQ, 0 , NE, "eq") /* equal */ \
- X(NE, 1 , EQ, "ne") /* not equal */ \
- X(CS, 2 , CC, "cs") /* carry set/unsigned (AKA hs: higher or same) */ \
- X(CC, 3 , CS, "cc") /* carry clear/unsigned (AKA lo: lower) */ \
- X(MI, 4 , PL, "mi") /* minus/negative */ \
- X(PL, 5 , MI, "pl") /* plus/positive or zero */ \
- X(VS, 6 , VC, "vs") /* overflow (float unordered) */ \
- X(VC, 7 , VS, "vc") /* no overflow (float not unordered) */ \
- X(HI, 8 , LS, "hi") /* unsigned higher */ \
- X(LS, 9 , HI, "ls") /* unsigned lower or same */ \
- X(GE, 10, LT, "ge") /* signed greater than or equal */ \
- X(LT, 11, GE, "lt") /* signed less than */ \
- X(GT, 12, LE, "gt") /* signed greater than */ \
- X(LE, 13, GT, "le") /* signed less than or equal */ \
- X(AL, 14, kNone, "") /* always (unconditional) */ \
+ X(EQ, 0, NE, "eq") /* equal */ \
+ X(NE, 1, EQ, "ne") /* not equal */ \
+ X(CS, 2, CC, "cs") /* carry set/unsigned (AKA hs: higher or same) */ \
+ X(CC, 3, CS, "cc") /* carry clear/unsigned (AKA lo: lower) */ \
+ X(MI, 4, PL, "mi") /* minus/negative */ \
+ X(PL, 5, MI, "pl") /* plus/positive or zero */ \
+ X(VS, 6, VC, "vs") /* overflow (float unordered) */ \
+ X(VC, 7, VS, "vc") /* no overflow (float not unordered) */ \
+ X(HI, 8, LS, "hi") /* unsigned higher */ \
+ X(LS, 9, HI, "ls") /* unsigned lower or same */ \
+ X(GE, 10, LT, "ge") /* signed greater than or equal */ \
+ X(LT, 11, GE, "lt") /* signed less than */ \
+ X(GT, 12, LE, "gt") /* signed greater than */ \
+ X(LE, 13, GT, "le") /* signed less than or equal */ \
+ X(AL, 14, kNone, "") /* always (unconditional) */ \
X(kNone, 15, kNone, "??") /* special condition / none */
//#define X(tag, encode, opp, emit)
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index 0837eef..b4e5972 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -32,7 +32,7 @@
const MachineTraits<TargetX8632>::InstBrAttributesType
MachineTraits<TargetX8632>::InstBrAttributes[] = {
-#define X(tag, encode, opp, dump, emit) \
+#define X(val, encode, opp, dump, emit) \
{ X8632::Traits::Cond::opp, dump, emit } \
,
ICEINSTX8632BR_TABLE
@@ -41,7 +41,7 @@
const MachineTraits<TargetX8632>::InstCmppsAttributesType
MachineTraits<TargetX8632>::InstCmppsAttributes[] = {
-#define X(tag, emit) \
+#define X(val, emit) \
{ emit } \
,
ICEINSTX8632CMPPS_TABLE
@@ -110,11 +110,11 @@
// '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr.
if (!Offset) {
// No offset, emit nothing.
- } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
+ } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
if (Base == nullptr || CI->getValue())
// Emit a non-zero offset without a leading '$'.
Str << CI->getValue();
- } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
+ } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
CR->emitWithoutPrefix(Func->getTarget());
} else {
llvm_unreachable("Invalid offset type for x86 mem operand");
@@ -167,7 +167,7 @@
bool OffsetIsNegative = false;
if (!Offset) {
OffsetIsZero = true;
- } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
+ } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
OffsetIsZero = (CI->getValue() == 0);
OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
} else {
@@ -201,7 +201,7 @@
AssemblerFixup *Fixup = nullptr;
// Determine the offset (is it relocatable?)
if (getOffset()) {
- if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
+ if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
Disp = static_cast<int32_t>(CI->getValue());
} else if (const auto CR =
llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
@@ -214,17 +214,17 @@
// Now convert to the various possible forms.
if (getBase() && getIndex()) {
- return X8632::Traits::Address(
- RegX8632::getEncodedGPR(getBase()->getRegNum()),
- RegX8632::getEncodedGPR(getIndex()->getRegNum()),
- X8632::Traits::ScaleFactor(getShift()), Disp, Fixup);
+ return X8632::Traits::Address(getEncodedGPR(getBase()->getRegNum()),
+ getEncodedGPR(getIndex()->getRegNum()),
+ X8632::Traits::ScaleFactor(getShift()), Disp,
+ Fixup);
} else if (getBase()) {
- return X8632::Traits::Address(
- RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp, Fixup);
+ return X8632::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp,
+ Fixup);
} else if (getIndex()) {
- return X8632::Traits::Address(
- RegX8632::getEncodedGPR(getIndex()->getRegNum()),
- X8632::Traits::ScaleFactor(getShift()), Disp, Fixup);
+ return X8632::Traits::Address(getEncodedGPR(getIndex()->getRegNum()),
+ X8632::Traits::ScaleFactor(getShift()), Disp,
+ Fixup);
} else {
return X8632::Traits::Address(Disp, Fixup);
}
@@ -236,9 +236,8 @@
const ::Ice::TargetLowering *Target = Func->getTarget();
int32_t Offset =
Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
- return X8632::Traits::Address(
- RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), Offset,
- AssemblerFixup::NoFixup);
+ return X8632::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()),
+ Offset, AssemblerFixup::NoFixup);
}
void MachineTraits<TargetX8632>::VariableSplit::emit(const Cfg *Func) const {
@@ -248,7 +247,7 @@
assert(!Var->hasReg());
// The following is copied/adapted from TargetX8632::emitVariable().
const ::Ice::TargetLowering *Target = Func->getTarget();
- const Type Ty = IceType_i32;
+ constexpr Type Ty = IceType_i32;
int32_t Offset =
Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
if (Offset)
diff --git a/src/IceInstX8632.def b/src/IceInstX8632.def
index 44310d7..dd70082 100644
--- a/src/IceInstX8632.def
+++ b/src/IceInstX8632.def
@@ -15,136 +15,219 @@
#ifndef SUBZERO_SRC_ICEINSTX8632_DEF
#define SUBZERO_SRC_ICEINSTX8632_DEF
-// NOTE: esp is not considered isInt, to avoid register allocating it.
-#define REGX8632_GPR_TABLE \
- /* val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP */ \
- X(Reg_eax, 0, "eax", "ax", "al", 1, 0, 0, 0, 1, 1, 0) \
- X(Reg_ecx, 1, "ecx", "cx", "cl", 1, 0, 0, 0, 1, 1, 0) \
- X(Reg_edx, 2, "edx", "dx", "dl", 1, 0, 0, 0, 1, 1, 0) \
- X(Reg_ebx, 3, "ebx", "bx", "bl", 0, 1, 0, 0, 1, 1, 0) \
- X(Reg_esp, 4, "esp", "sp", "" , 0, 0, 1, 0, 0, 0, 0) \
- X(Reg_ebp, 5, "ebp", "bp", "" , 0, 1, 0, 1, 0, 1, 0) \
- X(Reg_esi, 6, "esi", "si", "" , 0, 1, 0, 0, 0, 1, 0) \
- X(Reg_edi, 7, "edi", "di", "" , 0, 1, 0, 0, 0, 1, 0)
+#include "IceRegList.h"
-#define REGX8632_XMM_TABLE \
- X(Reg_xmm0, 0, "xmm0", "" , "" , 1, 0, 0, 0, 0, 0, 1) \
- X(Reg_xmm1, 1, "xmm1", "" , "" , 1, 0, 0, 0, 0, 0, 1) \
- X(Reg_xmm2, 2, "xmm2", "" , "" , 1, 0, 0, 0, 0, 0, 1) \
- X(Reg_xmm3, 3, "xmm3", "" , "" , 1, 0, 0, 0, 0, 0, 1) \
- X(Reg_xmm4, 4, "xmm4", "" , "" , 1, 0, 0, 0, 0, 0, 1) \
- X(Reg_xmm5, 5, "xmm5", "" , "" , 1, 0, 0, 0, 0, 0, 1) \
- X(Reg_xmm6, 6, "xmm6", "" , "" , 1, 0, 0, 0, 0, 0, 1) \
- X(Reg_xmm7, 7, "xmm7", "" , "" , 1, 0, 0, 0, 0, 0, 1) \
-//#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,
-// frameptr, isI8, isInt, isFP)
+// x86-32 ABI:
+// Scratch GPRs: eax, ecx, edx
+// Callee-save GPRs: ebx, ebp, esi, edi
+// Scratch XMMs: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
+// Key to table columns:
+// val: Enum value, when a specific register is needed during lowering.
+// encode: Encoding in the integrated assembler.
+// name: Name used for the external assembler.
+// scratch: Scratch (caller-save) register.
+// preserved: Preserved (callee-save) register.
+// stackptr: This register is used as the stack pointer.
+// frameptr: This register is used as the frame pointer if needed.
+// isGPR: This is a GPR (integer-type).
+// is64: This is a 64-bit GPR.
+// is32: This is a 32-bit GPR.
+// is16: This is a 16-bit GPR.
+// is8: This is an 8-bit GPR.
+// isXmm: This is an XMM register for FP and vector ops.
+// is64To8: A 64-bit GPR truncable to 8-bit.
+// is32To8: A 32-bit GPR truncable to 8-bit.
+// is16To8: A 16-bit GPR truncable to 8-bit.
+// isTrunc8Rcvr: An 8-bit GPR that a wider GPR trivially truncates to.
+// isAhRcvr: An 8-bit GPR that register "ah" can be assigned to.
+// aliases: List of register aliases, which need not include this register.
+#define REGX8632_BYTEREG_TABLE \
+ /* val, encode, name, base, scratch,preserved,stackptr,frameptr, \
+ isGPR,is64,is32,is16,is8, isXmm, \
+ is64To8,is32To8,is16To8,isTrunc8Rcvr,isAhRcvr, aliases */ \
+ /* 8-bit registers */ \
+ X(Reg_al, 0, "al", Reg_eax, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,1, \
+ REGLIST2(RegX8632, eax, ax)) \
+ X(Reg_cl, 1, "cl", Reg_ecx, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,1, \
+ REGLIST2(RegX8632, ecx, cx)) \
+ X(Reg_dl, 2, "dl", Reg_edx, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,1, \
+ REGLIST2(RegX8632, edx, dx)) \
+ X(Reg_bl, 3, "bl", Reg_ebx, 0,1,0,0, 1,0,0,0,1, 0, 0,0,0,1,1, \
+ REGLIST2(RegX8632, ebx, bx)) \
+ /* High 8-bit registers */ \
+ X(Reg_ah, 4, "ah", Reg_eax, 1,0,0,0, 1,0,0,0,0, 0, 0,0,0,0,1, \
+ REGLIST2(RegX8632, eax, ax)) \
+ X(Reg_ch, 5, "ch", Reg_ecx, 1,0,0,0, 1,0,0,0,0, 0, 0,0,0,0,1, \
+ REGLIST2(RegX8632, ecx, cx)) \
+ X(Reg_dh, 6, "dh", Reg_edx, 1,0,0,0, 1,0,0,0,0, 0, 0,0,0,0,1, \
+ REGLIST2(RegX8632, edx, dx)) \
+ X(Reg_bh, 7, "bh", Reg_ebx, 0,1,0,0, 1,0,0,0,0, 0, 0,0,0,0,1, \
+ REGLIST2(RegX8632, ebx, bx)) \
+ /* End of 8-bit register set */
+//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
+// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
+// isTrunc8Rcvr, isAhRcvr, aliases)
+
+#define REGX8632_GPR_TABLE \
+ /* val, encode, name, base, scratch,preserved,stackptr,frameptr, \
+ isGPR,is64,is32,is16,is8, isXmm, \
+ is64To8,is32To8,is16To8,isTrunc8Rcvr,isAhRcvr, aliases */ \
+ /* 32-bit registers */ \
+ X(Reg_eax, 0, "eax", Reg_eax, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8632, ax, al, ah)) \
+ X(Reg_ecx, 1, "ecx", Reg_ecx, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8632, cx, cl, ch)) \
+ X(Reg_edx, 2, "edx", Reg_edx, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8632, dx, dl, dh)) \
+ X(Reg_ebx, 3, "ebx", Reg_ebx, 0,1,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8632, bx, bl, bh)) \
+ X(Reg_esp, 4, "esp", Reg_esp, 0,0,1,0, 1,0,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST1(RegX8632, sp)) \
+ X(Reg_ebp, 5, "ebp", Reg_ebp, 0,1,0,1, 1,0,1,0,0, 0, 0,0,0,0,0, \
+ REGLIST1(RegX8632, bp)) \
+ X(Reg_esi, 6, "esi", Reg_esi, 0,1,0,0, 1,0,1,0,0, 0, 0,0,0,0,0, \
+ REGLIST1(RegX8632, si)) \
+ X(Reg_edi, 7, "edi", Reg_edi, 0,1,0,0, 1,0,1,0,0, 0, 0,0,0,0,0, \
+ REGLIST1(RegX8632, di)) \
+ /* 16-bit registers */ \
+ X(Reg_ax, 0, "ax", Reg_eax, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8632, eax, al, ah)) \
+ X(Reg_cx, 1, "cx", Reg_ecx, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8632, ecx, cl, ch)) \
+ X(Reg_dx, 2, "dx", Reg_edx, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8632, edx, dl, dh)) \
+ X(Reg_bx, 3, "bx", Reg_ebx, 0,1,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8632, ebx, bl, bh)) \
+ X(Reg_sp, 4, "sp", Reg_esp, 0,0,1,0, 1,0,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST1(RegX8632, esp)) \
+ X(Reg_bp, 5, "bp", Reg_ebp, 0,1,0,1, 1,0,0,1,0, 0, 0,0,0,0,0, \
+ REGLIST1(RegX8632, ebp)) \
+ X(Reg_si, 6, "si", Reg_esi, 0,1,0,0, 1,0,0,1,0, 0, 0,0,0,0,0, \
+ REGLIST1(RegX8632, esi)) \
+ X(Reg_di, 7, "di", Reg_edi, 0,1,0,0, 1,0,0,1,0, 0, 0,0,0,0,0, \
+ REGLIST1(RegX8632, edi)) \
+ /* 8-bit registers */ \
+ REGX8632_BYTEREG_TABLE \
+ /* End of GPR register set */
+//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
+// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
+// isTrunc8Rcvr, isAhRcvr, aliases)
+
+// Note: It would be more appropriate to list the xmm register aliases as
+// REGLIST0(), but the corresponding empty initializer gives a syntax error, so
+// we use REGLIST1() to redundantly assign the register itself as an alias.
+#define REGX8632_XMM_TABLE \
+ /* val, encode, name, base, scratch,preserved,stackptr,frameptr, \
+ isGPR,is64,is32,is16,is8, isXmm, \
+ is64To8,is32To8,is16To8,isTrunc8Rcvr,isAhRcvr, aliases */ \
+ /* xmm registers */ \
+ X(Reg_xmm0, 0, "xmm0", Reg_xmm0, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8632, xmm0)) \
+ X(Reg_xmm1, 1, "xmm1", Reg_xmm1, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8632, xmm1)) \
+ X(Reg_xmm2, 2, "xmm2", Reg_xmm2, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8632, xmm2)) \
+ X(Reg_xmm3, 3, "xmm3", Reg_xmm3, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8632, xmm3)) \
+ X(Reg_xmm4, 4, "xmm4", Reg_xmm4, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8632, xmm4)) \
+ X(Reg_xmm5, 5, "xmm5", Reg_xmm5, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8632, xmm5)) \
+ X(Reg_xmm6, 6, "xmm6", Reg_xmm6, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8632, xmm6)) \
+ X(Reg_xmm7, 7, "xmm7", Reg_xmm7, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8632, xmm7)) \
+ /* End of xmm register set */
+//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
+// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
+// isTrunc8Rcvr, isAhRcvr, aliases)
// We also provide a combined table, so that there is a namespace where
// all of the registers are considered and have distinct numberings.
// This is in contrast to the above, where the "encode" is based on how
// the register numbers will be encoded in binaries and values can overlap.
-#define REGX8632_TABLE \
- /* val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP */ \
- REGX8632_GPR_TABLE \
+#define REGX8632_TABLE \
+ REGX8632_GPR_TABLE \
REGX8632_XMM_TABLE
-//#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,
-// frameptr, isI8, isInt, isFP)
-
-#define REGX8632_TABLE_BOUNDS \
- /* val, init */ \
- X(Reg_GPR_First, = Reg_eax) \
- X(Reg_GPR_Last, = Reg_edi) \
- X(Reg_XMM_First, = Reg_xmm0) \
- X(Reg_XMM_Last, = Reg_xmm7) \
-//define X(val, init)
-
-// We also need the encodings for the Byte registers (other info overlaps
-// what is in the REGX8632_GPR_TABLE).
-#define REGX8632_BYTEREG_TABLE \
- /* val, encode */ \
- X(Reg_al, = 0) \
- X(Reg_cl, = 1) \
- X(Reg_dl, = 2) \
- X(Reg_bl, = 3)
-//#define X(val, encode)
+//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
+// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
+// isTrunc8Rcvr, isAhRcvr, aliases)
// X86 segment registers.
-#define SEG_REGX8632_TABLE \
- /* enum value, name, prefix */ \
- X(SegReg_CS, "cs", 0x2E) \
- X(SegReg_DS, "ds", 0x3E) \
- X(SegReg_ES, "es", 0x26) \
- X(SegReg_SS, "ss", 0x36) \
- X(SegReg_FS, "fs", 0x64) \
- X(SegReg_GS, "gs", 0x65) \
+#define SEG_REGX8632_TABLE \
+ /* val, name, prefix */ \
+ X(SegReg_CS, "cs", 0x2E) \
+ X(SegReg_DS, "ds", 0x3E) \
+ X(SegReg_ES, "es", 0x26) \
+ X(SegReg_SS, "ss", 0x36) \
+ X(SegReg_FS, "fs", 0x64) \
+ X(SegReg_GS, "gs", 0x65)
//#define X(val, name, prefix)
// X87 ST(n) registers.
-#define X87ST_REGX8632_TABLE \
- /* enum value, encode, name */ \
- X(X87ST_First, = 0, "st(0)") \
- X(X87ST_0, = 0, "st(0)") \
- X(X87ST_1, = 1, "st(1)") \
- X(X87ST_2, = 2, "st(2)") \
- X(X87ST_3, = 3, "st(3)") \
- X(X87ST_4, = 4, "st(4)") \
- X(X87ST_5, = 5, "st(5)") \
- X(X87ST_6, = 6, "st(6)") \
- X(X87ST_7, = 7, "st(7)") \
- X(X87ST_Last, = 7, "st(7)") \
+#define X87ST_REGX8632_TABLE \
+ /* val, encode, name */ \
+ X(X87ST_First, 0, "st(0)") \
+ X(X87ST_0, 0, "st(0)") \
+ X(X87ST_1, 1, "st(1)") \
+ X(X87ST_2, 2, "st(2)") \
+ X(X87ST_3, 3, "st(3)") \
+ X(X87ST_4, 4, "st(4)") \
+ X(X87ST_5, 5, "st(5)") \
+ X(X87ST_6, 6, "st(6)") \
+ X(X87ST_7, 7, "st(7)") \
+ X(X87ST_Last, 7, "st(7)")
//#define X(val, encode, name)
-#define ICEINSTX8632BR_TABLE \
- /* enum value, encode, opposite, dump, emit */ \
- X(Br_o, = 0, Br_no, "o", "jo") \
- X(Br_no, = 1, Br_o, "no", "jno") \
- X(Br_b, = 2, Br_ae, "b", "jb") \
- X(Br_ae, = 3, Br_b, "ae", "jae") \
- X(Br_e, = 4, Br_ne, "e", "je") \
- X(Br_ne, = 5, Br_e, "ne", "jne") \
- X(Br_be, = 6, Br_a, "be", "jbe") \
- X(Br_a, = 7, Br_be, "a", "ja") \
- X(Br_s, = 8, Br_ns, "s", "js") \
- X(Br_ns, = 9, Br_s, "ns", "jns") \
- X(Br_p, = 10, Br_np, "p", "jp") \
- X(Br_np, = 11, Br_p, "np", "jnp") \
- X(Br_l, = 12, Br_ge, "l", "jl") \
- X(Br_ge, = 13, Br_l, "ge", "jge") \
- X(Br_le, = 14, Br_g, "le", "jle") \
- X(Br_g, = 15, Br_le, "g", "jg") \
-//#define X(tag, encode, opp, dump, emit)
+#define ICEINSTX8632BR_TABLE \
+ /* val, encode, opposite, dump, emit */ \
+ X(Br_o, 0, Br_no, "o", "jo") \
+ X(Br_no, 1, Br_o, "no", "jno") \
+ X(Br_b, 2, Br_ae, "b", "jb") \
+ X(Br_ae, 3, Br_b, "ae", "jae") \
+ X(Br_e, 4, Br_ne, "e", "je") \
+ X(Br_ne, 5, Br_e, "ne", "jne") \
+ X(Br_be, 6, Br_a, "be", "jbe") \
+ X(Br_a, 7, Br_be, "a", "ja") \
+ X(Br_s, 8, Br_ns, "s", "js") \
+ X(Br_ns, 9, Br_s, "ns", "jns") \
+ X(Br_p, 10, Br_np, "p", "jp") \
+ X(Br_np, 11, Br_p, "np", "jnp") \
+ X(Br_l, 12, Br_ge, "l", "jl") \
+ X(Br_ge, 13, Br_l, "ge", "jge") \
+ X(Br_le, 14, Br_g, "le", "jle") \
+ X(Br_g, 15, Br_le, "g", "jg")
+//#define X(val, encode, opp, dump, emit)
-#define ICEINSTX8632CMPPS_TABLE \
- /* enum value, emit */ \
- X(Cmpps_eq, "eq") \
- X(Cmpps_lt, "lt") \
- X(Cmpps_le, "le") \
- X(Cmpps_unord, "unord") \
- X(Cmpps_neq, "neq") \
- X(Cmpps_nlt, "nlt") \
- X(Cmpps_nle, "nle") \
- X(Cmpps_ord, "ord") \
-//#define X(tag, emit)
+#define ICEINSTX8632CMPPS_TABLE \
+ /* val, emit */ \
+ X(Cmpps_eq, "eq") \
+ X(Cmpps_lt, "lt") \
+ X(Cmpps_le, "le") \
+ X(Cmpps_unord, "unord") \
+ X(Cmpps_neq, "neq") \
+ X(Cmpps_nlt, "nlt") \
+ X(Cmpps_nle, "nle") \
+ X(Cmpps_ord, "ord")
+//#define X(val, emit)
-#define ICETYPEX8632_TABLE \
- /* tag, element type, cvt, sdss, pack, width, fld */ \
- X(IceType_void, IceType_void, "?" , "" , "" , "", "") \
- X(IceType_i1, IceType_void, "si", "" , "" , "b", "") \
- X(IceType_i8, IceType_void, "si", "" , "" , "b", "") \
- X(IceType_i16, IceType_void, "si", "" , "" , "w", "") \
- X(IceType_i32, IceType_void, "si", "" , "" , "l", "") \
- X(IceType_i64, IceType_void, "si", "" , "" , "q", "") \
- X(IceType_f32, IceType_void, "ss", "ss", "d", "", "s") \
- X(IceType_f64, IceType_void, "sd", "sd", "q", "", "l") \
- X(IceType_v4i1, IceType_i32 , "?" , "" , "d", "", "") \
- X(IceType_v8i1, IceType_i16 , "?" , "" , "w", "", "") \
- X(IceType_v16i1, IceType_i8 , "?" , "" , "b", "", "") \
- X(IceType_v16i8, IceType_i8 , "?" , "" , "b", "", "") \
- X(IceType_v8i16, IceType_i16 , "?" , "" , "w", "", "") \
- X(IceType_v4i32, IceType_i32 , "dq", "" , "d", "", "") \
- X(IceType_v4f32, IceType_f32 , "ps", "" , "d", "", "") \
+#define ICETYPEX8632_TABLE \
+ /* tag, element type, cvt , sdss, pack, width, fld */ \
+ X(IceType_void, IceType_void, "?", "", "", "", "") \
+ X(IceType_i1, IceType_void, "si", "", "", "b", "") \
+ X(IceType_i8, IceType_void, "si", "", "", "b", "") \
+ X(IceType_i16, IceType_void, "si", "", "", "w", "") \
+ X(IceType_i32, IceType_void, "si", "", "", "l", "") \
+ X(IceType_i64, IceType_void, "si", "", "", "q", "") \
+ X(IceType_f32, IceType_void, "ss", "ss", "d", "", "s") \
+ X(IceType_f64, IceType_void, "sd", "sd", "q", "", "l") \
+ X(IceType_v4i1, IceType_i32, "?", "", "d", "", "") \
+ X(IceType_v8i1, IceType_i16, "?", "", "w", "", "") \
+ X(IceType_v16i1, IceType_i8, "?", "", "b", "", "") \
+ X(IceType_v16i8, IceType_i8, "?", "", "b", "", "") \
+ X(IceType_v8i16, IceType_i16, "?", "", "w", "", "") \
+ X(IceType_v4i32, IceType_i32, "dq", "", "d", "", "") \
+ X(IceType_v4f32, IceType_f32, "ps", "", "d", "", "")
//#define X(tag, elementty, cvt, sdss, pack, width, fld)
#endif // SUBZERO_SRC_ICEINSTX8632_DEF
diff --git a/src/IceInstX8664.cpp b/src/IceInstX8664.cpp
index bf38f1b..5c96aea 100644
--- a/src/IceInstX8664.cpp
+++ b/src/IceInstX8664.cpp
@@ -32,7 +32,7 @@
const MachineTraits<TargetX8664>::InstBrAttributesType
MachineTraits<TargetX8664>::InstBrAttributes[] = {
-#define X(tag, encode, opp, dump, emit) \
+#define X(val, encode, opp, dump, emit) \
{ X8664::Traits::Cond::opp, dump, emit } \
,
ICEINSTX8664BR_TABLE
@@ -41,7 +41,7 @@
const MachineTraits<TargetX8664>::InstCmppsAttributesType
MachineTraits<TargetX8664>::InstCmppsAttributes[] = {
-#define X(tag, emit) \
+#define X(val, emit) \
{ emit } \
,
ICEINSTX8664CMPPS_TABLE
@@ -96,11 +96,11 @@
// '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr.
if (!Offset) {
// No offset, emit nothing.
- } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
+ } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
if (Base == nullptr || CI->getValue())
// Emit a non-zero offset without a leading '$'.
Str << CI->getValue();
- } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
+ } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
CR->emitWithoutPrefix(Func->getTarget());
} else {
llvm_unreachable("Invalid offset type for x86 mem operand");
@@ -149,7 +149,7 @@
bool OffsetIsNegative = false;
if (!Offset) {
OffsetIsZero = true;
- } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
+ } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
OffsetIsZero = (CI->getValue() == 0);
OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
} else {
@@ -175,7 +175,7 @@
AssemblerFixup *Fixup = nullptr;
// Determine the offset (is it relocatable?)
if (getOffset()) {
- if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
+ if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
Disp = static_cast<int32_t>(CI->getValue());
} else if (const auto CR =
llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
@@ -188,17 +188,17 @@
// Now convert to the various possible forms.
if (getBase() && getIndex()) {
- return X8664::Traits::Address(
- RegX8664::getEncodedGPR(getBase()->getRegNum()),
- RegX8664::getEncodedGPR(getIndex()->getRegNum()),
- X8664::Traits::ScaleFactor(getShift()), Disp, Fixup);
+ return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()),
+ getEncodedGPR(getIndex()->getRegNum()),
+ X8664::Traits::ScaleFactor(getShift()), Disp,
+ Fixup);
} else if (getBase()) {
- return X8664::Traits::Address(
- RegX8664::getEncodedGPR(getBase()->getRegNum()), Disp, Fixup);
+ return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp,
+ Fixup);
} else if (getIndex()) {
- return X8664::Traits::Address(
- RegX8664::getEncodedGPR(getIndex()->getRegNum()),
- X8664::Traits::ScaleFactor(getShift()), Disp, Fixup);
+ return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()),
+ X8664::Traits::ScaleFactor(getShift()), Disp,
+ Fixup);
} else {
return X8664::Traits::Address(Disp, Fixup);
}
@@ -210,9 +210,8 @@
const ::Ice::TargetLowering *Target = Func->getTarget();
int32_t Offset =
Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
- return X8664::Traits::Address(
- RegX8664::getEncodedGPR(Target->getFrameOrStackReg()), Offset,
- AssemblerFixup::NoFixup);
+ return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()),
+ Offset, AssemblerFixup::NoFixup);
}
void MachineTraits<TargetX8664>::VariableSplit::emit(const Cfg *Func) const {
@@ -222,7 +221,7 @@
assert(!Var->hasReg());
// The following is copied/adapted from TargetX8664::emitVariable().
const ::Ice::TargetLowering *Target = Func->getTarget();
- const Type Ty = IceType_i32;
+ constexpr Type Ty = IceType_i32;
int32_t Offset =
Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
if (Offset)
diff --git a/src/IceInstX8664.def b/src/IceInstX8664.def
index 7ad1eaa..b3f452f 100644
--- a/src/IceInstX8664.def
+++ b/src/IceInstX8664.def
@@ -15,146 +15,299 @@
#ifndef SUBZERO_SRC_ICEINSTX8664_DEF
#define SUBZERO_SRC_ICEINSTX8664_DEF
-// NOTE: we use the 32bit register names for two reasons:
-// (1) it makes it easier to implement the x86 assembler template.
-// (2) when generating code, subzero defaults to using 32 bit registers,
-// so using the 32 bit register name would hopefully make this design
-// more explicit.
-// NOTE: esp is not considered isInt, to avoid register allocating it.
-#define REGX8664_GPR_TABLE \
- /* val, encode, name64, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isInt, isFP */ \
- X(Reg_eax, = 0, "rax", "eax" , "ax" , "al" , 1, 0, 0, 0, 1, 0) \
- X(Reg_ecx, = 1, "rcx", "ecx" , "cx" , "cl" , 1, 0, 0, 0, 1, 0) \
- X(Reg_edx, = 2, "rdx", "edx" , "dx" , "dl" , 1, 0, 0, 0, 1, 0) \
- X(Reg_ebx, = 3, "rbx", "ebx" , "bx" , "bl" , 0, 1, 0, 0, 1, 0) \
- X(Reg_esp, = 4, "rsp", "esp" , "sp" , "spl" , 0, 0, 1, 0, 0, 0) \
- X(Reg_ebp, = 5, "rbp", "ebp" , "bp" , "bpl" , 0, 0, 0, 1, 1, 0) \
- X(Reg_esi, = 6, "rsi", "esi" , "si" , "sil" , 1, 0, 0, 0, 1, 0) \
- X(Reg_edi, = 7, "rdi", "edi" , "di" , "dil" , 1, 0, 0, 0, 1, 0) \
- X(Reg_r8d, = 8, "r8" , "r8d" , "r8w", "r8l" , 1, 0, 0, 0, 1, 0) \
- X(Reg_r9d, = 9, "r9" , "r9d" , "r9w", "r9l" , 1, 0, 0, 0, 1, 0) \
- X(Reg_r10d, = 10, "r10", "r10d", "r10w", "r10l", 1, 0, 0, 0, 1, 0) \
- X(Reg_r11d, = 11, "r11", "r11d", "r11w", "r11l", 1, 0, 0, 0, 1, 0) \
- X(Reg_r12d, = 12, "r12", "r12d", "r12w", "r12l", 0, 1, 0, 0, 1, 0) \
- X(Reg_r13d, = 13, "r13", "r13d", "r13w", "r12l", 0, 1, 0, 0, 1, 0) \
- X(Reg_r14d, = 14, "r14", "r14d", "r14w", "r14l", 0, 1, 0, 0, 1, 0) \
- X(Reg_r15d, = 15, "r15", "r15d", "r15w", "r15l", 0, 1, 0, 0, 1, 0)
+#include "IceRegList.h"
+// x86-64 ABI:
+// Scratch GPRs: rax, rcx, rdx, rsi, rdi, r8, r9, r10, r11
+// Callee-save GPRs: rbx, rbp, r12, r13, r14, r15
+// Scratch XMMs: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
+// xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+// Key to table columns:
+// val: Enum value, when a specific register is needed during lowering.
+// encode: Encoding in the integrated assembler.
+// name: Name used for the external assembler.
+// scratch: Scratch (caller-save) register.
+// preserved: Preserved (callee-save) register.
+// stackptr: This register is used as the stack pointer.
+// frameptr: This register is used as the frame pointer if needed.
+// isGPR: This is a GPR (integer-type).
+// is64: This is a 64-bit GPR.
+// is32: This is a 32-bit GPR.
+// is16: This is a 16-bit GPR.
+// is8: This is an 8-bit GPR.
+// isXmm: This is an XMM register for FP and vector ops.
+// is64To8: A 64-bit GPR truncable to 8-bit.
+// is32To8: A 32-bit GPR truncable to 8-bit.
+// is16To8: A 16-bit GPR truncable to 8-bit.
+// isTrunc8Rcvr: An 8-bit GPR that a wider GPR trivially truncates to.
+// isAhRcvr: An 8-bit GPR that register "ah" can be assigned to.
+// aliases: List of register aliases, which need not include this register.
+#define REGX8664_BYTEREG_TABLE \
+ /* val, encode, name, base, scratch,preserved,stackptr,frameptr, \
+ isGPR,is64,is32,is16,is8, isXmm, \
+ is64To8,is32To8,is16To8,isTrunc8Rcvr,isAhRcvr, aliases */ \
+ /* 8-bit registers */ \
+ X(Reg_al, 0, "al", Reg_eax, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,1, \
+ REGLIST3(RegX8664, rax, eax, ax)) \
+ X(Reg_cl, 1, "cl", Reg_ecx, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,1, \
+ REGLIST3(RegX8664, rcx, ecx, cx)) \
+ X(Reg_dl, 2, "dl", Reg_edx, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,1, \
+ REGLIST3(RegX8664, rdx, edx, dx)) \
+ X(Reg_bl, 3, "bl", Reg_ebx, 0,1,0,0, 1,0,0,0,1, 0, 0,0,0,1,1, \
+ REGLIST3(RegX8664, rbx, ebx, bx)) \
+ X(Reg_spl, 4, "spl", Reg_esp, 0,0,1,0, 1,0,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, rsp, esp, sp)) \
+ X(Reg_bpl, 5, "bpl", Reg_ebp, 0,1,0,1, 1,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, rbp, ebp, bp)) \
+ X(Reg_sil, 6, "sil", Reg_esi, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, rsi, esi, si)) \
+ X(Reg_dil, 7, "dil", Reg_edi, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, rdi, edi, di)) \
+ X(Reg_r8l, 8, "r8b", Reg_r8, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, r8, r8d, r8w)) \
+ X(Reg_r9l, 9, "r9b", Reg_r9, 1,0,0,0, 1,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, r9, r9d, r9w)) \
+ X(Reg_r10l, 10, "r10b", Reg_r10, 1,0,0,1, 0,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, r10, r10d, r10w)) \
+ X(Reg_r11l, 11, "r11b", Reg_r11, 1,0,0,1, 0,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, r11, r11d, r11w)) \
+ X(Reg_r12l, 12, "r12b", Reg_r12, 0,1,0,1, 0,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, r12, r12d, r12w)) \
+ X(Reg_r13l, 13, "r13b", Reg_r13, 0,1,0,1, 0,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, r13, r13d, r13w)) \
+ X(Reg_r14l, 14, "r14b", Reg_r14, 0,1,0,1, 0,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, r14, r14d, r14w)) \
+ X(Reg_r15l, 15, "r15b", Reg_r15, 0,1,0,1, 0,0,0,0,1, 0, 0,0,0,1,0, \
+ REGLIST3(RegX8664, r15, r15d, r15w)) \
+ /* High 8-bit registers. None are allowed for register allocation. */ \
+ X(Reg_ah, 4, "ah", Reg_eax, 1,0,0,0, 1,0,0,0,0, 0, 0,0,0,0,1, \
+ REGLIST3(RegX8664, rax, eax, ax)) \
+ X(Reg_ch, 5, "ch", Reg_ecx, 1,0,0,0, 1,0,0,0,0, 0, 0,0,0,0,1, \
+ REGLIST3(RegX8664, rcx, ecx, cx)) \
+ X(Reg_dh, 6, "dh", Reg_edx, 1,0,0,0, 1,0,0,0,0, 0, 0,0,0,0,1, \
+ REGLIST3(RegX8664, rdx, edx, dx)) \
+ X(Reg_bh, 7, "bh", Reg_ebx, 0,1,0,0, 1,0,0,0,0, 0, 0,0,0,0,1, \
+ REGLIST3(RegX8664, rbx, ebx, bx)) \
+ /* End of 8-bit register set */
+//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
+// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
+// isTrunc8Rcvr, isAhRcvr, aliases)
+
+#define REGX8664_GPR_TABLE \
+ /* val, encode, name, base, scratch,preserved,stackptr,frameptr, \
+ isGPR,is64,is32,is16,is8, isXmm, \
+ is64To8,is32To8,is16To8,isTrunc8Rcvr,isAhRcvr, aliases */ \
+ /* 64-bit registers */ \
+ X(Reg_rax, 0, "rax", Reg_rax, 1,0,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST4(RegX8664, eax, ax, al, ah)) \
+ X(Reg_rcx, 1, "rcx", Reg_rcx, 1,0,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST4(RegX8664, ecx, cx, cl, ch)) \
+ X(Reg_rdx, 2, "rdx", Reg_rdx, 1,0,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST4(RegX8664, edx, dx, dl, dh)) \
+ X(Reg_rbx, 3, "rbx", Reg_rbx, 0,1,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST4(RegX8664, ebx, bx, bl, bh)) \
+ X(Reg_rsp, 4, "rsp", Reg_rsp, 0,0,1,0, 1,0,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, esp, sp, spl)) \
+ X(Reg_rbp, 5, "rbp", Reg_rbp, 0,1,0,1, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, ebp, bp, bpl)) \
+ X(Reg_rsi, 6, "rsi", Reg_rsi, 1,0,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, esi, si, sil)) \
+ X(Reg_rdi, 7, "rdi", Reg_rdi, 1,0,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, edi, di, dil)) \
+ X(Reg_r8, 8, "r8", Reg_r8, 1,0,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, r8d, r8w, r8l)) \
+ X(Reg_r9, 9, "r9", Reg_r9, 1,0,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, r9d, r9w, r9l)) \
+ X(Reg_r10, 10, "r10", Reg_r10, 1,0,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, r10d, r10w, r10l)) \
+ X(Reg_r11, 11, "r11", Reg_r11, 1,0,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, r11d, r11w, r11l)) \
+ X(Reg_r12, 12, "r12", Reg_r12, 0,1,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, r12d, r12w, r12l)) \
+ X(Reg_r13, 13, "r13", Reg_r13, 0,1,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, r13d, r13w, r13l)) \
+ X(Reg_r14, 14, "r14", Reg_r14, 0,1,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, r14d, r14w, r14l)) \
+ X(Reg_r15, 15, "r15", Reg_r15, 0,1,0,0, 1,1,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, r15d, r15w, r15l)) \
+ /* 32-bit registers */ \
+ X(Reg_eax, 0, "eax", Reg_eax, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST4(RegX8664, rax, ax, al, ah)) \
+ X(Reg_ecx, 1, "ecx", Reg_ecx, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST4(RegX8664, rcx, cx, cl, ch)) \
+ X(Reg_edx, 2, "edx", Reg_edx, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST4(RegX8664, rdx, dx, dl, dh)) \
+ X(Reg_ebx, 3, "ebx", Reg_ebx, 0,1,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST4(RegX8664, rbx, bx, bl, bh)) \
+ X(Reg_esp, 4, "esp", Reg_esp, 0,0,1,0, 1,0,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, rsp, sp, spl)) \
+ X(Reg_ebp, 5, "ebp", Reg_ebp, 0,1,0,1, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, rbp, bp, bpl)) \
+ X(Reg_esi, 6, "esi", Reg_esi, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, rsi, si, sil)) \
+ X(Reg_edi, 7, "edi", Reg_edi, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, rdi, di, dil)) \
+ X(Reg_r8d, 8, "r8d", Reg_r8, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, r8, r8w, r8l)) \
+ X(Reg_r9d, 9, "r9d", Reg_r9, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, r9, r9w, r9l)) \
+ X(Reg_r10d, 10, "r10d", Reg_r10, 1,0,0,1, 0,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, r10, r10w, r10l)) \
+ X(Reg_r11d, 11, "r11d", Reg_r11, 1,0,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, r11, r11w, r11l)) \
+ X(Reg_r12d, 12, "r12d", Reg_r12, 0,1,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, r12, r12w, r12l)) \
+ X(Reg_r13d, 13, "r13d", Reg_r13, 0,1,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, r13, r13w, r13l)) \
+ X(Reg_r14d, 14, "r14d", Reg_r14, 0,1,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, r14, r14w, r14l)) \
+ X(Reg_r15d, 15, "r15d", Reg_r15, 0,1,0,0, 1,0,1,0,0, 0, 0,1,0,0,0, \
+ REGLIST3(RegX8664, r15, r15w, r15l)) \
+ /* 16-bit registers */ \
+ X(Reg_ax, 0, "ax", Reg_eax, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST4(RegX8664, rax, eax, al, ah)) \
+ X(Reg_cx, 1, "cx", Reg_ecx, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST4(RegX8664, rcx, ecx, cl, ch)) \
+ X(Reg_dx, 2, "dx", Reg_edx, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST4(RegX8664, rdx, edx, dl, dh)) \
+ X(Reg_bx, 3, "bx", Reg_ebx, 0,1,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST4(RegX8664, rbx, ebx, bl, bh)) \
+ X(Reg_sp, 4, "sp", Reg_esp, 0,0,1,0, 1,0,0,0,0, 0, 0,0,0,0,0, \
+ REGLIST3(RegX8664, rsp, esp, spl)) \
+ X(Reg_bp, 5, "bp", Reg_ebp, 0,1,0,1, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, rbp, ebp, bpl)) \
+ X(Reg_si, 6, "si", Reg_esi, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, rsi, esi, sil)) \
+ X(Reg_di, 7, "di", Reg_edi, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, rdi, edi, dil)) \
+ X(Reg_r8w, 8, "r8w", Reg_r8, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, r8, r8d, r8l)) \
+ X(Reg_r9w, 9, "r9w", Reg_r9, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, r9, r9d, r9l)) \
+ X(Reg_r10w, 10, "r10w", Reg_r10, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, r10, r10d, r10l)) \
+ X(Reg_r11w, 11, "r11w", Reg_r11, 1,0,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, r11, r11d, r11l)) \
+ X(Reg_r12w, 12, "r12w", Reg_r12, 0,1,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, r12, r12d, r12l)) \
+ X(Reg_r13w, 13, "r13w", Reg_r13, 0,1,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, r13, r13d, r13l)) \
+ X(Reg_r14w, 14, "r14w", Reg_r14, 0,1,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, r14, r14d, r14l)) \
+ X(Reg_r15w, 15, "r15w", Reg_r15, 0,1,0,0, 1,0,0,1,0, 0, 0,0,1,0,0, \
+ REGLIST3(RegX8664, r15, r15d, r15l)) \
+ /* 8-bit registers */ \
+ REGX8664_BYTEREG_TABLE \
+ /* End of GPR register set */
+//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
+// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
+// isTrunc8Rcvr, isAhRcvr, aliases)
+
+// Note: It would be more appropriate to list the xmm register aliases as
+// REGLIST0(), but the corresponding empty initializer gives a syntax error, so
+// we use REGLIST1() to redundantly assign the register itself as an alias.
#define REGX8664_XMM_TABLE \
- /* val, encode, name64, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isInt, isFP */ \
- X(Reg_xmm0, = 0, "xmm0" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm1, = 1, "xmm1" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm2, = 2, "xmm2" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm3, = 3, "xmm3" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm4, = 4, "xmm4" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm5, = 5, "xmm5" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm6, = 6, "xmm6" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm7, = 7, "xmm7" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm8, = 8, "xmm8" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm9, = 9, "xmm9" , "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm10, = 10, "xmm10", "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm11, = 11, "xmm11", "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm12, = 12, "xmm12", "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm13, = 13, "xmm13", "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm14, = 14, "xmm14", "", "", "", 1, 0, 0, 0, 0, 1) \
- X(Reg_xmm15, = 15, "xmm15", "", "", "", 1, 0, 0, 0, 0, 1)
-//#define X(val, encode, name, name32, name16, name8, scratch, preserved,
-// stackptr, frameptr, isI8, isInt, isFP)
+ /* val, encode, name, base, scratch,preserved,stackptr,frameptr, \
+ isGPR,is64,is32,is16,is8, isXmm, \
+ is64To8,is32To8,is16To8,isTrunc8Rcvr,isAhRcvr, aliases */ \
+ /* xmm registers */ \
+ X(Reg_xmm0, 0, "xmm0", Reg_xmm0, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm0)) \
+ X(Reg_xmm1, 1, "xmm1", Reg_xmm1, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm1)) \
+ X(Reg_xmm2, 2, "xmm2", Reg_xmm2, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm2)) \
+ X(Reg_xmm3, 3, "xmm3", Reg_xmm3, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm3)) \
+ X(Reg_xmm4, 4, "xmm4", Reg_xmm4, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm4)) \
+ X(Reg_xmm5, 5, "xmm5", Reg_xmm5, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm5)) \
+ X(Reg_xmm6, 6, "xmm6", Reg_xmm6, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm6)) \
+ X(Reg_xmm7, 7, "xmm7", Reg_xmm7, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm7)) \
+ X(Reg_xmm8, 8, "xmm8", Reg_xmm8, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm8)) \
+ X(Reg_xmm9, 9, "xmm9", Reg_xmm9, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm9)) \
+ X(Reg_xmm10, 10, "xmm10", Reg_xmm10, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm10)) \
+ X(Reg_xmm11, 11, "xmm11", Reg_xmm11, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm11)) \
+ X(Reg_xmm12, 12, "xmm12", Reg_xmm12, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm12)) \
+ X(Reg_xmm13, 13, "xmm13", Reg_xmm13, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm13)) \
+ X(Reg_xmm14, 14, "xmm14", Reg_xmm14, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm14)) \
+ X(Reg_xmm15, 15, "xmm15", Reg_xmm15, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
+ REGLIST1(RegX8664, xmm15)) \
+ /* End of xmm register set */
+//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
+// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
+// isTrunc8Rcvr, isAhRcvr, aliases)
// We also provide a combined table, so that there is a namespace where
// all of the registers are considered and have distinct numberings.
// This is in contrast to the above, where the "encode" is based on how
// the register numbers will be encoded in binaries and values can overlap.
#define REGX8664_TABLE \
- /* val, encode, name64, name, name16, name8, scratch, preserved, \
- stackptr, frameptr, isInt, isFP */ \
REGX8664_GPR_TABLE \
REGX8664_XMM_TABLE
-//#define X(val, encode, name, name32, name16, name8, scratch, preserved,
-// stackptr, frameptr, isI8, isInt, isFP)
-
-#define REGX8664_TABLE_BOUNDS \
- /* val , init */ \
- X(Reg_GPR_First, = Reg_eax ) \
- X(Reg_GPR_Last , = Reg_r15d ) \
- X(Reg_XMM_First, = Reg_xmm0 ) \
- X(Reg_XMM_Last , = Reg_xmm15)
-// define X(val, init)
-
-// We also need the encodings for the Byte registers (other info overlaps
-// what is in the REGX8664_GPR_TABLE). We don't expose the ah, ch, dh,
-// bh registers to keep register selection simple.
-#define REGX8664_BYTEREG_TABLE \
- /* val , encode */ \
- X(Reg_al , = 0) \
- X(Reg_cl , = 1) \
- X(Reg_dl , = 2) \
- X(Reg_bl , = 3) \
- X(Reg_spl , = 4) \
- X(Reg_bpl , = 5) \
- X(Reg_sil , = 6) \
- X(Reg_dil , = 7) \
- X(Reg_r8l , = 8) \
- X(Reg_r9l , = 9) \
- X(Reg_r10l, = 10) \
- X(Reg_r11l, = 11) \
- X(Reg_r12l, = 12) \
- X(Reg_r13l, = 13) \
- X(Reg_r14l, = 14) \
- X(Reg_r15l, = 15)
-//#define X(val, encode)
+//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
+// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
+// isTrunc8Rcvr, isAhRcvr, aliases)
#define ICEINSTX8664BR_TABLE \
- /* enum value, encode, opposite, dump, emit */ \
- X(Br_o , = 0, Br_no , "o" , "jo" ) \
- X(Br_no , = 1, Br_o , "no", "jno") \
- X(Br_b , = 2, Br_ae , "b" , "jb" ) \
- X(Br_ae , = 3, Br_b , "ae", "jae") \
- X(Br_e , = 4, Br_ne , "e" , "je" ) \
- X(Br_ne , = 5, Br_e , "ne", "jne") \
- X(Br_be , = 6, Br_a , "be", "jbe") \
- X(Br_a , = 7, Br_be , "a" , "ja" ) \
- X(Br_s , = 8, Br_ns , "s" , "js" ) \
- X(Br_ns , = 9, Br_s , "ns", "jns") \
- X(Br_p , = 10, Br_np , "p" , "jp" ) \
- X(Br_np , = 11, Br_p , "np", "jnp") \
- X(Br_l , = 12, Br_ge , "l" , "jl" ) \
- X(Br_ge , = 13, Br_l , "ge", "jge") \
- X(Br_le , = 14, Br_g , "le", "jle") \
- X(Br_g , = 15, Br_le , "g" , "jg")
-//#define X(tag, encode, opp, dump, emit)
+ /* val, encode, opposite, dump, emit */ \
+ X(Br_o, 0, Br_no, "o", "jo") \
+ X(Br_no, 1, Br_o, "no", "jno") \
+ X(Br_b, 2, Br_ae, "b", "jb") \
+ X(Br_ae, 3, Br_b, "ae", "jae") \
+ X(Br_e, 4, Br_ne, "e", "je") \
+ X(Br_ne, 5, Br_e, "ne", "jne") \
+ X(Br_be, 6, Br_a, "be", "jbe") \
+ X(Br_a, 7, Br_be, "a", "ja") \
+ X(Br_s, 8, Br_ns, "s", "js") \
+ X(Br_ns, 9, Br_s, "ns", "jns") \
+ X(Br_p, 10, Br_np, "p", "jp") \
+ X(Br_np, 11, Br_p, "np", "jnp") \
+ X(Br_l, 12, Br_ge, "l", "jl") \
+ X(Br_ge, 13, Br_l, "ge", "jge") \
+ X(Br_le, 14, Br_g, "le", "jle") \
+ X(Br_g, 15, Br_le, "g", "jg")
+//#define X(val, encode, opp, dump, emit)
#define ICEINSTX8664CMPPS_TABLE \
- /* enum value, emit */ \
- X(Cmpps_eq , "eq" ) \
- X(Cmpps_lt , "lt" ) \
- X(Cmpps_le , "le" ) \
+ /* val, emit */ \
+ X(Cmpps_eq, "eq") \
+ X(Cmpps_lt, "lt") \
+ X(Cmpps_le, "le") \
X(Cmpps_unord, "unord") \
- X(Cmpps_neq , "neq" ) \
- X(Cmpps_nlt , "nlt" ) \
- X(Cmpps_nle , "nle" ) \
- X(Cmpps_ord , "ord" )
-//#define X(tag, emit)
+ X(Cmpps_neq, "neq") \
+ X(Cmpps_nlt, "nlt") \
+ X(Cmpps_nle, "nle") \
+ X(Cmpps_ord, "ord")
+//#define X(val, emit)
#define ICETYPEX8664_TABLE \
/* tag , element type, cvt , sdss, pack, width, fld */ \
- X(IceType_void , IceType_void, "?" , "" , "" , "" , "" ) \
- X(IceType_i1 , IceType_void, "si", "" , "" , "b" , "" ) \
- X(IceType_i8 , IceType_void, "si", "" , "" , "b" , "" ) \
- X(IceType_i16 , IceType_void, "si", "" , "" , "w" , "" ) \
- X(IceType_i32 , IceType_void, "si", "" , "" , "l" , "" ) \
- X(IceType_i64 , IceType_void, "si", "" , "" , "q" , "" ) \
- X(IceType_f32 , IceType_void, "ss", "ss", "d" , "" , "s") \
- X(IceType_f64 , IceType_void, "sd", "sd", "q" , "" , "l") \
- X(IceType_v4i1 , IceType_i32 , "?" , "" , "d" , "" , "" ) \
- X(IceType_v8i1 , IceType_i16 , "?" , "" , "w" , "" , "" ) \
- X(IceType_v16i1, IceType_i8 , "?" , "" , "b" , "" , "" ) \
- X(IceType_v16i8, IceType_i8 , "?" , "" , "b" , "" , "" ) \
- X(IceType_v8i16, IceType_i16 , "?" , "" , "w" , "" , "" ) \
- X(IceType_v4i32, IceType_i32 , "dq", "" , "d" , "" , "" ) \
- X(IceType_v4f32, IceType_f32 , "ps", "" , "d" , "" , "" )
+ X(IceType_void, IceType_void, "?", "", "", "", "") \
+ X(IceType_i1, IceType_void, "si", "", "", "b", "") \
+ X(IceType_i8, IceType_void, "si", "", "", "b", "") \
+ X(IceType_i16, IceType_void, "si", "", "", "w", "") \
+ X(IceType_i32, IceType_void, "si", "", "", "l", "") \
+ X(IceType_i64, IceType_void, "si", "", "", "q", "") \
+ X(IceType_f32, IceType_void, "ss", "ss", "d", "", "s") \
+ X(IceType_f64, IceType_void, "sd", "sd", "q", "", "l") \
+ X(IceType_v4i1, IceType_i32, "?", "", "d", "", "") \
+ X(IceType_v8i1, IceType_i16, "?", "", "w", "", "") \
+ X(IceType_v16i1, IceType_i8, "?", "", "b", "", "") \
+ X(IceType_v16i8, IceType_i8, "?", "", "b", "", "") \
+ X(IceType_v8i16, IceType_i16, "?", "", "w", "", "") \
+ X(IceType_v4i32, IceType_i32, "dq", "", "d", "", "") \
+ X(IceType_v4f32, IceType_f32, "ps", "", "d", "", "")
//#define X(tag, elementty, cvt, sdss, pack, width, fld)
#endif // SUBZERO_SRC_ICEINSTX8664_DEF
diff --git a/src/IceInstX86Base.h b/src/IceInstX86Base.h
index f93ac2b..d18c746 100644
--- a/src/IceInstX86Base.h
+++ b/src/IceInstX86Base.h
@@ -147,10 +147,9 @@
getOppositeCondition(typename Traits::Cond::BrCond Cond);
void dump(const Cfg *Func) const override;
- // Shared emit routines for common forms of instructions. See the definition
- // of emitTwoAddress() for a description of ShiftHack.
+ // Shared emit routines for common forms of instructions.
static void emitTwoAddress(const char *Opcode, const Inst *Inst,
- const Cfg *Func, bool ShiftHack = false);
+ const Cfg *Func);
static void
emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
@@ -303,14 +302,14 @@
typename InstX86Base<Machine>::Traits::Cond::BrCond Condition,
Mode Kind) {
assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
- const InstX86Label<Machine> *NoLabel = nullptr;
+ constexpr InstX86Label<Machine> *NoLabel = nullptr;
return new (Func->allocate<InstX86Br>())
InstX86Br(Func, TargetTrue, TargetFalse, NoLabel, Condition, Kind);
}
/// Create an unconditional branch to a node.
static InstX86Br *create(Cfg *Func, CfgNode *Target, Mode Kind) {
- const CfgNode *NoCondTarget = nullptr;
- const InstX86Label<Machine> *NoLabel = nullptr;
+ constexpr CfgNode *NoCondTarget = nullptr;
+ constexpr InstX86Label<Machine> *NoLabel = nullptr;
return new (Func->allocate<InstX86Br>())
InstX86Br(Func, NoCondTarget, Target, NoLabel,
InstX86Base<Machine>::Traits::Cond::Br_None, Kind);
@@ -323,8 +322,8 @@
typename InstX86Base<Machine>::Traits::Cond::BrCond Condition,
Mode Kind) {
assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
- const CfgNode *NoUncondTarget = nullptr;
- const InstX86Label<Machine> *NoLabel = nullptr;
+ constexpr CfgNode *NoUncondTarget = nullptr;
+ constexpr InstX86Label<Machine> *NoLabel = nullptr;
return new (Func->allocate<InstX86Br>())
InstX86Br(Func, Target, NoUncondTarget, NoLabel, Condition, Kind);
}
@@ -334,8 +333,8 @@
create(Cfg *Func, InstX86Label<Machine> *Label,
typename InstX86Base<Machine>::Traits::Cond::BrCond Condition,
Mode Kind) {
- const CfgNode *NoCondTarget = nullptr;
- const CfgNode *NoUncondTarget = nullptr;
+ constexpr CfgNode *NoCondTarget = nullptr;
+ constexpr CfgNode *NoUncondTarget = nullptr;
return new (Func->allocate<InstX86Br>())
InstX86Br(Func, NoCondTarget, NoUncondTarget, Label, Condition, Kind);
}
@@ -643,8 +642,7 @@
void emit(const Cfg *Func) const override {
if (!BuildDefs::dump())
return;
- const bool ShiftHack = true;
- this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+ this->emitTwoAddress(Opcode, this, Func);
}
void emitIAS(const Cfg *Func) const override {
Type Ty = this->getDest()->getType();
@@ -687,8 +685,7 @@
void emit(const Cfg *Func) const override {
if (!BuildDefs::dump())
return;
- const bool ShiftHack = false;
- this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+ this->emitTwoAddress(Opcode, this, Func);
}
void emitIAS(const Cfg *Func) const override {
Type Ty = this->getDest()->getType();
@@ -732,8 +729,7 @@
void emit(const Cfg *Func) const override {
if (!BuildDefs::dump())
return;
- const bool ShiftHack = false;
- this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+ this->emitTwoAddress(Opcode, this, Func);
}
void emitIAS(const Cfg *Func) const override {
Type Ty = this->getSrc(0)->getType();
@@ -780,8 +776,7 @@
if (!BuildDefs::dump())
return;
this->validateVectorAddrMode();
- const bool ShiftHack = false;
- this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+ this->emitTwoAddress(Opcode, this, Func);
}
void emitIAS(const Cfg *Func) const override {
this->validateVectorAddrMode();
@@ -837,8 +832,7 @@
if (!BuildDefs::dump())
return;
this->validateVectorAddrMode();
- const bool ShiftHack = false;
- this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+ this->emitTwoAddress(Opcode, this, Func);
}
void emitIAS(const Cfg *Func) const override {
this->validateVectorAddrMode();
@@ -975,6 +969,23 @@
using Base = InstX86BaseMovlike<Machine, K>;
bool isRedundantAssign() const override {
+ if (const auto *SrcVar = llvm::dyn_cast<const Variable>(this->getSrc(0))) {
+ if (SrcVar->hasReg() && this->Dest->hasReg()) {
+ // An assignment between physical registers is considered redundant if
+ // they have the same base register and the same encoding. E.g.:
+ // mov cl, ecx ==> redundant
+ // mov ch, ecx ==> not redundant due to different encodings
+ // mov ch, ebp ==> not redundant due to different base registers
+ // TODO(stichnot): Don't consider "mov eax, eax" to be redundant when
+ // used in 64-bit mode to clear the upper half of rax.
+ int32_t SrcReg = SrcVar->getRegNum();
+ int32_t DestReg = this->Dest->getRegNum();
+ return (InstX86Base<Machine>::Traits::getEncoding(SrcReg) ==
+ InstX86Base<Machine>::Traits::getEncoding(DestReg)) &&
+ (InstX86Base<Machine>::Traits::getBaseReg(SrcReg) ==
+ InstX86Base<Machine>::Traits::getBaseReg(DestReg));
+ }
+ }
return checkForRedundantAssign(this->getDest(), this->getSrc(0));
}
bool isVarAssign() const override {
@@ -997,6 +1008,11 @@
InstX86BaseMovlike(Cfg *Func, Variable *Dest, Operand *Source)
: InstX86Base<Machine>(Func, K, 1, Dest) {
this->addSource(Source);
+ // For an integer assignment, make sure it's either a same-type assignment
+ // or a truncation.
+ assert(!isScalarIntegerType(Dest->getType()) ||
+ (typeWidthInBytes(Dest->getType()) <=
+ typeWidthInBytes(Source->getType())));
}
static const char *Opcode;
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h
index 0f1ddd3..6428f53 100644
--- a/src/IceInstX86BaseImpl.h
+++ b/src/IceInstX86BaseImpl.h
@@ -206,7 +206,7 @@
: InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Cmpxchg, 3,
llvm::dyn_cast<Variable>(DestOrAddr),
Locked) {
- assert(Eax->getRegNum() ==
+ assert(InstX86Base<Machine>::Traits::getBaseReg(Eax->getRegNum()) ==
InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
this->addSource(DestOrAddr);
this->addSource(Eax);
@@ -521,10 +521,9 @@
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
Operand *Target = getJmpTarget();
- if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
+ if (const auto *Var = llvm::dyn_cast<Variable>(Target)) {
if (Var->hasReg()) {
- Asm->jmp(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- Var->getRegNum()));
+ Asm->jmp(InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()));
} else {
// The jmp instruction with a memory operand should be possible to
// encode, but it isn't a valid sandboxed instruction, and there
@@ -532,17 +531,17 @@
// register, so we don't really need to bother implementing it.
llvm::report_fatal_error("Assembler can't jmp to memory operand");
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(
Target)) {
(void)Mem;
assert(Mem->getSegmentRegister() ==
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
llvm::report_fatal_error("Assembler can't jmp to memory operand");
- } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
+ } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
assert(CR->getOffset() == 0 && "We only support jumping to a function");
Asm->jmp(CR);
- } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
+ } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
// NaCl trampoline calls refer to an address within the sandbox directly.
// This is usually only needed for non-IRT builds and otherwise not very
// portable or stable. Usually this is only done for "calls" and not jumps.
@@ -570,7 +569,7 @@
Ostream &Str = Func->getContext()->getStrEmit();
assert(this->getSrcSize() == 1);
Str << "\tcall\t";
- if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) {
+ if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) {
// Emit without a leading '$'.
Str << CI->getValue();
} else if (const auto CallTarget =
@@ -588,26 +587,25 @@
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
Operand *Target = getCallTarget();
- if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
+ if (const auto *Var = llvm::dyn_cast<Variable>(Target)) {
if (Var->hasReg()) {
- Asm->call(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- Var->getRegNum()));
+ Asm->call(InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()));
} else {
Asm->call(
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
Func->getTarget())
->stackVarToAsmOperand(Var));
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(
Target)) {
assert(Mem->getSegmentRegister() ==
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
Asm->call(Mem->toAsmAddress(Asm));
- } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
+ } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
assert(CR->getOffset() == 0 && "We only support calling a function");
Asm->call(CR);
- } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
+ } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
Asm->call(Immediate(Imm->getValue()));
} else {
llvm_unreachable("Unexpected operand type");
@@ -628,12 +626,11 @@
getCallTarget()->dump(Func);
}
-// The ShiftHack parameter is used to emit "cl" instead of "ecx" for shift
-// instructions, in order to be syntactically valid. The this->Opcode parameter
-// needs to be char* and not IceString because of template issues.
+// The this->Opcode parameter needs to be char* and not IceString because of
+// template issues.
template <class Machine>
void InstX86Base<Machine>::emitTwoAddress(const char *Opcode, const Inst *Inst,
- const Cfg *Func, bool ShiftHack) {
+ const Cfg *Func) {
if (!BuildDefs::dump())
return;
Ostream &Str = Func->getContext()->getStrEmit();
@@ -645,13 +642,7 @@
Operand *Src1 = Inst->getSrc(1);
Str << "\t" << Opcode << InstX86Base<Machine>::getWidthString(Dest->getType())
<< "\t";
- const auto ShiftReg = llvm::dyn_cast<Variable>(Src1);
- if (ShiftHack && ShiftReg &&
- ShiftReg->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx)
- Str << "%cl";
- else
- Src1->emit(Func);
+ Src1->emit(Func);
Str << ", ";
Dest->emit(Func);
}
@@ -662,12 +653,11 @@
Machine>::Traits::Assembler::GPREmitterOneOp &Emitter) {
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
- if (const auto Var = llvm::dyn_cast<Variable>(Op)) {
+ if (const auto *Var = llvm::dyn_cast<Variable>(Op)) {
if (Var->hasReg()) {
// We cheat a little and use GPRRegister even for byte operations.
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
- Ty, Var->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum());
(Asm->*(Emitter.Reg))(Ty, VarReg);
} else {
typename InstX86Base<Machine>::Traits::Address StackAddr(
@@ -676,7 +666,7 @@
->stackVarToAsmOperand(Var));
(Asm->*(Emitter.Addr))(Ty, StackAddr);
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Op)) {
Mem->emitSegmentOverride(Asm);
(Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm));
@@ -696,17 +686,14 @@
// We cheat a little and use GPRRegister even for byte operations.
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
VarCanBeByte
- ? InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
- Ty, Var->getRegNum())
- : InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- Var->getRegNum());
- if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ ? InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum())
+ : InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum());
+ if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
if (SrcVar->hasReg()) {
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
SrcCanBeByte
- ? InstX86Base<Machine>::Traits::RegisterSet::
- getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum())
- : InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+ ? InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum())
+ : InstX86Base<Machine>::Traits::getEncodedGPR(
SrcVar->getRegNum());
(Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
} else {
@@ -716,17 +703,17 @@
->stackVarToAsmOperand(SrcVar);
(Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
Mem->emitSegmentOverride(Asm);
(Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
- } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
+ } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue()));
- } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
+ } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
AssemblerFixup *Fixup =
Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc);
(Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup));
- } else if (const auto Split = llvm::dyn_cast<
+ } else if (const auto *Split = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) {
(Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
} else {
@@ -744,15 +731,14 @@
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
// Src can only be Reg or Immediate.
- if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
assert(SrcVar->hasReg());
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
- Ty, SrcVar->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum());
(Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg);
- } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
+ } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue()));
- } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
+ } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
AssemblerFixup *Fixup =
Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc);
(Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup));
@@ -766,21 +752,21 @@
const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp
&Emitter) {
- if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) {
+ if (const auto *Op0Var = llvm::dyn_cast<Variable>(Op0)) {
assert(!Op0Var->hasReg());
typename InstX86Base<Machine>::Traits::Address StackAddr(
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
Func->getTarget())
->stackVarToAsmOperand(Op0Var));
emitIASAddrOpTyGPR<Machine>(Func, Ty, StackAddr, Op1, Emitter);
- } else if (const auto Op0Mem = llvm::dyn_cast<
+ } else if (const auto *Op0Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Op0)) {
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
Op0Mem->emitSegmentOverride(Asm);
emitIASAddrOpTyGPR<Machine>(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1,
Emitter);
- } else if (const auto Split = llvm::dyn_cast<
+ } else if (const auto *Split = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::VariableSplit>(Op0)) {
emitIASAddrOpTyGPR<Machine>(Func, Ty, Split->toAsmAddress(Func), Op1,
Emitter);
@@ -801,16 +787,14 @@
assert(Var->hasReg());
// We cheat a little and use GPRRegister even for byte operations.
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
- Ty, Var->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum());
// Src must be reg == ECX or an Imm8. This is asserted by the assembler.
- if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
assert(SrcVar->hasReg());
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
- Ty, SrcVar->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum());
(Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
- } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
+ } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue()));
} else {
llvm_unreachable("Unexpected operand type");
@@ -828,22 +812,20 @@
// Dest can be reg or mem, but we only use the reg variant.
assert(Dest->hasReg());
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister DestReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- Dest->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum());
// SrcVar1 must be reg.
- const auto SrcVar1 = llvm::cast<Variable>(Src1Op);
+ const auto *SrcVar1 = llvm::cast<Variable>(Src1Op);
assert(SrcVar1->hasReg());
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- SrcVar1->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar1->getRegNum());
Type Ty = SrcVar1->getType();
// Src2 can be the implicit CL register or an immediate.
- if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) {
+ if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) {
(Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg,
Immediate(Imm->getValue()));
} else {
assert(llvm::cast<Variable>(Src2Op)->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_cl);
(Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg);
}
}
@@ -857,13 +839,11 @@
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
assert(Var->hasReg());
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- Var->getRegNum());
- if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum());
+ if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
if (SrcVar->hasReg()) {
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum());
(Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
} else {
typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
@@ -872,12 +852,12 @@
->stackVarToAsmOperand(SrcVar);
(Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
assert(Mem->getSegmentRegister() ==
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
(Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
- } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
+ } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(Asm->*(Emitter.XmmImm))(Ty, VarReg, Immediate(Imm->getValue()));
} else {
llvm_unreachable("Unexpected operand type");
@@ -893,13 +873,11 @@
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
assert(Var->hasReg());
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- Var->getRegNum());
- if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum());
+ if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
if (SrcVar->hasReg()) {
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum());
(Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
} else {
typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
@@ -908,12 +886,12 @@
->stackVarToAsmOperand(SrcVar);
(Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
assert(Mem->getSegmentRegister() ==
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
(Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
- } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
+ } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) {
(Asm->*(Emitter.XmmAddr))(
Ty, VarReg,
InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm));
@@ -932,7 +910,7 @@
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
assert(Dest->hasReg());
DReg_t DestReg = destEnc(Dest->getRegNum());
- if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
if (SrcVar->hasReg()) {
SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
(Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg);
@@ -943,7 +921,7 @@
->stackVarToAsmOperand(SrcVar);
(Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr);
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
Mem->emitSegmentOverride(Asm);
(Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, Mem->toAsmAddress(Asm));
@@ -965,7 +943,7 @@
assert(Dest->hasReg());
DReg_t DestReg = destEnc(Dest->getRegNum());
Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue());
- if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) {
+ if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src0)) {
if (SrcVar->hasReg()) {
SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
(Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm);
@@ -976,7 +954,7 @@
->stackVarToAsmOperand(SrcVar);
(Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm);
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Src0)) {
Mem->emitSegmentOverride(Asm);
(Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm),
@@ -995,13 +973,12 @@
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
if (Dest->hasReg()) {
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- Dest->getRegNum());
- if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum());
+ if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
if (SrcVar->hasReg()) {
(Asm->*(Emitter.XmmXmm))(
- DestReg, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum()));
+ DestReg,
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
} else {
typename InstX86Base<Machine>::Traits::Address StackAddr(
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering
@@ -1009,7 +986,7 @@
->stackVarToAsmOperand(SrcVar));
(Asm->*(Emitter.XmmAddr))(DestReg, StackAddr);
}
- } else if (const auto SrcMem = llvm::dyn_cast<
+ } else if (const auto *SrcMem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
assert(SrcMem->getSegmentRegister() ==
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
@@ -1023,11 +1000,11 @@
Func->getTarget())
->stackVarToAsmOperand(Dest));
// Src must be a register in this case.
- const auto SrcVar = llvm::cast<Variable>(Src);
+ const auto *SrcVar = llvm::cast<Variable>(Src);
assert(SrcVar->hasReg());
(Asm->*(Emitter.AddrXmm))(
- StackAddr, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum()));
+ StackAddr,
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
}
}
@@ -1292,11 +1269,10 @@
Variable *Dest = this->getDest();
if (isByteSizedArithType(Dest->getType())) {
// The 8-bit version of imul only allows the form "imul r/m8".
- const auto Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
+ const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
(void)Src0Var;
- assert(Src0Var &&
- Src0Var->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+ assert(Src0Var->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_al);
Str << "\timulb\t";
this->getSrc(1)->emit(Func);
} else if (llvm::isa<Constant>(this->getSrc(1))) {
@@ -1319,11 +1295,10 @@
const Operand *Src = this->getSrc(1);
if (isByteSizedArithType(Ty)) {
// The 8-bit version of imul only allows the form "imul r/m8".
- const auto Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
+ const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
(void)Src0Var;
- assert(Src0Var &&
- Src0Var->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+ assert(Src0Var->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_al);
static const typename InstX86Base<
Machine>::Traits::Assembler::GPREmitterOneOp Emitter = {
&InstX86Base<Machine>::Traits::Assembler::imul,
@@ -1374,8 +1349,8 @@
emitIASThreeOpImmOps<
Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>(
+ InstX86Base<Machine>::Traits::getEncodedGPR,
+ InstX86Base<Machine>::Traits::getEncodedGPR>(
Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter);
}
@@ -1397,8 +1372,8 @@
emitIASThreeOpImmOps<
Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
+ InstX86Base<Machine>::Traits::getEncodedXmm,
+ InstX86Base<Machine>::Traits::getEncodedXmm>(
Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter);
}
@@ -1410,25 +1385,29 @@
assert(this->getSrcSize() == 1);
Operand *Src0 = this->getSrc(0);
assert(llvm::isa<Variable>(Src0));
- assert(llvm::cast<Variable>(Src0)->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
switch (Src0->getType()) {
default:
llvm_unreachable("unexpected source type!");
break;
case IceType_i8:
+ assert(llvm::cast<Variable>(Src0)->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_al);
assert(this->getDest()->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_ax);
Str << "\t"
<< "cbtw";
break;
case IceType_i16:
+ assert(llvm::cast<Variable>(Src0)->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_ax);
assert(this->getDest()->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_dx);
Str << "\t"
<< "cwtd";
break;
case IceType_i32:
+ assert(llvm::cast<Variable>(Src0)->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
assert(this->getDest()->getRegNum() ==
InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
Str << "\t"
@@ -1450,23 +1429,27 @@
assert(this->getSrcSize() == 1);
Operand *Src0 = this->getSrc(0);
assert(llvm::isa<Variable>(Src0));
- assert(llvm::cast<Variable>(Src0)->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
switch (Src0->getType()) {
default:
llvm_unreachable("unexpected source type!");
break;
case IceType_i8:
+ assert(llvm::cast<Variable>(Src0)->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_al);
assert(this->getDest()->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_ax);
Asm->cbw();
break;
case IceType_i16:
+ assert(llvm::cast<Variable>(Src0)->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_ax);
assert(this->getDest()->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_dx);
Asm->cwd();
break;
case IceType_i32:
+ assert(llvm::cast<Variable>(Src0)->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
assert(this->getDest()->getRegNum() ==
InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
Asm->cdq();
@@ -1529,14 +1512,7 @@
assert(this->getSrcSize() == 3);
assert(Dest == this->getSrc(0));
Str << "\tshld" << this->getWidthString(Dest->getType()) << "\t";
- if (const auto ShiftReg = llvm::dyn_cast<Variable>(this->getSrc(2))) {
- (void)ShiftReg;
- assert(ShiftReg->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
- Str << "%cl";
- } else {
- this->getSrc(2)->emit(Func);
- }
+ this->getSrc(2)->emit(Func);
Str << ", ";
this->getSrc(1)->emit(Func);
Str << ", ";
@@ -1576,14 +1552,7 @@
assert(this->getSrcSize() == 3);
assert(Dest == this->getSrc(0));
Str << "\tshrd" << this->getWidthString(Dest->getType()) << "\t";
- if (const auto ShiftReg = llvm::dyn_cast<Variable>(this->getSrc(2))) {
- (void)ShiftReg;
- assert(ShiftReg->getRegNum() ==
- InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
- Str << "%cl";
- } else {
- this->getSrc(2)->emit(Func);
- }
+ this->getSrc(2)->emit(Func);
Str << ", ";
this->getSrc(1)->emit(Func);
Str << ", ";
@@ -1644,27 +1613,24 @@
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
if (SrcVar->hasReg()) {
- Asm->cmov(SrcTy, Condition,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- this->getDest()->getRegNum()),
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- SrcVar->getRegNum()));
+ Asm->cmov(
+ SrcTy, Condition, InstX86Base<Machine>::Traits::getEncodedGPR(
+ this->getDest()->getRegNum()),
+ InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()));
} else {
Asm->cmov(
- SrcTy, Condition,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- this->getDest()->getRegNum()),
+ SrcTy, Condition, InstX86Base<Machine>::Traits::getEncodedGPR(
+ this->getDest()->getRegNum()),
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
Func->getTarget())
->stackVarToAsmOperand(SrcVar));
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
assert(Mem->getSegmentRegister() ==
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
- Asm->cmov(SrcTy, Condition,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- this->getDest()->getRegNum()),
+ Asm->cmov(SrcTy, Condition, InstX86Base<Machine>::Traits::getEncodedGPR(
+ this->getDest()->getRegNum()),
Mem->toAsmAddress(Asm));
} else {
llvm_unreachable("Unexpected operand type");
@@ -1711,19 +1677,18 @@
// Assuming there isn't any load folding for cmpps, and vector constants are
// not allowed in PNaCl.
assert(llvm::isa<Variable>(this->getSrc(1)));
- const auto SrcVar = llvm::cast<Variable>(this->getSrc(1));
+ const auto *SrcVar = llvm::cast<Variable>(this->getSrc(1));
if (SrcVar->hasReg()) {
- Asm->cmpps(InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+ Asm->cmpps(InstX86Base<Machine>::Traits::getEncodedXmm(
this->getDest()->getRegNum()),
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum()),
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()),
Condition);
} else {
typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
Func->getTarget())
->stackVarToAsmOperand(SrcVar);
- Asm->cmpps(InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+ Asm->cmpps(InstX86Base<Machine>::Traits::getEncodedXmm(
this->getDest()->getRegNum()),
SrcStackAddr, Condition);
}
@@ -1772,11 +1737,10 @@
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
const typename InstX86Base<Machine>::Traits::Address Addr =
Mem->toAsmAddress(Asm);
- const auto VarReg = llvm::cast<Variable>(this->getSrc(2));
+ const auto *VarReg = llvm::cast<Variable>(this->getSrc(2));
assert(VarReg->hasReg());
const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- VarReg->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(VarReg->getRegNum());
Asm->cmpxchg(Ty, Addr, Reg, this->Locked);
}
@@ -1877,9 +1841,9 @@
Machine,
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>(
- Func, DestTy, Dest, SrcTy, Src, Emitter);
+ InstX86Base<Machine>::Traits::getEncodedXmm,
+ InstX86Base<Machine>::Traits::getEncodedGPR>(Func, DestTy, Dest, SrcTy,
+ Src, Emitter);
return;
}
case Tss2si: {
@@ -1900,9 +1864,9 @@
Machine,
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
- Func, DestTy, Dest, SrcTy, Src, Emitter);
+ InstX86Base<Machine>::Traits::getEncodedGPR,
+ InstX86Base<Machine>::Traits::getEncodedXmm>(Func, DestTy, Dest, SrcTy,
+ Src, Emitter);
return;
}
case Float2float: {
@@ -1982,7 +1946,7 @@
Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = {
&InstX86Base<Machine>::Traits::Assembler::cmp,
&InstX86Base<Machine>::Traits::Assembler::cmp};
- if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
+ if (const auto *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
if (SrcVar0->hasReg()) {
emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter);
return;
@@ -2021,7 +1985,7 @@
// Currently src0 is always a variable by convention, to avoid having two
// memory operands.
assert(llvm::isa<Variable>(this->getSrc(0)));
- const auto Src0Var = llvm::cast<Variable>(this->getSrc(0));
+ const auto *Src0Var = llvm::cast<Variable>(this->getSrc(0));
Type Ty = Src0Var->getType();
static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
Emitter = {&InstX86Base<Machine>::Traits::Assembler::ucomiss,
@@ -2086,7 +2050,7 @@
Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = {
&InstX86Base<Machine>::Traits::Assembler::test,
&InstX86Base<Machine>::Traits::Assembler::test};
- if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
+ if (const auto *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
if (SrcVar0->hasReg()) {
emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter);
return;
@@ -2150,14 +2114,13 @@
Type DestTy = Dest->getType();
if (isScalarFloatingType(DestTy)) {
// Src must be a register, since Dest is a Mem operand of some kind.
- const auto SrcVar = llvm::cast<Variable>(Src);
+ const auto *SrcVar = llvm::cast<Variable>(Src);
assert(SrcVar->hasReg());
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum());
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
- if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) {
+ if (const auto *DestVar = llvm::dyn_cast<Variable>(Dest)) {
assert(!DestVar->hasReg());
typename InstX86Base<Machine>::Traits::Address StackAddr(
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
@@ -2212,7 +2175,7 @@
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
assert(this->getSrcSize() == 2);
- const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
+ const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0));
const auto DestMem =
llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
this->getSrc(1));
@@ -2220,8 +2183,7 @@
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
assert(SrcVar->hasReg());
Asm->movups(DestMem->toAsmAddress(Asm),
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum()));
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
}
template <class Machine>
@@ -2255,7 +2217,7 @@
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
assert(this->getSrcSize() == 2);
- const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
+ const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0));
const auto DestMem =
llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
this->getSrc(1));
@@ -2263,8 +2225,7 @@
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
assert(SrcVar->hasReg());
Asm->movq(DestMem->toAsmAddress(Asm),
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum()));
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
}
template <class Machine>
@@ -2286,11 +2247,12 @@
assert(this->getDest()->hasReg());
Str << "\tleal\t";
Operand *Src0 = this->getSrc(0);
- if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) {
+ if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) {
Type Ty = Src0Var->getType();
// lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
// acceptable type.
- Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func);
+ Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister)
+ ->emit(Func);
} else {
Src0->emit(Func);
}
@@ -2334,7 +2296,14 @@
Func->getTarget()->typeWidthInBytesOnStack(SrcTy));
Src->emit(Func);
Str << ", ";
- this->getDest()->asType(SrcTy)->emit(Func);
+ int32_t NewRegNum = Variable::NoRegister;
+ if (this->getDest()->hasReg())
+ NewRegNum = InstX86Base<Machine>::Traits::getGprForType(
+ SrcTy, this->getDest()->getRegNum());
+ const Variable *NewDest = SrcTy == DestTy
+ ? this->getDest()
+ : this->getDest()->asType(SrcTy, NewRegNum);
+ NewDest->emit(Func);
}
template <class Machine>
@@ -2391,9 +2360,9 @@
Value = llvm::cast<ConstantInteger32>(Src)->getValue();
}
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>()
- ->movabs(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- Dest->getRegNum()),
- Value);
+ ->movabs(
+ InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum()),
+ Value);
return;
}
if (isScalarIntegerType(SrcTy)) {
@@ -2411,14 +2380,13 @@
->stackVarToAsmOperand(Dest));
if (isScalarFloatingType(SrcTy)) {
// Src must be a register.
- const auto SrcVar = llvm::cast<Variable>(Src);
+ const auto *SrcVar = llvm::cast<Variable>(Src);
assert(SrcVar->hasReg());
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<
typename InstX86Base<Machine>::Traits::Assembler>();
- Asm->movss(SrcTy, StackAddr,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum()));
+ Asm->movss(SrcTy, StackAddr, InstX86Base<Machine>::Traits::getEncodedXmm(
+ SrcVar->getRegNum()));
return;
} else {
// Src can be a register or immediate.
@@ -2436,7 +2404,7 @@
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
assert(this->getSrcSize() == 1);
const Variable *Dest = this->getDest();
- const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
+ const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0));
// For insert/extract element (one of Src/Dest is an Xmm vector and the other
// is an int type).
if (SrcVar->getType() == IceType_i32 ||
@@ -2448,12 +2416,11 @@
typeWidthInBytes(Dest->getType())));
assert(Dest->hasReg());
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- Dest->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum());
if (SrcVar->hasReg()) {
- Asm->movd(SrcVar->getType(), DestReg,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- SrcVar->getRegNum()));
+ Asm->movd(
+ SrcVar->getType(), DestReg,
+ InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()));
} else {
typename InstX86Base<Machine>::Traits::Address StackAddr(
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
@@ -2471,12 +2438,10 @@
(InstX86Base<Machine>::Traits::Is64Bit &&
Dest->getType() == IceType_i64));
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum());
if (Dest->hasReg()) {
Asm->movd(Dest->getType(),
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- Dest->getRegNum()),
+ InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum()),
SrcReg);
} else {
typename InstX86Base<Machine>::Traits::Address StackAddr(
@@ -2553,15 +2518,13 @@
assert(this->getSrcSize() == 2);
const Variable *Dest = this->getDest();
assert(Dest == this->getSrc(0));
- const auto SrcVar = llvm::cast<Variable>(this->getSrc(1));
+ const auto *SrcVar = llvm::cast<Variable>(this->getSrc(1));
assert(Dest->hasReg() && SrcVar->hasReg());
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
Asm->movss(IceType_f32,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- Dest->getRegNum()),
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- SrcVar->getRegNum()));
+ InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum()),
+ InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
}
template <class Machine>
@@ -2621,7 +2584,7 @@
assert(this->getSrcSize() == 1);
Type Ty = this->getSrc(0)->getType();
SizeT Width = typeWidthInBytes(Ty);
- const auto Var = llvm::dyn_cast<Variable>(this->getSrc(0));
+ const auto *Var = llvm::dyn_cast<Variable>(this->getSrc(0));
if (Var && Var->hasReg()) {
// This is a physical xmm register, so we need to spill it to a temporary
// stack slot.
@@ -2647,7 +2610,7 @@
assert(this->getSrcSize() == 1);
const Operand *Src = this->getSrc(0);
Type Ty = Src->getType();
- if (const auto Var = llvm::dyn_cast<Variable>(Src)) {
+ if (const auto *Var = llvm::dyn_cast<Variable>(Src)) {
if (Var->hasReg()) {
// This is a physical xmm register, so we need to spill it to a temporary
// stack slot.
@@ -2660,8 +2623,7 @@
InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0,
AssemblerFixup::NoFixup);
Asm->movss(Ty, StackSlot,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- Var->getRegNum()));
+ InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum()));
Asm->fld(Ty, StackSlot);
Asm->add(IceType_i32,
InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp,
@@ -2673,12 +2635,12 @@
->stackVarToAsmOperand(Var));
Asm->fld(Ty, StackAddr);
}
- } else if (const auto Mem = llvm::dyn_cast<
+ } else if (const auto *Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
assert(Mem->getSegmentRegister() ==
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
Asm->fld(Ty, Mem->toAsmAddress(Asm));
- } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
+ } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) {
Asm->fld(Ty, InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm));
} else {
llvm_unreachable("Unexpected operand type");
@@ -2759,8 +2721,8 @@
InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0,
AssemblerFixup::NoFixup);
Asm->fstp(Ty, StackSlot);
- Asm->movss(Ty, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
- Dest->getRegNum()),
+ Asm->movss(Ty,
+ InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum()),
StackSlot);
Asm->add(IceType_i32,
InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, Width);
@@ -2825,7 +2787,7 @@
// memory dest, but we aren't using it. For uniformity, just restrict them
// all to have a register dest for now.
assert(Dest->hasReg());
- Dest->asType(IceType_i32)->emit(Func);
+ Dest->asType(IceType_i32, Dest->getRegNum())->emit(Func);
}
template <class Machine>
@@ -2833,7 +2795,8 @@
assert(this->getSrcSize() == 2);
// pextrb and pextrd are SSE4.1 instructions.
const Variable *Dest = this->getDest();
- Type DispatchTy = Dest->getType();
+ Type DispatchTy = InstX86Base<Machine>::Traits::getInVectorElementType(
+ this->getSrc(0)->getType());
assert(DispatchTy == IceType_i16 ||
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
Func->getTarget())
@@ -2852,8 +2815,8 @@
emitIASThreeOpImmOps<
Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
+ InstX86Base<Machine>::Traits::getEncodedGPR,
+ InstX86Base<Machine>::Traits::getEncodedXmm>(
Func, DispatchTy, Dest, this->getSrc(0), this->getSrc(1), Emitter);
}
@@ -2876,10 +2839,13 @@
this->getSrc(2)->emit(Func);
Str << ", ";
Operand *Src1 = this->getSrc(1);
- if (const auto Src1Var = llvm::dyn_cast<Variable>(Src1)) {
+ if (const auto *Src1Var = llvm::dyn_cast<Variable>(Src1)) {
// If src1 is a register, it should always be r32.
if (Src1Var->hasReg()) {
- Src1Var->asType(IceType_i32)->emit(Func);
+ int32_t NewRegNum =
+ InstX86Base<Machine>::Traits::getBaseReg(Src1Var->getRegNum());
+ const Variable *NewSrc = Src1Var->asType(IceType_i32, NewRegNum);
+ NewSrc->emit(Func);
} else {
Src1Var->emit(Func);
}
@@ -2903,7 +2869,19 @@
->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
// If src1 is a register, it should always be r32 (this should fall out from
// the encodings for ByteRegs overlapping the encodings for r32), but we have
- // to trust the regalloc to not choose "ah", where it doesn't overlap.
+ // to make sure the register allocator didn't choose an 8-bit high register
+ // like "ah".
+ if (BuildDefs::asserts()) {
+ if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) {
+ if (Src0Var->hasReg()) {
+ int32_t RegNum = Src0Var->getRegNum();
+ int32_t BaseRegNum = InstX86Base<Machine>::Traits::getBaseReg(RegNum);
+ (void)BaseRegNum;
+ assert(InstX86Base<Machine>::Traits::getEncodedGPR(RegNum) ==
+ InstX86Base<Machine>::Traits::getEncodedGPR(BaseRegNum));
+ }
+ }
+ }
static const typename InstX86Base<Machine>::Traits::Assembler::
template ThreeOpImmEmitter<
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
@@ -2913,8 +2891,8 @@
emitIASThreeOpImmOps<
Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>(
+ InstX86Base<Machine>::Traits::getEncodedXmm,
+ InstX86Base<Machine>::Traits::getEncodedGPR>(
Func, DispatchTy, this->getDest(), Src0, this->getSrc(2), Emitter);
}
@@ -2932,8 +2910,8 @@
emitIASThreeOpImmOps<
Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
+ InstX86Base<Machine>::Traits::getEncodedXmm,
+ InstX86Base<Machine>::Traits::getEncodedXmm>(
Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter);
}
@@ -2952,8 +2930,8 @@
emitIASThreeOpImmOps<
Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
+ InstX86Base<Machine>::Traits::getEncodedXmm,
+ InstX86Base<Machine>::Traits::getEncodedXmm>(
Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter);
}
@@ -2972,7 +2950,7 @@
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
if (this->getDest()->hasReg()) {
- Asm->popl(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+ Asm->popl(InstX86Base<Machine>::Traits::getEncodedGPR(
this->getDest()->getRegNum()));
} else {
Asm->popl(
@@ -3024,7 +3002,7 @@
Ostream &Str = Func->getContext()->getStrEmit();
assert(this->getSrcSize() == 1);
// Push is currently only used for saving GPRs.
- const auto Var = llvm::cast<Variable>(this->getSrc(0));
+ const auto *Var = llvm::cast<Variable>(this->getSrc(0));
assert(Var->hasReg());
Str << "\tpush\t";
Var->emit(Func);
@@ -3034,12 +3012,11 @@
void InstX86Push<Machine>::emitIAS(const Cfg *Func) const {
assert(this->getSrcSize() == 1);
// Push is currently only used for saving GPRs.
- const auto Var = llvm::cast<Variable>(this->getSrc(0));
+ const auto *Var = llvm::cast<Variable>(this->getSrc(0));
assert(Var->hasReg());
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
- Asm->pushl(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- Var->getRegNum()));
+ Asm->pushl(InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()));
}
template <class Machine>
@@ -3138,9 +3115,8 @@
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
if (this->getDest()->hasReg())
- Asm->setcc(Condition,
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteReg(
- this->getDest()->getRegNum()));
+ Asm->setcc(Condition, InstX86Base<Machine>::Traits::getEncodedByteReg(
+ this->getDest()->getRegNum()));
else
Asm->setcc(
Condition,
@@ -3188,11 +3164,10 @@
InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
const typename InstX86Base<Machine>::Traits::Address Addr =
Mem->toAsmAddress(Asm);
- const auto VarReg = llvm::cast<Variable>(this->getSrc(1));
+ const auto *VarReg = llvm::cast<Variable>(this->getSrc(1));
assert(VarReg->hasReg());
const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- VarReg->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(VarReg->getRegNum());
Asm->xadd(Ty, Addr, Reg, this->Locked);
}
@@ -3229,14 +3204,12 @@
const auto *VarReg1 = llvm::cast<Variable>(this->getSrc(1));
assert(VarReg1->hasReg());
const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg1 =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- VarReg1->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(VarReg1->getRegNum());
if (const auto *VarReg0 = llvm::dyn_cast<Variable>(this->getSrc(0))) {
assert(VarReg0->hasReg());
const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg0 =
- InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
- VarReg0->getRegNum());
+ InstX86Base<Machine>::Traits::getEncodedGPR(VarReg0->getRegNum());
Asm->xchg(Ty, Reg0, Reg1);
return;
}
diff --git a/src/IceIntrinsics.h b/src/IceIntrinsics.h
index 208c3c1..11db543 100644
--- a/src/IceIntrinsics.h
+++ b/src/IceIntrinsics.h
@@ -22,7 +22,7 @@
class InstCall;
-static const size_t kMaxIntrinsicParameters = 6;
+static constexpr size_t kMaxIntrinsicParameters = 6;
class Intrinsics {
Intrinsics(const Intrinsics &) = delete;
diff --git a/src/IceOperand.cpp b/src/IceOperand.cpp
index 66321c2..e66a995 100644
--- a/src/IceOperand.cpp
+++ b/src/IceOperand.cpp
@@ -131,7 +131,7 @@
return "__" + std::to_string(getIndex());
}
-Variable *Variable::asType(Type Ty) {
+const Variable *Variable::asType(Type Ty, int32_t NewRegNum) const {
// Note: This returns a Variable, even if the "this" object is a subclass of
// Variable.
if (!BuildDefs::dump() || getType() == Ty)
@@ -139,7 +139,7 @@
Variable *V = new (getCurrentCfgAllocator()->Allocate<Variable>())
Variable(kVariable, Ty, Number);
V->NameIndex = NameIndex;
- V->RegNum = RegNum;
+ V->RegNum = NewRegNum == NoRegister ? RegNum : NewRegNum;
V->StackOffset = StackOffset;
return V;
}
diff --git a/src/IceOperand.h b/src/IceOperand.h
index ea56b29..0addc88 100644
--- a/src/IceOperand.h
+++ b/src/IceOperand.h
@@ -349,9 +349,9 @@
explicit RegWeight(uint32_t Weight) : Weight(Weight) {}
RegWeight(const RegWeight &) = default;
RegWeight &operator=(const RegWeight &) = default;
- const static uint32_t Inf = ~0; /// Force regalloc to give a register
- const static uint32_t Zero = 0; /// Force regalloc NOT to give a register
- const static uint32_t Max = Inf - 1; /// Max natural weight.
+ constexpr static uint32_t Inf = ~0; /// Force regalloc to give a register
+ constexpr static uint32_t Zero = 0; /// Force regalloc NOT to give a register
+ constexpr static uint32_t Max = Inf - 1; /// Max natural weight.
void addWeight(uint32_t Delta) {
if (Delta == Inf)
Weight = Inf;
@@ -472,7 +472,7 @@
return "lv$" + getName(Func);
}
- static const int32_t NoRegister = -1;
+ static constexpr int32_t NoRegister = -1;
bool hasReg() const { return getRegNum() != NoRegister; }
int32_t getRegNum() const { return RegNum; }
void setRegNum(int32_t NewRegNum) {
@@ -507,11 +507,11 @@
return Live.endsBefore(Other->Live);
}
bool rangeOverlaps(const Variable *Other) const {
- const bool UseTrimmed = true;
+ constexpr bool UseTrimmed = true;
return Live.overlaps(Other->Live, UseTrimmed);
}
bool rangeOverlapsStart(const Variable *Other) const {
- const bool UseTrimmed = true;
+ constexpr bool UseTrimmed = true;
return Live.overlapsInst(Other->Live.getStart(), UseTrimmed);
}
@@ -519,8 +519,9 @@
/// primarily for syntactic correctness of textual assembly emission. Note
/// that only basic information is copied, in particular not IsArgument,
/// IsImplicitArgument, IgnoreLiveness, RegNumTmp, Live, LoVar, HiVar,
- /// VarsReal.
- Variable *asType(Type Ty);
+ /// VarsReal. If NewRegNum!=NoRegister, then that register assignment is made
+ /// instead of copying the existing assignment.
+ const Variable *asType(Type Ty, int32_t NewRegNum) const;
void emit(const Cfg *Func) const override;
using Operand::dump;
diff --git a/src/IcePhiLoweringImpl.h b/src/IcePhiLoweringImpl.h
index 1957645..d65620e 100644
--- a/src/IcePhiLoweringImpl.h
+++ b/src/IcePhiLoweringImpl.h
@@ -32,7 +32,7 @@
template <class TargetT>
void prelowerPhis32Bit(TargetT *Target, CfgNode *Node, Cfg *Func) {
for (Inst &I : Node->getPhis()) {
- auto Phi = llvm::dyn_cast<InstPhi>(&I);
+ auto *Phi = llvm::dyn_cast<InstPhi>(&I);
if (Phi->isDeleted())
continue;
Variable *Dest = Phi->getDest();
diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp
index 908020f..6b8656b 100644
--- a/src/IceRegAlloc.cpp
+++ b/src/IceRegAlloc.cpp
@@ -123,7 +123,7 @@
return;
for (CfgNode *Node : Func->getNodes()) {
for (Inst &I : Node->getInsts()) {
- if (auto Kill = llvm::dyn_cast<InstFakeKill>(&I)) {
+ if (auto *Kill = llvm::dyn_cast<InstFakeKill>(&I)) {
if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted())
Kills.push_back(I.getNumber());
}
diff --git a/src/IceRegList.h b/src/IceRegList.h
new file mode 100644
index 0000000..4b21044
--- /dev/null
+++ b/src/IceRegList.h
@@ -0,0 +1,35 @@
+//===- subzero/src/IceRegList.h - Register list macro defs -----*- C++ -*-===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the REGLIST*() macros used in the IceInst*.def files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEINSTREGLIST_H
+#define SUBZERO_SRC_ICEINSTREGLIST_H
+
+// REGLISTn is a family of macros that we use to define register aliasing. "n"
+// indicates how many register aliases are being provided to the macro. It
+// assumes the parameters are register names declared in the "ns"
+// namespace/class, but with the common "Reg_" prefix removed for brevity.
+#define REGLIST1(ns, r0) \
+ { ns::Reg_##r0 }
+#define REGLIST2(ns, r0, r1) \
+ { ns::Reg_##r0, ns::Reg_##r1 }
+#define REGLIST3(ns, r0, r1, r2) \
+ { ns::Reg_##r0, ns::Reg_##r1, ns::Reg_##r2 }
+#define REGLIST4(ns, r0, r1, r2, r3) \
+ { ns::Reg_##r0, ns::Reg_##r1, ns::Reg_##r2, ns::Reg_##r3 }
+#define REGLIST6(ns, r0, r1, r2, r3, r4, r5) \
+ { \
+ ns::Reg_##r0, ns::Reg_##r1, ns::Reg_##r2, ns::Reg_##r3, ns::Reg_##r4, \
+ ns::Reg_##r5 \
+ }
+
+#endif // SUBZERO_SRC_ICEINSTREGLIST_H
diff --git a/src/IceRegistersX8632.h b/src/IceRegistersX8632.h
index 73492ef..3fa07f8 100644
--- a/src/IceRegistersX8632.h
+++ b/src/IceRegistersX8632.h
@@ -26,22 +26,21 @@
/// An enum of every register. The enum value may not match the encoding used
/// to binary encode register operands in instructions.
enum AllRegisters {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
val,
REGX8632_TABLE
#undef X
- Reg_NUM,
-#define X(val, init) val init,
- REGX8632_TABLE_BOUNDS
-#undef X
+ Reg_NUM
};
/// An enum of GPR Registers. The enum value does match the encoding used to
/// binary encode register operands in instructions.
enum GPRRegister {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
Encoded_##val = encode,
REGX8632_GPR_TABLE
#undef X
@@ -51,8 +50,9 @@
/// An enum of XMM Registers. The enum value does match the encoding used to
/// binary encode register operands in instructions.
enum XmmRegister {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
Encoded_##val = encode,
REGX8632_XMM_TABLE
#undef X
@@ -62,7 +62,10 @@
/// An enum of Byte Registers. The enum value does match the encoding used to
/// binary encode register operands in instructions.
enum ByteRegister {
-#define X(val, encode) Encoded_##val encode,
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ Encoded_8_##val = encode,
REGX8632_BYTEREG_TABLE
#undef X
Encoded_Not_ByteReg = -1
@@ -71,37 +74,12 @@
/// An enum of X87 Stack Registers. The enum value does match the encoding
/// used to binary encode register operands in instructions.
enum X87STRegister {
-#define X(val, encode, name) Encoded_##val encode,
+#define X(val, encode, name) Encoded_##val = encode,
X87ST_REGX8632_TABLE
#undef X
Encoded_Not_X87STReg = -1
};
- static inline GPRRegister getEncodedGPR(int32_t RegNum) {
- assert(Reg_GPR_First <= RegNum);
- assert(RegNum <= Reg_GPR_Last);
- return GPRRegister(RegNum - Reg_GPR_First);
- }
-
- static inline XmmRegister getEncodedXmm(int32_t RegNum) {
- assert(Reg_XMM_First <= RegNum);
- assert(RegNum <= Reg_XMM_Last);
- return XmmRegister(RegNum - Reg_XMM_First);
- }
-
- static inline ByteRegister getEncodedByteReg(int32_t RegNum) {
- assert(Reg_GPR_First <= RegNum);
- assert(RegNum <= Reg_ebx);
- return ByteRegister(RegNum - Reg_GPR_First);
- }
-
- static inline GPRRegister getEncodedByteRegOrGPR(Type Ty, int32_t RegNum) {
- if (isByteSizedType(Ty))
- return GPRRegister(getEncodedByteReg(RegNum));
- else
- return getEncodedGPR(RegNum);
- }
-
static inline X87STRegister getEncodedSTReg(int32_t RegNum) {
assert(Encoded_X87ST_First <= RegNum);
assert(RegNum <= Encoded_X87ST_Last);
diff --git a/src/IceRegistersX8664.h b/src/IceRegistersX8664.h
index 3a10f00..d9ca1f9 100644
--- a/src/IceRegistersX8664.h
+++ b/src/IceRegistersX8664.h
@@ -26,23 +26,22 @@
/// An enum of every register. The enum value may not match the encoding used
/// to binary encode register operands in instructions.
enum AllRegisters {
-#define X(val, encode, name64, name, name16, name8, scratch, preserved, \
- stackptr, frameptr, isInt, isFP) \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
val,
REGX8664_TABLE
#undef X
- Reg_NUM,
-#define X(val, init) val init,
- REGX8664_TABLE_BOUNDS
-#undef X
+ Reg_NUM
};
/// An enum of GPR Registers. The enum value does match the encoding used to
/// binary encode register operands in instructions.
enum GPRRegister {
-#define X(val, encode, name64, name, name16, name8, scratch, preserved, \
- stackptr, frameptr, isInt, isFP) \
- Encoded_##val encode,
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ Encoded_##val = encode,
REGX8664_GPR_TABLE
#undef X
Encoded_Not_GPR = -1
@@ -51,9 +50,10 @@
/// An enum of XMM Registers. The enum value does match the encoding used to
/// binary encode register operands in instructions.
enum XmmRegister {
-#define X(val, encode, name64, name, name16, name8, scratch, preserved, \
- stackptr, frameptr, isInt, isFP) \
- Encoded_##val encode,
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ Encoded_##val = encode,
REGX8664_XMM_TABLE
#undef X
Encoded_Not_Xmm = -1
@@ -62,36 +62,14 @@
/// An enum of Byte Registers. The enum value does match the encoding used to
/// binary encode register operands in instructions.
enum ByteRegister {
-#define X(val, encode) Encoded_##val encode,
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ Encoded_8_##val = encode,
REGX8664_BYTEREG_TABLE
#undef X
Encoded_Not_ByteReg = -1
};
-
- static inline GPRRegister getEncodedGPR(int32_t RegNum) {
- assert(Reg_GPR_First <= RegNum);
- assert(RegNum <= Reg_GPR_Last);
- return GPRRegister(RegNum - Reg_GPR_First);
- }
-
- static inline XmmRegister getEncodedXmm(int32_t RegNum) {
- assert(Reg_XMM_First <= RegNum);
- assert(RegNum <= Reg_XMM_Last);
- return XmmRegister(RegNum - Reg_XMM_First);
- }
-
- static inline ByteRegister getEncodedByteReg(int32_t RegNum) {
- assert(Reg_GPR_First <= RegNum);
- assert(RegNum <= Reg_GPR_Last);
- return ByteRegister(RegNum - Reg_GPR_First);
- }
-
- static inline GPRRegister getEncodedByteRegOrGPR(Type Ty, int32_t RegNum) {
- if (isByteSizedType(Ty))
- return GPRRegister(getEncodedByteReg(RegNum));
- else
- return getEncodedGPR(RegNum);
- }
};
} // end of namespace Ice
diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp
index 585f372..4902a3d 100644
--- a/src/IceTargetLowering.cpp
+++ b/src/IceTargetLowering.cpp
@@ -112,7 +112,7 @@
Cfg *Func) {
#define SUBZERO_TARGET(X) \
if (Target == Target_##X) \
- return std::unique_ptr<Assembler>(new X::Assembler##X(Func->getContext()));
+ return std::unique_ptr<Assembler>(new X::Assembler##X());
#include "llvm/Config/SZTargets.def"
Func->setError("Unsupported target assembler");
@@ -460,7 +460,7 @@
InstCall *TargetLowering::makeHelperCall(const IceString &Name, Variable *Dest,
SizeT MaxSrcs) {
- const bool HasTailCall = false;
+ constexpr bool HasTailCall = false;
Constant *CallTarget = Ctx->getConstantExternSym(Name);
InstCall *Call =
InstCall::create(Func, MaxSrcs, Dest, CallTarget, HasTailCall);
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 282fde1..a15b4f6 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -183,7 +183,7 @@
"Duplicate alias for " #val); \
RegisterAliases[RegARM32::val].set(RegAlias); \
} \
- assert(RegisterAliases[RegARM32::val][RegARM32::val]); \
+ RegisterAliases[RegARM32::val].set(RegARM32::val); \
ScratchRegs[RegARM32::val] = scratch;
REGARM32_TABLE;
#undef X
@@ -2578,7 +2578,7 @@
namespace {
inline uint64_t getConstantMemoryOrder(Operand *Opnd) {
- if (auto Integer = llvm::dyn_cast<ConstantInteger32>(Opnd))
+ if (auto *Integer = llvm::dyn_cast<ConstantInteger32>(Opnd))
return Integer->getValue();
return Intrinsics::MemoryOrderInvalid;
}
@@ -3496,7 +3496,7 @@
// OperandARM32Flex, Constant, and Variable. Given the above assertion, if
// type of operand is not legal (e.g., OperandARM32Mem and !Legal_Mem), we
// can always copy to a register.
- if (auto Mem = llvm::dyn_cast<OperandARM32Mem>(From)) {
+ if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(From)) {
static const struct {
bool CanHaveOffset;
bool CanHaveIndex;
@@ -3561,9 +3561,9 @@
return From;
}
- if (auto Flex = llvm::dyn_cast<OperandARM32Flex>(From)) {
+ if (auto *Flex = llvm::dyn_cast<OperandARM32Flex>(From)) {
if (!(Allowed & Legal_Flex)) {
- if (auto FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Flex)) {
+ if (auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Flex)) {
if (FlexReg->getShiftOp() == OperandARM32::kNoShift) {
From = FlexReg->getReg();
// Fall through and let From be checked as a Variable below, where it
@@ -3644,7 +3644,7 @@
}
}
- if (auto Var = llvm::dyn_cast<Variable>(From)) {
+ if (auto *Var = llvm::dyn_cast<Variable>(From)) {
// Check if the variable is guaranteed a physical register. This can happen
// either when the variable is pre-colored or when it is assigned infinite
// weight.
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
index a7e579e..2bfdf72 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -1000,7 +1000,7 @@
// Given the above assertion, if type of operand is not legal
// (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy
// to a register.
- if (auto C = llvm::dyn_cast<ConstantRelocatable>(From)) {
+ if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) {
(void)C;
return From;
} else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
@@ -1027,7 +1027,7 @@
}
return Reg;
}
- if (auto Var = llvm::dyn_cast<Variable>(From)) {
+ if (auto *Var = llvm::dyn_cast<Variable>(From)) {
// Check if the variable is guaranteed a physical register. This
// can happen either when the variable is pre-colored or when it is
// assigned infinite weight.
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index dfb42d8..6fab884 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -438,8 +438,7 @@
size_t PreservedRegsSizeBytes = 0;
llvm::SmallBitVector Pushed(CalleeSaves.size());
for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
- // SizeT Canonical = RegX8632::getCanonicalReg(i); // TODO(stichnot)
- SizeT Canonical = i;
+ SizeT Canonical = Traits::getBaseReg(i);
if (CalleeSaves[i] && RegsUsed[i]) {
Pushed[Canonical] = true;
}
@@ -611,18 +610,18 @@
getRegisterSet(RegSet_CalleeSave, RegSet_None);
llvm::SmallBitVector Popped(CalleeSaves.size());
for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
- // SizeT Canonical = RegX8632::getCanonicalReg(i); // TODO(stichnot)
- SizeT Canonical = i;
+ SizeT Canonical = Traits::getBaseReg(i);
if (CalleeSaves[i] && RegsUsed[i]) {
Popped[Canonical] = true;
}
}
for (SizeT i = 0; i < Popped.size(); ++i) {
SizeT j = Popped.size() - i - 1;
+ SizeT Canonical = Traits::getBaseReg(j);
if (j == Traits::RegisterSet::Reg_ebp && IsEbpBasedFrame)
continue;
if (Popped[j]) {
- _pop(getPhysicalRegister(j));
+ _pop(getPhysicalRegister(Canonical));
}
}
diff --git a/src/IceTargetLoweringX8632Traits.h b/src/IceTargetLoweringX8632Traits.h
index 6872547..1c92bed 100644
--- a/src/IceTargetLoweringX8632Traits.h
+++ b/src/IceTargetLoweringX8632Traits.h
@@ -60,8 +60,8 @@
enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
using GPRRegister = ::Ice::RegX8632::GPRRegister;
- using XmmRegister = ::Ice::RegX8632::XmmRegister;
using ByteRegister = ::Ice::RegX8632::ByteRegister;
+ using XmmRegister = ::Ice::RegX8632::XmmRegister;
using X87STRegister = ::Ice::RegX8632::X87STRegister;
using Cond = ::Ice::CondX86;
@@ -267,60 +267,161 @@
static const char *TargetName;
static constexpr Type WordType = IceType_i32;
- static IceString getRegName(SizeT RegNum, Type Ty) {
- assert(RegNum < RegisterSet::Reg_NUM);
- static const char *RegNames8[] = {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
- name8,
- REGX8632_TABLE
-#undef X
- };
-
- static const char *RegNames16[] = {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
- name16,
- REGX8632_TABLE
-#undef X
- };
-
- static const char *RegNames[] = {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
+ static IceString getRegName(int32_t RegNum) {
+ static const char *const RegNames[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
name,
REGX8632_TABLE
#undef X
};
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ return RegNames[RegNum];
+ }
- switch (Ty) {
- case IceType_i1:
- case IceType_i8:
- return RegNames8[RegNum];
- case IceType_i16:
- return RegNames16[RegNum];
- default:
- return RegNames[RegNum];
+ static GPRRegister getEncodedGPR(int32_t RegNum) {
+ static const GPRRegister GPRRegs[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR),
+ REGX8632_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR);
+ return GPRRegs[RegNum];
+ }
+
+ static ByteRegister getEncodedByteReg(int32_t RegNum) {
+ static const ByteRegister ByteRegs[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg),
+ REGX8632_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg);
+ return ByteRegs[RegNum];
+ }
+
+ static XmmRegister getEncodedXmm(int32_t RegNum) {
+ static const XmmRegister XmmRegs[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm),
+ REGX8632_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm);
+ return XmmRegs[RegNum];
+ }
+
+ static uint32_t getEncoding(int32_t RegNum) {
+ static const uint32_t Encoding[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ encode,
+ REGX8632_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ return Encoding[RegNum];
+ }
+
+ static int32_t getBaseReg(int32_t RegNum) {
+ static const int32_t BaseRegs[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ RegisterSet::base,
+ REGX8632_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ return BaseRegs[RegNum];
+ }
+
+ // Return a register in RegNum's alias set that is suitable for Ty.
+ static int32_t getGprForType(Type Ty, int32_t RegNum) {
+ assert(RegNum != Variable::NoRegister);
+ // TODO(stichnot): Rewrite this as a table lookup from a table computed in a
+ // TargetLowering static initializer.
+ RegNum = getBaseReg(RegNum);
+ if (Ty == IceType_i8 || Ty == IceType_i1) {
+ switch (RegNum) {
+ default:
+ assert(0);
+ case RegisterSet::Reg_eax:
+ return RegisterSet::Reg_al;
+ case RegisterSet::Reg_ecx:
+ return RegisterSet::Reg_cl;
+ case RegisterSet::Reg_edx:
+ return RegisterSet::Reg_dl;
+ case RegisterSet::Reg_ebx:
+ return RegisterSet::Reg_bl;
+ }
}
+ if (Ty == IceType_i16) {
+ switch (RegNum) {
+ default:
+ assert(0);
+ case RegisterSet::Reg_eax:
+ return RegisterSet::Reg_ax;
+ case RegisterSet::Reg_ecx:
+ return RegisterSet::Reg_cx;
+ case RegisterSet::Reg_edx:
+ return RegisterSet::Reg_dx;
+ case RegisterSet::Reg_ebx:
+ return RegisterSet::Reg_bx;
+ case RegisterSet::Reg_ebp:
+ return RegisterSet::Reg_bp;
+ case RegisterSet::Reg_esi:
+ return RegisterSet::Reg_si;
+ case RegisterSet::Reg_edi:
+ return RegisterSet::Reg_di;
+ }
+ }
+ return RegNum;
}
static void initRegisterSet(
std::array<llvm::SmallBitVector, IceType_NUM> *TypeToRegisterSet,
std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases,
llvm::SmallBitVector *ScratchRegs) {
- llvm::SmallBitVector IntegerRegisters(RegisterSet::Reg_NUM);
+ llvm::SmallBitVector IntegerRegistersI32(RegisterSet::Reg_NUM);
+ llvm::SmallBitVector IntegerRegistersI16(RegisterSet::Reg_NUM);
llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM);
llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM);
llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM);
llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM);
ScratchRegs->resize(RegisterSet::Reg_NUM);
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
- (IntegerRegisters)[RegisterSet::val] = isInt; \
- (IntegerRegistersI8)[RegisterSet::val] = isI8; \
- (FloatRegisters)[RegisterSet::val] = isFP; \
- (VectorRegisters)[RegisterSet::val] = isFP; \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ (IntegerRegistersI32)[RegisterSet::val] = is32; \
+ (IntegerRegistersI16)[RegisterSet::val] = is16; \
+ (IntegerRegistersI8)[RegisterSet::val] = is8; \
+ (FloatRegisters)[RegisterSet::val] = isXmm; \
+ (VectorRegisters)[RegisterSet::val] = isXmm; \
(*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \
+ for (SizeT RegAlias : aliases) { \
+ assert(!(*RegisterAliases)[RegisterSet::val][RegAlias] && \
+ "Duplicate alias for " #val); \
+ (*RegisterAliases)[RegisterSet::val].set(RegAlias); \
+ } \
(*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \
(*ScratchRegs)[RegisterSet::val] = scratch;
REGX8632_TABLE;
@@ -329,9 +430,9 @@
(*TypeToRegisterSet)[IceType_void] = InvalidRegisters;
(*TypeToRegisterSet)[IceType_i1] = IntegerRegistersI8;
(*TypeToRegisterSet)[IceType_i8] = IntegerRegistersI8;
- (*TypeToRegisterSet)[IceType_i16] = IntegerRegisters;
- (*TypeToRegisterSet)[IceType_i32] = IntegerRegisters;
- (*TypeToRegisterSet)[IceType_i64] = IntegerRegisters;
+ (*TypeToRegisterSet)[IceType_i16] = IntegerRegistersI16;
+ (*TypeToRegisterSet)[IceType_i32] = IntegerRegistersI32;
+ (*TypeToRegisterSet)[IceType_i64] = IntegerRegistersI32;
(*TypeToRegisterSet)[IceType_f32] = FloatRegisters;
(*TypeToRegisterSet)[IceType_f64] = FloatRegisters;
(*TypeToRegisterSet)[IceType_v4i1] = VectorRegisters;
@@ -348,8 +449,9 @@
TargetLowering::RegSetMask Exclude) {
llvm::SmallBitVector Registers(RegisterSet::Reg_NUM);
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \
Registers[RegisterSet::val] = true; \
if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \
@@ -394,15 +496,23 @@
// Build up the equivalence classes of registers by looking at the register
// properties as well as whether the registers should be explicitly excluded
// from shuffling.
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
if (ExcludeRegisters[RegisterSet::val]) { \
/* val stays the same in the resulting permutation. */ \
Permutation[RegisterSet::val] = RegisterSet::val; \
++NumPreserved; \
} else { \
- const uint32_t Index = (scratch << 0) | (preserved << 1) | (isI8 << 2) | \
- (isInt << 3) | (isFP << 4); \
+ uint32_t AttrKey = 0; \
+ uint32_t Index = 0; \
+ /* Combine relevant attributes into an equivalence class key. */ \
+ Index |= (scratch << (AttrKey++)); \
+ Index |= (preserved << (AttrKey++)); \
+ Index |= (is8 << (AttrKey++)); \
+ Index |= (is16 << (AttrKey++)); \
+ Index |= (is32 << (AttrKey++)); \
+ Index |= (isXmm << (AttrKey++)); \
/* val is assigned to an equivalence class based on its properties. */ \
EquivalenceClasses[Index].push_back(RegisterSet::val); \
}
@@ -439,7 +549,7 @@
if (!First)
Str << " ";
First = false;
- Str << getRegName(Register, IceType_i32);
+ Str << getRegName(Register);
}
Str << "}\n";
}
diff --git a/src/IceTargetLoweringX8664Traits.h b/src/IceTargetLoweringX8664Traits.h
index 4f1c6e4..331f076 100644
--- a/src/IceTargetLoweringX8664Traits.h
+++ b/src/IceTargetLoweringX8664Traits.h
@@ -60,8 +60,8 @@
enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
using GPRRegister = ::Ice::RegX8664::GPRRegister;
- using XmmRegister = ::Ice::RegX8664::XmmRegister;
using ByteRegister = ::Ice::RegX8664::ByteRegister;
+ using XmmRegister = ::Ice::RegX8664::XmmRegister;
using Cond = ::Ice::CondX8664;
@@ -289,53 +289,123 @@
static const char *TargetName;
static constexpr Type WordType = IceType_i64;
- static IceString getRegName(SizeT RegNum, Type Ty) {
- assert(RegNum < RegisterSet::Reg_NUM);
- static const struct {
- const char *const Name8;
- const char *const Name16;
- const char *const Name /*32*/;
- const char *const Name64;
- } RegNames[] = {
-#define X(val, encode, name64, name32, name16, name8, scratch, preserved, \
- stackptr, frameptr, isInt, isFP) \
- { name8, name16, name32, name64 } \
- ,
+ static IceString getRegName(int32_t RegNum) {
+ static const char *const RegNames[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ name,
REGX8664_TABLE
#undef X
};
-
- switch (Ty) {
- case IceType_i1:
- case IceType_i8:
- return RegNames[RegNum].Name8;
- case IceType_i16:
- return RegNames[RegNum].Name16;
- case IceType_i64:
- return RegNames[RegNum].Name64;
- default:
- return RegNames[RegNum].Name;
- }
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ return RegNames[RegNum];
}
+ static GPRRegister getEncodedGPR(int32_t RegNum) {
+ static const GPRRegister GPRRegs[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR),
+ REGX8664_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR);
+ return GPRRegs[RegNum];
+ }
+
+ static ByteRegister getEncodedByteReg(int32_t RegNum) {
+ static const ByteRegister ByteRegs[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg),
+ REGX8664_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg);
+ return ByteRegs[RegNum];
+ }
+
+ static XmmRegister getEncodedXmm(int32_t RegNum) {
+ static const XmmRegister XmmRegs[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm),
+ REGX8664_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm);
+ return XmmRegs[RegNum];
+ }
+
+ static uint32_t getEncoding(int32_t RegNum) {
+ static const uint32_t Encoding[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ encode,
+ REGX8664_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ return Encoding[RegNum];
+ }
+
+ static inline int32_t getBaseReg(int32_t RegNum) {
+ static const int32_t BaseRegs[] = {
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ RegisterSet::base,
+ REGX8664_TABLE
+#undef X
+ };
+ assert(RegNum >= 0);
+ assert(RegNum < RegisterSet::Reg_NUM);
+ return BaseRegs[RegNum];
+ }
+
+ static int32_t getGprForType(Type, int32_t RegNum) { return RegNum; }
+
static void initRegisterSet(
std::array<llvm::SmallBitVector, IceType_NUM> *TypeToRegisterSet,
std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases,
llvm::SmallBitVector *ScratchRegs) {
- llvm::SmallBitVector IntegerRegisters(RegisterSet::Reg_NUM);
+ llvm::SmallBitVector IntegerRegistersI64(RegisterSet::Reg_NUM);
+ llvm::SmallBitVector IntegerRegistersI32(RegisterSet::Reg_NUM);
+ llvm::SmallBitVector IntegerRegistersI16(RegisterSet::Reg_NUM);
llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM);
llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM);
llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM);
llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM);
ScratchRegs->resize(RegisterSet::Reg_NUM);
-#define X(val, encode, name64, name32, name16, name8, scratch, preserved, \
- stackptr, frameptr, isInt, isFP) \
- (IntegerRegisters)[RegisterSet::val] = isInt; \
- (IntegerRegistersI8)[RegisterSet::val] = isInt; \
- (FloatRegisters)[RegisterSet::val] = isFP; \
- (VectorRegisters)[RegisterSet::val] = isFP; \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
+ (IntegerRegistersI64)[RegisterSet::val] = is64; \
+ (IntegerRegistersI32)[RegisterSet::val] = is32; \
+ (IntegerRegistersI16)[RegisterSet::val] = is16; \
+ (IntegerRegistersI8)[RegisterSet::val] = is8; \
+ (FloatRegisters)[RegisterSet::val] = isXmm; \
+ (VectorRegisters)[RegisterSet::val] = isXmm; \
(*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \
+ for (SizeT RegAlias : aliases) { \
+ assert(!(*RegisterAliases)[RegisterSet::val][RegAlias] && \
+ "Duplicate alias for " #val); \
+ (*RegisterAliases)[RegisterSet::val].set(RegAlias); \
+ } \
(*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \
(*ScratchRegs)[RegisterSet::val] = scratch;
REGX8664_TABLE;
@@ -344,9 +414,9 @@
(*TypeToRegisterSet)[IceType_void] = InvalidRegisters;
(*TypeToRegisterSet)[IceType_i1] = IntegerRegistersI8;
(*TypeToRegisterSet)[IceType_i8] = IntegerRegistersI8;
- (*TypeToRegisterSet)[IceType_i16] = IntegerRegisters;
- (*TypeToRegisterSet)[IceType_i32] = IntegerRegisters;
- (*TypeToRegisterSet)[IceType_i64] = IntegerRegisters;
+ (*TypeToRegisterSet)[IceType_i16] = IntegerRegistersI16;
+ (*TypeToRegisterSet)[IceType_i32] = IntegerRegistersI32;
+ (*TypeToRegisterSet)[IceType_i64] = IntegerRegistersI64;
(*TypeToRegisterSet)[IceType_f32] = FloatRegisters;
(*TypeToRegisterSet)[IceType_f64] = FloatRegisters;
(*TypeToRegisterSet)[IceType_v4i1] = VectorRegisters;
@@ -363,8 +433,9 @@
TargetLowering::RegSetMask Exclude) {
llvm::SmallBitVector Registers(RegisterSet::Reg_NUM);
-#define X(val, encode, name64, name32, name16, name8, scratch, preserved, \
- stackptr, frameptr, isInt, isFP) \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \
Registers[RegisterSet::val] = true; \
if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \
@@ -409,15 +480,24 @@
// Build up the equivalence classes of registers by looking at the register
// properties as well as whether the registers should be explicitly excluded
// from shuffling.
-#define X(val, encode, name64, name32, name16, name8, scratch, preserved, \
- stackptr, frameptr, isInt, isFP) \
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
+ isTrunc8Rcvr, isAhRcvr, aliases) \
if (ExcludeRegisters[RegisterSet::val]) { \
/* val stays the same in the resulting permutation. */ \
Permutation[RegisterSet::val] = RegisterSet::val; \
++NumPreserved; \
} else { \
- const uint32_t Index = (scratch << 0) | (preserved << 1) | \
- (/*isI8=*/1 << 2) | (isInt << 3) | (isFP << 4); \
+ uint32_t AttrKey = 0; \
+ uint32_t Index = 0; \
+ /* Combine relevant attributes into an equivalence class key. */ \
+ Index |= (scratch << (AttrKey++)); \
+ Index |= (preserved << (AttrKey++)); \
+ Index |= (is8 << (AttrKey++)); \
+ Index |= (is16 << (AttrKey++)); \
+ Index |= (is32 << (AttrKey++)); \
+ Index |= (is64 << (AttrKey++)); \
+ Index |= (isXmm << (AttrKey++)); \
/* val is assigned to an equivalence class based on its properties. */ \
EquivalenceClasses[Index].push_back(RegisterSet::val); \
}
@@ -454,7 +534,7 @@
if (!First)
Str << " ";
First = false;
- Str << getRegName(Register, IceType_i32);
+ Str << getRegName(Register);
}
Str << "}\n";
}
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index 09bc6dd..1ad9b29 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -587,7 +587,7 @@
// Converts a ConstantInteger32 operand into its constant value, or
// MemoryOrderInvalid if the operand is not a ConstantInteger32.
inline uint64_t getConstantMemoryOrder(Operand *Opnd) {
- if (auto Integer = llvm::dyn_cast<ConstantInteger32>(Opnd))
+ if (auto *Integer = llvm::dyn_cast<ConstantInteger32>(Opnd))
return Integer->getValue();
return Intrinsics::MemoryOrderInvalid;
}
@@ -622,7 +622,7 @@
if (auto *Load = llvm::dyn_cast<InstLoad>(CurInst)) {
// An InstLoad always qualifies.
LoadDest = Load->getDest();
- const bool DoLegalize = false;
+ constexpr bool DoLegalize = false;
LoadSrc = formMemoryOperand(Load->getSourceAddress(),
LoadDest->getType(), DoLegalize);
} else if (auto *Intrin = llvm::dyn_cast<InstIntrinsicCall>(CurInst)) {
@@ -635,7 +635,7 @@
Intrinsics::isMemoryOrderValid(
ID, getConstantMemoryOrder(Intrin->getArg(1)))) {
LoadDest = Intrin->getDest();
- const bool DoLegalize = false;
+ constexpr bool DoLegalize = false;
LoadSrc = formMemoryOperand(Intrin->getArg(0), LoadDest->getType(),
DoLegalize);
}
@@ -733,8 +733,8 @@
}
template <class Machine>
-IceString TargetX86Base<Machine>::getRegName(SizeT RegNum, Type Ty) const {
- return Traits::getRegName(RegNum, Ty);
+IceString TargetX86Base<Machine>::getRegName(SizeT RegNum, Type) const {
+ return Traits::getRegName(RegNum);
}
template <class Machine>
@@ -797,9 +797,8 @@
if (!hasFramePointer())
Offset += getStackAdjustment();
}
- return typename Traits::Address(
- Traits::RegisterSet::getEncodedGPR(BaseRegNum), Offset,
- AssemblerFixup::NoFixup);
+ return typename Traits::Address(Traits::getEncodedGPR(BaseRegNum), Offset,
+ AssemblerFixup::NoFixup);
}
/// Helper function for addProlog().
@@ -1048,23 +1047,23 @@
return false;
// Limit the number of lea/shl operations for a single multiply, to a
// somewhat arbitrary choice of 3.
- const uint32_t MaxOpsForOptimizedMul = 3;
+ constexpr uint32_t MaxOpsForOptimizedMul = 3;
if (CountOps > MaxOpsForOptimizedMul)
return false;
_mov(T, Src0);
Constant *Zero = Ctx->getConstantZero(IceType_i32);
for (uint32_t i = 0; i < Count9; ++i) {
- const uint16_t Shift = 3; // log2(9-1)
+ constexpr uint16_t Shift = 3; // log2(9-1)
_lea(T,
Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
}
for (uint32_t i = 0; i < Count5; ++i) {
- const uint16_t Shift = 2; // log2(5-1)
+ constexpr uint16_t Shift = 2; // log2(5-1)
_lea(T,
Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
}
for (uint32_t i = 0; i < Count3; ++i) {
- const uint16_t Shift = 1; // log2(3-1)
+ constexpr uint16_t Shift = 1; // log2(3-1)
_lea(T,
Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
}
@@ -1216,7 +1215,8 @@
// t1:ecx = c.lo & 0xff
// t2 = b.lo
// t3 = b.hi
- _mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx);
+ T_1 = makeReg(IceType_i8, Traits::RegisterSet::Reg_cl);
+ _mov(T_1, Src1Lo);
_mov(T_2, Src0Lo);
_mov(T_3, Src0Hi);
switch (Op) {
@@ -1324,7 +1324,7 @@
// and hiOperand() to be used.
switch (Inst->getOp()) {
case InstArithmetic::Udiv: {
- const SizeT MaxSrcs = 2;
+ constexpr SizeT MaxSrcs = 2;
InstCall *Call = makeHelperCall(H_udiv_i64, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
Call->addArg(Inst->getSrc(1));
@@ -1332,7 +1332,7 @@
return;
}
case InstArithmetic::Sdiv: {
- const SizeT MaxSrcs = 2;
+ constexpr SizeT MaxSrcs = 2;
InstCall *Call = makeHelperCall(H_sdiv_i64, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
Call->addArg(Inst->getSrc(1));
@@ -1340,7 +1340,7 @@
return;
}
case InstArithmetic::Urem: {
- const SizeT MaxSrcs = 2;
+ constexpr SizeT MaxSrcs = 2;
InstCall *Call = makeHelperCall(H_urem_i64, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
Call->addArg(Inst->getSrc(1));
@@ -1348,7 +1348,7 @@
return;
}
case InstArithmetic::Srem: {
- const SizeT MaxSrcs = 2;
+ constexpr SizeT MaxSrcs = 2;
InstCall *Call = makeHelperCall(H_srem_i64, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
Call->addArg(Inst->getSrc(1));
@@ -1529,14 +1529,14 @@
// Mask that directs pshufd to create a vector with entries
// Src[1, 0, 3, 0]
- const unsigned Constant1030 = 0x31;
+ constexpr unsigned Constant1030 = 0x31;
Constant *Mask1030 = Ctx->getConstantInt32(Constant1030);
// Mask that directs shufps to create a vector with entries
// Dest[0, 2], Src[0, 2]
- const unsigned Mask0202 = 0x88;
+ constexpr unsigned Mask0202 = 0x88;
// Mask that directs pshufd to create a vector with entries
// Src[0, 2, 1, 3]
- const unsigned Mask0213 = 0xd8;
+ constexpr unsigned Mask0213 = 0xd8;
Variable *T1 = makeReg(IceType_v4i32);
Variable *T2 = makeReg(IceType_v4i32);
Variable *T3 = makeReg(IceType_v4i32);
@@ -1631,9 +1631,9 @@
return;
}
// The 8-bit version of imul only allows the form "imul r/m8" where T must
- // be in eax.
+ // be in al.
if (isByteSizedArithType(Dest->getType())) {
- _mov(T, Src0, Traits::RegisterSet::Reg_eax);
+ _mov(T, Src0, Traits::RegisterSet::Reg_al);
Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
_imul(T, Src0 == Src1 ? T : Src1);
_mov(Dest, T);
@@ -1649,22 +1649,31 @@
break;
case InstArithmetic::Shl:
_mov(T, Src0);
- if (!llvm::isa<ConstantInteger32>(Src1))
- Src1 = legalizeToReg(Src1, Traits::RegisterSet::Reg_ecx);
+ if (!llvm::isa<ConstantInteger32>(Src1)) {
+ Variable *Cl = makeReg(IceType_i8, Traits::RegisterSet::Reg_cl);
+ _mov(Cl, Src1);
+ Src1 = Cl;
+ }
_shl(T, Src1);
_mov(Dest, T);
break;
case InstArithmetic::Lshr:
_mov(T, Src0);
- if (!llvm::isa<ConstantInteger32>(Src1))
- Src1 = legalizeToReg(Src1, Traits::RegisterSet::Reg_ecx);
+ if (!llvm::isa<ConstantInteger32>(Src1)) {
+ Variable *Cl = makeReg(IceType_i8, Traits::RegisterSet::Reg_cl);
+ _mov(Cl, Src1);
+ Src1 = Cl;
+ }
_shr(T, Src1);
_mov(Dest, T);
break;
case InstArithmetic::Ashr:
_mov(T, Src0);
- if (!llvm::isa<ConstantInteger32>(Src1))
- Src1 = legalizeToReg(Src1, Traits::RegisterSet::Reg_ecx);
+ if (!llvm::isa<ConstantInteger32>(Src1)) {
+ Variable *Cl = makeReg(IceType_i8, Traits::RegisterSet::Reg_cl);
+ _mov(Cl, Src1);
+ Src1 = Cl;
+ }
_sar(T, Src1);
_mov(Dest, T);
break;
@@ -1684,14 +1693,28 @@
Variable *T_eax = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax);
Context.insert(InstFakeDef::create(Func, T_eax));
_xor(T_eax, T_eax);
- _mov(T, Src0, Traits::RegisterSet::Reg_eax);
+ _mov(T, Src0, Traits::RegisterSet::Reg_al);
_div(T, Src1, T);
_mov(Dest, T);
Context.insert(InstFakeUse::create(Func, T_eax));
} else {
- Constant *Zero = Ctx->getConstantZero(IceType_i32);
- _mov(T, Src0, Traits::RegisterSet::Reg_eax);
- _mov(T_edx, Zero, Traits::RegisterSet::Reg_edx);
+ Type Ty = Dest->getType();
+ uint32_t Eax = Traits::RegisterSet::Reg_eax;
+ uint32_t Edx = Traits::RegisterSet::Reg_edx;
+ switch (Ty) {
+ default:
+ llvm_unreachable("Bad type for udiv");
+ // fallthrough
+ case IceType_i32:
+ break;
+ case IceType_i16:
+ Eax = Traits::RegisterSet::Reg_ax;
+ Edx = Traits::RegisterSet::Reg_dx;
+ break;
+ }
+ Constant *Zero = Ctx->getConstantZero(Ty);
+ _mov(T, Src0, Eax);
+ _mov(T_edx, Zero, Edx);
_div(T, Src1, T_edx);
_mov(Dest, T);
}
@@ -1733,18 +1756,26 @@
}
}
Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
- if (isByteSizedArithType(Dest->getType())) {
+ switch (Type Ty = Dest->getType()) {
+ default:
+ llvm_unreachable("Bad type for sdiv");
+ // fallthrough
+ case IceType_i32:
+ T_edx = makeReg(Ty, Traits::RegisterSet::Reg_edx);
_mov(T, Src0, Traits::RegisterSet::Reg_eax);
- _cbwdq(T, T);
- _idiv(T, Src1, T);
- _mov(Dest, T);
- } else {
- T_edx = makeReg(IceType_i32, Traits::RegisterSet::Reg_edx);
- _mov(T, Src0, Traits::RegisterSet::Reg_eax);
- _cbwdq(T_edx, T);
- _idiv(T, Src1, T_edx);
- _mov(Dest, T);
+ break;
+ case IceType_i16:
+ T_edx = makeReg(Ty, Traits::RegisterSet::Reg_dx);
+ _mov(T, Src0, Traits::RegisterSet::Reg_ax);
+ break;
+ case IceType_i8:
+ T_edx = makeReg(IceType_i16, Traits::RegisterSet::Reg_ax);
+ _mov(T, Src0, Traits::RegisterSet::Reg_al);
+ break;
}
+ _cbwdq(T_edx, T);
+ _idiv(T, Src1, T_edx);
+ _mov(Dest, T);
break;
case InstArithmetic::Urem:
Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
@@ -1752,7 +1783,7 @@
Variable *T_eax = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax);
Context.insert(InstFakeDef::create(Func, T_eax));
_xor(T_eax, T_eax);
- _mov(T, Src0, Traits::RegisterSet::Reg_eax);
+ _mov(T, Src0, Traits::RegisterSet::Reg_al);
_div(T, Src1, T);
// shr $8, %eax shifts ah (i.e., the 8 bit remainder) into al. We don't
// mov %ah, %al because it would make x86-64 codegen more complicated. If
@@ -1764,10 +1795,24 @@
_mov(Dest, T);
Context.insert(InstFakeUse::create(Func, T_eax));
} else {
- Constant *Zero = Ctx->getConstantZero(IceType_i32);
- T_edx = makeReg(Dest->getType(), Traits::RegisterSet::Reg_edx);
+ Type Ty = Dest->getType();
+ uint32_t Eax = Traits::RegisterSet::Reg_eax;
+ uint32_t Edx = Traits::RegisterSet::Reg_edx;
+ switch (Ty) {
+ default:
+ llvm_unreachable("Bad type for urem");
+ // fallthrough
+ case IceType_i32:
+ break;
+ case IceType_i16:
+ Eax = Traits::RegisterSet::Reg_ax;
+ Edx = Traits::RegisterSet::Reg_dx;
+ break;
+ }
+ Constant *Zero = Ctx->getConstantZero(Ty);
+ T_edx = makeReg(Dest->getType(), Edx);
_mov(T_edx, Zero);
- _mov(T, Src0, Traits::RegisterSet::Reg_eax);
+ _mov(T, Src0, Eax);
_div(T_edx, Src1, T);
_mov(Dest, T_edx);
}
@@ -1814,28 +1859,35 @@
}
}
Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
- if (isByteSizedArithType(Dest->getType())) {
- _mov(T, Src0, Traits::RegisterSet::Reg_eax);
- // T is %al.
- _cbwdq(T, T);
- _idiv(T, Src1, T);
- Variable *T_eax = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax);
- Context.insert(InstFakeDef::create(Func, T_eax));
- // shr $8, %eax shifts ah (i.e., the 8 bit remainder) into al. We don't
- // mov %ah, %al because it would make x86-64 codegen more complicated. If
- // this ever becomes a problem we can introduce a pseudo rem instruction
- // that returns the remainder in %al directly (and uses a mov for copying
- // %ah to %al.)
- static constexpr uint8_t AlSizeInBits = 8;
- _shr(T_eax, Ctx->getConstantInt8(AlSizeInBits));
- _mov(Dest, T);
- Context.insert(InstFakeUse::create(Func, T_eax));
- } else {
- T_edx = makeReg(Dest->getType(), Traits::RegisterSet::Reg_edx);
+ switch (Type Ty = Dest->getType()) {
+ default:
+ llvm_unreachable("Bad type for srem");
+ // fallthrough
+ case IceType_i32:
+ T_edx = makeReg(Ty, Traits::RegisterSet::Reg_edx);
_mov(T, Src0, Traits::RegisterSet::Reg_eax);
_cbwdq(T_edx, T);
_idiv(T_edx, Src1, T);
_mov(Dest, T_edx);
+ break;
+ case IceType_i16:
+ T_edx = makeReg(Ty, Traits::RegisterSet::Reg_dx);
+ _mov(T, Src0, Traits::RegisterSet::Reg_ax);
+ _cbwdq(T_edx, T);
+ _idiv(T_edx, Src1, T);
+ _mov(Dest, T_edx);
+ break;
+ case IceType_i8:
+ T_edx = makeReg(IceType_i16, Traits::RegisterSet::Reg_ax);
+ // TODO(stichnot): Use register ah for T_edx, and remove the _shr().
+ // T_edx = makeReg(Ty, Traits::RegisterSet::Reg_ah);
+ _mov(T, Src0, Traits::RegisterSet::Reg_al);
+ _cbwdq(T_edx, T);
+ _idiv(T_edx, Src1, T);
+ static constexpr uint8_t AlSizeInBits = 8;
+ _shr(T_edx, Ctx->getConstantInt8(AlSizeInBits));
+ _mov(Dest, T_edx);
+ break;
}
break;
case InstArithmetic::Fadd:
@@ -1859,7 +1911,7 @@
_mov(Dest, T);
break;
case InstArithmetic::Frem: {
- const SizeT MaxSrcs = 2;
+ constexpr SizeT MaxSrcs = 2;
Type Ty = Dest->getType();
InstCall *Call = makeHelperCall(
isFloat32Asserting32Or64(Ty) ? H_frem_f32 : H_frem_f64, Dest, MaxSrcs);
@@ -2114,7 +2166,7 @@
_cvt(T, Src0RM, Traits::Insts::Cvt::Tps2dq);
_movp(Dest, T);
} else if (!Traits::Is64Bit && Dest->getType() == IceType_i64) {
- const SizeT MaxSrcs = 1;
+ constexpr SizeT MaxSrcs = 1;
Type SrcType = Inst->getSrc(0)->getType();
InstCall *Call =
makeHelperCall(isFloat32Asserting32Or64(SrcType) ? H_fptosi_f32_i64
@@ -2145,14 +2197,14 @@
if (isVectorType(Dest->getType())) {
assert(Dest->getType() == IceType_v4i32 &&
Inst->getSrc(0)->getType() == IceType_v4f32);
- const SizeT MaxSrcs = 1;
+ constexpr SizeT MaxSrcs = 1;
InstCall *Call = makeHelperCall(H_fptoui_4xi32_f32, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
lowerCall(Call);
} else if (Dest->getType() == IceType_i64 ||
(!Traits::Is64Bit && Dest->getType() == IceType_i32)) {
// Use a helper for both x86-32 and x86-64.
- const SizeT MaxSrcs = 1;
+ constexpr SizeT MaxSrcs = 1;
Type DestType = Dest->getType();
Type SrcType = Inst->getSrc(0)->getType();
IceString TargetString;
@@ -2201,7 +2253,7 @@
_movp(Dest, T);
} else if (!Traits::Is64Bit && Inst->getSrc(0)->getType() == IceType_i64) {
// Use a helper for x86-32.
- const SizeT MaxSrcs = 1;
+ constexpr SizeT MaxSrcs = 1;
Type DestType = Dest->getType();
InstCall *Call =
makeHelperCall(isFloat32Asserting32Or64(DestType) ? H_sitofp_i64_f32
@@ -2236,7 +2288,7 @@
if (isVectorType(Src0->getType())) {
assert(Dest->getType() == IceType_v4f32 &&
Src0->getType() == IceType_v4i32);
- const SizeT MaxSrcs = 1;
+ constexpr SizeT MaxSrcs = 1;
InstCall *Call = makeHelperCall(H_uitofp_4xi32_4xf32, Dest, MaxSrcs);
Call->addArg(Src0);
lowerCall(Call);
@@ -2244,7 +2296,7 @@
(!Traits::Is64Bit && Src0->getType() == IceType_i32)) {
// Use a helper for x86-32 and x86-64. Also use a helper for i32 on
// x86-32.
- const SizeT MaxSrcs = 1;
+ constexpr SizeT MaxSrcs = 1;
Type DestType = Dest->getType();
IceString TargetString;
if (isInt32Asserting32Or64(Src0->getType())) {
@@ -2460,13 +2512,17 @@
Type Ty = SourceVectNotLegalized->getType();
Type ElementTy = typeElementType(Ty);
Type InVectorElementTy = Traits::getInVectorElementType(Ty);
- Variable *ExtractedElementR = makeReg(InVectorElementTy);
// TODO(wala): Determine the best lowering sequences for each type.
bool CanUsePextr = Ty == IceType_v8i16 || Ty == IceType_v8i1 ||
- InstructionSet >= Traits::SSE4_1;
- if (CanUsePextr && Ty != IceType_v4f32) {
- // Use pextrb, pextrw, or pextrd.
+ (InstructionSet >= Traits::SSE4_1 && Ty != IceType_v4f32);
+ Variable *ExtractedElementR =
+ makeReg(CanUsePextr ? IceType_i32 : InVectorElementTy);
+ if (CanUsePextr) {
+ // Use pextrb, pextrw, or pextrd. The "b" and "w" versions clear the upper
+ // bits of the destination register, so we represent this by always
+ // extracting into an i32 register. The _mov into Dest below will do
+ // truncation as necessary.
Constant *Mask = Ctx->getConstantInt32(Index);
Variable *SourceVectR = legalizeToReg(SourceVectNotLegalized);
_pextr(ExtractedElementR, SourceVectR, Mask);
@@ -2983,6 +3039,13 @@
if (Ty == IceType_v4f32)
_insertps(T, ElementRM, Ctx->getConstantInt32(Index << 4));
else
+ // TODO(stichnot): For the pinsrb and pinsrw instructions, when the source
+ // operand is a register, it must be a full r32 register like eax, and not
+ // ax/al/ah. For filetype=asm, InstX86Pinsr<Machine>::emit() compensates
+ // for the use of r16 and r8 by converting them through getBaseReg(),
+ // while emitIAS() validates that the original and base register encodings
+ // are the same. But for an "interior" register like ah, it should
+ // probably be copied into an r32 via movzx so that the types work out.
_pinsr(T, ElementRM, Ctx->getConstantInt32(Index));
_movp(Inst->getDest(), T);
} else if (Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v4i1) {
@@ -3317,7 +3380,7 @@
} else {
FirstVal = Val;
}
- const bool IsCttz = false;
+ constexpr bool IsCttz = false;
lowerCountZeros(IsCttz, Val->getType(), Instr->getDest(), FirstVal,
SecondVal);
return;
@@ -3334,7 +3397,7 @@
} else {
FirstVal = Val;
}
- const bool IsCttz = true;
+ constexpr bool IsCttz = true;
lowerCountZeros(IsCttz, Val->getType(), Instr->getDest(), FirstVal,
SecondVal);
return;
@@ -3432,7 +3495,8 @@
void TargetX86Base<Machine>::lowerAtomicCmpxchg(Variable *DestPrev,
Operand *Ptr, Operand *Expected,
Operand *Desired) {
- if (!Traits::Is64Bit && Expected->getType() == IceType_i64) {
+ Type Ty = Expected->getType();
+ if (!Traits::Is64Bit && Ty == IceType_i64) {
// Reserve the pre-colored registers first, before adding any more
// infinite-weight variables from formMemoryOperand's legalization.
Variable *T_edx = makeReg(IceType_i32, Traits::RegisterSet::Reg_edx);
@@ -3443,9 +3507,8 @@
_mov(T_edx, hiOperand(Expected));
_mov(T_ebx, loOperand(Desired));
_mov(T_ecx, hiOperand(Desired));
- typename Traits::X86OperandMem *Addr =
- formMemoryOperand(Ptr, Expected->getType());
- const bool Locked = true;
+ typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
+ constexpr bool Locked = true;
_cmpxchg8b(Addr, T_edx, T_eax, T_ecx, T_ebx, Locked);
Variable *DestLo = llvm::cast<Variable>(loOperand(DestPrev));
Variable *DestHi = llvm::cast<Variable>(hiOperand(DestPrev));
@@ -3453,12 +3516,26 @@
_mov(DestHi, T_edx);
return;
}
- Variable *T_eax = makeReg(Expected->getType(), Traits::RegisterSet::Reg_eax);
+ int32_t Eax;
+ switch (Ty) {
+ default:
+ llvm_unreachable("Bad type for cmpxchg");
+ // fallthrough
+ case IceType_i32:
+ Eax = Traits::RegisterSet::Reg_eax;
+ break;
+ case IceType_i16:
+ Eax = Traits::RegisterSet::Reg_ax;
+ break;
+ case IceType_i8:
+ Eax = Traits::RegisterSet::Reg_al;
+ break;
+ }
+ Variable *T_eax = makeReg(Ty, Eax);
_mov(T_eax, Expected);
- typename Traits::X86OperandMem *Addr =
- formMemoryOperand(Ptr, Expected->getType());
+ typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
Variable *DesiredReg = legalizeToReg(Desired);
- const bool Locked = true;
+ constexpr bool Locked = true;
_cmpxchg(Addr, T_eax, DesiredReg, Locked);
_mov(DestPrev, T_eax);
}
@@ -3560,7 +3637,7 @@
}
typename Traits::X86OperandMem *Addr =
formMemoryOperand(Ptr, Dest->getType());
- const bool Locked = true;
+ constexpr bool Locked = true;
Variable *T = nullptr;
_mov(T, Val);
_xadd(Addr, T, Locked);
@@ -3576,7 +3653,7 @@
}
typename Traits::X86OperandMem *Addr =
formMemoryOperand(Ptr, Dest->getType());
- const bool Locked = true;
+ constexpr bool Locked = true;
Variable *T = nullptr;
_mov(T, Val);
_neg(T);
@@ -3684,7 +3761,7 @@
_mov(T_ecx, hiOperand(Val));
Context.insert(Label);
}
- const bool Locked = true;
+ constexpr bool Locked = true;
_cmpxchg8b(Addr, T_edx, T_eax, T_ecx, T_ebx, Locked);
_br(Traits::Cond::Br_ne, Label);
if (!IsXchg8b) {
@@ -3711,7 +3788,22 @@
return;
}
typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
- Variable *T_eax = makeReg(Ty, Traits::RegisterSet::Reg_eax);
+ int32_t Eax;
+ switch (Ty) {
+ default:
+ llvm_unreachable("Bad type for atomicRMW");
+ // fallthrough
+ case IceType_i32:
+ Eax = Traits::RegisterSet::Reg_eax;
+ break;
+ case IceType_i16:
+ Eax = Traits::RegisterSet::Reg_ax;
+ break;
+ case IceType_i8:
+ Eax = Traits::RegisterSet::Reg_al;
+ break;
+ }
+ Variable *T_eax = makeReg(Ty, Eax);
_mov(T_eax, Addr);
typename Traits::Insts::Label *Label =
Traits::Insts::Label::create(Func, this);
@@ -3721,7 +3813,7 @@
Variable *T = makeReg(Ty);
_mov(T, T_eax);
(this->*Op_Lo)(T, Val);
- const bool Locked = true;
+ constexpr bool Locked = true;
_cmpxchg(Addr, T_eax, T, Locked);
_br(Traits::Cond::Br_ne, Label);
// If Val is a variable, model the extended live range of Val through
@@ -5218,7 +5310,7 @@
return Reg;
} else {
// SSE has no left shift operation for vectors of 8 bit integers.
- const uint32_t HIGH_ORDER_BITS_MASK = 0x80808080;
+ constexpr uint32_t HIGH_ORDER_BITS_MASK = 0x80808080;
Constant *ConstantMask = Ctx->getConstantInt32(HIGH_ORDER_BITS_MASK);
Variable *Reg = makeReg(Ty, RegNum);
_movd(Reg, legalize(ConstantMask, Legal_Reg | Legal_Mem));
@@ -5252,7 +5344,7 @@
// TODO(wala,stichnot): lea should not
// be required. The address of the stack slot is known at compile time
// (although not until after addProlog()).
- const Type PointerType = IceType_i32;
+ constexpr Type PointerType = IceType_i32;
Variable *Loc = makeReg(PointerType);
_lea(Loc, Slot);
Constant *ConstantOffset = Ctx->getConstantInt32(Offset);
@@ -5305,7 +5397,7 @@
}
}
- if (auto Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(From)) {
+ if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(From)) {
// Before doing anything with a Mem operand, we need to ensure that the
// Base and Index components are in physical registers.
Variable *Base = Mem->getBase();
@@ -5383,7 +5475,7 @@
}
return From;
}
- if (auto Var = llvm::dyn_cast<Variable>(From)) {
+ if (auto *Var = llvm::dyn_cast<Variable>(From)) {
// Check if the variable is guaranteed a physical register. This can happen
// either when the variable is pre-colored or when it is assigned infinite
// weight.
@@ -5638,8 +5730,8 @@
IceString Label;
llvm::raw_string_ostream Label_stream(Label);
Immediate->emitPoolLabel(Label_stream, Ctx);
- const RelocOffsetT Offset = 0;
- const bool SuppressMangling = true;
+ constexpr RelocOffsetT Offset = 0;
+ constexpr bool SuppressMangling = true;
Constant *Symbol =
Ctx->getConstantSym(Offset, Label_stream.str(), SuppressMangling);
typename Traits::X86OperandMem *MemOperand =
@@ -5735,8 +5827,8 @@
llvm::raw_string_ostream Label_stream(Label);
MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx);
MemOperand->getOffset()->setShouldBePooled(true);
- const RelocOffsetT SymOffset = 0;
- bool SuppressMangling = true;
+ constexpr RelocOffsetT SymOffset = 0;
+ constexpr bool SuppressMangling = true;
Constant *Symbol = Ctx->getConstantSym(SymOffset, Label_stream.str(),
SuppressMangling);
typename Traits::X86OperandMem *SymbolOperand =
diff --git a/src/IceTimerTree.cpp b/src/IceTimerTree.cpp
index 133cd41..bcf8eaf 100644
--- a/src/IceTimerTree.cpp
+++ b/src/IceTimerTree.cpp
@@ -142,7 +142,7 @@
void TimerStack::push(TimerIdT ID) {
if (!BuildDefs::dump())
return;
- const bool UpdateCounts = false;
+ constexpr bool UpdateCounts = false;
update(UpdateCounts);
StackTop = getChildIndex(StackTop, ID);
assert(StackTop);
@@ -153,7 +153,7 @@
void TimerStack::pop(TimerIdT ID) {
if (!BuildDefs::dump())
return;
- const bool UpdateCounts = true;
+ constexpr bool UpdateCounts = true;
update(UpdateCounts);
assert(StackTop);
assert(Nodes[StackTop].Parent < StackTop);
@@ -253,7 +253,7 @@
void TimerStack::dump(Ostream &Str, bool DumpCumulative) {
if (!BuildDefs::dump())
return;
- const bool UpdateCounts = true;
+ constexpr bool UpdateCounts = true;
update(UpdateCounts);
double TotalTime = LastTimestamp - FirstTimestamp;
assert(TotalTime);
diff --git a/tests_lit/llvm2ice_tests/randomize-regalloc.ll b/tests_lit/llvm2ice_tests/randomize-regalloc.ll
index 51e4b72..e84740a 100644
--- a/tests_lit/llvm2ice_tests/randomize-regalloc.ll
+++ b/tests_lit/llvm2ice_tests/randomize-regalloc.ll
@@ -26,11 +26,11 @@
; OPTM1_1-NEXT: movups XMMWORD PTR [esp+0x20],xmm0
; OPTM1_1-NEXT: movups XMMWORD PTR [esp+0x10],xmm1
; OPTM1_1-NEXT: movups xmm0,XMMWORD PTR [esp+0x20]
-; OPTM1_1-NEXT: pshufd xmm7,XMMWORD PTR [esp+0x20],0x31
-; OPTM1_1-NEXT: pshufd xmm3,XMMWORD PTR [esp+0x10],0x31
+; OPTM1_1-NEXT: pshufd xmm1,XMMWORD PTR [esp+0x20],0x31
+; OPTM1_1-NEXT: pshufd xmm2,XMMWORD PTR [esp+0x10],0x31
; OPTM1_1-NEXT: pmuludq xmm0,XMMWORD PTR [esp+0x10]
-; OPTM1_1-NEXT: pmuludq xmm7,xmm3
-; OPTM1_1-NEXT: shufps xmm0,xmm7,0x88
+; OPTM1_1-NEXT: pmuludq xmm1,xmm2
+; OPTM1_1-NEXT: shufps xmm0,xmm1,0x88
; OPTM1_1-NEXT: pshufd xmm0,xmm0,0xd8
; OPTM1_1-NEXT: movups XMMWORD PTR [esp],xmm0
; OPTM1_1-NEXT: movups xmm0,XMMWORD PTR [esp]
@@ -40,9 +40,9 @@
; CHECK_1-LABEL: mul_v4i32
; CHECK_1: movups xmm7,xmm0
; CHECK_1-NEXT: pshufd xmm0,xmm0,0x31
-; CHECK_1-NEXT: pshufd xmm3,xmm1,0x31
+; CHECK_1-NEXT: pshufd xmm4,xmm1,0x31
; CHECK_1-NEXT: pmuludq xmm7,xmm1
-; CHECK_1-NEXT: pmuludq xmm0,xmm3
+; CHECK_1-NEXT: pmuludq xmm0,xmm4
; CHECK_1-NEXT: shufps xmm7,xmm0,0x88
; CHECK_1-NEXT: pshufd xmm7,xmm7,0xd8
; CHECK_1-NEXT: movups xmm0,xmm7
@@ -53,11 +53,11 @@
; OPTM1_123-NEXT: movups XMMWORD PTR [esp+0x20],xmm0
; OPTM1_123-NEXT: movups XMMWORD PTR [esp+0x10],xmm1
; OPTM1_123-NEXT: movups xmm0,XMMWORD PTR [esp+0x20]
-; OPTM1_123-NEXT: pshufd xmm2,XMMWORD PTR [esp+0x20],0x31
-; OPTM1_123-NEXT: pshufd xmm1,XMMWORD PTR [esp+0x10],0x31
+; OPTM1_123-NEXT: pshufd xmm3,XMMWORD PTR [esp+0x20],0x31
+; OPTM1_123-NEXT: pshufd xmm7,XMMWORD PTR [esp+0x10],0x31
; OPTM1_123-NEXT: pmuludq xmm0,XMMWORD PTR [esp+0x10]
-; OPTM1_123-NEXT: pmuludq xmm2,xmm1
-; OPTM1_123-NEXT: shufps xmm0,xmm2,0x88
+; OPTM1_123-NEXT: pmuludq xmm3,xmm7
+; OPTM1_123-NEXT: shufps xmm0,xmm3,0x88
; OPTM1_123-NEXT: pshufd xmm0,xmm0,0xd8
; OPTM1_123-NEXT: movups XMMWORD PTR [esp],xmm0
; OPTM1_123-NEXT: movups xmm0,XMMWORD PTR [esp]
@@ -65,14 +65,14 @@
; OPTM1_123-NEXT: ret
; CHECK_123-LABEL: mul_v4i32
-; CHECK_123: movups xmm3,xmm0
+; CHECK_123: movups xmm4,xmm0
; CHECK_123-NEXT: pshufd xmm0,xmm0,0x31
-; CHECK_123-NEXT: pshufd xmm5,xmm1,0x31
-; CHECK_123-NEXT: pmuludq xmm3,xmm1
-; CHECK_123-NEXT: pmuludq xmm0,xmm5
-; CHECK_123-NEXT: shufps xmm3,xmm0,0x88
-; CHECK_123-NEXT: pshufd xmm3,xmm3,0xd8
-; CHECK_123-NEXT: movups xmm0,xmm3
+; CHECK_123-NEXT: pshufd xmm7,xmm1,0x31
+; CHECK_123-NEXT: pmuludq xmm4,xmm1
+; CHECK_123-NEXT: pmuludq xmm0,xmm7
+; CHECK_123-NEXT: shufps xmm4,xmm0,0x88
+; CHECK_123-NEXT: pshufd xmm4,xmm4,0xd8
+; CHECK_123-NEXT: movups xmm0,xmm4
; CHECK_123-NEXT: ret
}
diff --git a/tests_lit/llvm2ice_tests/rng.ll b/tests_lit/llvm2ice_tests/rng.ll
index aa61530..036b91b 100644
--- a/tests_lit/llvm2ice_tests/rng.ll
+++ b/tests_lit/llvm2ice_tests/rng.ll
@@ -189,14 +189,14 @@
ret <4 x i32> %res
; REGALLOC-LABEL: func4
-; REGALLOC: movups xmm3,xmm0
+; REGALLOC: movups xmm5,xmm0
; REGALLOC-NEXT: pshufd xmm0,xmm0,0x31
-; REGALLOC-NEXT: pshufd xmm5,xmm1,0x31
-; REGALLOC-NEXT: pmuludq xmm3,xmm1
-; REGALLOC-NEXT: pmuludq xmm0,xmm5
-; REGALLOC-NEXT: shufps xmm3,xmm0,0x88
-; REGALLOC-NEXT: pshufd xmm3,xmm3,0xd8
-; REGALLOC-NEXT: movups xmm0,xmm3
+; REGALLOC-NEXT: pshufd xmm4,xmm1,0x31
+; REGALLOC-NEXT: pmuludq xmm5,xmm1
+; REGALLOC-NEXT: pmuludq xmm0,xmm4
+; REGALLOC-NEXT: shufps xmm5,xmm0,0x88
+; REGALLOC-NEXT: pshufd xmm5,xmm5,0xd8
+; REGALLOC-NEXT: movups xmm0,xmm5
; REGALLOC-NEXT: ret
}
diff --git a/unittest/AssemblerX8632/GPRArith.cpp b/unittest/AssemblerX8632/GPRArith.cpp
index 309e345..e6ef73a 100644
--- a/unittest/AssemblerX8632/GPRArith.cpp
+++ b/unittest/AssemblerX8632/GPRArith.cpp
@@ -54,8 +54,7 @@
__ cmp(IceType_i32, GPRRegister::Encoded_Reg_##Src0, \
GPRRegister::Encoded_Reg_##Src1); \
__ mov(IceType_i32, GPRRegister::Encoded_Reg_##Dest, Immediate(0)); \
- __ setcc(Cond::Br_##C, \
- RegX8632::getEncodedByteReg(GPRRegister::Encoded_Reg_##Dest)); \
+ __ setcc(Cond::Br_##C, ByteRegister(GPRRegister::Encoded_Reg_##Dest)); \
__ setcc(Cond::Br_##C, dwordAddress(T0)); \
\
AssembledTest test = assemble(); \
@@ -1756,7 +1755,7 @@
__ mov(IceType_i32, GPRRegister::Encoded_Reg_##Dst, Immediate(Value0)); \
__ mov(IceType_i32, GPRRegister::Encoded_Reg_##Src, Immediate(Value1)); \
__ bt(GPRRegister::Encoded_Reg_##Dst, GPRRegister::Encoded_Reg_##Src); \
- __ setcc(Cond::Br_b, ByteRegister::Encoded_Reg_al); \
+ __ setcc(Cond::Br_b, ByteRegister::Encoded_8_Reg_al); \
__ And(IceType_i32, GPRRegister::Encoded_Reg_eax, Immediate(0xFFu)); \
\
AssembledTest test = assemble(); \
diff --git a/unittest/AssemblerX8632/LowLevel.cpp b/unittest/AssemblerX8632/LowLevel.cpp
index 1f01e8e..a963da5 100644
--- a/unittest/AssemblerX8632/LowLevel.cpp
+++ b/unittest/AssemblerX8632/LowLevel.cpp
@@ -203,10 +203,10 @@
"(" #Inst ", " #Base ", " #Index ", " #Scale ", " #Disp ", " #Imm \
", " #OpType ", " #ByteCountUntyped ", " #__VA_ARGS__ ")"; \
static constexpr uint8_t ByteCount = ByteCountUntyped; \
- __ Inst(IceType_##OpType, Address(GPRRegister::Encoded_Reg_##Base, \
- GPRRegister::Encoded_Reg_##Index, \
- Traits::TIMES_##Scale, Disp, \
- AssemblerFixup::NoFixup), \
+ __ Inst(IceType_##OpType, \
+ Address(GPRRegister::Encoded_Reg_##Base, \
+ GPRRegister::Encoded_Reg_##Index, Traits::TIMES_##Scale, \
+ Disp, AssemblerFixup::NoFixup), \
Immediate(Imm)); \
ASSERT_EQ(ByteCount, codeBytesSize()) << TestString; \
ASSERT_TRUE(verifyBytes<ByteCount>(codeBytes(), __VA_ARGS__)) \
@@ -221,10 +221,10 @@
"(" #Inst ", " #Base ", " #Index ", " #Scale ", " #Disp ", " #Src \
", " #OpType ", " #ByteCountUntyped ", " #__VA_ARGS__ ")"; \
static constexpr uint8_t ByteCount = ByteCountUntyped; \
- __ Inst(IceType_##OpType, Address(GPRRegister::Encoded_Reg_##Base, \
- GPRRegister::Encoded_Reg_##Index, \
- Traits::TIMES_##Scale, Disp, \
- AssemblerFixup::NoFixup), \
+ __ Inst(IceType_##OpType, \
+ Address(GPRRegister::Encoded_Reg_##Base, \
+ GPRRegister::Encoded_Reg_##Index, Traits::TIMES_##Scale, \
+ Disp, AssemblerFixup::NoFixup), \
GPRRegister::Encoded_Reg_##Src); \
ASSERT_EQ(ByteCount, codeBytesSize()) << TestString; \
ASSERT_TRUE(verifyBytes<ByteCount>(codeBytes(), __VA_ARGS__)) \
diff --git a/unittest/AssemblerX8632/TestUtil.h b/unittest/AssemblerX8632/TestUtil.h
index c11868f..6adf27b 100644
--- a/unittest/AssemblerX8632/TestUtil.h
+++ b/unittest/AssemblerX8632/TestUtil.h
@@ -28,9 +28,9 @@
class AssemblerX8632TestBase : public ::testing::Test {
protected:
using Address = AssemblerX8632::Traits::Address;
- using ByteRegister = AssemblerX8632::Traits::ByteRegister;
using Cond = AssemblerX8632::Traits::Cond;
using GPRRegister = AssemblerX8632::Traits::GPRRegister;
+ using ByteRegister = AssemblerX8632::Traits::ByteRegister;
using Label = ::Ice::X86Internal::Label;
using Traits = AssemblerX8632::Traits;
using XmmRegister = AssemblerX8632::Traits::XmmRegister;
diff --git a/unittest/AssemblerX8632/X87.cpp b/unittest/AssemblerX8632/X87.cpp
index ff36f7e..79a2d45 100644
--- a/unittest/AssemblerX8632/X87.cpp
+++ b/unittest/AssemblerX8632/X87.cpp
@@ -14,8 +14,8 @@
namespace {
TEST_F(AssemblerX8632LowLevelTest, Fld) {
- __ fld(IceType_f32, Address(GPRRegister::Encoded_Reg_ebp, 1,
- AssemblerFixup::NoFixup));
+ __ fld(IceType_f32,
+ Address(GPRRegister::Encoded_Reg_ebp, 1, AssemblerFixup::NoFixup));
__ fld(IceType_f64, Address(GPRRegister::Encoded_Reg_ebp, 0x10000,
AssemblerFixup::NoFixup));
@@ -33,8 +33,8 @@
}
TEST_F(AssemblerX8632LowLevelTest, FstpAddr) {
- __ fstp(IceType_f32, Address(GPRRegister::Encoded_Reg_ebp, 1,
- AssemblerFixup::NoFixup));
+ __ fstp(IceType_f32,
+ Address(GPRRegister::Encoded_Reg_ebp, 1, AssemblerFixup::NoFixup));
__ fstp(IceType_f64, Address(GPRRegister::Encoded_Reg_ebp, 0x10000,
AssemblerFixup::NoFixup));
@@ -61,8 +61,8 @@
}
TEST_F(AssemblerX8632LowLevelTest, FnstcwAddr) {
- __ fnstcw(Address(GPRRegister::Encoded_Reg_ebp, 0x12345,
- AssemblerFixup::NoFixup));
+ __ fnstcw(
+ Address(GPRRegister::Encoded_Reg_ebp, 0x12345, AssemblerFixup::NoFixup));
constexpr size_t ByteCount = 6;
ASSERT_EQ(ByteCount, codeBytesSize());
@@ -74,8 +74,8 @@
}
TEST_F(AssemblerX8632LowLevelTest, FldcwAddr) {
- __ fldcw(Address(GPRRegister::Encoded_Reg_ebp, 0x12345,
- AssemblerFixup::NoFixup));
+ __ fldcw(
+ Address(GPRRegister::Encoded_Reg_ebp, 0x12345, AssemblerFixup::NoFixup));
constexpr size_t ByteCount = 6;
ASSERT_EQ(ByteCount, codeBytesSize());
diff --git a/unittest/AssemblerX8664/GPRArith.cpp b/unittest/AssemblerX8664/GPRArith.cpp
index ee5c01c..09f29f7 100644
--- a/unittest/AssemblerX8664/GPRArith.cpp
+++ b/unittest/AssemblerX8664/GPRArith.cpp
@@ -41,7 +41,7 @@
__ mov(IceType_i32, Encoded_GPR_##Src1(), Immediate(Value1)); \
__ cmp(IceType_i32, Encoded_GPR_##Src0(), Encoded_GPR_##Src1()); \
__ mov(IceType_i32, Encoded_GPR_##Dest(), Immediate(0)); \
- __ setcc(Cond::Br_##C, RegX8664::getEncodedByteReg(Encoded_GPR_##Dest())); \
+ __ setcc(Cond::Br_##C, Encoded_Bytereg_##Dest()); \
__ setcc(Cond::Br_##C, dwordAddress(T0)); \
\
AssembledTest test = assemble(); \
@@ -92,6 +92,7 @@
TestImpl(r2, r3, r4);
TestImpl(r3, r4, r5);
TestImpl(r4, r5, r6);
+ TestImpl(r4, r6, r7);
TestImpl(r5, r6, r7);
TestImpl(r6, r7, r8);
TestImpl(r7, r8, r10);
@@ -1759,7 +1760,7 @@
__ mov(IceType_i32, Encoded_GPR_##Dst(), Immediate(Value0)); \
__ mov(IceType_i32, Encoded_GPR_##Src(), Immediate(Value1)); \
__ bt(Encoded_GPR_##Dst(), Encoded_GPR_##Src()); \
- __ setcc(Cond::Br_b, ByteRegister::Encoded_Reg_al); \
+ __ setcc(Cond::Br_b, ByteRegister::Encoded_8_Reg_al); \
__ And(IceType_i32, Encoded_GPR_eax(), Immediate(0xFFu)); \
\
AssembledTest test = assemble(); \
diff --git a/unittest/AssemblerX8664/LowLevel.cpp b/unittest/AssemblerX8664/LowLevel.cpp
index 20f2252..44ce00b 100644
--- a/unittest/AssemblerX8664/LowLevel.cpp
+++ b/unittest/AssemblerX8664/LowLevel.cpp
@@ -215,10 +215,9 @@
"(" #Inst ", " #Dst ", " #Index ", " #Scale ", " #Disp ", " #OpType \
", " #ByteCountUntyped ", " #__VA_ARGS__ ")"; \
static constexpr uint8_t ByteCount = ByteCountUntyped; \
- __ Inst( \
- IceType_##OpType, Encoded_GPR_##Dst(), \
- Address(Encoded_GPR_##Index(), Traits::TIMES_##Scale, Disp, \
- AssemblerFixup::NoFixup)); \
+ __ Inst(IceType_##OpType, Encoded_GPR_##Dst(), \
+ Address(Encoded_GPR_##Index(), Traits::TIMES_##Scale, Disp, \
+ AssemblerFixup::NoFixup)); \
ASSERT_EQ(ByteCount, codeBytesSize()) << TestString; \
ASSERT_TRUE(verifyBytes<ByteCount>(codeBytes(), __VA_ARGS__)) \
<< TestString; \
diff --git a/unittest/AssemblerX8664/TestUtil.h b/unittest/AssemblerX8664/TestUtil.h
index 5a1d4a5..455fe9c 100644
--- a/unittest/AssemblerX8664/TestUtil.h
+++ b/unittest/AssemblerX8664/TestUtil.h
@@ -29,9 +29,9 @@
class AssemblerX8664TestBase : public ::testing::Test {
protected:
using Address = AssemblerX8664::Traits::Address;
- using ByteRegister = AssemblerX8664::Traits::ByteRegister;
using Cond = AssemblerX8664::Traits::Cond;
using GPRRegister = AssemblerX8664::Traits::GPRRegister;
+ using ByteRegister = AssemblerX8664::Traits::ByteRegister;
using Traits = AssemblerX8664::Traits;
using XmmRegister = AssemblerX8664::Traits::XmmRegister;
@@ -59,6 +59,9 @@
static constexpr GPRRegister Encoded_GPR_##NewName##l() { \
return GPRRegister::Encoded_Reg_##Name32; \
} \
+ static constexpr ByteRegister Encoded_Bytereg_##NewName() { \
+ return ByteRegister::Encoded_8_Reg_##Name8; \
+ } \
static constexpr GPRRegister Encoded_GPR_##Name64() { \
return GPRRegister::Encoded_Reg_##Name32; \
} \
@@ -86,6 +89,9 @@
} \
static constexpr GPRRegister Encoded_GPR_##Name##l() { \
return GPRRegister::Encoded_Reg_##Name##d; \
+ } \
+ static constexpr ByteRegister Encoded_Bytereg_##Name() { \
+ return ByteRegister::Encoded_8_Reg_##Name##l; \
}
#define XmmRegAliases(Name) \
static constexpr XmmRegister Encoded_Xmm_##Name() { \