/// 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 = [];
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> {
// 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
}
//---
(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
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)>;
// 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]
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]
// 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]
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]
// 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]
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]
// 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]
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]
; 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]
; 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]
; 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]
; 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]
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();
// 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);
}
if (CantHandle) continue;
- IAPrinterMap[I->first].push_back(IAP);
+ IAPrinterMap[Aliases.first].push_back(IAP);
}
}