mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-15 20:26:36 +00:00
Add 'isCodeGenOnly' bit to Instruction .td records.
- Used to mark fake instructions which don't correspond to an actual machine instruction (or are duplicates of a real instruction). This is to be used for "special cases" in the .td files, which should be ignored by things like the assembler and disassembler. We still need a good solution to handle pervasive duplication, like with the Int_ instructions. - Set the bit on fake "mov 0" style instructions, which allows turning an assembler matcher warning into a hard error. - -2 FIXMEs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78731 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b6ba9c36db
commit
7417b761c2
@ -221,6 +221,11 @@ class Instruction {
|
|||||||
bit mayHaveSideEffects = 0;
|
bit mayHaveSideEffects = 0;
|
||||||
bit neverHasSideEffects = 0;
|
bit neverHasSideEffects = 0;
|
||||||
|
|
||||||
|
// Is this instruction a "real" instruction (with a distinct machine
|
||||||
|
// encoding), or is it a pseudo instruction used for codegen modeling
|
||||||
|
// purposes.
|
||||||
|
bit isCodeGenOnly = 0;
|
||||||
|
|
||||||
InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
|
InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
|
||||||
|
|
||||||
string Constraints = ""; // OperandConstraint, e.g. $src = $dst.
|
string Constraints = ""; // OperandConstraint, e.g. $src = $dst.
|
||||||
@ -386,7 +391,8 @@ class InstrInfo {
|
|||||||
bit isLittleEndianEncoding = 0;
|
bit isLittleEndianEncoding = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standard Instructions.
|
// Standard Pseudo Instructions.
|
||||||
|
let isCodeGenOnly = 1 in {
|
||||||
def PHI : Instruction {
|
def PHI : Instruction {
|
||||||
let OutOperandList = (ops);
|
let OutOperandList = (ops);
|
||||||
let InOperandList = (ops variable_ops);
|
let InOperandList = (ops variable_ops);
|
||||||
@ -466,6 +472,7 @@ def COPY_TO_REGCLASS : Instruction {
|
|||||||
let neverHasSideEffects = 1;
|
let neverHasSideEffects = 1;
|
||||||
let isAsCheapAsAMove = 1;
|
let isAsCheapAsAMove = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// AsmParser - This class can be implemented by targets that wish to implement
|
// AsmParser - This class can be implemented by targets that wish to implement
|
||||||
|
@ -3166,7 +3166,8 @@ let neverHasSideEffects = 1 in {
|
|||||||
|
|
||||||
// Alias instructions that map movr0 to xor.
|
// Alias instructions that map movr0 to xor.
|
||||||
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
|
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
|
||||||
let Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1 in {
|
let Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1,
|
||||||
|
isCodeGenOnly = 1 in {
|
||||||
def MOV8r0 : I<0x30, MRMInitReg, (outs GR8 :$dst), (ins),
|
def MOV8r0 : I<0x30, MRMInitReg, (outs GR8 :$dst), (ins),
|
||||||
"xor{b}\t$dst, $dst",
|
"xor{b}\t$dst, $dst",
|
||||||
[(set GR8:$dst, 0)]>;
|
[(set GR8:$dst, 0)]>;
|
||||||
|
@ -516,7 +516,7 @@ def MMX_MASKMOVQ64: MMXI64<0xF7, MRMSrcReg, (outs), (ins VR64:$src, VR64:$mask),
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Alias instructions that map zero vector to pxor.
|
// Alias instructions that map zero vector to pxor.
|
||||||
let isReMaterializable = 1 in {
|
let isReMaterializable = 1, isCodeGenOnly = 1 in {
|
||||||
def MMX_V_SET0 : MMXI<0xEF, MRMInitReg, (outs VR64:$dst), (ins),
|
def MMX_V_SET0 : MMXI<0xEF, MRMInitReg, (outs VR64:$dst), (ins),
|
||||||
"pxor\t$dst, $dst",
|
"pxor\t$dst, $dst",
|
||||||
[(set VR64:$dst, (v2i32 immAllZerosV))]>;
|
[(set VR64:$dst, (v2i32 immAllZerosV))]>;
|
||||||
|
@ -472,7 +472,7 @@ def Int_COMISSrm: PSI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
|
|||||||
// that start with 'Fs'.
|
// that start with 'Fs'.
|
||||||
|
|
||||||
// Alias instructions that map fld0 to pxor for sse.
|
// Alias instructions that map fld0 to pxor for sse.
|
||||||
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
|
let isReMaterializable = 1, isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
|
||||||
def FsFLD0SS : I<0xEF, MRMInitReg, (outs FR32:$dst), (ins),
|
def FsFLD0SS : I<0xEF, MRMInitReg, (outs FR32:$dst), (ins),
|
||||||
"pxor\t$dst, $dst", [(set FR32:$dst, fp32imm0)]>,
|
"pxor\t$dst, $dst", [(set FR32:$dst, fp32imm0)]>,
|
||||||
Requires<[HasSSE1]>, TB, OpSize;
|
Requires<[HasSSE1]>, TB, OpSize;
|
||||||
@ -992,7 +992,8 @@ def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
|
|||||||
// Alias instructions that map zero vector to pxor / xorp* for sse.
|
// Alias instructions that map zero vector to pxor / xorp* for sse.
|
||||||
// We set canFoldAsLoad because this can be converted to a constant-pool
|
// We set canFoldAsLoad because this can be converted to a constant-pool
|
||||||
// load of an all-zeros value if folding it would be beneficial.
|
// load of an all-zeros value if folding it would be beneficial.
|
||||||
let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1 in
|
let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
|
||||||
|
isCodeGenOnly = 1 in
|
||||||
def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins),
|
def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins),
|
||||||
"xorps\t$dst, $dst",
|
"xorps\t$dst, $dst",
|
||||||
[(set VR128:$dst, (v4i32 immAllZerosV))]>;
|
[(set VR128:$dst, (v4i32 immAllZerosV))]>;
|
||||||
@ -1208,7 +1209,7 @@ def Int_COMISDrm: PDI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
|
|||||||
// that start with 'Fs'.
|
// that start with 'Fs'.
|
||||||
|
|
||||||
// Alias instructions that map fld0 to pxor for sse.
|
// Alias instructions that map fld0 to pxor for sse.
|
||||||
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
|
let isReMaterializable = 1, isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
|
||||||
def FsFLD0SD : I<0xEF, MRMInitReg, (outs FR64:$dst), (ins),
|
def FsFLD0SD : I<0xEF, MRMInitReg, (outs FR64:$dst), (ins),
|
||||||
"pxor\t$dst, $dst", [(set FR64:$dst, fpimm0)]>,
|
"pxor\t$dst, $dst", [(set FR64:$dst, fpimm0)]>,
|
||||||
Requires<[HasSSE2]>, TB, OpSize;
|
Requires<[HasSSE2]>, TB, OpSize;
|
||||||
@ -2245,7 +2246,8 @@ def : Pat<(membarrier (i8 imm:$ll), (i8 imm:$ls), (i8 imm:$sl), (i8 imm:$ss),
|
|||||||
// Alias instructions that map zero vector to pxor / xorp* for sse.
|
// Alias instructions that map zero vector to pxor / xorp* for sse.
|
||||||
// We set canFoldAsLoad because this can be converted to a constant-pool
|
// We set canFoldAsLoad because this can be converted to a constant-pool
|
||||||
// load of an all-ones value if folding it would be beneficial.
|
// load of an all-ones value if folding it would be beneficial.
|
||||||
let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1 in
|
let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
|
||||||
|
isCodeGenOnly = 1 in
|
||||||
def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins),
|
def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins),
|
||||||
"pcmpeqd\t$dst, $dst",
|
"pcmpeqd\t$dst, $dst",
|
||||||
[(set VR128:$dst, (v4i32 immAllOnesV))]>;
|
[(set VR128:$dst, (v4i32 immAllOnesV))]>;
|
||||||
|
@ -210,17 +210,16 @@ static void TokenizeAsmString(const StringRef &AsmString,
|
|||||||
static bool IsAssemblerInstruction(const StringRef &Name,
|
static bool IsAssemblerInstruction(const StringRef &Name,
|
||||||
const CodeGenInstruction &CGI,
|
const CodeGenInstruction &CGI,
|
||||||
const SmallVectorImpl<StringRef> &Tokens) {
|
const SmallVectorImpl<StringRef> &Tokens) {
|
||||||
// Ignore psuedo ops.
|
// Ignore "codegen only" instructions.
|
||||||
//
|
if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
|
||||||
// FIXME: This is a hack.
|
|
||||||
if (const RecordVal *Form = CGI.TheDef->getValue("Form"))
|
|
||||||
if (Form->getValue()->getAsString() == "Pseudo")
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Ignore "PHI" node.
|
// Ignore pseudo ops.
|
||||||
//
|
//
|
||||||
// FIXME: This is also a hack.
|
// FIXME: This is a hack; can we convert these instructions to set the
|
||||||
if (Name == "PHI")
|
// "codegen only" bit instead?
|
||||||
|
if (const RecordVal *Form = CGI.TheDef->getValue("Form"))
|
||||||
|
if (Form->getValue()->getAsString() == "Pseudo")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Ignore "Int_*" and "*_Int" instructions, which are internal aliases.
|
// Ignore "Int_*" and "*_Int" instructions, which are internal aliases.
|
||||||
@ -245,11 +244,8 @@ static bool IsAssemblerInstruction(const StringRef &Name,
|
|||||||
//
|
//
|
||||||
// FIXME: Is this true?
|
// FIXME: Is this true?
|
||||||
//
|
//
|
||||||
// Also, we ignore instructions which reference the operand multiple times;
|
// Also, check for instructions which reference the operand multiple times;
|
||||||
// this implies a constraint we would not currently honor. These are
|
// this implies a constraint we would not honor.
|
||||||
// currently always fake instructions for simplifying codegen.
|
|
||||||
//
|
|
||||||
// FIXME: Encode this assumption in the .td, so we can error out here.
|
|
||||||
std::set<std::string> OperandNames;
|
std::set<std::string> OperandNames;
|
||||||
for (unsigned i = 1, e = Tokens.size(); i < e; ++i) {
|
for (unsigned i = 1, e = Tokens.size(); i < e; ++i) {
|
||||||
if (Tokens[i][0] == '$' &&
|
if (Tokens[i][0] == '$' &&
|
||||||
@ -258,18 +254,15 @@ static bool IsAssemblerInstruction(const StringRef &Name,
|
|||||||
DEBUG({
|
DEBUG({
|
||||||
errs() << "warning: '" << Name << "': "
|
errs() << "warning: '" << Name << "': "
|
||||||
<< "ignoring instruction; operand with attribute '"
|
<< "ignoring instruction; operand with attribute '"
|
||||||
<< Tokens[i] << "', \n";
|
<< Tokens[i] << "'\n";
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) {
|
if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) {
|
||||||
DEBUG({
|
std::string Err = "'" + Name.str() + "': " +
|
||||||
errs() << "warning: '" << Name << "': "
|
"invalid assembler instruction; tied operand '" + Tokens[i].str() + "'";
|
||||||
<< "ignoring instruction; tied operand '"
|
throw TGError(CGI.TheDef->getLoc(), Err);
|
||||||
<< Tokens[i] << "'\n";
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user