forked from OSchip/llvm-project
[SystemZ] Refactor branch and conditional instruction patterns
Rework patterns for branches, call & return instructions, compare-and-branch, compare-and-trap, and conditional move instructions. In particular, simplify creation of patterns for the extended opcodes of instructions that take a CC mask. Also, use semantical instruction classes for all the instructions instead of open-coding them in SystemZInstrInfo.td. Adds a couple of the basic branch instructions (that are unused for codegen) for the assembler/disassembler. llvm-svn: 286263
This commit is contained in:
parent
e527dc6223
commit
d2148caffc
|
@ -418,10 +418,10 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||||
|
|
||||||
case SystemZ::Serialize:
|
case SystemZ::Serialize:
|
||||||
if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
|
if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
|
||||||
LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
|
LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
|
||||||
.addImm(14).addReg(SystemZ::R0D);
|
.addImm(14).addReg(SystemZ::R0D);
|
||||||
else
|
else
|
||||||
LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
|
LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
|
||||||
.addImm(15).addReg(SystemZ::R0D);
|
.addImm(15).addReg(SystemZ::R0D);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,34 @@ class InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
let Inst{15-0} = I2;
|
let Inst{15-0} = I2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InstRIb<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
||||||
|
field bits<32> Inst;
|
||||||
|
field bits<32> SoftFail = 0;
|
||||||
|
|
||||||
|
bits<4> R1;
|
||||||
|
bits<16> RI2;
|
||||||
|
|
||||||
|
let Inst{31-24} = op{11-4};
|
||||||
|
let Inst{23-20} = R1;
|
||||||
|
let Inst{19-16} = op{3-0};
|
||||||
|
let Inst{15-0} = RI2;
|
||||||
|
}
|
||||||
|
|
||||||
|
class InstRIc<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
||||||
|
field bits<32> Inst;
|
||||||
|
field bits<32> SoftFail = 0;
|
||||||
|
|
||||||
|
bits<4> M1;
|
||||||
|
bits<16> RI2;
|
||||||
|
|
||||||
|
let Inst{31-24} = op{11-4};
|
||||||
|
let Inst{23-20} = M1;
|
||||||
|
let Inst{19-16} = op{3-0};
|
||||||
|
let Inst{15-0} = RI2;
|
||||||
|
}
|
||||||
|
|
||||||
class InstRIEa<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
class InstRIEa<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
||||||
field bits<48> Inst;
|
field bits<48> Inst;
|
||||||
|
@ -283,6 +311,23 @@ class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
let Inst{7-0} = op{7-0};
|
let Inst{7-0} = op{7-0};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InstRIEg<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
||||||
|
field bits<48> Inst;
|
||||||
|
field bits<48> SoftFail = 0;
|
||||||
|
|
||||||
|
bits<4> R1;
|
||||||
|
bits<4> M3;
|
||||||
|
bits<16> I2;
|
||||||
|
|
||||||
|
let Inst{47-40} = op{15-8};
|
||||||
|
let Inst{39-36} = R1;
|
||||||
|
let Inst{35-32} = M3;
|
||||||
|
let Inst{31-16} = I2;
|
||||||
|
let Inst{15-8} = 0;
|
||||||
|
let Inst{7-0} = op{7-0};
|
||||||
|
}
|
||||||
|
|
||||||
class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
||||||
field bits<48> Inst;
|
field bits<48> Inst;
|
||||||
|
@ -297,6 +342,34 @@ class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
let Inst{31-0} = I2;
|
let Inst{31-0} = I2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InstRILb<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
||||||
|
field bits<48> Inst;
|
||||||
|
field bits<48> SoftFail = 0;
|
||||||
|
|
||||||
|
bits<4> R1;
|
||||||
|
bits<32> RI2;
|
||||||
|
|
||||||
|
let Inst{47-40} = op{11-4};
|
||||||
|
let Inst{39-36} = R1;
|
||||||
|
let Inst{35-32} = op{3-0};
|
||||||
|
let Inst{31-0} = RI2;
|
||||||
|
}
|
||||||
|
|
||||||
|
class InstRILc<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
||||||
|
field bits<48> Inst;
|
||||||
|
field bits<48> SoftFail = 0;
|
||||||
|
|
||||||
|
bits<4> M1;
|
||||||
|
bits<32> RI2;
|
||||||
|
|
||||||
|
let Inst{47-40} = op{11-4};
|
||||||
|
let Inst{39-36} = M1;
|
||||||
|
let Inst{35-32} = op{3-0};
|
||||||
|
let Inst{31-0} = RI2;
|
||||||
|
}
|
||||||
|
|
||||||
class InstRIS<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
class InstRIS<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
||||||
field bits<48> Inst;
|
field bits<48> Inst;
|
||||||
|
@ -425,6 +498,21 @@ class InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
let HasIndex = 1;
|
let HasIndex = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InstRXb<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
||||||
|
field bits<32> Inst;
|
||||||
|
field bits<32> SoftFail = 0;
|
||||||
|
|
||||||
|
bits<4> M1;
|
||||||
|
bits<20> XBD2;
|
||||||
|
|
||||||
|
let Inst{31-24} = op;
|
||||||
|
let Inst{23-20} = M1;
|
||||||
|
let Inst{19-0} = XBD2;
|
||||||
|
|
||||||
|
let HasIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
||||||
field bits<48> Inst;
|
field bits<48> Inst;
|
||||||
|
@ -480,6 +568,23 @@ class InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
let HasIndex = 1;
|
let HasIndex = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InstRXYb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
||||||
|
field bits<48> Inst;
|
||||||
|
field bits<48> SoftFail = 0;
|
||||||
|
|
||||||
|
bits<4> M1;
|
||||||
|
bits<28> XBD2;
|
||||||
|
|
||||||
|
let Inst{47-40} = op{15-8};
|
||||||
|
let Inst{39-36} = M1;
|
||||||
|
let Inst{35-8} = XBD2;
|
||||||
|
let Inst{7-0} = op{7-0};
|
||||||
|
|
||||||
|
let Has20BitOffset = 1;
|
||||||
|
let HasIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
||||||
field bits<32> Inst;
|
field bits<32> Inst;
|
||||||
|
@ -495,6 +600,21 @@ class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
let Inst{15-0} = BD2;
|
let Inst{15-0} = BD2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InstRSb<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
||||||
|
field bits<32> Inst;
|
||||||
|
field bits<32> SoftFail = 0;
|
||||||
|
|
||||||
|
bits<4> R1;
|
||||||
|
bits<4> M3;
|
||||||
|
bits<16> BD2;
|
||||||
|
|
||||||
|
let Inst{31-24} = op;
|
||||||
|
let Inst{23-20} = R1;
|
||||||
|
let Inst{19-16} = M3;
|
||||||
|
let Inst{15-0} = BD2;
|
||||||
|
}
|
||||||
|
|
||||||
class InstRSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
class InstRSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
||||||
field bits<32> Inst;
|
field bits<32> Inst;
|
||||||
|
@ -528,6 +648,24 @@ class InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
let Has20BitOffset = 1;
|
let Has20BitOffset = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InstRSYb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: InstSystemZ<6, outs, ins, asmstr, pattern> {
|
||||||
|
field bits<48> Inst;
|
||||||
|
field bits<48> SoftFail = 0;
|
||||||
|
|
||||||
|
bits<4> R1;
|
||||||
|
bits<4> M3;
|
||||||
|
bits<24> BD2;
|
||||||
|
|
||||||
|
let Inst{47-40} = op{15-8};
|
||||||
|
let Inst{39-36} = R1;
|
||||||
|
let Inst{35-32} = M3;
|
||||||
|
let Inst{31-8} = BD2;
|
||||||
|
let Inst{7-0} = op{7-0};
|
||||||
|
|
||||||
|
let Has20BitOffset = 1;
|
||||||
|
}
|
||||||
|
|
||||||
class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
: InstSystemZ<4, outs, ins, asmstr, pattern> {
|
||||||
field bits<32> Inst;
|
field bits<32> Inst;
|
||||||
|
@ -1205,6 +1343,104 @@ class DirectiveInsnSSF<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
let Inst{35-32} = enc{35-32};
|
let Inst{35-32} = enc{35-32};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Variants of instructions with condition mask
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// For instructions using a condition mask (e.g. conditional branches,
|
||||||
|
// compare-and-branch instructions, or conditional move instructions),
|
||||||
|
// we generally need to create multiple instruction patterns:
|
||||||
|
//
|
||||||
|
// - One used for code generation, which encodes the condition mask as an
|
||||||
|
// MI operand, but writes out an extended mnemonic for better readability.
|
||||||
|
// - One pattern for the base form of the instruction with an explicit
|
||||||
|
// condition mask (encoded as a plain integer MI operand).
|
||||||
|
// - Specific patterns for each extended mnemonic, where the condition mask
|
||||||
|
// is implied by the pattern name and not otherwise encoded at all.
|
||||||
|
//
|
||||||
|
// We need the latter primarily for the assembler and disassembler, since the
|
||||||
|
// assembler parser is not able to decode part of an instruction mnemonic
|
||||||
|
// into an operand. Thus we provide separate patterns for each mnemonic.
|
||||||
|
//
|
||||||
|
// Note that in some cases there are two different mnemonics for the same
|
||||||
|
// condition mask. In this case we cannot have both instructions available
|
||||||
|
// to the disassembler at the same time since the encodings are not distinct.
|
||||||
|
// Therefore the alternate forms are marked isAsmParserOnly.
|
||||||
|
//
|
||||||
|
// We don't make one of the two names an alias of the other because
|
||||||
|
// we need the custom parsing routines to select the correct register class.
|
||||||
|
//
|
||||||
|
// This section provides helpers for generating the specific forms.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// A class to describe a variant of an instruction with condition mask.
|
||||||
|
class CondVariant<bits<4> ccmaskin, string suffixin, bit alternatein> {
|
||||||
|
// The fixed condition mask to use.
|
||||||
|
bits<4> ccmask = ccmaskin;
|
||||||
|
|
||||||
|
// The suffix to use for the extended assembler mnemonic.
|
||||||
|
string suffix = suffixin;
|
||||||
|
|
||||||
|
// Whether this is an alternate that needs to be marked isAsmParserOnly.
|
||||||
|
bit alternate = alternatein;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Condition mask 15 means "always true", which is used to define
|
||||||
|
// unconditional branches as a variant of conditional branches.
|
||||||
|
def CondAlways : CondVariant<15, "", 0>;
|
||||||
|
|
||||||
|
// Condition masks for general instructions that can set all 4 bits.
|
||||||
|
def CondVariantO : CondVariant<1, "o", 0>;
|
||||||
|
def CondVariantH : CondVariant<2, "h", 0>;
|
||||||
|
def CondVariantP : CondVariant<2, "p", 1>;
|
||||||
|
def CondVariantNLE : CondVariant<3, "nle", 0>;
|
||||||
|
def CondVariantL : CondVariant<4, "l", 0>;
|
||||||
|
def CondVariantM : CondVariant<4, "m", 1>;
|
||||||
|
def CondVariantNHE : CondVariant<5, "nhe", 0>;
|
||||||
|
def CondVariantLH : CondVariant<6, "lh", 0>;
|
||||||
|
def CondVariantNE : CondVariant<7, "ne", 0>;
|
||||||
|
def CondVariantNZ : CondVariant<7, "nz", 1>;
|
||||||
|
def CondVariantE : CondVariant<8, "e", 0>;
|
||||||
|
def CondVariantZ : CondVariant<8, "z", 1>;
|
||||||
|
def CondVariantNLH : CondVariant<9, "nlh", 0>;
|
||||||
|
def CondVariantHE : CondVariant<10, "he", 0>;
|
||||||
|
def CondVariantNL : CondVariant<11, "nl", 0>;
|
||||||
|
def CondVariantNM : CondVariant<11, "nm", 1>;
|
||||||
|
def CondVariantLE : CondVariant<12, "le", 0>;
|
||||||
|
def CondVariantNH : CondVariant<13, "nh", 0>;
|
||||||
|
def CondVariantNP : CondVariant<13, "np", 1>;
|
||||||
|
def CondVariantNO : CondVariant<14, "no", 0>;
|
||||||
|
|
||||||
|
// A helper class to look up one of the above by name.
|
||||||
|
class CV<string name>
|
||||||
|
: CondVariant<!cast<CondVariant>("CondVariant"#name).ccmask,
|
||||||
|
!cast<CondVariant>("CondVariant"#name).suffix,
|
||||||
|
!cast<CondVariant>("CondVariant"#name).alternate>;
|
||||||
|
|
||||||
|
// Condition masks for integer instructions (e.g. compare-and-branch).
|
||||||
|
// This is like the list above, except that condition 3 is not possible
|
||||||
|
// and that the low bit of the mask is therefore always 0. This means
|
||||||
|
// that each condition has two names. Conditions "o" and "no" are not used.
|
||||||
|
def IntCondVariantH : CondVariant<2, "h", 0>;
|
||||||
|
def IntCondVariantNLE : CondVariant<2, "nle", 1>;
|
||||||
|
def IntCondVariantL : CondVariant<4, "l", 0>;
|
||||||
|
def IntCondVariantNHE : CondVariant<4, "nhe", 1>;
|
||||||
|
def IntCondVariantLH : CondVariant<6, "lh", 0>;
|
||||||
|
def IntCondVariantNE : CondVariant<6, "ne", 1>;
|
||||||
|
def IntCondVariantE : CondVariant<8, "e", 0>;
|
||||||
|
def IntCondVariantNLH : CondVariant<8, "nlh", 1>;
|
||||||
|
def IntCondVariantHE : CondVariant<10, "he", 0>;
|
||||||
|
def IntCondVariantNL : CondVariant<10, "nl", 1>;
|
||||||
|
def IntCondVariantLE : CondVariant<12, "le", 0>;
|
||||||
|
def IntCondVariantNH : CondVariant<12, "nh", 1>;
|
||||||
|
|
||||||
|
// A helper class to look up one of the above by name.
|
||||||
|
class ICV<string name>
|
||||||
|
: CondVariant<!cast<CondVariant>("IntCondVariant"#name).ccmask,
|
||||||
|
!cast<CondVariant>("IntCondVariant"#name).suffix,
|
||||||
|
!cast<CondVariant>("IntCondVariant"#name).alternate>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instruction definitions with semantics
|
// Instruction definitions with semantics
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -1218,6 +1454,17 @@ class DirectiveInsnSSF<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
// Inherent:
|
// Inherent:
|
||||||
// One register output operand and no input operands.
|
// One register output operand and no input operands.
|
||||||
//
|
//
|
||||||
|
// Branch:
|
||||||
|
// One branch target. The instruction branches to the target.
|
||||||
|
//
|
||||||
|
// Call:
|
||||||
|
// One output operand and one branch target. The instruction stores
|
||||||
|
// the return address to the output operand and branches to the target.
|
||||||
|
//
|
||||||
|
// CmpBranch:
|
||||||
|
// Two input operands and one optional branch target. The instruction
|
||||||
|
// compares the two input operands and branches or traps on the result.
|
||||||
|
//
|
||||||
// BranchUnary:
|
// BranchUnary:
|
||||||
// One register output operand, one register input operand and
|
// One register output operand, one register input operand and
|
||||||
// one branch displacement. The instructions stores a modified
|
// one branch displacement. The instructions stores a modified
|
||||||
|
@ -1314,11 +1561,257 @@ class InherentVRIa<string mnemonic, bits<16> opcode, bits<16> value>
|
||||||
let M3 = 0;
|
let M3 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow an optional TLS marker symbol to generate TLS call relocations.
|
||||||
|
class CallRI<string mnemonic, bits<12> opcode>
|
||||||
|
: InstRIb<opcode, (outs), (ins GR64:$R1, brtarget16tls:$RI2),
|
||||||
|
mnemonic#"\t$R1, $RI2", []>;
|
||||||
|
|
||||||
|
// Allow an optional TLS marker symbol to generate TLS call relocations.
|
||||||
|
class CallRIL<string mnemonic, bits<12> opcode>
|
||||||
|
: InstRILb<opcode, (outs), (ins GR64:$R1, brtarget32tls:$RI2),
|
||||||
|
mnemonic#"\t$R1, $RI2", []>;
|
||||||
|
|
||||||
|
class CallRR<string mnemonic, bits<8> opcode>
|
||||||
|
: InstRR<opcode, (outs), (ins GR64:$R1, ADDR64:$R2),
|
||||||
|
mnemonic#"\t$R1, $R2", []>;
|
||||||
|
|
||||||
|
class CallRX<string mnemonic, bits<8> opcode>
|
||||||
|
: InstRX<opcode, (outs), (ins GR64:$R1, bdxaddr12only:$XBD2),
|
||||||
|
mnemonic#"\t$R1, $XBD2", []>;
|
||||||
|
|
||||||
|
class CondBranchRI<string mnemonic, bits<12> opcode,
|
||||||
|
SDPatternOperator operator = null_frag>
|
||||||
|
: InstRIc<opcode, (outs), (ins cond4:$valid, cond4:$M1, brtarget16:$RI2),
|
||||||
|
!subst("#", "${M1}", mnemonic)#"\t$RI2",
|
||||||
|
[(operator cond4:$valid, cond4:$M1, bb:$RI2)]> {
|
||||||
|
let CCMaskFirst = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AsmCondBranchRI<string mnemonic, bits<12> opcode>
|
||||||
|
: InstRIc<opcode, (outs), (ins imm32zx4:$M1, brtarget16:$RI2),
|
||||||
|
mnemonic#"\t$M1, $RI2", []>;
|
||||||
|
|
||||||
|
class FixedCondBranchRI<CondVariant V, string mnemonic, bits<12> opcode,
|
||||||
|
SDPatternOperator operator = null_frag>
|
||||||
|
: InstRIc<opcode, (outs), (ins brtarget16:$RI2),
|
||||||
|
!subst("#", V.suffix, mnemonic)#"\t$RI2", [(operator bb:$RI2)]> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M1 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CondBranchRIL<string mnemonic, bits<12> opcode>
|
||||||
|
: InstRILc<opcode, (outs), (ins cond4:$valid, cond4:$M1, brtarget32:$RI2),
|
||||||
|
!subst("#", "${M1}", mnemonic)#"\t$RI2", []> {
|
||||||
|
let CCMaskFirst = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AsmCondBranchRIL<string mnemonic, bits<12> opcode>
|
||||||
|
: InstRILc<opcode, (outs), (ins imm32zx4:$M1, brtarget32:$RI2),
|
||||||
|
mnemonic#"\t$M1, $RI2", []>;
|
||||||
|
|
||||||
|
class FixedCondBranchRIL<CondVariant V, string mnemonic, bits<12> opcode>
|
||||||
|
: InstRILc<opcode, (outs), (ins brtarget32:$RI2),
|
||||||
|
!subst("#", V.suffix, mnemonic)#"\t$RI2", []> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M1 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CondBranchRR<string mnemonic, bits<8> opcode>
|
||||||
|
: InstRR<opcode, (outs), (ins cond4:$valid, cond4:$R1, GR64:$R2),
|
||||||
|
!subst("#", "${R1}", mnemonic)#"\t$R2", []> {
|
||||||
|
let CCMaskFirst = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AsmCondBranchRR<string mnemonic, bits<8> opcode>
|
||||||
|
: InstRR<opcode, (outs), (ins imm32zx4:$R1, GR64:$R2),
|
||||||
|
mnemonic#"\t$R1, $R2", []>;
|
||||||
|
|
||||||
|
class FixedCondBranchRR<CondVariant V, string mnemonic, bits<8> opcode,
|
||||||
|
SDPatternOperator operator = null_frag>
|
||||||
|
: InstRR<opcode, (outs), (ins ADDR64:$R2),
|
||||||
|
!subst("#", V.suffix, mnemonic)#"\t$R2", [(operator ADDR64:$R2)]> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let R1 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CondBranchRX<string mnemonic, bits<8> opcode>
|
||||||
|
: InstRXb<opcode, (outs), (ins cond4:$valid, cond4:$M1, bdxaddr12only:$XBD2),
|
||||||
|
!subst("#", "${M1}", mnemonic)#"\t$XBD2", []> {
|
||||||
|
let CCMaskFirst = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AsmCondBranchRX<string mnemonic, bits<8> opcode>
|
||||||
|
: InstRXb<opcode, (outs), (ins imm32zx4:$M1, bdxaddr12only:$XBD2),
|
||||||
|
mnemonic#"\t$M1, $XBD2", []>;
|
||||||
|
|
||||||
|
class FixedCondBranchRX<CondVariant V, string mnemonic, bits<8> opcode>
|
||||||
|
: InstRXb<opcode, (outs), (ins bdxaddr12only:$XBD2),
|
||||||
|
!subst("#", V.suffix, mnemonic)#"\t$XBD2", []> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M1 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CmpBranchRIEa<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm>
|
||||||
|
: InstRIEa<opcode, (outs), (ins cls:$R1, imm:$I2, cond4:$M3),
|
||||||
|
mnemonic#"$M3\t$R1, $I2", []>;
|
||||||
|
|
||||||
|
class AsmCmpBranchRIEa<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm>
|
||||||
|
: InstRIEa<opcode, (outs), (ins cls:$R1, imm:$I2, imm32zx4:$M3),
|
||||||
|
mnemonic#"\t$R1, $I2, $M3", []>;
|
||||||
|
|
||||||
|
class FixedCmpBranchRIEa<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm>
|
||||||
|
: InstRIEa<opcode, (outs), (ins cls:$R1, imm:$I2),
|
||||||
|
mnemonic#V.suffix#"\t$R1, $I2", []> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M3 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass CmpBranchRIEaPair<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CmpBranchRIEa<mnemonic, opcode, cls, imm>;
|
||||||
|
def Asm : AsmCmpBranchRIEa<mnemonic, opcode, cls, imm>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CmpBranchRIEb<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls>
|
||||||
|
: InstRIEb<opcode, (outs),
|
||||||
|
(ins cls:$R1, cls:$R2, cond4:$M3, brtarget16:$RI4),
|
||||||
|
mnemonic#"$M3\t$R1, $R2, $RI4", []>;
|
||||||
|
|
||||||
|
class AsmCmpBranchRIEb<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls>
|
||||||
|
: InstRIEb<opcode, (outs),
|
||||||
|
(ins cls:$R1, cls:$R2, imm32zx4:$M3, brtarget16:$RI4),
|
||||||
|
mnemonic#"\t$R1, $R2, $M3, $RI4", []>;
|
||||||
|
|
||||||
|
class FixedCmpBranchRIEb<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls>
|
||||||
|
: InstRIEb<opcode, (outs), (ins cls:$R1, cls:$R2, brtarget16:$RI4),
|
||||||
|
mnemonic#V.suffix#"\t$R1, $R2, $RI4", []> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M3 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass CmpBranchRIEbPair<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CmpBranchRIEb<mnemonic, opcode, cls>;
|
||||||
|
def Asm : AsmCmpBranchRIEb<mnemonic, opcode, cls>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CmpBranchRIEc<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm>
|
||||||
|
: InstRIEc<opcode, (outs),
|
||||||
|
(ins cls:$R1, imm:$I2, cond4:$M3, brtarget16:$RI4),
|
||||||
|
mnemonic#"$M3\t$R1, $I2, $RI4", []>;
|
||||||
|
|
||||||
|
class AsmCmpBranchRIEc<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm>
|
||||||
|
: InstRIEc<opcode, (outs),
|
||||||
|
(ins cls:$R1, imm:$I2, imm32zx4:$M3, brtarget16:$RI4),
|
||||||
|
mnemonic#"\t$R1, $I2, $M3, $RI4", []>;
|
||||||
|
|
||||||
|
class FixedCmpBranchRIEc<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm>
|
||||||
|
: InstRIEc<opcode, (outs), (ins cls:$R1, imm:$I2, brtarget16:$RI4),
|
||||||
|
mnemonic#V.suffix#"\t$R1, $I2, $RI4", []> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M3 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass CmpBranchRIEcPair<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CmpBranchRIEc<mnemonic, opcode, cls, imm>;
|
||||||
|
def Asm : AsmCmpBranchRIEc<mnemonic, opcode, cls, imm>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CmpBranchRRFc<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls>
|
||||||
|
: InstRRFc<opcode, (outs), (ins cls:$R1, cls:$R2, cond4:$M3),
|
||||||
|
mnemonic#"$M3\t$R1, $R2", []>;
|
||||||
|
|
||||||
|
class AsmCmpBranchRRFc<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls>
|
||||||
|
: InstRRFc<opcode, (outs), (ins cls:$R1, cls:$R2, imm32zx4:$M3),
|
||||||
|
mnemonic#"\t$R1, $R2, $M3", []>;
|
||||||
|
|
||||||
|
multiclass CmpBranchRRFcPair<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CmpBranchRRFc<mnemonic, opcode, cls>;
|
||||||
|
def Asm : AsmCmpBranchRRFc<mnemonic, opcode, cls>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FixedCmpBranchRRFc<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls>
|
||||||
|
: InstRRFc<opcode, (outs), (ins cls:$R1, cls:$R2),
|
||||||
|
mnemonic#V.suffix#"\t$R1, $R2", []> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M3 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CmpBranchRRS<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls>
|
||||||
|
: InstRRS<opcode, (outs),
|
||||||
|
(ins cls:$R1, cls:$R2, cond4:$M3, bdaddr12only:$BD4),
|
||||||
|
mnemonic#"$M3\t$R1, $R2, $BD4", []>;
|
||||||
|
|
||||||
|
class AsmCmpBranchRRS<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls>
|
||||||
|
: InstRRS<opcode, (outs),
|
||||||
|
(ins cls:$R1, cls:$R2, imm32zx4:$M3, bdaddr12only:$BD4),
|
||||||
|
mnemonic#"\t$R1, $R2, $M3, $BD4", []>;
|
||||||
|
|
||||||
|
class FixedCmpBranchRRS<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls>
|
||||||
|
: InstRRS<opcode, (outs), (ins cls:$R1, cls:$R2, bdaddr12only:$BD4),
|
||||||
|
mnemonic#V.suffix#"\t$R1, $R2, $BD4", []> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M3 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass CmpBranchRRSPair<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CmpBranchRRS<mnemonic, opcode, cls>;
|
||||||
|
def Asm : AsmCmpBranchRRS<mnemonic, opcode, cls>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CmpBranchRIS<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm>
|
||||||
|
: InstRIS<opcode, (outs),
|
||||||
|
(ins cls:$R1, imm:$I2, cond4:$M3, bdaddr12only:$BD4),
|
||||||
|
mnemonic#"$M3\t$R1, $I2, $BD4", []>;
|
||||||
|
|
||||||
|
class AsmCmpBranchRIS<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm>
|
||||||
|
: InstRIS<opcode, (outs),
|
||||||
|
(ins cls:$R1, imm:$I2, imm32zx4:$M3, bdaddr12only:$BD4),
|
||||||
|
mnemonic#"\t$R1, $I2, $M3, $BD4", []>;
|
||||||
|
|
||||||
|
class FixedCmpBranchRIS<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm>
|
||||||
|
: InstRIS<opcode, (outs), (ins cls:$R1, imm:$I2, bdaddr12only:$BD4),
|
||||||
|
mnemonic#V.suffix#"\t$R1, $I2, $BD4", []> {
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M3 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass CmpBranchRISPair<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CmpBranchRIS<mnemonic, opcode, cls, imm>;
|
||||||
|
def Asm : AsmCmpBranchRIS<mnemonic, opcode, cls, imm>;
|
||||||
|
}
|
||||||
|
|
||||||
class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
|
class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
|
||||||
: InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$I2),
|
: InstRIb<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$RI2),
|
||||||
mnemonic##"\t$R1, $I2", []> {
|
mnemonic##"\t$R1, $RI2", []> {
|
||||||
let isBranch = 1;
|
|
||||||
let isTerminator = 1;
|
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
}
|
}
|
||||||
|
@ -1326,8 +1819,6 @@ class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
|
||||||
class BranchBinaryRSI<string mnemonic, bits<8> opcode, RegisterOperand cls>
|
class BranchBinaryRSI<string mnemonic, bits<8> opcode, RegisterOperand cls>
|
||||||
: InstRSI<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, brtarget16:$RI2),
|
: InstRSI<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, brtarget16:$RI2),
|
||||||
mnemonic##"\t$R1, $R3, $RI2", []> {
|
mnemonic##"\t$R1, $R3, $RI2", []> {
|
||||||
let isBranch = 1;
|
|
||||||
let isTerminator = 1;
|
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
}
|
}
|
||||||
|
@ -1365,9 +1856,9 @@ class LoadMultipleVRSa<string mnemonic, bits<16> opcode>
|
||||||
|
|
||||||
class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
||||||
RegisterOperand cls>
|
RegisterOperand cls>
|
||||||
: InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
|
: InstRILb<opcode, (outs), (ins cls:$R1, pcrel32:$RI2),
|
||||||
mnemonic#"\t$R1, $I2",
|
mnemonic#"\t$R1, $RI2",
|
||||||
[(operator cls:$R1, pcrel32:$I2)]> {
|
[(operator cls:$R1, pcrel32:$RI2)]> {
|
||||||
let mayStore = 1;
|
let mayStore = 1;
|
||||||
// We want PC-relative addresses to be tried ahead of BD and BDX addresses.
|
// We want PC-relative addresses to be tried ahead of BD and BDX addresses.
|
||||||
// However, BDXs have two extra operands and are therefore 6 units more
|
// However, BDXs have two extra operands and are therefore 6 units more
|
||||||
|
@ -1505,9 +1996,8 @@ multiclass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
|
||||||
class CondStoreRSY<string mnemonic, bits<16> opcode,
|
class CondStoreRSY<string mnemonic, bits<16> opcode,
|
||||||
RegisterOperand cls, bits<5> bytes,
|
RegisterOperand cls, bits<5> bytes,
|
||||||
AddressingMode mode = bdaddr20only>
|
AddressingMode mode = bdaddr20only>
|
||||||
: InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, cond4:$valid, cond4:$R3),
|
: InstRSYb<opcode, (outs), (ins cls:$R1, mode:$BD2, cond4:$valid, cond4:$M3),
|
||||||
mnemonic#"$R3\t$R1, $BD2", []>,
|
mnemonic#"$M3\t$R1, $BD2", []> {
|
||||||
Requires<[FeatureLoadStoreOnCond]> {
|
|
||||||
let mayStore = 1;
|
let mayStore = 1;
|
||||||
let AccessBytes = bytes;
|
let AccessBytes = bytes;
|
||||||
let CCMaskLast = 1;
|
let CCMaskLast = 1;
|
||||||
|
@ -1518,23 +2008,30 @@ class CondStoreRSY<string mnemonic, bits<16> opcode,
|
||||||
class AsmCondStoreRSY<string mnemonic, bits<16> opcode,
|
class AsmCondStoreRSY<string mnemonic, bits<16> opcode,
|
||||||
RegisterOperand cls, bits<5> bytes,
|
RegisterOperand cls, bits<5> bytes,
|
||||||
AddressingMode mode = bdaddr20only>
|
AddressingMode mode = bdaddr20only>
|
||||||
: InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, imm32zx4:$R3),
|
: InstRSYb<opcode, (outs), (ins cls:$R1, mode:$BD2, imm32zx4:$M3),
|
||||||
mnemonic#"\t$R1, $BD2, $R3", []>,
|
mnemonic#"\t$R1, $BD2, $M3", []> {
|
||||||
Requires<[FeatureLoadStoreOnCond]> {
|
|
||||||
let mayStore = 1;
|
let mayStore = 1;
|
||||||
let AccessBytes = bytes;
|
let AccessBytes = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like CondStoreRSY, but with a fixed CC mask.
|
// Like CondStoreRSY, but with a fixed CC mask.
|
||||||
class FixedCondStoreRSY<string mnemonic, bits<16> opcode,
|
class FixedCondStoreRSY<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
|
RegisterOperand cls, bits<5> bytes,
|
||||||
AddressingMode mode = bdaddr20only>
|
AddressingMode mode = bdaddr20only>
|
||||||
: InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2),
|
: InstRSYb<opcode, (outs), (ins cls:$R1, mode:$BD2),
|
||||||
mnemonic#"\t$R1, $BD2", []>,
|
mnemonic#V.suffix#"\t$R1, $BD2", []> {
|
||||||
Requires<[FeatureLoadStoreOnCond]> {
|
|
||||||
let mayStore = 1;
|
let mayStore = 1;
|
||||||
let AccessBytes = bytes;
|
let AccessBytes = bytes;
|
||||||
let R3 = ccmask;
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M3 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass CondStoreRSYPair<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, bits<5> bytes,
|
||||||
|
AddressingMode mode = bdaddr20only> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CondStoreRSY<mnemonic, opcode, cls, bytes, mode>;
|
||||||
|
def Asm : AsmCondStoreRSY<mnemonic, opcode, cls, bytes, mode>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
|
class UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
|
||||||
|
@ -1573,19 +2070,15 @@ class UnaryRRF4<string mnemonic, bits<16> opcode, RegisterOperand cls1,
|
||||||
// is added as an implicit use.
|
// is added as an implicit use.
|
||||||
class CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
|
class CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
|
||||||
RegisterOperand cls2>
|
RegisterOperand cls2>
|
||||||
: InstRRF<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$valid, cond4:$R3),
|
: InstRRFc<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$valid, cond4:$M3),
|
||||||
mnemonic#"r$R3\t$R1, $R2", []>,
|
mnemonic#"$M3\t$R1, $R2", []> {
|
||||||
Requires<[FeatureLoadStoreOnCond]> {
|
|
||||||
let CCMaskLast = 1;
|
let CCMaskLast = 1;
|
||||||
let R4 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CondUnaryRIE<string mnemonic, bits<16> opcode, RegisterOperand cls,
|
class CondUnaryRIE<string mnemonic, bits<16> opcode, RegisterOperand cls,
|
||||||
Immediate imm>
|
Immediate imm>
|
||||||
: InstRIEd<opcode, (outs cls:$R1),
|
: InstRIEg<opcode, (outs cls:$R1), (ins imm:$I2, cond4:$valid, cond4:$M3),
|
||||||
(ins imm:$I2, cond4:$valid, cond4:$R3),
|
mnemonic#"$M3\t$R1, $I2", []> {
|
||||||
mnemonic#"$R3\t$R1, $I2", []>,
|
|
||||||
Requires<[FeatureLoadStoreOnCond2]> {
|
|
||||||
let CCMaskLast = 1;
|
let CCMaskLast = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1593,45 +2086,55 @@ class CondUnaryRIE<string mnemonic, bits<16> opcode, RegisterOperand cls,
|
||||||
// mask is the third operand rather than being part of the mnemonic.
|
// mask is the third operand rather than being part of the mnemonic.
|
||||||
class AsmCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
|
class AsmCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
|
||||||
RegisterOperand cls2>
|
RegisterOperand cls2>
|
||||||
: InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2, imm32zx4:$R3),
|
: InstRRFc<opcode, (outs cls1:$R1),
|
||||||
mnemonic#"r\t$R1, $R2, $R3", []>,
|
(ins cls1:$R1src, cls2:$R2, imm32zx4:$M3),
|
||||||
Requires<[FeatureLoadStoreOnCond]> {
|
mnemonic#"\t$R1, $R2, $M3", []> {
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
let R4 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AsmCondUnaryRIE<string mnemonic, bits<16> opcode, RegisterOperand cls,
|
class AsmCondUnaryRIE<string mnemonic, bits<16> opcode, RegisterOperand cls,
|
||||||
Immediate imm>
|
Immediate imm>
|
||||||
: InstRIEd<opcode, (outs cls:$R1),
|
: InstRIEg<opcode, (outs cls:$R1),
|
||||||
(ins cls:$R1src, imm:$I2, imm32zx4:$R3),
|
(ins cls:$R1src, imm:$I2, imm32zx4:$M3),
|
||||||
mnemonic#"\t$R1, $I2, $R3", []>,
|
mnemonic#"\t$R1, $I2, $M3", []> {
|
||||||
Requires<[FeatureLoadStoreOnCond2]> {
|
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like CondUnaryRRF, but with a fixed CC mask.
|
// Like CondUnaryRRF, but with a fixed CC mask.
|
||||||
class FixedCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
|
class FixedCondUnaryRRF<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
RegisterOperand cls2, bits<4> ccmask>
|
RegisterOperand cls1, RegisterOperand cls2>
|
||||||
: InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
|
: InstRRFc<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
|
||||||
mnemonic#"\t$R1, $R2", []>,
|
mnemonic#V.suffix#"\t$R1, $R2", []> {
|
||||||
Requires<[FeatureLoadStoreOnCond]> {
|
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
let R3 = ccmask;
|
let isAsmParserOnly = V.alternate;
|
||||||
let R4 = 0;
|
let M3 = V.ccmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
class FixedCondUnaryRIE<string mnemonic, bits<16> opcode, RegisterOperand cls,
|
class FixedCondUnaryRIE<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
Immediate imm, bits<4> ccmask>
|
RegisterOperand cls, Immediate imm>
|
||||||
: InstRIEd<opcode, (outs cls:$R1),
|
: InstRIEg<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
|
||||||
(ins cls:$R1src, imm:$I2),
|
mnemonic#V.suffix#"\t$R1, $I2", []> {
|
||||||
mnemonic#"\t$R1, $I2", []>,
|
|
||||||
Requires<[FeatureLoadStoreOnCond2]> {
|
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
let R3 = ccmask;
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M3 = V.ccmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass CondUnaryRRFPair<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls1, RegisterOperand cls2> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CondUnaryRRF<mnemonic, opcode, cls1, cls2>;
|
||||||
|
def Asm : AsmCondUnaryRRF<mnemonic, opcode, cls1, cls2>;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass CondUnaryRIEPair<string mnemonic, bits<16> opcode,
|
||||||
|
RegisterOperand cls, Immediate imm> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CondUnaryRIE<mnemonic, opcode, cls, imm>;
|
||||||
|
def Asm : AsmCondUnaryRIE<mnemonic, opcode, cls, imm>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
||||||
|
@ -1648,9 +2151,9 @@ class UnaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
||||||
|
|
||||||
class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
||||||
RegisterOperand cls>
|
RegisterOperand cls>
|
||||||
: InstRIL<opcode, (outs cls:$R1), (ins pcrel32:$I2),
|
: InstRILb<opcode, (outs cls:$R1), (ins pcrel32:$RI2),
|
||||||
mnemonic#"\t$R1, $I2",
|
mnemonic#"\t$R1, $RI2",
|
||||||
[(set cls:$R1, (operator pcrel32:$I2))]> {
|
[(set cls:$R1, (operator pcrel32:$RI2))]> {
|
||||||
let mayLoad = 1;
|
let mayLoad = 1;
|
||||||
// We want PC-relative addresses to be tried ahead of BD and BDX addresses.
|
// We want PC-relative addresses to be tried ahead of BD and BDX addresses.
|
||||||
// However, BDXs have two extra operands and are therefore 6 units more
|
// However, BDXs have two extra operands and are therefore 6 units more
|
||||||
|
@ -1661,13 +2164,12 @@ class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
||||||
class CondUnaryRSY<string mnemonic, bits<16> opcode,
|
class CondUnaryRSY<string mnemonic, bits<16> opcode,
|
||||||
SDPatternOperator operator, RegisterOperand cls,
|
SDPatternOperator operator, RegisterOperand cls,
|
||||||
bits<5> bytes, AddressingMode mode = bdaddr20only>
|
bits<5> bytes, AddressingMode mode = bdaddr20only>
|
||||||
: InstRSY<opcode, (outs cls:$R1),
|
: InstRSYb<opcode, (outs cls:$R1),
|
||||||
(ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$R3),
|
(ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$M3),
|
||||||
mnemonic#"$R3\t$R1, $BD2",
|
mnemonic#"$M3\t$R1, $BD2",
|
||||||
[(set cls:$R1,
|
[(set cls:$R1,
|
||||||
(z_select_ccmask (operator bdaddr20only:$BD2), cls:$R1src,
|
(z_select_ccmask (operator bdaddr20only:$BD2), cls:$R1src,
|
||||||
cond4:$valid, cond4:$R3))]>,
|
cond4:$valid, cond4:$M3))]> {
|
||||||
Requires<[FeatureLoadStoreOnCond]> {
|
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
let mayLoad = 1;
|
let mayLoad = 1;
|
||||||
|
@ -1680,9 +2182,8 @@ class CondUnaryRSY<string mnemonic, bits<16> opcode,
|
||||||
class AsmCondUnaryRSY<string mnemonic, bits<16> opcode,
|
class AsmCondUnaryRSY<string mnemonic, bits<16> opcode,
|
||||||
RegisterOperand cls, bits<5> bytes,
|
RegisterOperand cls, bits<5> bytes,
|
||||||
AddressingMode mode = bdaddr20only>
|
AddressingMode mode = bdaddr20only>
|
||||||
: InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, imm32zx4:$R3),
|
: InstRSYb<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, imm32zx4:$M3),
|
||||||
mnemonic#"\t$R1, $BD2, $R3", []>,
|
mnemonic#"\t$R1, $BD2, $M3", []> {
|
||||||
Requires<[FeatureLoadStoreOnCond]> {
|
|
||||||
let mayLoad = 1;
|
let mayLoad = 1;
|
||||||
let AccessBytes = bytes;
|
let AccessBytes = bytes;
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
|
@ -1690,19 +2191,29 @@ class AsmCondUnaryRSY<string mnemonic, bits<16> opcode,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like CondUnaryRSY, but with a fixed CC mask.
|
// Like CondUnaryRSY, but with a fixed CC mask.
|
||||||
class FixedCondUnaryRSY<string mnemonic, bits<16> opcode,
|
class FixedCondUnaryRSY<CondVariant V, string mnemonic, bits<16> opcode,
|
||||||
RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
|
RegisterOperand cls, bits<5> bytes,
|
||||||
AddressingMode mode = bdaddr20only>
|
AddressingMode mode = bdaddr20only>
|
||||||
: InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2),
|
: InstRSYb<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2),
|
||||||
mnemonic#"\t$R1, $BD2", []>,
|
mnemonic#V.suffix#"\t$R1, $BD2", []> {
|
||||||
Requires<[FeatureLoadStoreOnCond]> {
|
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
let R3 = ccmask;
|
|
||||||
let mayLoad = 1;
|
let mayLoad = 1;
|
||||||
let AccessBytes = bytes;
|
let AccessBytes = bytes;
|
||||||
|
let isAsmParserOnly = V.alternate;
|
||||||
|
let M3 = V.ccmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
multiclass CondUnaryRSYPair<string mnemonic, bits<16> opcode,
|
||||||
|
SDPatternOperator operator,
|
||||||
|
RegisterOperand cls, bits<5> bytes,
|
||||||
|
AddressingMode mode = bdaddr20only> {
|
||||||
|
let isCodeGenOnly = 1 in
|
||||||
|
def "" : CondUnaryRSY<mnemonic, opcode, operator, cls, bytes, mode>;
|
||||||
|
def Asm : AsmCondUnaryRSY<mnemonic, opcode, cls, bytes, mode>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
|
class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
|
||||||
RegisterOperand cls, bits<5> bytes,
|
RegisterOperand cls, bits<5> bytes,
|
||||||
AddressingMode mode = bdxaddr12only>
|
AddressingMode mode = bdxaddr12only>
|
||||||
|
@ -2321,9 +2832,9 @@ class CompareRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
||||||
|
|
||||||
class CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
class CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
||||||
RegisterOperand cls, SDPatternOperator load>
|
RegisterOperand cls, SDPatternOperator load>
|
||||||
: InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
|
: InstRILb<opcode, (outs), (ins cls:$R1, pcrel32:$RI2),
|
||||||
mnemonic#"\t$R1, $I2",
|
mnemonic#"\t$R1, $RI2",
|
||||||
[(operator cls:$R1, (load pcrel32:$I2))]> {
|
[(operator cls:$R1, (load pcrel32:$RI2))]> {
|
||||||
let isCompare = 1;
|
let isCompare = 1;
|
||||||
let mayLoad = 1;
|
let mayLoad = 1;
|
||||||
// We want PC-relative addresses to be tried ahead of BD and BDX addresses.
|
// We want PC-relative addresses to be tried ahead of BD and BDX addresses.
|
||||||
|
@ -2473,9 +2984,9 @@ class TernaryRRD<string mnemonic, bits<16> opcode,
|
||||||
|
|
||||||
class TernaryRS<string mnemonic, bits<8> opcode, RegisterOperand cls,
|
class TernaryRS<string mnemonic, bits<8> opcode, RegisterOperand cls,
|
||||||
bits<5> bytes, AddressingMode mode = bdaddr12only>
|
bits<5> bytes, AddressingMode mode = bdaddr12only>
|
||||||
: InstRS<opcode, (outs cls:$R1),
|
: InstRSb<opcode, (outs cls:$R1),
|
||||||
(ins cls:$R1src, imm32zx4:$R3, mode:$BD2),
|
(ins cls:$R1src, imm32zx4:$M3, mode:$BD2),
|
||||||
mnemonic#"\t$R1, $R3, $BD2", []> {
|
mnemonic#"\t$R1, $M3, $BD2", []> {
|
||||||
|
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
|
@ -2485,9 +2996,9 @@ class TernaryRS<string mnemonic, bits<8> opcode, RegisterOperand cls,
|
||||||
|
|
||||||
class TernaryRSY<string mnemonic, bits<16> opcode, RegisterOperand cls,
|
class TernaryRSY<string mnemonic, bits<16> opcode, RegisterOperand cls,
|
||||||
bits<5> bytes, AddressingMode mode = bdaddr20only>
|
bits<5> bytes, AddressingMode mode = bdaddr20only>
|
||||||
: InstRSY<opcode, (outs cls:$R1),
|
: InstRSYb<opcode, (outs cls:$R1),
|
||||||
(ins cls:$R1src, imm32zx4:$R3, mode:$BD2),
|
(ins cls:$R1src, imm32zx4:$M3, mode:$BD2),
|
||||||
mnemonic#"\t$R1, $R3, $BD2", []> {
|
mnemonic#"\t$R1, $M3, $BD2", []> {
|
||||||
|
|
||||||
let Constraints = "$R1 = $R1src";
|
let Constraints = "$R1 = $R1src";
|
||||||
let DisableEncoding = "$R1src";
|
let DisableEncoding = "$R1src";
|
||||||
|
@ -2815,15 +3326,15 @@ class RotateSelectRIEf<string mnemonic, bits<16> opcode, RegisterOperand cls1,
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrefetchRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator>
|
class PrefetchRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator>
|
||||||
: InstRXY<opcode, (outs), (ins imm32zx4:$R1, bdxaddr20only:$XBD2),
|
: InstRXYb<opcode, (outs), (ins imm32zx4:$M1, bdxaddr20only:$XBD2),
|
||||||
mnemonic##"\t$R1, $XBD2",
|
mnemonic##"\t$M1, $XBD2",
|
||||||
[(operator imm32zx4:$R1, bdxaddr20only:$XBD2)]>;
|
[(operator imm32zx4:$M1, bdxaddr20only:$XBD2)]>;
|
||||||
|
|
||||||
class PrefetchRILPC<string mnemonic, bits<12> opcode,
|
class PrefetchRILPC<string mnemonic, bits<12> opcode,
|
||||||
SDPatternOperator operator>
|
SDPatternOperator operator>
|
||||||
: InstRIL<opcode, (outs), (ins imm32zx4:$R1, pcrel32:$I2),
|
: InstRILc<opcode, (outs), (ins imm32zx4:$M1, pcrel32:$RI2),
|
||||||
mnemonic##"\t$R1, $I2",
|
mnemonic##"\t$M1, $RI2",
|
||||||
[(operator imm32zx4:$R1, pcrel32:$I2)]> {
|
[(operator imm32zx4:$M1, pcrel32:$RI2)]> {
|
||||||
// We want PC-relative addresses to be tried ahead of BD and BDX addresses.
|
// We want PC-relative addresses to be tried ahead of BD and BDX addresses.
|
||||||
// However, BDXs have two extra operands and are therefore 6 units more
|
// However, BDXs have two extra operands and are therefore 6 units more
|
||||||
// complex.
|
// complex.
|
||||||
|
|
|
@ -31,9 +31,244 @@ let hasSideEffects = 0 in {
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Control flow instructions
|
// Branch instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Conditional branches.
|
||||||
|
let isBranch = 1, isTerminator = 1, Uses = [CC] in {
|
||||||
|
// It's easier for LLVM to handle these branches in their raw BRC/BRCL form
|
||||||
|
// with the condition-code mask being the first operand. It seems friendlier
|
||||||
|
// to use mnemonic forms like JE and JLH when writing out the assembly though.
|
||||||
|
let isCodeGenOnly = 1 in {
|
||||||
|
// An assembler extended mnemonic for BRC.
|
||||||
|
def BRC : CondBranchRI <"j#", 0xA74, z_br_ccmask>;
|
||||||
|
// An assembler extended mnemonic for BRCL. (The extension is "G"
|
||||||
|
// rather than "L" because "JL" is "Jump if Less".)
|
||||||
|
def BRCL : CondBranchRIL<"jg#", 0xC04>;
|
||||||
|
let isIndirectBranch = 1 in {
|
||||||
|
def BC : CondBranchRX<"b#", 0x47>;
|
||||||
|
def BCR : CondBranchRR<"b#r", 0x07>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow using the raw forms directly from the assembler (and occasional
|
||||||
|
// special code generation needs) as well.
|
||||||
|
def BRCAsm : AsmCondBranchRI <"brc", 0xA74>;
|
||||||
|
def BRCLAsm : AsmCondBranchRIL<"brcl", 0xC04>;
|
||||||
|
let isIndirectBranch = 1 in {
|
||||||
|
def BCAsm : AsmCondBranchRX<"bc", 0x47>;
|
||||||
|
def BCRAsm : AsmCondBranchRR<"bcr", 0x07>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define AsmParser extended mnemonics for each general condition-code mask
|
||||||
|
// (integer or floating-point)
|
||||||
|
foreach V = [ "E", "NE", "H", "NH", "L", "NL", "HE", "NHE", "LE", "NLE",
|
||||||
|
"Z", "NZ", "P", "NP", "M", "NM", "LH", "NLH", "O", "NO" ] in {
|
||||||
|
def JAsm#V : FixedCondBranchRI <CV<V>, "j#", 0xA74>;
|
||||||
|
def JGAsm#V : FixedCondBranchRIL<CV<V>, "jg#", 0xC04>;
|
||||||
|
let isIndirectBranch = 1 in {
|
||||||
|
def BAsm#V : FixedCondBranchRX <CV<V>, "b#", 0x47>;
|
||||||
|
def BRAsm#V : FixedCondBranchRR <CV<V>, "b#r", 0x07>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unconditional branches. These are in fact simply variants of the
|
||||||
|
// conditional branches with the condition mask set to "always".
|
||||||
|
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
|
||||||
|
def J : FixedCondBranchRI <CondAlways, "j", 0xA74, br>;
|
||||||
|
def JG : FixedCondBranchRIL<CondAlways, "jg", 0xC04>;
|
||||||
|
let isIndirectBranch = 1 in {
|
||||||
|
def B : FixedCondBranchRX<CondAlways, "b", 0x47>;
|
||||||
|
def BR : FixedCondBranchRR<CondAlways, "br", 0x07, brind>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOPs. These are again variants of the conditional branches,
|
||||||
|
// with the condition mask set to "never".
|
||||||
|
def NOP : InstAlias<"nop\t$XBD", (BCAsm 0, bdxaddr12only:$XBD), 0>;
|
||||||
|
def NOPR : InstAlias<"nopr\t$R", (BCRAsm 0, GR64:$R), 0>;
|
||||||
|
|
||||||
|
// Fused compare-and-branch instructions.
|
||||||
|
//
|
||||||
|
// These instructions do not use or clobber the condition codes.
|
||||||
|
// We nevertheless pretend that the relative compare-and-branch
|
||||||
|
// instructions clobber CC, so that we can lower them to separate
|
||||||
|
// comparisons and BRCLs if the branch ends up being out of range.
|
||||||
|
let isBranch = 1, isTerminator = 1 in {
|
||||||
|
// As for normal branches, we handle these instructions internally in
|
||||||
|
// their raw CRJ-like form, but use assembly macros like CRJE when writing
|
||||||
|
// them out. Using the *Pair multiclasses, we also create the raw forms.
|
||||||
|
let Defs = [CC] in {
|
||||||
|
defm CRJ : CmpBranchRIEbPair<"crj", 0xEC76, GR32>;
|
||||||
|
defm CGRJ : CmpBranchRIEbPair<"cgrj", 0xEC64, GR64>;
|
||||||
|
defm CIJ : CmpBranchRIEcPair<"cij", 0xEC7E, GR32, imm32sx8>;
|
||||||
|
defm CGIJ : CmpBranchRIEcPair<"cgij", 0xEC7C, GR64, imm64sx8>;
|
||||||
|
defm CLRJ : CmpBranchRIEbPair<"clrj", 0xEC77, GR32>;
|
||||||
|
defm CLGRJ : CmpBranchRIEbPair<"clgrj", 0xEC65, GR64>;
|
||||||
|
defm CLIJ : CmpBranchRIEcPair<"clij", 0xEC7F, GR32, imm32zx8>;
|
||||||
|
defm CLGIJ : CmpBranchRIEcPair<"clgij", 0xEC7D, GR64, imm64zx8>;
|
||||||
|
}
|
||||||
|
let isIndirectBranch = 1 in {
|
||||||
|
defm CRB : CmpBranchRRSPair<"crb", 0xECF6, GR32>;
|
||||||
|
defm CGRB : CmpBranchRRSPair<"cgrb", 0xECE4, GR64>;
|
||||||
|
defm CIB : CmpBranchRISPair<"cib", 0xECFE, GR32, imm32sx8>;
|
||||||
|
defm CGIB : CmpBranchRISPair<"cgib", 0xECFC, GR64, imm64sx8>;
|
||||||
|
defm CLRB : CmpBranchRRSPair<"clrb", 0xECF7, GR32>;
|
||||||
|
defm CLGRB : CmpBranchRRSPair<"clgrb", 0xECE5, GR64>;
|
||||||
|
defm CLIB : CmpBranchRISPair<"clib", 0xECFF, GR32, imm32zx8>;
|
||||||
|
defm CLGIB : CmpBranchRISPair<"clgib", 0xECFD, GR64, imm64zx8>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define AsmParser mnemonics for each integer condition-code mask.
|
||||||
|
foreach V = [ "E", "H", "L", "HE", "LE", "LH",
|
||||||
|
"NE", "NH", "NL", "NHE", "NLE", "NLH" ] in {
|
||||||
|
let Defs = [CC] in {
|
||||||
|
def CRJAsm#V : FixedCmpBranchRIEb<ICV<V>, "crj", 0xEC76, GR32>;
|
||||||
|
def CGRJAsm#V : FixedCmpBranchRIEb<ICV<V>, "cgrj", 0xEC64, GR64>;
|
||||||
|
def CIJAsm#V : FixedCmpBranchRIEc<ICV<V>, "cij", 0xEC7E, GR32,
|
||||||
|
imm32sx8>;
|
||||||
|
def CGIJAsm#V : FixedCmpBranchRIEc<ICV<V>, "cgij", 0xEC7C, GR64,
|
||||||
|
imm64sx8>;
|
||||||
|
def CLRJAsm#V : FixedCmpBranchRIEb<ICV<V>, "clrj", 0xEC77, GR32>;
|
||||||
|
def CLGRJAsm#V : FixedCmpBranchRIEb<ICV<V>, "clgrj", 0xEC65, GR64>;
|
||||||
|
def CLIJAsm#V : FixedCmpBranchRIEc<ICV<V>, "clij", 0xEC7F, GR32,
|
||||||
|
imm32zx8>;
|
||||||
|
def CLGIJAsm#V : FixedCmpBranchRIEc<ICV<V>, "clgij", 0xEC7D, GR64,
|
||||||
|
imm64zx8>;
|
||||||
|
}
|
||||||
|
let isIndirectBranch = 1 in {
|
||||||
|
def CRBAsm#V : FixedCmpBranchRRS<ICV<V>, "crb", 0xECF6, GR32>;
|
||||||
|
def CGRBAsm#V : FixedCmpBranchRRS<ICV<V>, "cgrb", 0xECE4, GR64>;
|
||||||
|
def CIBAsm#V : FixedCmpBranchRIS<ICV<V>, "cib", 0xECFE, GR32,
|
||||||
|
imm32sx8>;
|
||||||
|
def CGIBAsm#V : FixedCmpBranchRIS<ICV<V>, "cgib", 0xECFC, GR64,
|
||||||
|
imm64sx8>;
|
||||||
|
def CLRBAsm#V : FixedCmpBranchRRS<ICV<V>, "clrb", 0xECF7, GR32>;
|
||||||
|
def CLGRBAsm#V : FixedCmpBranchRRS<ICV<V>, "clgrb", 0xECE5, GR64>;
|
||||||
|
def CLIBAsm#V : FixedCmpBranchRIS<ICV<V>, "clib", 0xECFF, GR32,
|
||||||
|
imm32zx8>;
|
||||||
|
def CLGIBAsm#V : FixedCmpBranchRIS<ICV<V>, "clgib", 0xECFD, GR64,
|
||||||
|
imm64zx8>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrement a register and branch if it is nonzero. These don't clobber CC,
|
||||||
|
// but we might need to split long branches into sequences that do.
|
||||||
|
let isBranch = 1, isTerminator = 1, Defs = [CC] in {
|
||||||
|
def BRCT : BranchUnaryRI<"brct", 0xA76, GR32>;
|
||||||
|
def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isBranch = 1, isTerminator = 1, Defs = [CC] in {
|
||||||
|
def BRXH : BranchBinaryRSI<"brxh", 0x84, GR32>;
|
||||||
|
def BRXLE : BranchBinaryRSI<"brxle", 0x85, GR32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Trap instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Unconditional trap.
|
||||||
|
// FIXME: This trap instruction should be marked as isTerminator, but there is
|
||||||
|
// currently a general bug that allows non-terminators to be placed between
|
||||||
|
// terminators. Temporarily leave this unmarked until the bug is fixed.
|
||||||
|
let isBarrier = 1, hasCtrlDep = 1 in
|
||||||
|
def Trap : Alias<4, (outs), (ins), [(trap)]>;
|
||||||
|
|
||||||
|
// Conditional trap.
|
||||||
|
let isTerminator = 1, hasCtrlDep = 1, Uses = [CC] in
|
||||||
|
def CondTrap : Alias<4, (outs), (ins cond4:$valid, cond4:$R1), []>;
|
||||||
|
|
||||||
|
// Fused compare-and-trap instructions.
|
||||||
|
let isTerminator = 1, hasCtrlDep = 1 in {
|
||||||
|
// These patterns work the same way as for compare-and-branch.
|
||||||
|
defm CRT : CmpBranchRRFcPair<"crt", 0xB972, GR32>;
|
||||||
|
defm CGRT : CmpBranchRRFcPair<"cgrt", 0xB960, GR64>;
|
||||||
|
defm CLRT : CmpBranchRRFcPair<"clrt", 0xB973, GR32>;
|
||||||
|
defm CLGRT : CmpBranchRRFcPair<"clgrt", 0xB961, GR64>;
|
||||||
|
defm CIT : CmpBranchRIEaPair<"cit", 0xEC72, GR32, imm32sx16>;
|
||||||
|
defm CGIT : CmpBranchRIEaPair<"cgit", 0xEC70, GR64, imm64sx16>;
|
||||||
|
defm CLFIT : CmpBranchRIEaPair<"clfit", 0xEC73, GR32, imm32zx16>;
|
||||||
|
defm CLGIT : CmpBranchRIEaPair<"clgit", 0xEC71, GR64, imm64zx16>;
|
||||||
|
|
||||||
|
foreach V = [ "E", "H", "L", "HE", "LE", "LH",
|
||||||
|
"NE", "NH", "NL", "NHE", "NLE", "NLH" ] in {
|
||||||
|
def CRTAsm#V : FixedCmpBranchRRFc<ICV<V>, "crt", 0xB972, GR32>;
|
||||||
|
def CGRTAsm#V : FixedCmpBranchRRFc<ICV<V>, "cgrt", 0xB960, GR64>;
|
||||||
|
def CLRTAsm#V : FixedCmpBranchRRFc<ICV<V>, "clrt", 0xB973, GR32>;
|
||||||
|
def CLGRTAsm#V : FixedCmpBranchRRFc<ICV<V>, "clgrt", 0xB961, GR64>;
|
||||||
|
def CITAsm#V : FixedCmpBranchRIEa<ICV<V>, "cit", 0xEC72, GR32,
|
||||||
|
imm32sx16>;
|
||||||
|
def CGITAsm#V : FixedCmpBranchRIEa<ICV<V>, "cgit", 0xEC70, GR64,
|
||||||
|
imm64sx16>;
|
||||||
|
def CLFITAsm#V : FixedCmpBranchRIEa<ICV<V>, "clfit", 0xEC73, GR32,
|
||||||
|
imm32zx16>;
|
||||||
|
def CLGITAsm#V : FixedCmpBranchRIEa<ICV<V>, "clgit", 0xEC71, GR64,
|
||||||
|
imm64zx16>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Call and return instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Define the general form of the call instructions for the asm parser.
|
||||||
|
// These instructions don't hard-code %r14 as the return address register.
|
||||||
|
let isCall = 1, Defs = [CC] in {
|
||||||
|
def BRAS : CallRI <"bras", 0xA75>;
|
||||||
|
def BRASL : CallRIL<"brasl", 0xC05>;
|
||||||
|
def BAS : CallRX <"bas", 0x4D>;
|
||||||
|
def BASR : CallRR <"basr", 0x0D>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regular calls.
|
||||||
|
let isCall = 1, Defs = [R14D, CC] in {
|
||||||
|
def CallBRASL : Alias<6, (outs), (ins pcrel32:$I2, variable_ops),
|
||||||
|
[(z_call pcrel32:$I2)]>;
|
||||||
|
def CallBASR : Alias<2, (outs), (ins ADDR64:$R2, variable_ops),
|
||||||
|
[(z_call ADDR64:$R2)]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLS calls. These will be lowered into a call to __tls_get_offset,
|
||||||
|
// with an extra relocation specifying the TLS symbol.
|
||||||
|
let isCall = 1, Defs = [R14D, CC] in {
|
||||||
|
def TLS_GDCALL : Alias<6, (outs), (ins tlssym:$I2, variable_ops),
|
||||||
|
[(z_tls_gdcall tglobaltlsaddr:$I2)]>;
|
||||||
|
def TLS_LDCALL : Alias<6, (outs), (ins tlssym:$I2, variable_ops),
|
||||||
|
[(z_tls_ldcall tglobaltlsaddr:$I2)]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sibling calls. Indirect sibling calls must be via R1, since R2 upwards
|
||||||
|
// are argument registers and since branching to R0 is a no-op.
|
||||||
|
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
||||||
|
def CallJG : Alias<6, (outs), (ins pcrel32:$I2),
|
||||||
|
[(z_sibcall pcrel32:$I2)]>;
|
||||||
|
let Uses = [R1D] in
|
||||||
|
def CallBR : Alias<2, (outs), (ins), [(z_sibcall R1D)]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conditional sibling calls.
|
||||||
|
let CCMaskFirst = 1, isCall = 1, isTerminator = 1, isReturn = 1 in {
|
||||||
|
def CallBRCL : Alias<6, (outs), (ins cond4:$valid, cond4:$R1,
|
||||||
|
pcrel32:$I2), []>;
|
||||||
|
let Uses = [R1D] in
|
||||||
|
def CallBCR : Alias<2, (outs), (ins cond4:$valid, cond4:$R1), []>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fused compare and conditional sibling calls.
|
||||||
|
let isCall = 1, isTerminator = 1, isReturn = 1, Uses = [R1D] in {
|
||||||
|
def CRBCall : Alias<6, (outs), (ins GR32:$R1, GR32:$R2, cond4:$M3), []>;
|
||||||
|
def CGRBCall : Alias<6, (outs), (ins GR64:$R1, GR64:$R2, cond4:$M3), []>;
|
||||||
|
def CIBCall : Alias<6, (outs), (ins GR32:$R1, imm32sx8:$I2, cond4:$M3), []>;
|
||||||
|
def CGIBCall : Alias<6, (outs), (ins GR64:$R1, imm64sx8:$I2, cond4:$M3), []>;
|
||||||
|
def CLRBCall : Alias<6, (outs), (ins GR32:$R1, GR32:$R2, cond4:$M3), []>;
|
||||||
|
def CLGRBCall : Alias<6, (outs), (ins GR64:$R1, GR64:$R2, cond4:$M3), []>;
|
||||||
|
def CLIBCall : Alias<6, (outs), (ins GR32:$R1, imm32zx8:$I2, cond4:$M3), []>;
|
||||||
|
def CLGIBCall : Alias<6, (outs), (ins GR64:$R1, imm64zx8:$I2, cond4:$M3), []>;
|
||||||
|
}
|
||||||
|
|
||||||
// A return instruction (br %r14).
|
// A return instruction (br %r14).
|
||||||
let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in
|
let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in
|
||||||
def Return : Alias<2, (outs), (ins), [(z_retflag)]>;
|
def Return : Alias<2, (outs), (ins), [(z_retflag)]>;
|
||||||
|
@ -54,292 +289,6 @@ let isReturn = 1, isTerminator = 1, hasCtrlDep = 1 in {
|
||||||
def CLGIBReturn : Alias<6, (outs), (ins GR64:$R1, imm64zx8:$I2, cond4:$M3), []>;
|
def CLGIBReturn : Alias<6, (outs), (ins GR64:$R1, imm64zx8:$I2, cond4:$M3), []>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unconditional branches. R1 is the condition-code mask (all 1s).
|
|
||||||
let isBranch = 1, isTerminator = 1, isBarrier = 1, R1 = 15 in {
|
|
||||||
let isIndirectBranch = 1 in
|
|
||||||
def BR : InstRR<0x07, (outs), (ins ADDR64:$R2),
|
|
||||||
"br\t$R2", [(brind ADDR64:$R2)]>;
|
|
||||||
|
|
||||||
// An assembler extended mnemonic for BRC.
|
|
||||||
def J : InstRI<0xA74, (outs), (ins brtarget16:$I2), "j\t$I2",
|
|
||||||
[(br bb:$I2)]>;
|
|
||||||
|
|
||||||
// An assembler extended mnemonic for BRCL. (The extension is "G"
|
|
||||||
// rather than "L" because "JL" is "Jump if Less".)
|
|
||||||
def JG : InstRIL<0xC04, (outs), (ins brtarget32:$I2), "jg\t$I2", []>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: This trap instruction should be marked as isTerminator, but there is
|
|
||||||
// currently a general bug that allows non-terminators to be placed between
|
|
||||||
// terminators. Temporarily leave this unmarked until the bug is fixed.
|
|
||||||
let isBarrier = 1, hasCtrlDep = 1 in {
|
|
||||||
def Trap : Alias<4, (outs), (ins), [(trap)]>;
|
|
||||||
}
|
|
||||||
|
|
||||||
let isTerminator = 1, hasCtrlDep = 1, Uses = [CC] in {
|
|
||||||
def CondTrap : Alias<4, (outs), (ins cond4:$valid, cond4:$R1), []>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conditional branches. It's easier for LLVM to handle these branches
|
|
||||||
// in their raw BRC/BRCL form, with the 4-bit condition-code mask being
|
|
||||||
// the first operand. It seems friendlier to use mnemonic forms like
|
|
||||||
// JE and JLH when writing out the assembly though.
|
|
||||||
let isBranch = 1, isTerminator = 1, Uses = [CC] in {
|
|
||||||
let isCodeGenOnly = 1, CCMaskFirst = 1 in {
|
|
||||||
def BRC : InstRI<0xA74, (outs), (ins cond4:$valid, cond4:$R1,
|
|
||||||
brtarget16:$I2), "j$R1\t$I2",
|
|
||||||
[(z_br_ccmask cond4:$valid, cond4:$R1, bb:$I2)]>;
|
|
||||||
def BRCL : InstRIL<0xC04, (outs), (ins cond4:$valid, cond4:$R1,
|
|
||||||
brtarget32:$I2), "jg$R1\t$I2", []>;
|
|
||||||
let isIndirectBranch = 1 in
|
|
||||||
def BCR : InstRR<0x07, (outs), (ins cond4:$valid, cond4:$R1, GR64:$R2),
|
|
||||||
"b${R1}r\t$R2", []>;
|
|
||||||
}
|
|
||||||
def AsmBRC : InstRI<0xA74, (outs), (ins imm32zx4:$R1, brtarget16:$I2),
|
|
||||||
"brc\t$R1, $I2", []>;
|
|
||||||
def AsmBRCL : InstRIL<0xC04, (outs), (ins imm32zx4:$R1, brtarget32:$I2),
|
|
||||||
"brcl\t$R1, $I2", []>;
|
|
||||||
let isIndirectBranch = 1 in {
|
|
||||||
def AsmBC : InstRX<0x47, (outs), (ins imm32zx4:$R1, bdxaddr12only:$XBD2),
|
|
||||||
"bc\t$R1, $XBD2", []>;
|
|
||||||
def AsmBCR : InstRR<0x07, (outs), (ins imm32zx4:$R1, GR64:$R2),
|
|
||||||
"bcr\t$R1, $R2", []>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def AsmNop : InstAlias<"nop\t$XBD", (AsmBC 0, bdxaddr12only:$XBD), 0>;
|
|
||||||
def AsmNopR : InstAlias<"nopr\t$R", (AsmBCR 0, GR64:$R), 0>;
|
|
||||||
|
|
||||||
// Fused compare-and-branch instructions. As for normal branches,
|
|
||||||
// we handle these instructions internally in their raw CRJ-like form,
|
|
||||||
// but use assembly macros like CRJE when writing them out.
|
|
||||||
//
|
|
||||||
// These instructions do not use or clobber the condition codes.
|
|
||||||
// We nevertheless pretend that they clobber CC, so that we can lower
|
|
||||||
// them to separate comparisons and BRCLs if the branch ends up being
|
|
||||||
// out of range.
|
|
||||||
multiclass CompareBranches<Operand ccmask, string pos1, string pos2> {
|
|
||||||
let isBranch = 1, isTerminator = 1, Defs = [CC] in {
|
|
||||||
def RJ : InstRIEb<0xEC76, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"crj"##pos1##"\t$R1, $R2"##pos2##", $RI4", []>;
|
|
||||||
def GRJ : InstRIEb<0xEC64, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"cgrj"##pos1##"\t$R1, $R2"##pos2##", $RI4", []>;
|
|
||||||
def IJ : InstRIEc<0xEC7E, (outs), (ins GR32:$R1, imm32sx8:$I2, ccmask:$M3,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"cij"##pos1##"\t$R1, $I2"##pos2##", $RI4", []>;
|
|
||||||
def GIJ : InstRIEc<0xEC7C, (outs), (ins GR64:$R1, imm64sx8:$I2, ccmask:$M3,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"cgij"##pos1##"\t$R1, $I2"##pos2##", $RI4", []>;
|
|
||||||
def LRJ : InstRIEb<0xEC77, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"clrj"##pos1##"\t$R1, $R2"##pos2##", $RI4", []>;
|
|
||||||
def LGRJ : InstRIEb<0xEC65, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"clgrj"##pos1##"\t$R1, $R2"##pos2##", $RI4", []>;
|
|
||||||
def LIJ : InstRIEc<0xEC7F, (outs), (ins GR32:$R1, imm32zx8:$I2, ccmask:$M3,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"clij"##pos1##"\t$R1, $I2"##pos2##", $RI4", []>;
|
|
||||||
def LGIJ : InstRIEc<0xEC7D, (outs), (ins GR64:$R1, imm64zx8:$I2, ccmask:$M3,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"clgij"##pos1##"\t$R1, $I2"##pos2##", $RI4", []>;
|
|
||||||
let isIndirectBranch = 1 in {
|
|
||||||
def RB : InstRRS<0xECF6, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"crb"##pos1##"\t$R1, $R2"##pos2##", $BD4", []>;
|
|
||||||
def GRB : InstRRS<0xECE4, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"cgrb"##pos1##"\t$R1, $R2"##pos2##", $BD4", []>;
|
|
||||||
def IB : InstRIS<0xECFE, (outs), (ins GR32:$R1, imm32sx8:$I2, ccmask:$M3,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"cib"##pos1##"\t$R1, $I2"##pos2##", $BD4", []>;
|
|
||||||
def GIB : InstRIS<0xECFC, (outs), (ins GR64:$R1, imm64sx8:$I2, ccmask:$M3,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"cgib"##pos1##"\t$R1, $I2"##pos2##", $BD4", []>;
|
|
||||||
def LRB : InstRRS<0xECF7, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"clrb"##pos1##"\t$R1, $R2"##pos2##", $BD4", []>;
|
|
||||||
def LGRB : InstRRS<0xECE5, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"clgrb"##pos1##"\t$R1, $R2"##pos2##", $BD4", []>;
|
|
||||||
def LIB : InstRIS<0xECFF, (outs), (ins GR32:$R1, imm32zx8:$I2, ccmask:$M3,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"clib"##pos1##"\t$R1, $I2"##pos2##", $BD4", []>;
|
|
||||||
def LGIB : InstRIS<0xECFD, (outs), (ins GR64:$R1, imm64zx8:$I2, ccmask:$M3,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"clgib"##pos1##"\t$R1, $I2"##pos2##", $BD4", []>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let isTerminator = 1, hasCtrlDep = 1 in {
|
|
||||||
def RT : InstRRFc<0xB972, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3),
|
|
||||||
"crt"##pos1##"\t$R1, $R2"##pos2, []>;
|
|
||||||
def GRT : InstRRFc<0xB960, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3),
|
|
||||||
"cgrt"##pos1##"\t$R1, $R2"##pos2, []>;
|
|
||||||
def LRT : InstRRFc<0xB973, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3),
|
|
||||||
"clrt"##pos1##"\t$R1, $R2"##pos2, []>;
|
|
||||||
def LGRT : InstRRFc<0xB961, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3),
|
|
||||||
"clgrt"##pos1##"\t$R1, $R2"##pos2, []>;
|
|
||||||
def IT : InstRIEa<0xEC72, (outs), (ins GR32:$R1, imm32sx16:$I2, ccmask:$M3),
|
|
||||||
"cit"##pos1##"\t$R1, $I2"##pos2, []>;
|
|
||||||
def GIT : InstRIEa<0xEC70, (outs), (ins GR64:$R1, imm32sx16:$I2, ccmask:$M3),
|
|
||||||
"cgit"##pos1##"\t$R1, $I2"##pos2, []>;
|
|
||||||
def LFIT : InstRIEa<0xEC73, (outs), (ins GR32:$R1, imm32zx16:$I2, ccmask:$M3),
|
|
||||||
"clfit"##pos1##"\t$R1, $I2"##pos2, []>;
|
|
||||||
def LGIT : InstRIEa<0xEC71, (outs), (ins GR64:$R1, imm32zx16:$I2, ccmask:$M3),
|
|
||||||
"clgit"##pos1##"\t$R1, $I2"##pos2, []>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let isCodeGenOnly = 1 in
|
|
||||||
defm C : CompareBranches<cond4, "$M3", "">;
|
|
||||||
defm AsmC : CompareBranches<imm32zx4, "", ", $M3">;
|
|
||||||
|
|
||||||
// Define AsmParser mnemonics for each general condition-code mask
|
|
||||||
// (integer or floating-point)
|
|
||||||
multiclass CondExtendedMnemonicA<bits<4> ccmask, string name> {
|
|
||||||
let isBranch = 1, isTerminator = 1, R1 = ccmask in {
|
|
||||||
def J : InstRI<0xA74, (outs), (ins brtarget16:$I2),
|
|
||||||
"j"##name##"\t$I2", []>;
|
|
||||||
def JG : InstRIL<0xC04, (outs), (ins brtarget32:$I2),
|
|
||||||
"jg"##name##"\t$I2", []>;
|
|
||||||
def BR : InstRR<0x07, (outs), (ins ADDR64:$R2), "b"##name##"r\t$R2", []>;
|
|
||||||
}
|
|
||||||
def LOCR : FixedCondUnaryRRF<"locr"##name, 0xB9F2, GR32, GR32, ccmask>;
|
|
||||||
def LOCGR : FixedCondUnaryRRF<"locgr"##name, 0xB9E2, GR64, GR64, ccmask>;
|
|
||||||
def LOCHI : FixedCondUnaryRIE<"lochi"##name, 0xEC42, GR64, imm32sx16,
|
|
||||||
ccmask>;
|
|
||||||
def LOCGHI: FixedCondUnaryRIE<"locghi"##name, 0xEC46, GR64, imm64sx16,
|
|
||||||
ccmask>;
|
|
||||||
def LOC : FixedCondUnaryRSY<"loc"##name, 0xEBF2, GR32, ccmask, 4>;
|
|
||||||
def LOCG : FixedCondUnaryRSY<"locg"##name, 0xEBE2, GR64, ccmask, 8>;
|
|
||||||
def STOC : FixedCondStoreRSY<"stoc"##name, 0xEBF3, GR32, ccmask, 4>;
|
|
||||||
def STOCG : FixedCondStoreRSY<"stocg"##name, 0xEBE3, GR64, ccmask, 8>;
|
|
||||||
}
|
|
||||||
|
|
||||||
multiclass CondExtendedMnemonic<bits<4> ccmask, string name1, string name2>
|
|
||||||
: CondExtendedMnemonicA<ccmask, name1> {
|
|
||||||
let isAsmParserOnly = 1 in
|
|
||||||
defm Alt : CondExtendedMnemonicA<ccmask, name2>;
|
|
||||||
}
|
|
||||||
|
|
||||||
defm AsmO : CondExtendedMnemonicA<1, "o">;
|
|
||||||
defm AsmH : CondExtendedMnemonic<2, "h", "p">;
|
|
||||||
defm AsmNLE : CondExtendedMnemonicA<3, "nle">;
|
|
||||||
defm AsmL : CondExtendedMnemonic<4, "l", "m">;
|
|
||||||
defm AsmNHE : CondExtendedMnemonicA<5, "nhe">;
|
|
||||||
defm AsmLH : CondExtendedMnemonicA<6, "lh">;
|
|
||||||
defm AsmNE : CondExtendedMnemonic<7, "ne", "nz">;
|
|
||||||
defm AsmE : CondExtendedMnemonic<8, "e", "z">;
|
|
||||||
defm AsmNLH : CondExtendedMnemonicA<9, "nlh">;
|
|
||||||
defm AsmHE : CondExtendedMnemonicA<10, "he">;
|
|
||||||
defm AsmNL : CondExtendedMnemonic<11, "nl", "nm">;
|
|
||||||
defm AsmLE : CondExtendedMnemonicA<12, "le">;
|
|
||||||
defm AsmNH : CondExtendedMnemonic<13, "nh", "np">;
|
|
||||||
defm AsmNO : CondExtendedMnemonicA<14, "no">;
|
|
||||||
|
|
||||||
// Define AsmParser mnemonics for each integer condition-code mask.
|
|
||||||
// This is like the list above, except that condition 3 is not possible
|
|
||||||
// and that the low bit of the mask is therefore always 0. This means
|
|
||||||
// that each condition has two names. Conditions "o" and "no" are not used.
|
|
||||||
//
|
|
||||||
// We don't make one of the two names an alias of the other because
|
|
||||||
// we need the custom parsing routines to select the correct register class.
|
|
||||||
multiclass IntCondExtendedMnemonicA<bits<4> ccmask, string name> {
|
|
||||||
let isBranch = 1, isTerminator = 1, M3 = ccmask in {
|
|
||||||
def CRJ : InstRIEb<0xEC76, (outs), (ins GR32:$R1, GR32:$R2,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"crj"##name##"\t$R1, $R2, $RI4", []>;
|
|
||||||
def CGRJ : InstRIEb<0xEC64, (outs), (ins GR64:$R1, GR64:$R2,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"cgrj"##name##"\t$R1, $R2, $RI4", []>;
|
|
||||||
def CIJ : InstRIEc<0xEC7E, (outs), (ins GR32:$R1, imm32sx8:$I2,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"cij"##name##"\t$R1, $I2, $RI4", []>;
|
|
||||||
def CGIJ : InstRIEc<0xEC7C, (outs), (ins GR64:$R1, imm64sx8:$I2,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"cgij"##name##"\t$R1, $I2, $RI4", []>;
|
|
||||||
def CLRJ : InstRIEb<0xEC77, (outs), (ins GR32:$R1, GR32:$R2,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"clrj"##name##"\t$R1, $R2, $RI4", []>;
|
|
||||||
def CLGRJ : InstRIEb<0xEC65, (outs), (ins GR64:$R1, GR64:$R2,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"clgrj"##name##"\t$R1, $R2, $RI4", []>;
|
|
||||||
def CLIJ : InstRIEc<0xEC7F, (outs), (ins GR32:$R1, imm32zx8:$I2,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"clij"##name##"\t$R1, $I2, $RI4", []>;
|
|
||||||
def CLGIJ : InstRIEc<0xEC7D, (outs), (ins GR64:$R1, imm64zx8:$I2,
|
|
||||||
brtarget16:$RI4),
|
|
||||||
"clgij"##name##"\t$R1, $I2, $RI4", []>;
|
|
||||||
let isIndirectBranch = 1 in {
|
|
||||||
def CRB : InstRRS<0xECF6, (outs), (ins GR32:$R1, GR32:$R2,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"crb"##name##"\t$R1, $R2, $BD4", []>;
|
|
||||||
def CGRB : InstRRS<0xECE4, (outs), (ins GR64:$R1, GR64:$R2,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"cgrb"##name##"\t$R1, $R2, $BD4", []>;
|
|
||||||
def CIB : InstRIS<0xECFE, (outs), (ins GR32:$R1, imm32sx8:$I2,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"cib"##name##"\t$R1, $I2, $BD4", []>;
|
|
||||||
def CGIB : InstRIS<0xECFC, (outs), (ins GR64:$R1, imm64sx8:$I2,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"cgib"##name##"\t$R1, $I2, $BD4", []>;
|
|
||||||
def CLRB : InstRRS<0xECF7, (outs), (ins GR32:$R1, GR32:$R2,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"clrb"##name##"\t$R1, $R2, $BD4", []>;
|
|
||||||
def CLGRB : InstRRS<0xECE5, (outs), (ins GR64:$R1, GR64:$R2,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"clgrb"##name##"\t$R1, $R2, $BD4", []>;
|
|
||||||
def CLIB : InstRIS<0xECFF, (outs), (ins GR32:$R1, imm32zx8:$I2,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"clib"##name##"\t$R1, $I2, $BD4", []>;
|
|
||||||
def CLGIB : InstRIS<0xECFD, (outs), (ins GR64:$R1, imm64zx8:$I2,
|
|
||||||
bdaddr12only:$BD4),
|
|
||||||
"clgib"##name##"\t$R1, $I2, $BD4", []>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let hasCtrlDep = 1, isTerminator = 1, M3 = ccmask in {
|
|
||||||
def CRT : InstRRFc<0xB972, (outs), (ins GR32:$R1, GR32:$R2),
|
|
||||||
"crt"##name##"\t$R1, $R2", []>;
|
|
||||||
def CGRT : InstRRFc<0xB960, (outs), (ins GR64:$R1, GR64:$R2),
|
|
||||||
"cgrt"##name##"\t$R1, $R2", []>;
|
|
||||||
def CLRT : InstRRFc<0xB973, (outs), (ins GR32:$R1, GR32:$R2),
|
|
||||||
"clrt"##name##"\t$R1, $R2", []>;
|
|
||||||
def CLGRT : InstRRFc<0xB961, (outs), (ins GR64:$R1, GR64:$R2),
|
|
||||||
"clgrt"##name##"\t$R1, $R2", []>;
|
|
||||||
def CIT : InstRIEa<0xEC72, (outs), (ins GR32:$R1, imm32sx16:$I2),
|
|
||||||
"cit"##name##"\t$R1, $I2", []>;
|
|
||||||
def CGIT : InstRIEa<0xEC70, (outs), (ins GR64:$R1, imm32sx16:$I2),
|
|
||||||
"cgit"##name##"\t$R1, $I2", []>;
|
|
||||||
def CLFIT : InstRIEa<0xEC73, (outs), (ins GR32:$R1, imm32zx16:$I2),
|
|
||||||
"clfit"##name##"\t$R1, $I2", []>;
|
|
||||||
def CLGIT : InstRIEa<0xEC71, (outs), (ins GR64:$R1, imm32zx16:$I2),
|
|
||||||
"clgit"##name##"\t$R1, $I2", []>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
multiclass IntCondExtendedMnemonic<bits<4> ccmask, string name1, string name2>
|
|
||||||
: IntCondExtendedMnemonicA<ccmask, name1> {
|
|
||||||
let isAsmParserOnly = 1 in
|
|
||||||
defm Alt : IntCondExtendedMnemonicA<ccmask, name2>;
|
|
||||||
}
|
|
||||||
defm AsmJH : IntCondExtendedMnemonic<2, "h", "nle">;
|
|
||||||
defm AsmJL : IntCondExtendedMnemonic<4, "l", "nhe">;
|
|
||||||
defm AsmJLH : IntCondExtendedMnemonic<6, "lh", "ne">;
|
|
||||||
defm AsmJE : IntCondExtendedMnemonic<8, "e", "nlh">;
|
|
||||||
defm AsmJHE : IntCondExtendedMnemonic<10, "he", "nl">;
|
|
||||||
defm AsmJLE : IntCondExtendedMnemonic<12, "le", "nh">;
|
|
||||||
|
|
||||||
// Decrement a register and branch if it is nonzero. These don't clobber CC,
|
|
||||||
// but we might need to split long branches into sequences that do.
|
|
||||||
let Defs = [CC] in {
|
|
||||||
def BRCT : BranchUnaryRI<"brct", 0xA76, GR32>;
|
|
||||||
def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>;
|
|
||||||
}
|
|
||||||
|
|
||||||
def BRXH : BranchBinaryRSI<"brxh", 0x84, GR64>;
|
|
||||||
def BRXLE : BranchBinaryRSI<"brxle", 0x85, GR64>;
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Select instructions
|
// Select instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -372,67 +321,6 @@ defm : CondStores64<CondStore32, CondStore32Inv, nonvolatile_truncstorei32,
|
||||||
defm CondStore64 : CondStores<GR64, nonvolatile_store,
|
defm CondStore64 : CondStores<GR64, nonvolatile_store,
|
||||||
nonvolatile_load, bdxaddr20only>;
|
nonvolatile_load, bdxaddr20only>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Call instructions
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
let isCall = 1, Defs = [R14D, CC] in {
|
|
||||||
def CallBRASL : Alias<6, (outs), (ins pcrel32:$I2, variable_ops),
|
|
||||||
[(z_call pcrel32:$I2)]>;
|
|
||||||
def CallBASR : Alias<2, (outs), (ins ADDR64:$R2, variable_ops),
|
|
||||||
[(z_call ADDR64:$R2)]>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sibling calls. Indirect sibling calls must be via R1, since R2 upwards
|
|
||||||
// are argument registers and since branching to R0 is a no-op.
|
|
||||||
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
|
||||||
def CallJG : Alias<6, (outs), (ins pcrel32:$I2),
|
|
||||||
[(z_sibcall pcrel32:$I2)]>;
|
|
||||||
let Uses = [R1D] in
|
|
||||||
def CallBR : Alias<2, (outs), (ins), [(z_sibcall R1D)]>;
|
|
||||||
}
|
|
||||||
|
|
||||||
let CCMaskFirst = 1, isCall = 1, isTerminator = 1, isReturn = 1 in {
|
|
||||||
def CallBRCL : Alias<6, (outs), (ins cond4:$valid, cond4:$R1,
|
|
||||||
pcrel32:$I2), []>;
|
|
||||||
|
|
||||||
let Uses = [R1D] in
|
|
||||||
def CallBCR : Alias<2, (outs), (ins cond4:$valid, cond4:$R1), []>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fused compare and conditional sibling calls.
|
|
||||||
let isCall = 1, isTerminator = 1, isReturn = 1, Uses = [R1D] in {
|
|
||||||
def CRBCall : Alias<6, (outs), (ins GR32:$R1, GR32:$R2, cond4:$M3), []>;
|
|
||||||
def CGRBCall : Alias<6, (outs), (ins GR64:$R1, GR64:$R2, cond4:$M3), []>;
|
|
||||||
def CIBCall : Alias<6, (outs), (ins GR32:$R1, imm32sx8:$I2, cond4:$M3), []>;
|
|
||||||
def CGIBCall : Alias<6, (outs), (ins GR64:$R1, imm64sx8:$I2, cond4:$M3), []>;
|
|
||||||
def CLRBCall : Alias<6, (outs), (ins GR32:$R1, GR32:$R2, cond4:$M3), []>;
|
|
||||||
def CLGRBCall : Alias<6, (outs), (ins GR64:$R1, GR64:$R2, cond4:$M3), []>;
|
|
||||||
def CLIBCall : Alias<6, (outs), (ins GR32:$R1, imm32zx8:$I2, cond4:$M3), []>;
|
|
||||||
def CLGIBCall : Alias<6, (outs), (ins GR64:$R1, imm64zx8:$I2, cond4:$M3), []>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TLS calls. These will be lowered into a call to __tls_get_offset,
|
|
||||||
// with an extra relocation specifying the TLS symbol.
|
|
||||||
let isCall = 1, Defs = [R14D, CC] in {
|
|
||||||
def TLS_GDCALL : Alias<6, (outs), (ins tlssym:$I2, variable_ops),
|
|
||||||
[(z_tls_gdcall tglobaltlsaddr:$I2)]>;
|
|
||||||
def TLS_LDCALL : Alias<6, (outs), (ins tlssym:$I2, variable_ops),
|
|
||||||
[(z_tls_ldcall tglobaltlsaddr:$I2)]>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define the general form of the call instructions for the asm parser.
|
|
||||||
// These instructions don't hard-code %r14 as the return address register.
|
|
||||||
// Allow an optional TLS marker symbol to generate TLS call relocations.
|
|
||||||
let isCall = 1, Defs = [CC] in {
|
|
||||||
def BRAS : InstRI<0xA75, (outs), (ins GR64:$R1, brtarget16tls:$I2),
|
|
||||||
"bras\t$R1, $I2", []>;
|
|
||||||
def BRASL : InstRIL<0xC05, (outs), (ins GR64:$R1, brtarget32tls:$I2),
|
|
||||||
"brasl\t$R1, $I2", []>;
|
|
||||||
def BASR : InstRR<0x0D, (outs), (ins GR64:$R1, ADDR64:$R2),
|
|
||||||
"basr\t$R1, $R2", []>;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Move instructions
|
// Move instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -450,24 +338,6 @@ let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in {
|
||||||
def LTGR : UnaryRRE<"ltg", 0xB902, null_frag, GR64, GR64>;
|
def LTGR : UnaryRRE<"ltg", 0xB902, null_frag, GR64, GR64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move on condition.
|
|
||||||
let isCodeGenOnly = 1, Uses = [CC] in {
|
|
||||||
def LOCR : CondUnaryRRF<"loc", 0xB9F2, GR32, GR32>;
|
|
||||||
def LOCGR : CondUnaryRRF<"locg", 0xB9E2, GR64, GR64>;
|
|
||||||
}
|
|
||||||
let Uses = [CC] in {
|
|
||||||
def AsmLOCR : AsmCondUnaryRRF<"loc", 0xB9F2, GR32, GR32>;
|
|
||||||
def AsmLOCGR : AsmCondUnaryRRF<"locg", 0xB9E2, GR64, GR64>;
|
|
||||||
}
|
|
||||||
let isCodeGenOnly = 1, Uses = [CC] in {
|
|
||||||
def LOCHI : CondUnaryRIE<"lochi", 0xEC42, GR32, imm32sx16>;
|
|
||||||
def LOCGHI : CondUnaryRIE<"locghi", 0xEC46, GR64, imm64sx16>;
|
|
||||||
}
|
|
||||||
let Uses = [CC] in {
|
|
||||||
def AsmLOCHI : AsmCondUnaryRIE<"lochi", 0xEC42, GR32, imm32sx16>;
|
|
||||||
def AsmLOCGHI : AsmCondUnaryRIE<"locghi", 0xEC46, GR64, imm64sx16>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Immediate moves.
|
// Immediate moves.
|
||||||
let hasSideEffects = 0, isAsCheapAsAMove = 1, isMoveImm = 1,
|
let hasSideEffects = 0, isAsCheapAsAMove = 1, isMoveImm = 1,
|
||||||
isReMaterializable = 1 in {
|
isReMaterializable = 1 in {
|
||||||
|
@ -517,16 +387,6 @@ let canFoldAsLoad = 1 in {
|
||||||
def LGRL : UnaryRILPC<"lgrl", 0xC48, aligned_load, GR64>;
|
def LGRL : UnaryRILPC<"lgrl", 0xC48, aligned_load, GR64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load on condition.
|
|
||||||
let isCodeGenOnly = 1, Uses = [CC] in {
|
|
||||||
def LOC : CondUnaryRSY<"loc", 0xEBF2, nonvolatile_load, GR32, 4>;
|
|
||||||
def LOCG : CondUnaryRSY<"locg", 0xEBE2, nonvolatile_load, GR64, 8>;
|
|
||||||
}
|
|
||||||
let Uses = [CC] in {
|
|
||||||
def AsmLOC : AsmCondUnaryRSY<"loc", 0xEBF2, GR32, 4>;
|
|
||||||
def AsmLOCG : AsmCondUnaryRSY<"locg", 0xEBE2, GR64, 8>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register stores.
|
// Register stores.
|
||||||
let SimpleBDXStore = 1 in {
|
let SimpleBDXStore = 1 in {
|
||||||
// Expands to ST, STY or STFH, depending on the choice of register.
|
// Expands to ST, STY or STFH, depending on the choice of register.
|
||||||
|
@ -547,16 +407,6 @@ let SimpleBDXStore = 1 in {
|
||||||
def STRL : StoreRILPC<"strl", 0xC4F, aligned_store, GR32>;
|
def STRL : StoreRILPC<"strl", 0xC4F, aligned_store, GR32>;
|
||||||
def STGRL : StoreRILPC<"stgrl", 0xC4B, aligned_store, GR64>;
|
def STGRL : StoreRILPC<"stgrl", 0xC4B, aligned_store, GR64>;
|
||||||
|
|
||||||
// Store on condition.
|
|
||||||
let isCodeGenOnly = 1, Uses = [CC] in {
|
|
||||||
def STOC : CondStoreRSY<"stoc", 0xEBF3, GR32, 4>;
|
|
||||||
def STOCG : CondStoreRSY<"stocg", 0xEBE3, GR64, 8>;
|
|
||||||
}
|
|
||||||
let Uses = [CC] in {
|
|
||||||
def AsmSTOC : AsmCondStoreRSY<"stoc", 0xEBF3, GR32, 4>;
|
|
||||||
def AsmSTOCG : AsmCondStoreRSY<"stocg", 0xEBE3, GR64, 8>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8-bit immediate stores to 8-bit fields.
|
// 8-bit immediate stores to 8-bit fields.
|
||||||
defm MVI : StoreSIPair<"mvi", 0x92, 0xEB52, truncstorei8, imm32zx8trunc>;
|
defm MVI : StoreSIPair<"mvi", 0x92, 0xEB52, truncstorei8, imm32zx8trunc>;
|
||||||
|
|
||||||
|
@ -573,6 +423,49 @@ let mayLoad = 1, mayStore = 1 in
|
||||||
let mayLoad = 1, mayStore = 1, Defs = [CC] in
|
let mayLoad = 1, mayStore = 1, Defs = [CC] in
|
||||||
defm MVST : StringRRE<"mvst", 0xB255, z_stpcpy>;
|
defm MVST : StringRRE<"mvst", 0xB255, z_stpcpy>;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Conditional move instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
let Predicates = [FeatureLoadStoreOnCond2], Uses = [CC] in {
|
||||||
|
// Load immediate on condition. Created by if-conversion.
|
||||||
|
defm LOCHI : CondUnaryRIEPair<"lochi", 0xEC42, GR32, imm32sx16>;
|
||||||
|
defm LOCGHI : CondUnaryRIEPair<"locghi", 0xEC46, GR64, imm64sx16>;
|
||||||
|
|
||||||
|
// Define AsmParser extended mnemonics for each general condition-code mask.
|
||||||
|
foreach V = [ "E", "NE", "H", "NH", "L", "NL", "HE", "NHE", "LE", "NLE",
|
||||||
|
"Z", "NZ", "P", "NP", "M", "NM", "LH", "NLH", "O", "NO" ] in {
|
||||||
|
def LOCHIAsm#V : FixedCondUnaryRIE<CV<V>, "lochi", 0xEC42, GR32,
|
||||||
|
imm32sx16>;
|
||||||
|
def LOCGHIAsm#V : FixedCondUnaryRIE<CV<V>, "locghi", 0xEC46, GR64,
|
||||||
|
imm64sx16>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let Predicates = [FeatureLoadStoreOnCond], Uses = [CC] in {
|
||||||
|
// Move register on condition. Created by if-conversion.
|
||||||
|
defm LOCR : CondUnaryRRFPair<"locr", 0xB9F2, GR32, GR32>;
|
||||||
|
defm LOCGR : CondUnaryRRFPair<"locgr", 0xB9E2, GR64, GR64>;
|
||||||
|
|
||||||
|
// Load on condition. Matched via DAG pattern.
|
||||||
|
defm LOC : CondUnaryRSYPair<"loc", 0xEBF2, nonvolatile_load, GR32, 4>;
|
||||||
|
defm LOCG : CondUnaryRSYPair<"locg", 0xEBE2, nonvolatile_load, GR64, 8>;
|
||||||
|
|
||||||
|
// Store on condition. Expanded from CondStore* pseudos.
|
||||||
|
defm STOC : CondStoreRSYPair<"stoc", 0xEBF3, GR32, 4>;
|
||||||
|
defm STOCG : CondStoreRSYPair<"stocg", 0xEBE3, GR64, 8>;
|
||||||
|
|
||||||
|
// Define AsmParser extended mnemonics for each general condition-code mask.
|
||||||
|
foreach V = [ "E", "NE", "H", "NH", "L", "NL", "HE", "NHE", "LE", "NLE",
|
||||||
|
"Z", "NZ", "P", "NP", "M", "NM", "LH", "NLH", "O", "NO" ] in {
|
||||||
|
def LOCRAsm#V : FixedCondUnaryRRF<CV<V>, "locr", 0xB9F2, GR32, GR32>;
|
||||||
|
def LOCGRAsm#V : FixedCondUnaryRRF<CV<V>, "locgr", 0xB9E2, GR64, GR64>;
|
||||||
|
def LOCAsm#V : FixedCondUnaryRSY<CV<V>, "loc", 0xEBF2, GR32, 4>;
|
||||||
|
def LOCGAsm#V : FixedCondUnaryRSY<CV<V>, "locg", 0xEBE2, GR64, 8>;
|
||||||
|
def STOCAsm#V : FixedCondStoreRSY<CV<V>, "stoc", 0xEBF3, GR32, 4>;
|
||||||
|
def STOCGAsm#V : FixedCondStoreRSY<CV<V>, "stocg", 0xEBE3, GR64, 8>;
|
||||||
|
}
|
||||||
|
}
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Sign extensions
|
// Sign extensions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -107,51 +107,47 @@ def : WriteRes<VBU, [Z13_VBUnit]>; // Virtual Branching Unit
|
||||||
def : InstRW<[FXa], (instregex "ADJDYNALLOC$")>; // Pseudo -> LA / LAY
|
def : InstRW<[FXa], (instregex "ADJDYNALLOC$")>; // Pseudo -> LA / LAY
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Control flow instructions
|
// Branch instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Return
|
// Branch
|
||||||
def : InstRW<[FXb, EndGroup], (instregex "Return$")>;
|
def : InstRW<[VBU], (instregex "(Call)?BRC(L)?(Asm.*)?$")>;
|
||||||
def : InstRW<[FXb], (instregex "CondReturn$")>;
|
def : InstRW<[VBU], (instregex "(Call)?J(G)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXb], (instregex "(Call)?BC(R)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXb], (instregex "(Call)?B(R)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXa, EndGroup], (instregex "BRCT(G)?$")>;
|
||||||
|
def : InstRW<[FXa, FXa, FXb, FXb, Lat4, GroupAlone], (instregex "BRX(H|LE)$")>;
|
||||||
|
|
||||||
// Compare and branch
|
// Compare and branch
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?C(I|R)J$")>;
|
def : InstRW<[FXb], (instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>;
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?CG(I|R)J$")>;
|
def : InstRW<[FXb, FXb, Lat2, GroupAlone],
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?CL(I|R)J$")>;
|
(instregex "C(L)?(G)?(I|R)B(Call|Return|Asm.*)?$")>;
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?CLG(I|R)J$")>;
|
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?CG(R|I)J$")>;
|
|
||||||
def : InstRW<[FXb], (instregex "CLR$")>;
|
|
||||||
def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CLIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CLGIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CGIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CGRB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CLGRB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "CLR(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CLRB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CRB(Call|Return)?$")>;
|
|
||||||
|
|
||||||
// Branch
|
//===----------------------------------------------------------------------===//
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?BR$")>;
|
// Trap instructions
|
||||||
def : InstRW<[FXb], (instregex "(Asm)?BC(R)?$")>;
|
//===----------------------------------------------------------------------===//
|
||||||
def : InstRW<[VBU], (instregex "(Asm)?BRC(L)?$")>;
|
|
||||||
def : InstRW<[FXa, EndGroup], (instregex "BRCT(G)?$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "(Asm.*)?JG$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "J$")>;
|
|
||||||
// (Need to avoid conflict with "(Asm.*)?CG(I|R)J$")
|
|
||||||
def : InstRW<[VBU], (instregex "Asm(EAlt|E|HAlt|HE|H|LAlt|LE|LH|L|NEAlt|NE)J$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "Asm(NHAlt|NHE|NH|NLAlt|NLE|NLH|NL|NO|O)J$")>;
|
|
||||||
def : InstRW<[FXa, FXa, FXb, FXb, Lat4, GroupAlone], (instregex "BRX(H|LE)$")>;
|
|
||||||
|
|
||||||
// Trap
|
// Trap
|
||||||
def : InstRW<[VBU], (instregex "(Cond)?Trap$")>;
|
def : InstRW<[VBU], (instregex "(Cond)?Trap$")>;
|
||||||
|
|
||||||
// Compare and trap
|
// Compare and trap
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?C(G)?IT$")>;
|
def : InstRW<[FXb], (instregex "C(G)?(I|R)T(Asm.*)?$")>;
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?C(G)?RT$")>;
|
def : InstRW<[FXb], (instregex "CL(G)?RT(Asm.*)?$")>;
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?CLG(I|R)T$")>;
|
def : InstRW<[FXb], (instregex "CL(F|G)IT(Asm.*)?$")>;
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?CLFIT$")>;
|
|
||||||
def : InstRW<[FXb], (instregex "(Asm.*)?CLRT$")>;
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Call and return instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Call
|
||||||
|
def : InstRW<[VBU, FXa, FXa, Lat3, GroupAlone], (instregex "(Call)?BRAS$")>;
|
||||||
|
def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "(Call)?BRASL$")>;
|
||||||
|
def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "(Call)?BAS(R)?$")>;
|
||||||
|
def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "TLS_(G|L)DCALL$")>;
|
||||||
|
|
||||||
|
// Return
|
||||||
|
def : InstRW<[FXb, EndGroup], (instregex "Return$")>;
|
||||||
|
def : InstRW<[FXb], (instregex "CondReturn$")>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Select instructions
|
// Select instructions
|
||||||
|
@ -168,18 +164,6 @@ def : InstRW<[FXa], (instregex "CondStore64(Inv)?$")>;
|
||||||
def : InstRW<[FXa], (instregex "CondStore8(Inv)?$")>;
|
def : InstRW<[FXa], (instregex "CondStore8(Inv)?$")>;
|
||||||
def : InstRW<[FXa], (instregex "CondStore8Mux(Inv)?$")>;
|
def : InstRW<[FXa], (instregex "CondStore8Mux(Inv)?$")>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Call instructions
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
def : InstRW<[VBU, FXa, FXa, Lat3, GroupAlone], (instregex "BRAS$")>;
|
|
||||||
def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "(Call)?BASR$")>;
|
|
||||||
def : InstRW<[FXb], (instregex "CallB(C)?R$")>;
|
|
||||||
def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "(Call)?BRASL$")>;
|
|
||||||
def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "TLS_(G|L)DCALL$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "CallBRCL$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "CallJG$")>;
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Move instructions
|
// Move instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -214,22 +198,23 @@ def : InstRW<[FXa], (instregex "LR(Mux)?$")>;
|
||||||
def : InstRW<[FXa, LSU, Lat5], (instregex "LT(G)?$")>;
|
def : InstRW<[FXa, LSU, Lat5], (instregex "LT(G)?$")>;
|
||||||
def : InstRW<[FXa], (instregex "LT(G)?R$")>;
|
def : InstRW<[FXa], (instregex "LT(G)?R$")>;
|
||||||
|
|
||||||
// Load on condition
|
|
||||||
def : InstRW<[FXa, LSU, Lat6], (instregex "(Asm.*)?LOC(G)?$")>;
|
|
||||||
def : InstRW<[FXa, Lat2], (instregex "(Asm.*)?LOC(G)?R$")>;
|
|
||||||
def : InstRW<[FXa, Lat2], (instregex "(Asm.*)?LOC(G)?HI$")>;
|
|
||||||
|
|
||||||
// Stores
|
// Stores
|
||||||
def : InstRW<[FXb, LSU, Lat5], (instregex "STG(RL)?$")>;
|
def : InstRW<[FXb, LSU, Lat5], (instregex "STG(RL)?$")>;
|
||||||
def : InstRW<[FXb, LSU, Lat5], (instregex "ST128$")>;
|
def : InstRW<[FXb, LSU, Lat5], (instregex "ST128$")>;
|
||||||
def : InstRW<[FXb, LSU, Lat5], (instregex "ST(Y|FH|RL|Mux)?$")>;
|
def : InstRW<[FXb, LSU, Lat5], (instregex "ST(Y|FH|RL|Mux)?$")>;
|
||||||
|
|
||||||
// Store on condition
|
|
||||||
def : InstRW<[FXb, LSU, Lat5], (instregex "(Asm.*)?STOC(G)?$")>;
|
|
||||||
|
|
||||||
// String moves.
|
// String moves.
|
||||||
def : InstRW<[LSU, Lat30, GroupAlone], (instregex "MVST$")>;
|
def : InstRW<[LSU, Lat30, GroupAlone], (instregex "MVST$")>;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Conditional move instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def : InstRW<[FXa, Lat2], (instregex "LOC(G)?R(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXa, Lat2], (instregex "LOC(G)?HI(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXa, LSU, Lat6], (instregex "LOC(G)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXb, LSU, Lat5], (instregex "STOC(G)?(Asm.*)?$")>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Sign extensions
|
// Sign extensions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -82,50 +82,48 @@ def : WriteRes<FPU2, [Z196_FPUnit, Z196_FPUnit]> { let Latency = 9; }
|
||||||
def : InstRW<[FXU], (instregex "ADJDYNALLOC$")>; // Pseudo -> LA / LAY
|
def : InstRW<[FXU], (instregex "ADJDYNALLOC$")>; // Pseudo -> LA / LAY
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Control flow instructions
|
// Branch instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Return
|
// Branch
|
||||||
def : InstRW<[LSU_lat1, EndGroup], (instregex "Return$")>;
|
def : InstRW<[LSU, EndGroup], (instregex "(Call)?BRC(L)?(Asm.*)?$")>;
|
||||||
def : InstRW<[LSU_lat1, EndGroup], (instregex "CondReturn$")>;
|
def : InstRW<[LSU, EndGroup], (instregex "(Call)?J(G)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[LSU, EndGroup], (instregex "(Call)?BC(R)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[LSU, EndGroup], (instregex "(Call)?B(R)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BRCT(G)?$")>;
|
||||||
|
def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>;
|
||||||
|
|
||||||
// Compare and branch
|
// Compare and branch
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?C(I|R)J$")>;
|
def : InstRW<[FXU, LSU, Lat5, GroupAlone],
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CG(I|R)J$")>;
|
(instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>;
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CL(I|R)J$")>;
|
def : InstRW<[FXU, LSU, Lat5, GroupAlone],
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLG(I|R)J$")>;
|
(instregex "C(L)?(G)?(I|R)B(Call|Return|Asm.*)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "CLR$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLGIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CGIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CGRB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLGRB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "CLR(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLRB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CRB(Call|Return)?$")>;
|
|
||||||
|
|
||||||
// Branch
|
//===----------------------------------------------------------------------===//
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "(Asm.*)?BR$")>;
|
// Trap instructions
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "(Asm)?BC(R)?$")>;
|
//===----------------------------------------------------------------------===//
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "(Asm)?BRC(L)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BRCT(G)?$")>;
|
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "(Asm.*)?JG$")>;
|
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "J$")>;
|
|
||||||
// (Need to avoid conflict with "(Asm.*)?CG(I|R)J$")
|
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "Asm(EAlt|E|HAlt|HE|H|LAlt|LE|LH|L|NEAlt|NE)J$")>;
|
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "Asm(NHAlt|NHE|NH|NLAlt|NLE|NLH|NL|NO|O)J$")>;
|
|
||||||
def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>;
|
|
||||||
|
|
||||||
// Trap
|
// Trap
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "(Cond)?Trap$")>;
|
def : InstRW<[LSU, EndGroup], (instregex "(Cond)?Trap$")>;
|
||||||
|
|
||||||
// Compare and trap
|
// Compare and trap
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?C(G)?IT$")>;
|
def : InstRW<[FXU], (instregex "C(G)?(I|R)T(Asm.*)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?C(G)?RT$")>;
|
def : InstRW<[FXU], (instregex "CL(G)?RT(Asm.*)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CLG(I|R)T$")>;
|
def : InstRW<[FXU], (instregex "CL(F|G)IT(Asm.*)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CLFIT$")>;
|
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CLRT$")>;
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Call and return instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Call
|
||||||
|
def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "(Call)?BRAS$")>;
|
||||||
|
def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "(Call)?BRASL$")>;
|
||||||
|
def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BAS(R)?$")>;
|
||||||
|
def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "TLS_(G|L)DCALL$")>;
|
||||||
|
|
||||||
|
// Return
|
||||||
|
def : InstRW<[LSU_lat1, EndGroup], (instregex "Return$")>;
|
||||||
|
def : InstRW<[LSU_lat1, EndGroup], (instregex "CondReturn$")>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Select instructions
|
// Select instructions
|
||||||
|
@ -142,18 +140,6 @@ def : InstRW<[FXU], (instregex "CondStore64(Inv)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "CondStore8(Inv)?$")>;
|
def : InstRW<[FXU], (instregex "CondStore8(Inv)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "CondStore8Mux(Inv)?$")>;
|
def : InstRW<[FXU], (instregex "CondStore8Mux(Inv)?$")>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Call instructions
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "BRAS$")>;
|
|
||||||
def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BASR$")>;
|
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "CallB(C)?R$")>;
|
|
||||||
def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "(Call)?BRASL$")>;
|
|
||||||
def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "TLS_(G|L)DCALL$")>;
|
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "CallBRCL$")>;
|
|
||||||
def : InstRW<[LSU, EndGroup], (instregex "CallJG$")>;
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Move instructions
|
// Move instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -188,21 +174,23 @@ def : InstRW<[FXU], (instregex "LR(Mux)?$")>;
|
||||||
def : InstRW<[FXU, LSU, Lat5], (instregex "LT(G)?$")>;
|
def : InstRW<[FXU, LSU, Lat5], (instregex "LT(G)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "LT(G)?R$")>;
|
def : InstRW<[FXU], (instregex "LT(G)?R$")>;
|
||||||
|
|
||||||
// Load on condition
|
|
||||||
def : InstRW<[FXU, LSU, Lat6, EndGroup], (instregex "(Asm.*)?LOC(G)?$")>;
|
|
||||||
def : InstRW<[FXU, Lat2, EndGroup], (instregex "(Asm.*)?LOC(G)?R$")>;
|
|
||||||
|
|
||||||
// Stores
|
// Stores
|
||||||
def : InstRW<[FXU, LSU, Lat5], (instregex "STG(RL)?$")>;
|
def : InstRW<[FXU, LSU, Lat5], (instregex "STG(RL)?$")>;
|
||||||
def : InstRW<[FXU, LSU, Lat5], (instregex "ST128$")>;
|
def : InstRW<[FXU, LSU, Lat5], (instregex "ST128$")>;
|
||||||
def : InstRW<[FXU, LSU, Lat5], (instregex "ST(Y|FH|RL|Mux)?$")>;
|
def : InstRW<[FXU, LSU, Lat5], (instregex "ST(Y|FH|RL|Mux)?$")>;
|
||||||
|
|
||||||
// Store on condition
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, EndGroup], (instregex "(Asm.*)?STOC(G)?$")>;
|
|
||||||
|
|
||||||
// String moves.
|
// String moves.
|
||||||
def : InstRW<[LSU, Lat30, GroupAlone], (instregex "MVST$")>;
|
def : InstRW<[LSU, Lat30, GroupAlone], (instregex "MVST$")>;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Conditional move instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def : InstRW<[FXU, Lat2, EndGroup], (instregex "LOC(G)?R(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXU, Lat2, EndGroup], (instregex "LOC(G)?HI(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXU, LSU, Lat6, EndGroup], (instregex "LOC(G)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXU, LSU, Lat5, EndGroup], (instregex "STOC(G)?(Asm.*)?$")>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Sign extensions
|
// Sign extensions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -84,51 +84,47 @@ def : WriteRes<VBU, [ZEC12_VBUnit]>; // Virtual Branching Unit
|
||||||
def : InstRW<[FXU], (instregex "ADJDYNALLOC$")>; // Pseudo -> LA / LAY
|
def : InstRW<[FXU], (instregex "ADJDYNALLOC$")>; // Pseudo -> LA / LAY
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Control flow instructions
|
// Branch instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Return
|
// Branch
|
||||||
def : InstRW<[LSU_lat1, EndGroup], (instregex "Return$")>;
|
def : InstRW<[VBU], (instregex "(Call)?BRC(L)?(Asm.*)?$")>;
|
||||||
def : InstRW<[LSU_lat1], (instregex "CondReturn$")>;
|
def : InstRW<[VBU], (instregex "(Call)?J(G)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[LSU, Lat4], (instregex "(Call)?BC(R)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[LSU, Lat4], (instregex "(Call)?B(R)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXU, EndGroup], (instregex "BRCT(G)?$")>;
|
||||||
|
def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>;
|
||||||
|
|
||||||
// Compare and branch
|
// Compare and branch
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?C(I|R)J$")>;
|
def : InstRW<[FXU], (instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CG(I|R)J$")>;
|
def : InstRW<[FXU, LSU, Lat5, GroupAlone],
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CL(I|R)J$")>;
|
(instregex "C(L)?(G)?(I|R)B(Call|Return|Asm.*)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CLG(I|R)J$")>;
|
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CG(R|I)J$")>;
|
|
||||||
def : InstRW<[FXU], (instregex "CLR$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLGIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CGIB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CGRB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLGRB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "CLR(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLRB(Call|Return)?$")>;
|
|
||||||
def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CRB(Call|Return)?$")>;
|
|
||||||
|
|
||||||
// Branch
|
//===----------------------------------------------------------------------===//
|
||||||
def : InstRW<[LSU, Lat4], (instregex "(Asm.*)?BR$")>;
|
// Trap instructions
|
||||||
def : InstRW<[LSU, Lat4], (instregex "(Asm)?BC(R)?$")>;
|
//===----------------------------------------------------------------------===//
|
||||||
def : InstRW<[VBU], (instregex "(Asm)?BRC(L)?$")>;
|
|
||||||
def : InstRW<[FXU, EndGroup], (instregex "BRCT(G)?$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "(Asm.*)?JG$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "J$")>;
|
|
||||||
// (Need to avoid conflict with "(Asm.*)?CG(I|R)J$")
|
|
||||||
def : InstRW<[VBU], (instregex "Asm(EAlt|E|HAlt|HE|H|LAlt|LE|LH|L|NEAlt|NE)J$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "Asm(NHAlt|NHE|NH|NLAlt|NLE|NLH|NL|NO|O)J$")>;
|
|
||||||
def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>;
|
|
||||||
|
|
||||||
// Trap
|
// Trap
|
||||||
def : InstRW<[VBU], (instregex "(Cond)?Trap$")>;
|
def : InstRW<[VBU], (instregex "(Cond)?Trap$")>;
|
||||||
|
|
||||||
// Compare and trap
|
// Compare and trap
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?C(G)?IT$")>;
|
def : InstRW<[FXU], (instregex "C(G)?(I|R)T(Asm.*)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?C(G)?RT$")>;
|
def : InstRW<[FXU], (instregex "CL(G)?RT(Asm.*)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CLG(I|R)T$")>;
|
def : InstRW<[FXU], (instregex "CL(F|G)IT(Asm.*)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CLFIT$")>;
|
|
||||||
def : InstRW<[FXU], (instregex "(Asm.*)?CLRT$")>;
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Call and return instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Call
|
||||||
|
def : InstRW<[VBU, FXU, FXU, Lat3, GroupAlone], (instregex "(Call)?BRAS$")>;
|
||||||
|
def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BRASL$")>;
|
||||||
|
def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BAS(R)?$")>;
|
||||||
|
def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "TLS_(G|L)DCALL$")>;
|
||||||
|
|
||||||
|
// Return
|
||||||
|
def : InstRW<[LSU_lat1, EndGroup], (instregex "Return$")>;
|
||||||
|
def : InstRW<[LSU_lat1], (instregex "CondReturn$")>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Select instructions
|
// Select instructions
|
||||||
|
@ -145,18 +141,6 @@ def : InstRW<[FXU], (instregex "CondStore64(Inv)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "CondStore8(Inv)?$")>;
|
def : InstRW<[FXU], (instregex "CondStore8(Inv)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "CondStore8Mux(Inv)?$")>;
|
def : InstRW<[FXU], (instregex "CondStore8Mux(Inv)?$")>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Call instructions
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
def : InstRW<[VBU, FXU, FXU, Lat3, GroupAlone], (instregex "BRAS$")>;
|
|
||||||
def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BASR$")>;
|
|
||||||
def : InstRW<[LSU, Lat4], (instregex "CallB(C)?R$")>;
|
|
||||||
def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BRASL$")>;
|
|
||||||
def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "TLS_(G|L)DCALL$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "CallBRCL$")>;
|
|
||||||
def : InstRW<[VBU], (instregex "CallJG$")>;
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Move instructions
|
// Move instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -191,21 +175,23 @@ def : InstRW<[FXU], (instregex "LR(Mux)?$")>;
|
||||||
def : InstRW<[FXU, LSU, Lat5], (instregex "LT(G)?$")>;
|
def : InstRW<[FXU, LSU, Lat5], (instregex "LT(G)?$")>;
|
||||||
def : InstRW<[FXU], (instregex "LT(G)?R$")>;
|
def : InstRW<[FXU], (instregex "LT(G)?R$")>;
|
||||||
|
|
||||||
// Load on condition
|
|
||||||
def : InstRW<[FXU, LSU, Lat6], (instregex "(Asm.*)?LOC(G)?$")>;
|
|
||||||
def : InstRW<[FXU, Lat2], (instregex "(Asm.*)?LOC(G)?R$")>;
|
|
||||||
|
|
||||||
// Stores
|
// Stores
|
||||||
def : InstRW<[FXU, LSU, Lat5], (instregex "STG(RL)?$")>;
|
def : InstRW<[FXU, LSU, Lat5], (instregex "STG(RL)?$")>;
|
||||||
def : InstRW<[FXU, LSU, Lat5], (instregex "ST128$")>;
|
def : InstRW<[FXU, LSU, Lat5], (instregex "ST128$")>;
|
||||||
def : InstRW<[FXU, LSU, Lat5], (instregex "ST(Y|FH|RL|Mux)?$")>;
|
def : InstRW<[FXU, LSU, Lat5], (instregex "ST(Y|FH|RL|Mux)?$")>;
|
||||||
|
|
||||||
// Store on condition
|
|
||||||
def : InstRW<[FXU, LSU, Lat5], (instregex "(Asm.*)?STOC(G)?$")>;
|
|
||||||
|
|
||||||
// String moves.
|
// String moves.
|
||||||
def : InstRW<[LSU, Lat30, GroupAlone], (instregex "MVST$")>;
|
def : InstRW<[LSU, Lat30, GroupAlone], (instregex "MVST$")>;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Conditional move instructions
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def : InstRW<[FXU, Lat2], (instregex "LOC(G)?R(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXU, Lat2], (instregex "LOC(G)?HI(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXU, LSU, Lat6], (instregex "LOC(G)?(Asm.*)?$")>;
|
||||||
|
def : InstRW<[FXU, LSU, Lat5], (instregex "STOC(G)?(Asm.*)?$")>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Sign extensions
|
// Sign extensions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -778,6 +778,24 @@
|
||||||
# CHECK: ay %r15, 0
|
# CHECK: ay %r15, 0
|
||||||
0xe3 0xf0 0x00 0x00 0x00 0x5a
|
0xe3 0xf0 0x00 0x00 0x00 0x5a
|
||||||
|
|
||||||
|
# CHECK: bas %r0, 0
|
||||||
|
0x4d 0x00 0x00 0x00
|
||||||
|
|
||||||
|
# CHECK: bas %r1, 4095
|
||||||
|
0x4d 0x10 0x0f 0xff
|
||||||
|
|
||||||
|
# CHECK: bas %r2, 0(%r1)
|
||||||
|
0x4d 0x20 0x10 0x00
|
||||||
|
|
||||||
|
# CHECK: bas %r3, 0(%r15)
|
||||||
|
0x4d 0x30 0xf0 0x00
|
||||||
|
|
||||||
|
# CHECK: bas %r14, 4095(%r1,%r15)
|
||||||
|
0x4d 0xe1 0xff 0xff
|
||||||
|
|
||||||
|
# CHECK: bas %r15, 4095(%r15,%r1)
|
||||||
|
0x4d 0xff 0x1f 0xff
|
||||||
|
|
||||||
# CHECK: basr %r0, %r1
|
# CHECK: basr %r0, %r1
|
||||||
0x0d 0x01
|
0x0d 0x01
|
||||||
|
|
||||||
|
@ -790,6 +808,84 @@
|
||||||
# CHECK: basr %r15, %r1
|
# CHECK: basr %r15, %r1
|
||||||
0x0d 0xf1
|
0x0d 0xf1
|
||||||
|
|
||||||
|
# CHECK: b 0
|
||||||
|
0x47 0xf0 0x00 0x00
|
||||||
|
|
||||||
|
# CHECK: b 4095
|
||||||
|
0x47 0xf0 0x0f 0xff
|
||||||
|
|
||||||
|
# CHECK: b 0(%r1)
|
||||||
|
0x47 0xf0 0x10 0x00
|
||||||
|
|
||||||
|
# CHECK: b 0(%r15)
|
||||||
|
0x47 0xf0 0xf0 0x00
|
||||||
|
|
||||||
|
# CHECK: b 4095(%r1,%r15)
|
||||||
|
0x47 0xf1 0xff 0xff
|
||||||
|
|
||||||
|
# CHECK: b 4095(%r15,%r1)
|
||||||
|
0x47 0xff 0x1f 0xff
|
||||||
|
|
||||||
|
# CHECK: bc 0, 0
|
||||||
|
0x47 0x00 0x00 0x00
|
||||||
|
|
||||||
|
# CHECK: bc 0, 4095
|
||||||
|
0x47 0x00 0x0f 0xff
|
||||||
|
|
||||||
|
# CHECK: bc 0, 0(%r1)
|
||||||
|
0x47 0x00 0x10 0x00
|
||||||
|
|
||||||
|
# CHECK: bc 0, 0(%r15)
|
||||||
|
0x47 0x00 0xf0 0x00
|
||||||
|
|
||||||
|
# CHECK: bc 0, 4095(%r1,%r15)
|
||||||
|
0x47 0x01 0xff 0xff
|
||||||
|
|
||||||
|
# CHECK: bc 0, 4095(%r15,%r1)
|
||||||
|
0x47 0x0f 0x1f 0xff
|
||||||
|
|
||||||
|
# CHECK: bo 0(%r13)
|
||||||
|
0x47 0x10 0xd0 0x00
|
||||||
|
|
||||||
|
# CHECK: bh 0(%r12)
|
||||||
|
0x47 0x20 0xc0 0x00
|
||||||
|
|
||||||
|
# CHECK: bnle 0(%r11)
|
||||||
|
0x47 0x30 0xb0 0x00
|
||||||
|
|
||||||
|
# CHECK: bl 0(%r10)
|
||||||
|
0x47 0x40 0xa0 0x00
|
||||||
|
|
||||||
|
# CHECK: bnhe 0(%r9)
|
||||||
|
0x47 0x50 0x90 0x00
|
||||||
|
|
||||||
|
# CHECK: blh 0(%r8)
|
||||||
|
0x47 0x60 0x80 0x00
|
||||||
|
|
||||||
|
# CHECK: bne 0(%r7)
|
||||||
|
0x47 0x70 0x70 0x00
|
||||||
|
|
||||||
|
# CHECK: be 0(%r6)
|
||||||
|
0x47 0x80 0x60 0x00
|
||||||
|
|
||||||
|
# CHECK: bnlh 0(%r5)
|
||||||
|
0x47 0x90 0x50 0x00
|
||||||
|
|
||||||
|
# CHECK: bhe 0(%r4)
|
||||||
|
0x47 0xa0 0x40 0x00
|
||||||
|
|
||||||
|
# CHECK: bnl 0(%r3)
|
||||||
|
0x47 0xb0 0x30 0x00
|
||||||
|
|
||||||
|
# CHECK: ble 0(%r2)
|
||||||
|
0x47 0xc0 0x20 0x00
|
||||||
|
|
||||||
|
# CHECK: bnh 0(%r1)
|
||||||
|
0x47 0xd0 0x10 0x00
|
||||||
|
|
||||||
|
# CHECK: bno 0
|
||||||
|
0x47 0xe0 0x00 0x00
|
||||||
|
|
||||||
# CHECK: bcr 0, %r14
|
# CHECK: bcr 0, %r14
|
||||||
0x07 0x0e
|
0x07 0x0e
|
||||||
|
|
||||||
|
|
|
@ -258,6 +258,28 @@
|
||||||
ay %r0, -524289
|
ay %r0, -524289
|
||||||
ay %r0, 524288
|
ay %r0, 524288
|
||||||
|
|
||||||
|
#CHECK: error: invalid operand
|
||||||
|
#CHECK: bas %r0, -1
|
||||||
|
#CHECK: error: invalid operand
|
||||||
|
#CHECK: bas %r0, 4096
|
||||||
|
|
||||||
|
bas %r0, -1
|
||||||
|
bas %r0, 4096
|
||||||
|
|
||||||
|
#CHECK: error: invalid operand
|
||||||
|
#CHECK: bc -1, 0(%r1)
|
||||||
|
#CHECK: error: invalid operand
|
||||||
|
#CHECK: bc 16, 0(%r1)
|
||||||
|
#CHECK: error: invalid operand
|
||||||
|
#CHECK: bc 0, -1
|
||||||
|
#CHECK: error: invalid operand
|
||||||
|
#CHECK: bc 0, 4096
|
||||||
|
|
||||||
|
bc -1, 0(%r1)
|
||||||
|
bc 16, 0(%r1)
|
||||||
|
bc 0, -1
|
||||||
|
bc 0, 4096
|
||||||
|
|
||||||
#CHECK: error: invalid operand
|
#CHECK: error: invalid operand
|
||||||
#CHECK: bcr -1, %r1
|
#CHECK: bcr -1, %r1
|
||||||
#CHECK: error: invalid operand
|
#CHECK: error: invalid operand
|
||||||
|
|
|
@ -517,6 +517,20 @@
|
||||||
ay %r0, 524287(%r15,%r1)
|
ay %r0, 524287(%r15,%r1)
|
||||||
ay %r15, 0
|
ay %r15, 0
|
||||||
|
|
||||||
|
#CHECK: bas %r0, 0 # encoding: [0x4d,0x00,0x00,0x00]
|
||||||
|
#CHECK: bas %r1, 4095 # encoding: [0x4d,0x10,0x0f,0xff]
|
||||||
|
#CHECK: bas %r2, 0(%r1) # encoding: [0x4d,0x20,0x10,0x00]
|
||||||
|
#CHECK: bas %r3, 0(%r15) # encoding: [0x4d,0x30,0xf0,0x00]
|
||||||
|
#CHECK: bas %r14, 4095(%r1,%r15) # encoding: [0x4d,0xe1,0xff,0xff]
|
||||||
|
#CHECK: bas %r15, 4095(%r15,%r1) # encoding: [0x4d,0xff,0x1f,0xff]
|
||||||
|
|
||||||
|
bas %r0, 0
|
||||||
|
bas %r1, 4095
|
||||||
|
bas %r2, 0(%r1)
|
||||||
|
bas %r3, 0(%r15)
|
||||||
|
bas %r14, 4095(%r1,%r15)
|
||||||
|
bas %r15, 4095(%r15,%r1)
|
||||||
|
|
||||||
#CHECK: basr %r0, %r1 # encoding: [0x0d,0x01]
|
#CHECK: basr %r0, %r1 # encoding: [0x0d,0x01]
|
||||||
#CHECK: basr %r0, %r15 # encoding: [0x0d,0x0f]
|
#CHECK: basr %r0, %r15 # encoding: [0x0d,0x0f]
|
||||||
#CHECK: basr %r14, %r9 # encoding: [0x0d,0xe9]
|
#CHECK: basr %r14, %r9 # encoding: [0x0d,0xe9]
|
||||||
|
@ -527,6 +541,120 @@
|
||||||
basr %r14,%r9
|
basr %r14,%r9
|
||||||
basr %r15,%r1
|
basr %r15,%r1
|
||||||
|
|
||||||
|
#CHECK: b 0 # encoding: [0x47,0xf0,0x00,0x00]
|
||||||
|
#CHECK: b 4095 # encoding: [0x47,0xf0,0x0f,0xff]
|
||||||
|
#CHECK: b 0(%r1) # encoding: [0x47,0xf0,0x10,0x00]
|
||||||
|
#CHECK: b 0(%r15) # encoding: [0x47,0xf0,0xf0,0x00]
|
||||||
|
#CHECK: b 4095(%r1,%r15) # encoding: [0x47,0xf1,0xff,0xff]
|
||||||
|
#CHECK: b 4095(%r15,%r1) # encoding: [0x47,0xff,0x1f,0xff]
|
||||||
|
|
||||||
|
b 0
|
||||||
|
b 4095
|
||||||
|
b 0(%r1)
|
||||||
|
b 0(%r15)
|
||||||
|
b 4095(%r1,%r15)
|
||||||
|
b 4095(%r15,%r1)
|
||||||
|
|
||||||
|
#CHECK: bc 0, 0 # encoding: [0x47,0x00,0x00,0x00]
|
||||||
|
#CHECK: bc 0, 4095 # encoding: [0x47,0x00,0x0f,0xff]
|
||||||
|
#CHECK: bc 0, 0(%r1) # encoding: [0x47,0x00,0x10,0x00]
|
||||||
|
#CHECK: bc 0, 0(%r15) # encoding: [0x47,0x00,0xf0,0x00]
|
||||||
|
#CHECK: bc 0, 4095(%r1,%r15) # encoding: [0x47,0x01,0xff,0xff]
|
||||||
|
#CHECK: bc 0, 4095(%r15,%r1) # encoding: [0x47,0x0f,0x1f,0xff]
|
||||||
|
#CHECK: bc 15, 0 # encoding: [0x47,0xf0,0x00,0x00]
|
||||||
|
|
||||||
|
bc 0, 0
|
||||||
|
bc 0, 4095
|
||||||
|
bc 0, 0(%r1)
|
||||||
|
bc 0, 0(%r15)
|
||||||
|
bc 0, 4095(%r1,%r15)
|
||||||
|
bc 0, 4095(%r15,%r1)
|
||||||
|
bc 15, 0
|
||||||
|
|
||||||
|
#CHECK: bc 1, 0(%r7) # encoding: [0x47,0x10,0x70,0x00]
|
||||||
|
#CHECK: bo 0(%r15) # encoding: [0x47,0x10,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 1, 0(%r7)
|
||||||
|
bo 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 2, 0(%r7) # encoding: [0x47,0x20,0x70,0x00]
|
||||||
|
#CHECK: bh 0(%r15) # encoding: [0x47,0x20,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 2, 0(%r7)
|
||||||
|
bh 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 3, 0(%r7) # encoding: [0x47,0x30,0x70,0x00]
|
||||||
|
#CHECK: bnle 0(%r15) # encoding: [0x47,0x30,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 3, 0(%r7)
|
||||||
|
bnle 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 4, 0(%r7) # encoding: [0x47,0x40,0x70,0x00]
|
||||||
|
#CHECK: bl 0(%r15) # encoding: [0x47,0x40,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 4, 0(%r7)
|
||||||
|
bl 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 5, 0(%r7) # encoding: [0x47,0x50,0x70,0x00]
|
||||||
|
#CHECK: bnhe 0(%r15) # encoding: [0x47,0x50,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 5, 0(%r7)
|
||||||
|
bnhe 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 6, 0(%r7) # encoding: [0x47,0x60,0x70,0x00]
|
||||||
|
#CHECK: blh 0(%r15) # encoding: [0x47,0x60,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 6, 0(%r7)
|
||||||
|
blh 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 7, 0(%r7) # encoding: [0x47,0x70,0x70,0x00]
|
||||||
|
#CHECK: bne 0(%r15) # encoding: [0x47,0x70,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 7, 0(%r7)
|
||||||
|
bne 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 8, 0(%r7) # encoding: [0x47,0x80,0x70,0x00]
|
||||||
|
#CHECK: be 0(%r15) # encoding: [0x47,0x80,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 8, 0(%r7)
|
||||||
|
be 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 9, 0(%r7) # encoding: [0x47,0x90,0x70,0x00]
|
||||||
|
#CHECK: bnlh 0(%r15) # encoding: [0x47,0x90,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 9, 0(%r7)
|
||||||
|
bnlh 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 10, 0(%r7) # encoding: [0x47,0xa0,0x70,0x00]
|
||||||
|
#CHECK: bhe 0(%r15) # encoding: [0x47,0xa0,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 10, 0(%r7)
|
||||||
|
bhe 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 11, 0(%r7) # encoding: [0x47,0xb0,0x70,0x00]
|
||||||
|
#CHECK: bnl 0(%r15) # encoding: [0x47,0xb0,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 11, 0(%r7)
|
||||||
|
bnl 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 12, 0(%r7) # encoding: [0x47,0xc0,0x70,0x00]
|
||||||
|
#CHECK: ble 0(%r15) # encoding: [0x47,0xc0,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 12, 0(%r7)
|
||||||
|
ble 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 13, 0(%r7) # encoding: [0x47,0xd0,0x70,0x00]
|
||||||
|
#CHECK: bnh 0(%r15) # encoding: [0x47,0xd0,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 13, 0(%r7)
|
||||||
|
bnh 0(%r15)
|
||||||
|
|
||||||
|
#CHECK: bc 14, 0(%r7) # encoding: [0x47,0xe0,0x70,0x00]
|
||||||
|
#CHECK: bno 0(%r15) # encoding: [0x47,0xe0,0xf0,0x00]
|
||||||
|
|
||||||
|
bc 14, 0(%r7)
|
||||||
|
bno 0(%r15)
|
||||||
|
|
||||||
#CHECK: bcr 0, %r0 # encoding: [0x07,0x00]
|
#CHECK: bcr 0, %r0 # encoding: [0x07,0x00]
|
||||||
#CHECK: bcr 0, %r15 # encoding: [0x07,0x0f]
|
#CHECK: bcr 0, %r15 # encoding: [0x07,0x0f]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue