#define BIT_WIDTH 32
// Forward declaration.
-class FilterChooser;
+class ARMFilterChooser;
// Representation of the instruction to work on.
typedef bit_value_t insn_t[BIT_WIDTH];
/// decoder could try to decode the even/odd register numbering and assign to
/// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
/// version and return the Opcode since the two have the same Asm format string.
-class Filter {
+class ARMFilter {
protected:
- FilterChooser *Owner; // points to the FilterChooser who owns this filter
+ ARMFilterChooser *Owner; // points to the FilterChooser who owns this filter
unsigned StartBit; // the starting bit position
unsigned NumBits; // number of bits to filter
bool Mixed; // a mixed region contains both set and unset bits
std::vector<unsigned> VariableInstructions;
// Map of well-known segment value to its delegate.
- std::map<unsigned, FilterChooser*> FilterChooserMap;
+ std::map<unsigned, ARMFilterChooser*> FilterChooserMap;
// Number of instructions which fall under FilteredInstructions category.
unsigned NumFiltered;
}
// Return the filter chooser for the group of instructions without constant
// segment values.
- FilterChooser &getVariableFC() {
+ ARMFilterChooser &getVariableFC() {
assert(NumFiltered == 1);
assert(FilterChooserMap.size() == 1);
return *(FilterChooserMap.find((unsigned)-1)->second);
}
- Filter(const Filter &f);
- Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed);
+ ARMFilter(const ARMFilter &f);
+ ARMFilter(ARMFilterChooser &owner, unsigned startBit, unsigned numBits,
+ bool mixed);
- ~Filter();
+ ~ARMFilter();
// Divides the decoding task into sub tasks and delegates them to the
// inferior FilterChooser's.
ATTR_MIXED
} bitAttr_t;
-/// FilterChooser - FilterChooser chooses the best filter among a set of Filters
+/// ARMFilterChooser - FilterChooser chooses the best filter among a set of Filters
/// in order to perform the decoding of instructions at the current level.
///
/// Decoding proceeds from the top down. Based on the well-known encoding bits
/// It is useful to think of a Filter as governing the switch stmts of the
/// decoding tree. And each case is delegated to an inferior FilterChooser to
/// decide what further remaining bits to look at.
-class FilterChooser {
+class ARMFilterChooser {
static TARGET_NAME_t TargetName;
protected:
- friend class Filter;
+ friend class ARMFilter;
// Vector of codegen instructions to choose our filter.
const std::vector<const CodeGenInstruction*> &AllInstructions;
const std::vector<unsigned> Opcodes;
// Vector of candidate filters.
- std::vector<Filter> Filters;
+ std::vector<ARMFilter> Filters;
// Array of bit values passed down from our parent.
// Set to all BIT_UNFILTERED's for Parent == NULL.
bit_value_t FilterBitValues[BIT_WIDTH];
// Links to the FilterChooser above us in the decoding tree.
- FilterChooser *Parent;
+ ARMFilterChooser *Parent;
// Index of the best filter from Filters.
int BestIndex;
public:
static void setTargetName(TARGET_NAME_t tn) { TargetName = tn; }
- FilterChooser(const FilterChooser &FC) :
+ ARMFilterChooser(const ARMFilterChooser &FC) :
AllInstructions(FC.AllInstructions), Opcodes(FC.Opcodes),
Filters(FC.Filters), Parent(FC.Parent), BestIndex(FC.BestIndex) {
memcpy(FilterBitValues, FC.FilterBitValues, sizeof(FilterBitValues));
}
- FilterChooser(const std::vector<const CodeGenInstruction*> &Insts,
+ ARMFilterChooser(const std::vector<const CodeGenInstruction*> &Insts,
const std::vector<unsigned> &IDs) :
AllInstructions(Insts), Opcodes(IDs), Filters(), Parent(NULL),
BestIndex(-1) {
doFilter();
}
- FilterChooser(const std::vector<const CodeGenInstruction*> &Insts,
- const std::vector<unsigned> &IDs,
- bit_value_t (&ParentFilterBitValues)[BIT_WIDTH],
- FilterChooser &parent) :
+ ARMFilterChooser(const std::vector<const CodeGenInstruction*> &Insts,
+ const std::vector<unsigned> &IDs,
+ bit_value_t (&ParentFilterBitValues)[BIT_WIDTH],
+ ARMFilterChooser &parent) :
AllInstructions(Insts), Opcodes(IDs), Filters(), Parent(&parent),
BestIndex(-1) {
for (unsigned i = 0; i < BIT_WIDTH; ++i)
Insn[i] = bitFromBits(Bits, i);
// Set Inst{21} to 1 (wback) when IndexModeBits == IndexModeUpd.
- if (getByteField(*AllInstructions[Opcode]->TheDef, "IndexModeBits")
- == IndexModeUpd)
+ Record *R = AllInstructions[Opcode]->TheDef;
+ if (R->getValue("IndexModeBits") &&
+ getByteField(*R, "IndexModeBits") == IndexModeUpd)
Insn[21] = BIT_TRUE;
}
/// dumpFilterArray on each filter chooser up to the top level one.
void dumpStack(raw_ostream &o, const char *prefix);
- Filter &bestFilter() {
+ ARMFilter &bestFilter() {
assert(BestIndex != -1 && "BestIndex not set");
return Filters[BestIndex];
}
bool emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,unsigned Opc);
// Emits code to decode the singleton, and then to decode the rest.
- void emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,Filter &Best);
+ void emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
+ ARMFilter &Best);
// Assign a single filter and run with it.
- void runSingleFilter(FilterChooser &owner, unsigned startBit, unsigned numBit,
- bool mixed);
+ void runSingleFilter(ARMFilterChooser &owner, unsigned startBit,
+ unsigned numBit, bool mixed);
// reportRegion is a helper function for filterProcessor to mark a region as
// eligible for use as a filter region.
// //
///////////////////////////
-Filter::Filter(const Filter &f) :
+ARMFilter::ARMFilter(const ARMFilter &f) :
Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed),
FilteredInstructions(f.FilteredInstructions),
VariableInstructions(f.VariableInstructions),
LastOpcFiltered(f.LastOpcFiltered), NumVariable(f.NumVariable) {
}
-Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits,
+ARMFilter::ARMFilter(ARMFilterChooser &owner, unsigned startBit, unsigned numBits,
bool mixed) : Owner(&owner), StartBit(startBit), NumBits(numBits),
Mixed(mixed) {
assert(StartBit + NumBits - 1 < BIT_WIDTH);
&& "Filter returns no instruction categories");
}
-Filter::~Filter() {
- std::map<unsigned, FilterChooser*>::iterator filterIterator;
+ARMFilter::~ARMFilter() {
+ std::map<unsigned, ARMFilterChooser*>::iterator filterIterator;
for (filterIterator = FilterChooserMap.begin();
filterIterator != FilterChooserMap.end();
filterIterator++) {
// A special case arises when there's only one entry in the filtered
// instructions. In order to unambiguously decode the singleton, we need to
// match the remaining undecoded encoding bits against the singleton.
-void Filter::recurse() {
+void ARMFilter::recurse() {
std::map<uint64_t, std::vector<unsigned> >::const_iterator mapIterator;
bit_value_t BitValueArray[BIT_WIDTH];
for (bitIndex = 0; bitIndex < NumBits; bitIndex++)
BitValueArray[StartBit + bitIndex] = BIT_UNSET;
- // Delegates to an inferior filter chooser for futher processing on this
+ // Delegates to an inferior filter chooser for further processing on this
// group of instructions whose segment values are variable.
- FilterChooserMap.insert(std::pair<unsigned, FilterChooser*>(
+ FilterChooserMap.insert(std::pair<unsigned, ARMFilterChooser*>(
(unsigned)-1,
- new FilterChooser(Owner->AllInstructions,
- VariableInstructions,
- BitValueArray,
- *Owner)
+ new ARMFilterChooser(Owner->AllInstructions,
+ VariableInstructions,
+ BitValueArray,
+ *Owner)
));
}
BitValueArray[StartBit + bitIndex] = BIT_FALSE;
}
- // Delegates to an inferior filter chooser for futher processing on this
+ // Delegates to an inferior filter chooser for further processing on this
// category of instructions.
- FilterChooserMap.insert(std::pair<unsigned, FilterChooser*>(
+ FilterChooserMap.insert(std::pair<unsigned, ARMFilterChooser*>(
mapIterator->first,
- new FilterChooser(Owner->AllInstructions,
- mapIterator->second,
- BitValueArray,
- *Owner)
+ new ARMFilterChooser(Owner->AllInstructions,
+ mapIterator->second,
+ BitValueArray,
+ *Owner)
));
}
}
// Emit code to decode instructions given a segment or segments of bits.
-void Filter::emit(raw_ostream &o, unsigned &Indentation) {
+void ARMFilter::emit(raw_ostream &o, unsigned &Indentation) {
o.indent(Indentation) << "// Check Inst{";
if (NumBits > 1)
o.indent(Indentation) << "switch (fieldFromInstruction(insn, "
<< StartBit << ", " << NumBits << ")) {\n";
- std::map<unsigned, FilterChooser*>::iterator filterIterator;
+ std::map<unsigned, ARMFilterChooser*>::iterator filterIterator;
bool DefaultCase = false;
for (filterIterator = FilterChooserMap.begin();
// Returns the number of fanout produced by the filter. More fanout implies
// the filter distinguishes more categories of instructions.
-unsigned Filter::usefulness() const {
+unsigned ARMFilter::usefulness() const {
if (VariableInstructions.size())
return FilteredInstructions.size();
else
//////////////////////////////////
// Define the symbol here.
-TARGET_NAME_t FilterChooser::TargetName;
+TARGET_NAME_t ARMFilterChooser::TargetName;
// This provides an opportunity for target specific code emission.
-void FilterChooser::emitTopHook(raw_ostream &o) {
+void ARMFilterChooser::emitTopHook(raw_ostream &o) {
if (TargetName == TARGET_ARM) {
// Emit code that references the ARMFormat data type.
o << "static const ARMFormat ARMFormats[] = {\n";
}
// Emit the top level typedef and decodeInstruction() function.
-void FilterChooser::emitTop(raw_ostream &o, unsigned &Indentation) {
+void ARMFilterChooser::emitTop(raw_ostream &o, unsigned &Indentation) {
// Run the target specific emit hook.
emitTopHook(o);
// This provides an opportunity for target specific code emission after
// emitTop().
-void FilterChooser::emitBot(raw_ostream &o, unsigned &Indentation) {
+void ARMFilterChooser::emitBot(raw_ostream &o, unsigned &Indentation) {
if (TargetName != TARGET_THUMB) return;
// Emit code that decodes the Thumb ISA.
//
// Returns false if and on the first uninitialized bit value encountered.
// Returns true, otherwise.
-bool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn,
+bool ARMFilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn,
unsigned StartBit, unsigned NumBits) const {
Field = 0;
/// dumpFilterArray - dumpFilterArray prints out debugging info for the given
/// filter array as a series of chars.
-void FilterChooser::dumpFilterArray(raw_ostream &o,
+void ARMFilterChooser::dumpFilterArray(raw_ostream &o,
bit_value_t (&filter)[BIT_WIDTH]) {
unsigned bitIndex;
/// dumpStack - dumpStack traverses the filter chooser chain and calls
/// dumpFilterArray on each filter chooser up to the top level one.
-void FilterChooser::dumpStack(raw_ostream &o, const char *prefix) {
- FilterChooser *current = this;
+void ARMFilterChooser::dumpStack(raw_ostream &o, const char *prefix) {
+ ARMFilterChooser *current = this;
while (current) {
o << prefix;
}
// Called from Filter::recurse() when singleton exists. For debug purpose.
-void FilterChooser::SingletonExists(unsigned Opc) {
+void ARMFilterChooser::SingletonExists(unsigned Opc) {
insn_t Insn0;
insnWithID(Insn0, Opc);
// This returns a list of undecoded bits of an instructions, for example,
// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
// decoded bits in order to verify that the instruction matches the Opcode.
-unsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits,
+unsigned ARMFilterChooser::getIslands(std::vector<unsigned> &StartBits,
std::vector<unsigned> &EndBits, std::vector<uint64_t> &FieldVals,
insn_t &Insn) {
unsigned Num, BitNo;
// Emits code to decode the singleton. Return true if we have matched all the
// well-known bits.
-bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
+bool ARMFilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
unsigned Opc) {
std::vector<unsigned> StartBits;
std::vector<unsigned> EndBits;
}
// Emits code to decode the singleton, and then to decode the rest.
-void FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
- Filter &Best) {
+void ARMFilterChooser::emitSingletonDecoder(raw_ostream &o,
+ unsigned &Indentation,
+ ARMFilter &Best) {
unsigned Opc = Best.getSingletonOpc();
// Assign a single filter and run with it. Top level API client can initialize
// with a single filter to start the filtering process.
-void FilterChooser::runSingleFilter(FilterChooser &owner, unsigned startBit,
- unsigned numBit, bool mixed) {
+void ARMFilterChooser::runSingleFilter(ARMFilterChooser &owner,
+ unsigned startBit,
+ unsigned numBit, bool mixed) {
Filters.clear();
- Filter F(*this, startBit, numBit, true);
+ ARMFilter F(*this, startBit, numBit, true);
Filters.push_back(F);
BestIndex = 0; // Sole Filter instance to choose from.
bestFilter().recurse();
// reportRegion is a helper function for filterProcessor to mark a region as
// eligible for use as a filter region.
-void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
- unsigned BitIndex, bool AllowMixed) {
+void ARMFilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
+ unsigned BitIndex, bool AllowMixed) {
if (RA == ATTR_MIXED && AllowMixed)
- Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, true));
+ Filters.push_back(ARMFilter(*this, StartBit, BitIndex - StartBit, true));
else if (RA == ATTR_ALL_SET && !AllowMixed)
- Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, false));
+ Filters.push_back(ARMFilter(*this, StartBit, BitIndex - StartBit, false));
}
// FilterProcessor scans the well-known encoding bits of the instructions and
// builds up a list of candidate filters. It chooses the best filter and
// recursively descends down the decoding tree.
-bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
+bool ARMFilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
Filters.clear();
BestIndex = -1;
unsigned numInstructions = Opcodes.size();
// Decides on the best configuration of filter(s) to use in order to decode
// the instructions. A conflict of instructions may occur, in which case we
// dump the conflict set to the standard error.
-void FilterChooser::doFilter() {
+void ARMFilterChooser::doFilter() {
unsigned Num = Opcodes.size();
assert(Num && "FilterChooser created with no instructions");
// Emits code to decode our share of instructions. Returns true if the
// emitted code causes a return, which occurs if we know how to decode
// the instruction at this level or the instruction is not decodeable.
-bool FilterChooser::emit(raw_ostream &o, unsigned &Indentation) {
+bool ARMFilterChooser::emit(raw_ostream &o, unsigned &Indentation) {
if (Opcodes.size() == 1)
// There is only one instruction in the set, which is great!
// Call emitSingletonDecoder() to see whether there are any remaining
// Choose the best filter to do the decodings!
if (BestIndex != -1) {
- Filter &Best = bestFilter();
+ ARMFilter &Best = bestFilter();
if (Best.getNumFiltered() == 1)
emitSingletonDecoder(o, Indentation, Best);
else
// 2. source registers are identical => VMOVQ; otherwise => VORRq
// 3. LDR, LDRcp => return LDR for now.
// FIXME: How can we distinguish between LDR and LDRcp? Do we need to?
- // 4. tLDM, tLDM_UPD => Rn = Inst{10-8}, reglist = Inst{7-0},
+ // 4. tLDMIA, tLDMIA_UPD => Rn = Inst{10-8}, reglist = Inst{7-0},
// wback = registers<Rn> = 0
// NOTE: (tLDM, tLDM_UPD) resolution must come before Advanced SIMD
// addressing mode resolution!!!
<< "; // Returning LDR for {LDR, LDRcp}\n";
return true;
}
- if (name1 == "tLDM" && name2 == "tLDM_UPD") {
+ if (name1 == "tLDMIA" && name2 == "tLDMIA_UPD") {
// Inserting the opening curly brace for this case block.
--Indentation; --Indentation;
o.indent(Indentation) << "{\n";
std::vector<unsigned> Opcodes2;
ARMDecoderEmitter &Frontend;
CodeGenTarget Target;
- FilterChooser *FC;
+ ARMFilterChooser *FC;
TARGET_NAME_t TargetName;
};
// which is a better design and less fragile than the name matchings.
if (Bits.allInComplete()) return false;
+ // Ignore "asm parser only" instructions.
+ if (Def.getValueAsBit("isAsmParserOnly"))
+ return false;
+
if (TN == TARGET_ARM) {
- // FIXME: what about Int_MemBarrierV6 and Int_SyncBarrierV6?
- if ((Name != "Int_MemBarrierV7" && Name != "Int_SyncBarrierV7") &&
- Form == ARM_FORMAT_PSEUDO)
+ if (Form == ARM_FORMAT_PSEUDO)
return false;
if (thumbInstruction(Form))
return false;
Name == "MOVr_TC")
return false;
+ // Delegate ADR disassembly to the more generic ADDri/SUBri instructions.
+ if (Name == "ADR")
+ return false;
+
//
// The following special cases are for conflict resolutions.
//
- // NEON NLdStFrm conflict resolutions:
- //
- // 1. Ignore suffix "odd" and "odd_UPD", prefer the "even" register-
- // numbered ones which have the same Asm format string.
- // 2. Ignore VST2d64_UPD, which conflicts with VST1q64_UPD.
- // 3. Ignore VLD2d64_UPD, which conflicts with VLD1q64_UPD.
- // 4. Ignore VLD1q[_UPD], which conflicts with VLD1q64[_UPD].
- // 5. Ignore VST1q[_UPD], which conflicts with VST1q64[_UPD].
- if (Name.endswith("odd") || Name.endswith("odd_UPD") ||
- Name == "VST2d64_UPD" || Name == "VLD2d64_UPD" ||
- Name == "VLD1q" || Name == "VLD1q_UPD" ||
- Name == "VST1q" || Name == "VST1q_UPD")
- return false;
-
// RSCSri and RSCSrs set the 's' bit, but are not predicated. We are
// better off using the generic RSCri and RSCrs instructions.
if (Name == "RSCSri" || Name == "RSCSrs") return false;
- // MOVCCr, MOVCCs, MOVCCi, MOVCCi16, FCYPScc, FCYPDcc, FNEGScc, and
- // FNEGDcc are used in the compiler to implement conditional moves.
- // We can ignore them in favor of their more generic versions of
- // instructions. See also SDNode *ARMDAGToDAGISel::Select(SDValue Op).
- if (Name == "MOVCCr" || Name == "MOVCCs" || Name == "MOVCCi" ||
- Name == "MOVCCi16" || Name == "FCPYScc" || Name == "FCPYDcc" ||
- Name == "FNEGScc" || Name == "FNEGDcc")
- return false;
-
- // Ditto for VMOVDcc, VMOVScc, VNEGDcc, and VNEGScc.
- if (Name == "VMOVDcc" || Name == "VMOVScc" || Name == "VNEGDcc" ||
- Name == "VNEGScc")
- return false;
-
- // LDMIA_RET is a special case of LDM (Load Multiple) where the registers
- // loaded include the PC, causing a branch to a loaded address. Ignore
- // the LDMIA_RET instruction when decoding.
- if (Name == "LDMIA_RET") return false;
-
- // Bcc is in a more generic form than B. Ignore B when decoding.
- if (Name == "B") return false;
-
- // Ignore the non-Darwin BL instructions and the TPsoft (TLS) instruction.
- if (Name == "BL" || Name == "BL_pred" || Name == "BLX" || Name == "BX" ||
- Name == "TPsoft")
- return false;
-
- // Ignore VDUPf[d|q] instructions known to conflict with VDUP32[d-q] for
- // decoding. The instruction duplicates an element from an ARM core
- // register into every element of the destination vector. There is no
- // distinction between data types.
- if (Name == "VDUPfd" || Name == "VDUPfq") return false;
-
// A8-598: VEXT
// Vector Extract extracts elements from the bottom end of the second
// operand vector and the top end of the first, concatenates them and
if (Name == "VEXTd16" || Name == "VEXTd32" || Name == "VEXTdf" ||
Name == "VEXTq16" || Name == "VEXTq32" || Name == "VEXTqf")
return false;
-
- // Vector Reverse is similar to Vector Extract. There is no distinction
- // between data types, other than size.
- //
- // VREV64df is equivalent to VREV64d32.
- // VREV64qf is equivalent to VREV64q32.
- if (Name == "VREV64df" || Name == "VREV64qf") return false;
-
- // VDUPLNfd is equivalent to VDUPLN32d.
- // VDUPLNfq is equivalent to VDUPLN32q.
- // VLD1df is equivalent to VLD1d32.
- // VLD1qf is equivalent to VLD1q32.
- // VLD2d64 is equivalent to VLD1q64.
- // VST1df is equivalent to VST1d32.
- // VST1qf is equivalent to VST1q32.
- // VST2d64 is equivalent to VST1q64.
- if (Name == "VDUPLNfd" || Name == "VDUPLNfq" ||
- Name == "VLD1df" || Name == "VLD1qf" || Name == "VLD2d64" ||
- Name == "VST1df" || Name == "VST1qf" || Name == "VST2d64")
- return false;
} else if (TN == TARGET_THUMB) {
if (!thumbInstruction(Form))
return false;
+ // A8.6.189 STM / STMIA / STMEA -- Encoding T1
+ // There's only STMIA_UPD for Thumb1.
+ if (Name == "tSTMIA")
+ return false;
+
// On Darwin R9 is call-clobbered. Ignore the non-Darwin counterparts.
if (Name == "tBL" || Name == "tBLXi" || Name == "tBLXr")
return false;
+ // A8.6.25 BX. Use the generic tBX_Rm, ignore tBX_RET and tBX_RET_vararg.
+ if (Name == "tBX_RET" || Name == "tBX_RET_vararg")
+ return false;
+
// Ignore the TPsoft (TLS) instructions, which conflict with tBLr9.
if (Name == "tTPsoft" || Name == "t2TPsoft")
return false;
- // Ignore tLEApcrel and tLEApcrelJT, prefer tADDrPCi.
- if (Name == "tLEApcrel" || Name == "tLEApcrelJT")
+ // Ignore tADR, prefer tADDrPCi.
+ if (Name == "tADR")
return false;
- // Ignore t2LEApcrel, prefer the generic t2ADD* for disassembly printing.
- if (Name == "t2LEApcrel")
+ // Delegate t2ADR disassembly to the more generic t2ADDri12/t2SUBri12
+ // instructions.
+ if (Name == "t2ADR")
return false;
// Ignore tADDrSP, tADDspr, and tPICADD, prefer the generic tADDhirr.
Name == "t2ADDrSPi12" || Name == "t2SUBrSPi12")
return false;
+ // FIXME: Use ldr.n to work around a Darwin assembler bug.
+ // Introduce a workaround with tLDRpciDIS opcode.
+ if (Name == "tLDRpci")
+ return false;
+
// Ignore t2LDRDpci, prefer the generic t2LDRDi8, t2LDRD_PRE, t2LDRD_POST.
if (Name == "t2LDRDpci")
return false;
// tSpill conflicts with tSTRspi
// tLDRcp conflicts with tLDRspi
// tRestore conflicts with tLDRspi
- // t2LEApcrelJT conflicts with t2LEApcrel
// t2MOVCCi16 conflicts with tMOVi16
if (Name == "tBfar" ||
Name == "tPOP_RET" || Name == "t2LDMIA_RET" ||
Name == "tMOVCCi" || Name == "tMOVCCr" ||
Name == "tSpill" || Name == "tLDRcp" || Name == "tRestore" ||
- Name == "t2LEApcrelJT" || Name == "t2MOVCCi16")
+ Name == "t2MOVCCi16")
return false;
}
void ARMDecoderEmitter::ARMDEBackend::populateInstructions() {
getInstructionsByEnumValue(NumberedInstructions);
- uint16_t numUIDs = NumberedInstructions.size();
- uint16_t uid;
-
- const char *instClass = NULL;
-
- switch (TargetName) {
- case TARGET_ARM:
- instClass = "InstARM";
- break;
- default:
- assert(0 && "Unreachable code!");
- }
-
- for (uid = 0; uid < numUIDs; uid++) {
- // filter out intrinsics
- if (!NumberedInstructions[uid]->TheDef->isSubClassOf(instClass))
- continue;
+ unsigned numUIDs = NumberedInstructions.size();
+ if (TargetName == TARGET_ARM) {
+ for (unsigned uid = 0; uid < numUIDs; uid++) {
+ // filter out intrinsics
+ if (!NumberedInstructions[uid]->TheDef->isSubClassOf("InstARM"))
+ continue;
- if (populateInstruction(*NumberedInstructions[uid], TargetName))
- Opcodes.push_back(uid);
- }
+ if (populateInstruction(*NumberedInstructions[uid], TargetName))
+ Opcodes.push_back(uid);
+ }
- // Special handling for the ARM chip, which supports two modes of execution.
- // This branch handles the Thumb opcodes.
- if (TargetName == TARGET_ARM) {
- for (uid = 0; uid < numUIDs; uid++) {
+ // Special handling for the ARM chip, which supports two modes of execution.
+ // This branch handles the Thumb opcodes.
+ for (unsigned uid = 0; uid < numUIDs; uid++) {
// filter out intrinsics
if (!NumberedInstructions[uid]->TheDef->isSubClassOf("InstARM")
&& !NumberedInstructions[uid]->TheDef->isSubClassOf("InstThumb"))
if (populateInstruction(*NumberedInstructions[uid], TARGET_THUMB))
Opcodes2.push_back(uid);
}
+
+ return;
+ }
+
+ // For other targets.
+ for (unsigned uid = 0; uid < numUIDs; uid++) {
+ Record *R = NumberedInstructions[uid]->TheDef;
+ if (R->getValueAsString("Namespace") == "TargetOpcode")
+ continue;
+
+ if (populateInstruction(*NumberedInstructions[uid], TargetName))
+ Opcodes.push_back(uid);
}
}
o << '\n';
o << "namespace llvm {\n\n";
- FilterChooser::setTargetName(TargetName);
+ ARMFilterChooser::setTargetName(TargetName);
switch (TargetName) {
case TARGET_ARM: {
// Emit common utility and ARM ISA decoder.
- FC = new FilterChooser(NumberedInstructions, Opcodes);
+ FC = new ARMFilterChooser(NumberedInstructions, Opcodes);
// Reset indentation level.
unsigned Indentation = 0;
FC->emitTop(o, Indentation);
delete FC;
// Emit Thumb ISA decoder as well.
- FilterChooser::setTargetName(TARGET_THUMB);
- FC = new FilterChooser(NumberedInstructions, Opcodes2);
+ ARMFilterChooser::setTargetName(TARGET_THUMB);
+ FC = new ARMFilterChooser(NumberedInstructions, Opcodes2);
// Reset indentation level.
Indentation = 0;
FC->emitBot(o, Indentation);