diff options
Diffstat (limited to 'lib/Target/AArch64/AArch64InstrFormats.td')
-rw-r--r-- | lib/Target/AArch64/AArch64InstrFormats.td | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/lib/Target/AArch64/AArch64InstrFormats.td b/lib/Target/AArch64/AArch64InstrFormats.td index d455d7e..5007172 100644 --- a/lib/Target/AArch64/AArch64InstrFormats.td +++ b/lib/Target/AArch64/AArch64InstrFormats.td @@ -448,13 +448,19 @@ def logical_imm64_XFORM : SDNodeXForm<imm, [{ return CurDAG->getTargetConstant(enc, MVT::i32); }]>; -def LogicalImm32Operand : AsmOperandClass { - let Name = "LogicalImm32"; - let DiagnosticType = "LogicalSecondSource"; -} -def LogicalImm64Operand : AsmOperandClass { - let Name = "LogicalImm64"; - let DiagnosticType = "LogicalSecondSource"; +let DiagnosticType = "LogicalSecondSource" in { + def LogicalImm32Operand : AsmOperandClass { + let Name = "LogicalImm32"; + } + def LogicalImm64Operand : AsmOperandClass { + let Name = "LogicalImm64"; + } + def LogicalImm32NotOperand : AsmOperandClass { + let Name = "LogicalImm32Not"; + } + def LogicalImm64NotOperand : AsmOperandClass { + let Name = "LogicalImm64Not"; + } } def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{ return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32); @@ -468,6 +474,12 @@ def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{ let PrintMethod = "printLogicalImm64"; let ParserMatchClass = LogicalImm64Operand; } +def logical_imm32_not : Operand<i32> { + let ParserMatchClass = LogicalImm32NotOperand; +} +def logical_imm64_not : Operand<i64> { + let ParserMatchClass = LogicalImm64NotOperand; +} // imm0_65535 predicate - True if the immediate is in the range [0,65535]. def Imm0_65535Operand : AsmImmRange<0, 65535>; @@ -963,8 +975,14 @@ def ccode : Operand<i32> { let ParserMatchClass = CondCode; } def inv_ccode : Operand<i32> { + // AL and NV are invalid in the aliases which use inv_ccode let PrintMethod = "printInverseCondCode"; let ParserMatchClass = CondCode; + let MCOperandPredicate = [{ + return MCOp.isImm() && + MCOp.getImm() != AArch64CC::AL && + MCOp.getImm() != AArch64CC::NV; + }]; } // Conditional branch target. 19-bit immediate. The low two bits of the target @@ -1323,13 +1341,13 @@ class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, [(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))]>, - Sched<[WriteIM32, ReadIMA, ReadIM, ReadIM]> { + Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { let Inst{31} = 0; } def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, [(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))]>, - Sched<[WriteIM64, ReadIMA, ReadIM, ReadIM]> { + Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { let Inst{31} = 1; } } @@ -1339,7 +1357,7 @@ class WideMulAccum<bit isSub, bits<3> opc, string asm, : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, [(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, - Sched<[WriteIM32, ReadIMA, ReadIM, ReadIM]> { + Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { let Inst{31} = 1; } @@ -1738,6 +1756,10 @@ multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp> { WZR, GPR32:$src1, GPR32:$src2, 0), 5>; def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrs") XZR, GPR64:$src1, GPR64:$src2, 0), 5>; + def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrx") + WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; + def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrx64") + XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; // Register/register aliases with no shift when SP is not used. def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), @@ -1925,22 +1947,32 @@ class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> : InstAlias<asm#" $dst, $src1, $src2", (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; -let AddedComplexity = 6 in -multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode> { +multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, + string Alias> { + let AddedComplexity = 6 in def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { let Inst{31} = 0; let Inst{22} = 0; // 64-bit version has an additional bit of immediate. } + let AddedComplexity = 6 in def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { let Inst{31} = 1; } + + def : InstAlias<Alias # " $Rd, $Rn, $imm", + (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, + logical_imm32_not:$imm), 0>; + def : InstAlias<Alias # " $Rd, $Rn, $imm", + (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, + logical_imm64_not:$imm), 0>; } -multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode> { +multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, + string Alias> { let isCompare = 1, Defs = [NZCV] in { def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { @@ -1952,6 +1984,13 @@ multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode> { let Inst{31} = 1; } } // end Defs = [NZCV] + + def : InstAlias<Alias # " $Rd, $Rn, $imm", + (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, + logical_imm32_not:$imm), 0>; + def : InstAlias<Alias # " $Rd, $Rn, $imm", + (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, + logical_imm64_not:$imm), 0>; } class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> |