diff options
-rw-r--r-- | llvm/include/llvm/Target/Target.td | 9 | ||||
-rw-r--r-- | llvm/lib/Target/ARM64/ARM64InstrFormats.td | 49 | ||||
-rw-r--r-- | llvm/lib/Target/ARM64/ARM64InstrInfo.td | 84 | ||||
-rw-r--r-- | llvm/test/MC/AArch64/basic-a64-instructions.s | 24 | ||||
-rw-r--r-- | llvm/test/MC/ARM64/arithmetic-encoding.s | 8 | ||||
-rw-r--r-- | llvm/utils/TableGen/AsmWriterEmitter.cpp | 44 |
6 files changed, 115 insertions, 103 deletions
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index facb89ade63..7d1f19c477c 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -950,10 +950,15 @@ class MnemonicAlias<string From, string To, string VariantName = ""> { /// InstAlias - This defines an alternate assembly syntax that is allowed to /// match an instruction that has a different (more canonical) assembly /// representation. -class InstAlias<string Asm, dag Result, bit Emit = 0b1> { +class InstAlias<string Asm, dag Result, int Emit = 1> { string AsmString = Asm; // The .s format to match the instruction with. dag ResultInst = Result; // The MCInst to generate. - bit EmitAlias = Emit; // Emit the alias instead of what's aliased. + + // This determines which order the InstPrinter detects aliases for + // printing. A larger value makes the alias more likely to be + // emitted. The Instruction's own definition is notionally 0.5, so 0 + // disables printing and 1 enables it if there are no conflicting aliases. + int EmitPriority = Emit; // Predicates - Predicates that must be true for this to match. list<Predicate> Predicates = []; diff --git a/llvm/lib/Target/ARM64/ARM64InstrFormats.td b/llvm/lib/Target/ARM64/ARM64InstrFormats.td index 3f9104deaf1..0ac27e09358 100644 --- a/llvm/lib/Target/ARM64/ARM64InstrFormats.td +++ b/llvm/lib/Target/ARM64/ARM64InstrFormats.td @@ -1658,14 +1658,24 @@ multiclass AddSub<bit isSub, string mnemonic, let Inst{31} = 1; } + // Register/register aliases with no shift when SP is not used. + def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), + GPR32, GPR32, GPR32, 0>; + def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), + GPR64, GPR64, GPR64, 0>; + // Register/register aliases with no shift when either the destination or - // first source register is SP. This relies on the shifted register aliases - // above matching first in the case when SP is not used. + // first source register is SP. + def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), + GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), - GPR32sp, GPR32sp, GPR32, 16>; // UXTW #0 + GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrx64"), - GPR64sp, GPR64sp, GPR64, 24>; // UXTX #0 + GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 + def : AddSubRegAlias<mnemonic, + !cast<Instruction>(NAME#"Xrx64"), + GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 } multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp> { @@ -1716,34 +1726,39 @@ multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp> { // Compare aliases def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Wri") - WZR, GPR32sp:$src, addsub_shifted_imm32:$imm)>; + WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Xri") - XZR, GPR64sp:$src, addsub_shifted_imm64:$imm)>; + XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") - WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh)>; + WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") - XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh)>; + XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") - XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh)>; + XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") - WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh)>; + WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") - XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh)>; + XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; // Compare shorthands def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrs") - WZR, GPR32:$src1, GPR32:$src2, 0)>; + WZR, GPR32:$src1, GPR32:$src2, 0), 5>; def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrs") - XZR, GPR64:$src1, GPR64:$src2, 0)>; + XZR, GPR64:$src1, GPR64:$src2, 0), 5>; + + // Register/register aliases with no shift when SP is not used. + def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), + GPR32, GPR32, GPR32, 0>; + def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), + GPR64, GPR64, GPR64, 0>; // Register/register aliases with no shift when the first source register - // is SP. This relies on the shifted register aliases above matching first - // in the case when SP is not used. + // is SP. def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), - GPR32, GPR32sp, GPR32, 16>; // UXTW #0 + GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrx64"), - GPR64, GPR64sp, GPR64, 24>; // UXTX #0 + GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 } //--- diff --git a/llvm/lib/Target/ARM64/ARM64InstrInfo.td b/llvm/lib/Target/ARM64/ARM64InstrInfo.td index fa6e3f1162f..4c735c057a2 100644 --- a/llvm/lib/Target/ARM64/ARM64InstrInfo.td +++ b/llvm/lib/Target/ARM64/ARM64InstrInfo.td @@ -568,30 +568,19 @@ def : Pat<(ARM64sub_flag GPR64:$Rn, neg_addsub_shifted_imm64:$imm), (ADDSXri GPR64:$Rn, neg_addsub_shifted_imm64:$imm)>; } -def : InstAlias<"neg $dst, $src", (SUBWrs GPR32:$dst, WZR, GPR32:$src, 0)>; -def : InstAlias<"neg $dst, $src", (SUBXrs GPR64:$dst, XZR, GPR64:$src, 0)>; +def : InstAlias<"neg $dst, $src", (SUBWrs GPR32:$dst, WZR, GPR32:$src, 0), 3>; +def : InstAlias<"neg $dst, $src", (SUBXrs GPR64:$dst, XZR, GPR64:$src, 0), 3>; def : InstAlias<"neg $dst, $src$shift", - (SUBWrs GPR32:$dst, WZR, GPR32:$src, arith_shift32:$shift)>; + (SUBWrs GPR32:$dst, WZR, GPR32:$src, arith_shift32:$shift), 2>; def : InstAlias<"neg $dst, $src$shift", - (SUBXrs GPR64:$dst, XZR, GPR64:$src, arith_shift64:$shift)>; + (SUBXrs GPR64:$dst, XZR, GPR64:$src, arith_shift64:$shift), 2>; -def : InstAlias<"negs $dst, $src", (SUBSWrs GPR32:$dst, WZR, GPR32:$src, 0)>; -def : InstAlias<"negs $dst, $src", (SUBSXrs GPR64:$dst, XZR, GPR64:$src, 0)>; +def : InstAlias<"negs $dst, $src", (SUBSWrs GPR32:$dst, WZR, GPR32:$src, 0), 3>; +def : InstAlias<"negs $dst, $src", (SUBSXrs GPR64:$dst, XZR, GPR64:$src, 0), 3>; def : InstAlias<"negs $dst, $src$shift", - (SUBSWrs GPR32:$dst, WZR, GPR32:$src, arith_shift32:$shift)>; + (SUBSWrs GPR32:$dst, WZR, GPR32:$src, arith_shift32:$shift), 2>; def : InstAlias<"negs $dst, $src$shift", - (SUBSXrs GPR64:$dst, XZR, GPR64:$src, arith_shift64:$shift)>; - - -// Register/register aliases with no shift when SP is not used. -def : AddSubRegAlias<"add", ADDWrs, GPR32, GPR32, GPR32, 0>; -def : AddSubRegAlias<"add", ADDXrs, GPR64, GPR64, GPR64, 0>; -def : AddSubRegAlias<"sub", SUBWrs, GPR32, GPR32, GPR32, 0>; -def : AddSubRegAlias<"sub", SUBXrs, GPR64, GPR64, GPR64, 0>; -def : AddSubRegAlias<"adds", ADDSWrs, GPR32, GPR32, GPR32, 0>; -def : AddSubRegAlias<"adds", ADDSXrs, GPR64, GPR64, GPR64, 0>; -def : AddSubRegAlias<"subs", SUBSWrs, GPR32, GPR32, GPR32, 0>; -def : AddSubRegAlias<"subs", SUBSXrs, GPR64, GPR64, GPR64, 0>; + (SUBSXrs GPR64:$dst, XZR, GPR64:$src, arith_shift64:$shift), 2>; // Unsigned/Signed divide @@ -708,38 +697,31 @@ defm ORN : LogicalReg<0b01, 1, "orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>; defm ORR : LogicalReg<0b01, 0, "orr", or>; -// FIXME: these aliases are named so that they get considered by TableGen before -// the already instantiated anonymous_ABC ones. Some kind of explicit priority -// system would be better. -def AA_MOVWr : InstAlias<"mov $dst, $src", - (ORRWrs GPR32:$dst, WZR, GPR32:$src, 0)>; -def AA_MOVXr : InstAlias<"mov $dst, $src", - (ORRXrs GPR64:$dst, XZR, GPR64:$src, 0)>; - -def AA_MVNWr : InstAlias<"mvn $Wd, $Wm", - (ORNWrs GPR32:$Wd, WZR, GPR32:$Wm, 0)>; -def AA_MVNXr : InstAlias<"mvn $Xd, $Xm", - (ORNXrs GPR64:$Xd, XZR, GPR64:$Xm, 0)>; - -def AA_MVNWrs : InstAlias<"mvn $Wd, $Wm$sh", - (ORNWrs GPR32:$Wd, WZR, GPR32:$Wm, logical_shift32:$sh)>; -def AA_MVNXrs : InstAlias<"mvn $Xd, $Xm$sh", - (ORNXrs GPR64:$Xd, XZR, GPR64:$Xm, logical_shift64:$sh)>; - -def AA_TSTWri : InstAlias<"tst $src1, $src2", - (ANDSWri WZR, GPR32:$src1, logical_imm32:$src2)>; -def AA_TSTXri : InstAlias<"tst $src1, $src2", - (ANDSXri XZR, GPR64:$src1, logical_imm64:$src2)>; - -def AA_TSTWr: InstAlias<"tst $src1, $src2", - (ANDSWrs WZR, GPR32:$src1, GPR32:$src2, 0)>; -def AA_TSTXr: InstAlias<"tst $src1, $src2", - (ANDSXrs XZR, GPR64:$src1, GPR64:$src2, 0)>; - -def AB_TSTWrs : InstAlias<"tst $src1, $src2$sh", - (ANDSWrs WZR, GPR32:$src1, GPR32:$src2, logical_shift32:$sh)>; -def AB_TSTXrs : InstAlias<"tst $src1, $src2$sh", - (ANDSXrs XZR, GPR64:$src1, GPR64:$src2, logical_shift64:$sh)>; +def : InstAlias<"mov $dst, $src", (ORRWrs GPR32:$dst, WZR, GPR32:$src, 0), 2>; +def : InstAlias<"mov $dst, $src", (ORRXrs GPR64:$dst, XZR, GPR64:$src, 0), 2>; + +def : InstAlias<"mvn $Wd, $Wm", (ORNWrs GPR32:$Wd, WZR, GPR32:$Wm, 0), 3>; +def : InstAlias<"mvn $Xd, $Xm", (ORNXrs GPR64:$Xd, XZR, GPR64:$Xm, 0), 3>; + +def : InstAlias<"mvn $Wd, $Wm$sh", + (ORNWrs GPR32:$Wd, WZR, GPR32:$Wm, logical_shift32:$sh), 2>; +def : InstAlias<"mvn $Xd, $Xm$sh", + (ORNXrs GPR64:$Xd, XZR, GPR64:$Xm, logical_shift64:$sh), 2>; + +def : InstAlias<"tst $src1, $src2", + (ANDSWri WZR, GPR32:$src1, logical_imm32:$src2), 2>; +def : InstAlias<"tst $src1, $src2", + (ANDSXri XZR, GPR64:$src1, logical_imm64:$src2), 2>; + +def : InstAlias<"tst $src1, $src2", + (ANDSWrs WZR, GPR32:$src1, GPR32:$src2, 0), 3>; +def : InstAlias<"tst $src1, $src2", + (ANDSXrs XZR, GPR64:$src1, GPR64:$src2, 0), 3>; + +def : InstAlias<"tst $src1, $src2$sh", + (ANDSWrs WZR, GPR32:$src1, GPR32:$src2, logical_shift32:$sh), 2>; +def : InstAlias<"tst $src1, $src2$sh", + (ANDSXrs XZR, GPR64:$src1, GPR64:$src2, logical_shift64:$sh), 2>; def : Pat<(not GPR32:$Wm), (ORNWrr WZR, GPR32:$Wm)>; diff --git a/llvm/test/MC/AArch64/basic-a64-instructions.s b/llvm/test/MC/AArch64/basic-a64-instructions.s index 672eab90aa5..9a4ec81aae9 100644 --- a/llvm/test/MC/AArch64/basic-a64-instructions.s +++ b/llvm/test/MC/AArch64/basic-a64-instructions.s @@ -27,8 +27,7 @@ _func: // CHECK: add x2, x4, w5, uxtb // encoding: [0x82,0x00,0x25,0x8b] // CHECK: add x20, sp, w19, uxth // encoding: [0xf4,0x23,0x33,0x8b] // CHECK: add x12, x1, w20, uxtw // encoding: [0x2c,0x40,0x34,0x8b] -// CHECK-AARCH64: add x20, x3, x13, uxtx // encoding: [0x74,0x60,0x2d,0x8b] -// CHECK-ARM64: add x20, x3, x13 // encoding: [0x74,0x60,0x2d,0x8b] +// CHECK: add x20, x3, x13, uxtx // encoding: [0x74,0x60,0x2d,0x8b] // CHECK: add x17, x25, w20, sxtb // encoding: [0x31,0x83,0x34,0x8b] // CHECK: add x18, x13, w19, sxth // encoding: [0xb2,0xa1,0x33,0x8b] // CHECK: add sp, x2, w3, sxtw // encoding: [0x5f,0xc0,0x23,0x8b] @@ -45,8 +44,7 @@ _func: add w2, w3, w5, sxtx // CHECK: add w2, w5, w7, uxtb // encoding: [0xa2,0x00,0x27,0x0b] // CHECK: add w21, w15, w17, uxth // encoding: [0xf5,0x21,0x31,0x0b] -// CHECK-AARCH64: add w30, w29, wzr, uxtw // encoding: [0xbe,0x43,0x3f,0x0b] -// CHECK-ARM64: add w30, w29, wzr // encoding: [0xbe,0x43,0x3f,0x0b] +// CHECK: add w30, w29, wzr, uxtw // encoding: [0xbe,0x43,0x3f,0x0b] // CHECK: add w19, w17, w1, uxtx // encoding: [0x33,0x62,0x21,0x0b] // CHECK: add w2, w5, w1, sxtb // encoding: [0xa2,0x80,0x21,0x0b] // CHECK: add w26, w17, w19, sxth // encoding: [0x3a,0xa2,0x33,0x0b] @@ -75,8 +73,7 @@ _func: // CHECK: sub x2, x4, w5, uxtb #2 // encoding: [0x82,0x08,0x25,0xcb] // CHECK: sub x20, sp, w19, uxth #4 // encoding: [0xf4,0x33,0x33,0xcb] // CHECK: sub x12, x1, w20, uxtw // encoding: [0x2c,0x40,0x34,0xcb] -// CHECK-AARCH64: sub x20, x3, x13, uxtx // encoding: [0x74,0x60,0x2d,0xcb] -// CHECK-ARM64: sub x20, x3, x13 // encoding: [0x74,0x60,0x2d,0xcb] +// CHECK: sub x20, x3, x13, uxtx // encoding: [0x74,0x60,0x2d,0xcb] // CHECK: sub x17, x25, w20, sxtb // encoding: [0x31,0x83,0x34,0xcb] // CHECK: sub x18, x13, w19, sxth // encoding: [0xb2,0xa1,0x33,0xcb] // CHECK: sub sp, x2, w3, sxtw // encoding: [0x5f,0xc0,0x23,0xcb] @@ -92,8 +89,7 @@ _func: sub w2, w3, w5, sxtx // CHECK: sub w2, w5, w7, uxtb // encoding: [0xa2,0x00,0x27,0x4b] // CHECK: sub w21, w15, w17, uxth // encoding: [0xf5,0x21,0x31,0x4b] -// CHECK-AARCH64: sub w30, w29, wzr, uxtw // encoding: [0xbe,0x43,0x3f,0x4b] -// CHECK-ARM64: sub w30, w29, wzr // encoding: [0xbe,0x43,0x3f,0x4b] +// CHECK: sub w30, w29, wzr, uxtw // encoding: [0xbe,0x43,0x3f,0x4b] // CHECK: sub w19, w17, w1, uxtx // encoding: [0x33,0x62,0x21,0x4b] // CHECK: sub w2, w5, w1, sxtb // encoding: [0xa2,0x80,0x21,0x4b] // CHECK: sub w26, wsp, w19, sxth // encoding: [0xfa,0xa3,0x33,0x4b] @@ -112,8 +108,7 @@ _func: // CHECK: adds x2, x4, w5, uxtb #2 // encoding: [0x82,0x08,0x25,0xab] // CHECK: adds x20, sp, w19, uxth #4 // encoding: [0xf4,0x33,0x33,0xab] // CHECK: adds x12, x1, w20, uxtw // encoding: [0x2c,0x40,0x34,0xab] -// CHECK-AARCH64: adds x20, x3, x13, uxtx // encoding: [0x74,0x60,0x2d,0xab] -// CHECK-ARM64: adds x20, x3, x13 // encoding: [0x74,0x60,0x2d,0xab] +// CHECK: adds x20, x3, x13, uxtx // encoding: [0x74,0x60,0x2d,0xab] // CHECK: {{adds xzr,|cmn}} x25, w20, sxtb #3 // encoding: [0x3f,0x8f,0x34,0xab] // CHECK: adds x18, sp, w19, sxth // encoding: [0xf2,0xa3,0x33,0xab] // CHECK: {{adds xzr,|cmn}} x2, w3, sxtw // encoding: [0x5f,0xc0,0x23,0xab] @@ -129,8 +124,7 @@ _func: adds w2, w3, w5, sxtx // CHECK: adds w2, w5, w7, uxtb // encoding: [0xa2,0x00,0x27,0x2b] // CHECK: adds w21, w15, w17, uxth // encoding: [0xf5,0x21,0x31,0x2b] -// CHECK-AARCH64: adds w30, w29, wzr, uxtw // encoding: [0xbe,0x43,0x3f,0x2b] -// CHECK-ARM64: adds w30, w29, wzr // encoding: [0xbe,0x43,0x3f,0x2b] +// CHECK: adds w30, w29, wzr, uxtw // encoding: [0xbe,0x43,0x3f,0x2b] // CHECK: adds w19, w17, w1, uxtx // encoding: [0x33,0x62,0x21,0x2b] // CHECK: adds w2, w5, w1, sxtb #1 // encoding: [0xa2,0x84,0x21,0x2b] // CHECK: adds w26, wsp, w19, sxth // encoding: [0xfa,0xa3,0x33,0x2b] @@ -150,8 +144,7 @@ _func: // CHECK: subs x2, x4, w5, uxtb #2 // encoding: [0x82,0x08,0x25,0xeb] // CHECK: subs x20, sp, w19, uxth #4 // encoding: [0xf4,0x33,0x33,0xeb] // CHECK: subs x12, x1, w20, uxtw // encoding: [0x2c,0x40,0x34,0xeb] -// CHECK-AARCH64: subs x20, x3, x13, uxtx // encoding: [0x74,0x60,0x2d,0xeb] -// CHECK-ARM64: subs x20, x3, x13 // encoding: [0x74,0x60,0x2d,0xeb] +// CHECK: subs x20, x3, x13, uxtx // encoding: [0x74,0x60,0x2d,0xeb] // CHECK: {{subs xzr,|cmp}} x25, w20, sxtb #3 // encoding: [0x3f,0x8f,0x34,0xeb] // CHECK: subs x18, sp, w19, sxth // encoding: [0xf2,0xa3,0x33,0xeb] // CHECK: {{subs xzr,|cmp}} x2, w3, sxtw // encoding: [0x5f,0xc0,0x23,0xeb] @@ -167,8 +160,7 @@ _func: subs w2, w3, w5, sxtx // CHECK: subs w2, w5, w7, uxtb // encoding: [0xa2,0x00,0x27,0x6b] // CHECK: subs w21, w15, w17, uxth // encoding: [0xf5,0x21,0x31,0x6b] -// CHECK-AARCH64: subs w30, w29, wzr, uxtw // encoding: [0xbe,0x43,0x3f,0x6b] -// CHECK-ARM64: subs w30, w29, wzr // encoding: [0xbe,0x43,0x3f,0x6b] +// CHECK: subs w30, w29, wzr, uxtw // encoding: [0xbe,0x43,0x3f,0x6b] // CHECK: subs w19, w17, w1, uxtx // encoding: [0x33,0x62,0x21,0x6b] // CHECK: subs w2, w5, w1, sxtb #1 // encoding: [0xa2,0x84,0x21,0x6b] // CHECK: subs w26, wsp, w19, sxth // encoding: [0xfa,0xa3,0x33,0x6b] diff --git a/llvm/test/MC/ARM64/arithmetic-encoding.s b/llvm/test/MC/ARM64/arithmetic-encoding.s index de7989b2013..5fd591240e2 100644 --- a/llvm/test/MC/ARM64/arithmetic-encoding.s +++ b/llvm/test/MC/ARM64/arithmetic-encoding.s @@ -178,7 +178,7 @@ foo: ; CHECK: add w1, w2, w3, uxtb ; encoding: [0x41,0x00,0x23,0x0b] ; CHECK: add w1, w2, w3, uxth ; encoding: [0x41,0x20,0x23,0x0b] -; CHECK: add w1, w2, w3 ; encoding: [0x41,0x40,0x23,0x0b] +; CHECK: add w1, w2, w3, uxtw ; encoding: [0x41,0x40,0x23,0x0b] ; CHECK: add w1, w2, w3, uxtx ; encoding: [0x41,0x60,0x23,0x0b] ; CHECK: add w1, w2, w3, sxtb ; encoding: [0x41,0x80,0x23,0x0b] ; CHECK: add w1, w2, w3, sxth ; encoding: [0x41,0xa0,0x23,0x0b] @@ -222,7 +222,7 @@ foo: ; CHECK: sub w1, w2, w3, uxtb ; encoding: [0x41,0x00,0x23,0x4b] ; CHECK: sub w1, w2, w3, uxth ; encoding: [0x41,0x20,0x23,0x4b] -; CHECK: sub w1, w2, w3 ; encoding: [0x41,0x40,0x23,0x4b] +; CHECK: sub w1, w2, w3, uxtw ; encoding: [0x41,0x40,0x23,0x4b] ; CHECK: sub w1, w2, w3, uxtx ; encoding: [0x41,0x60,0x23,0x4b] ; CHECK: sub w1, w2, w3, sxtb ; encoding: [0x41,0x80,0x23,0x4b] ; CHECK: sub w1, w2, w3, sxth ; encoding: [0x41,0xa0,0x23,0x4b] @@ -266,7 +266,7 @@ foo: ; CHECK: adds w1, w2, w3, uxtb ; encoding: [0x41,0x00,0x23,0x2b] ; CHECK: adds w1, w2, w3, uxth ; encoding: [0x41,0x20,0x23,0x2b] -; CHECK: adds w1, w2, w3 ; encoding: [0x41,0x40,0x23,0x2b] +; CHECK: adds w1, w2, w3, uxtw ; encoding: [0x41,0x40,0x23,0x2b] ; CHECK: adds w1, w2, w3, uxtx ; encoding: [0x41,0x60,0x23,0x2b] ; CHECK: adds w1, w2, w3, sxtb ; encoding: [0x41,0x80,0x23,0x2b] ; CHECK: adds w1, w2, w3, sxth ; encoding: [0x41,0xa0,0x23,0x2b] @@ -310,7 +310,7 @@ foo: ; CHECK: subs w1, w2, w3, uxtb ; encoding: [0x41,0x00,0x23,0x6b] ; CHECK: subs w1, w2, w3, uxth ; encoding: [0x41,0x20,0x23,0x6b] -; CHECK: subs w1, w2, w3 ; encoding: [0x41,0x40,0x23,0x6b] +; CHECK: subs w1, w2, w3, uxtw ; encoding: [0x41,0x40,0x23,0x6b] ; CHECK: subs w1, w2, w3, uxtx ; encoding: [0x41,0x60,0x23,0x6b] ; CHECK: subs w1, w2, w3, sxtb ; encoding: [0x41,0x80,0x23,0x6b] ; CHECK: subs w1, w2, w3, sxth ; encoding: [0x41,0xa0,0x23,0x6b] diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp index c31c120a2f7..2741d8f4ade 100644 --- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -750,6 +750,23 @@ static unsigned CountNumOperands(StringRef AsmString, unsigned Variant) { return AsmString.count(' ') + AsmString.count('\t'); } +namespace { +struct AliasPriorityComparator { + typedef std::pair<CodeGenInstAlias *, int> ValueType; + bool operator()(const ValueType &LHS, const ValueType &RHS) { + if (LHS.second == RHS.second) { + // We don't actually care about the order, but for consistency it + // shouldn't depend on pointer comparisons. + return LHS.first->TheDef->getName() < RHS.first->TheDef->getName(); + } + + // Aliases with larger priorities should be considered first. + return LHS.second > RHS.second; + } +}; +} + + void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { Record *AsmWriter = Target.getAsmWriter(); @@ -762,35 +779,36 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { // Emit the method that prints the alias instruction. std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); + unsigned Variant = AsmWriter->getValueAsInt("Variant"); std::vector<Record*> AllInstAliases = Records.getAllDerivedDefinitions("InstAlias"); // Create a map from the qualified name to a list of potential matches. - std::map<std::string, std::vector<CodeGenInstAlias*> > AliasMap; - unsigned Variant = AsmWriter->getValueAsInt("Variant"); + typedef std::set<std::pair<CodeGenInstAlias*, int>, AliasPriorityComparator> + AliasWithPriority; + std::map<std::string, AliasWithPriority> AliasMap; for (std::vector<Record*>::iterator I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) { CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Variant, Target); const Record *R = *I; - if (!R->getValueAsBit("EmitAlias")) - continue; // We were told not to emit the alias, but to emit the aliasee. + int Priority = R->getValueAsInt("EmitPriority"); + if (Priority < 1) + continue; // Aliases with priority 0 are never emitted. + const DagInit *DI = R->getValueAsDag("ResultInst"); const DefInit *Op = cast<DefInit>(DI->getOperator()); - AliasMap[getQualifiedName(Op->getDef())].push_back(Alias); + AliasMap[getQualifiedName(Op->getDef())].insert(std::make_pair(Alias, + Priority)); } // A map of which conditions need to be met for each instruction operand // before it can be matched to the mnemonic. std::map<std::string, std::vector<IAPrinter*> > IAPrinterMap; - for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator - I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) { - std::vector<CodeGenInstAlias*> &Aliases = I->second; - - for (std::vector<CodeGenInstAlias*>::iterator - II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) { - const CodeGenInstAlias *CGA = *II; + for (auto &Aliases : AliasMap) { + for (auto &Alias : Aliases.second) { + const CodeGenInstAlias *CGA = Alias.first; unsigned LastOpNo = CGA->ResultInstOperandIndex.size(); unsigned NumResultOps = CountNumOperands(CGA->ResultInst->AsmString, Variant); @@ -900,7 +918,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { } if (CantHandle) continue; - IAPrinterMap[I->first].push_back(IAP); + IAPrinterMap[Aliases.first].push_back(IAP); } } |