TableGen: convert InstAlias's Emit bit to an int.
authorTim Northover <tnorthover@apple.com>
Tue, 20 May 2014 09:17:16 +0000 (09:17 +0000)
committerTim Northover <tnorthover@apple.com>
Tue, 20 May 2014 09:17:16 +0000 (09:17 +0000)
When multiple aliases overlap, the correct string to print can often be
determined purely by considering the InstAlias declarations in some particular
order. This allows the user to specify that order manually when desired,
without resorting to hacking around with the default lexicographical order on
Record instantiation, which is error-prone and ugly.

I was also mistaken about "add w2, w3, w4" being the same as "add w2, w3, w4,
uxtw". That's only true if Rn is the stack pointer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209199 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/Target.td
lib/Target/ARM64/ARM64InstrFormats.td
lib/Target/ARM64/ARM64InstrInfo.td
test/MC/AArch64/basic-a64-instructions.s
test/MC/ARM64/arithmetic-encoding.s
utils/TableGen/AsmWriterEmitter.cpp

index facb89ade631b38cea522e9be3721fa2b67b5078..7d1f19c477cfaf25c7b7b7ef71e7bd9913cd7939 100644 (file)
@@ -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 = [];
index 3f9104deaf18991a2740f4370708c20a3ce1634e..0ac27e09358cfb98409551ec8832dd6ae430fd61 100644 (file)
@@ -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
 }
 
 //---
index fa6e3f1162f49b4b0624cd266a0a5de5935b4392..4c735c057a27df0eda97f83df1c4e7305ffda935 100644 (file)
@@ -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)>;
index 672eab90aa556d9aa57772969a7e8e79edb13549..9a4ec81aae9ae18b4f1e6b7bb2ee86be3e7ddead 100644 (file)
@@ -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]
index de7989b2013f07f1b7bf69830dc3ba85af3c6b95..5fd591240e2544e60d1c19d968f3cc7fe83666d3 100644 (file)
@@ -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]
index c31c120a2f726c124e6b816b80cfb787de2e1fe4..2741d8f4adecd2db0c260dbb2298868b183e9743 100644 (file)
@@ -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);
     }
   }