[PowerPC] Support basic compare mnemonics
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Mon, 8 Jul 2013 14:49:37 +0000 (14:49 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Mon, 8 Jul 2013 14:49:37 +0000 (14:49 +0000)
This adds support for the basic mnemoics (with the L operand) for the
fixed-point compare instructions.  These are defined as aliases for the
already existing CMPW/CMPD patterns, depending on the value of L.

This requires use of InstAlias patterns with immediate literal operands.
To make this work, we need two further changes:

 - define a RegisterPrefix, because otherwise literals 0 and 1 would
   be parsed as literal register names

 - provide a PPCAsmParser::validateTargetOperandClass routine to
   recognize immediate literals (like ARM does)

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

lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
lib/Target/PowerPC/PPC.td
lib/Target/PowerPC/PPCInstrInfo.td
test/MC/PowerPC/ppc64-encoding.s

index 237ecdc60e428e2df53d9f4f70da2b301aa9d2fb..790a98e06db75c8e95952d8dc9c5cf5d848fee3b 100644 (file)
@@ -229,6 +229,8 @@ public:
                                 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
 
   virtual bool ParseDirective(AsmToken DirectiveID);
+
+  unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, unsigned Kind);
 };
 
 /// PPCOperand - Instances of this class represent a parsed PowerPC machine
@@ -1232,3 +1234,25 @@ extern "C" void LLVMInitializePowerPCAsmParser() {
 #define GET_REGISTER_MATCHER
 #define GET_MATCHER_IMPLEMENTATION
 #include "PPCGenAsmMatcher.inc"
+
+// Define this matcher function after the auto-generated include so we
+// have the match class enum definitions.
+unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
+                                                  unsigned Kind) {
+  // If the kind is a token for a literal immediate, check if our asm
+  // operand matches. This is for InstAliases which have a fixed-value
+  // immediate in the syntax.
+  int64_t ImmVal;
+  switch (Kind) {
+    case MCK_0: ImmVal = 0; break;
+    case MCK_1: ImmVal = 1; break;
+    default: return Match_InvalidOperand;
+  }
+
+  PPCOperand *Op = static_cast<PPCOperand*>(AsmOp);
+  if (Op->isImm() && Op->getImm() == ImmVal)
+    return Match_Success;
+
+  return Match_InvalidOperand;
+}
+
index eb73c676ad71db7ab60784628cc7f159d043b95f..d7e2cad961ac4bc935afcd1e41507b2792156378 100644 (file)
@@ -272,10 +272,20 @@ def PPCAsmParser : AsmParser {
   let ShouldEmitMatchRegisterName = 0;
 }
 
+def PPCAsmParserVariant : AsmParserVariant {
+  int Variant = 0;
+
+  // We do not use hard coded registers in asm strings.  However, some
+  // InstAlias definitions use immediate literals.  Set RegisterPrefix
+  // so that those are not misinterpreted as registers.
+  string RegisterPrefix = "%";
+}
+
 def PPC : Target {
   // Information about the instructions.
   let InstructionSet = PPCInstrInfo;
   
   let AssemblyWriters = [PPCAsmWriter];
   let AssemblyParsers = [PPCAsmParser];
+  let AssemblyParserVariants = [PPCAsmParserVariant];
 }
index fbf61f063aa47fec2c0e6293040a22bf82086967..3aafb5c9638675526f2d59614a9df15f355d656b 100644 (file)
@@ -2578,6 +2578,15 @@ def : InstAlias<"cmpd $rA, $rB", (CMPD CR0, g8rc:$rA, g8rc:$rB)>;
 def : InstAlias<"cmpldi $rA, $imm", (CMPLDI CR0, g8rc:$rA, u16imm:$imm)>;
 def : InstAlias<"cmpld $rA, $rB", (CMPLD CR0, g8rc:$rA, g8rc:$rB)>;
 
+def : InstAlias<"cmpi $bf, 0, $rA, $imm", (CMPWI crrc:$bf, gprc:$rA, s16imm:$imm)>;
+def : InstAlias<"cmp $bf, 0, $rA, $rB", (CMPW crrc:$bf, gprc:$rA, gprc:$rB)>;
+def : InstAlias<"cmpli $bf, 0, $rA, $imm", (CMPLWI crrc:$bf, gprc:$rA, u16imm:$imm)>;
+def : InstAlias<"cmpl $bf, 0, $rA, $rB", (CMPLW crrc:$bf, gprc:$rA, gprc:$rB)>;
+def : InstAlias<"cmpi $bf, 1, $rA, $imm", (CMPDI crrc:$bf, g8rc:$rA, s16imm:$imm)>;
+def : InstAlias<"cmp $bf, 1, $rA, $rB", (CMPD crrc:$bf, g8rc:$rA, g8rc:$rB)>;
+def : InstAlias<"cmpli $bf, 1, $rA, $imm", (CMPLDI crrc:$bf, g8rc:$rA, u16imm:$imm)>;
+def : InstAlias<"cmpl $bf, 1, $rA, $rB", (CMPLD crrc:$bf, g8rc:$rA, g8rc:$rB)>;
+
 multiclass TrapExtendedMnemonic<string name, int to> {
   def : InstAlias<"td"#name#"i $rA, $imm", (TDI to, g8rc:$rA, s16imm:$imm)>;
   def : InstAlias<"td"#name#" $rA, $rB", (TD to, g8rc:$rA, g8rc:$rB)>;
index eac039a61bd7c871bae685b9ee704353220ca05f..d82d86fd0102ec767f27b24adc8c6f53997c0915 100644 (file)
 # FIXME: divdeuo 2, 3, 4
 # FIXME: divdeuo. 2, 3, 4
 
-# FIXME: Fixed-point compare instructions
+# Fixed-point compare instructions
+
+# CHECK: cmpdi 2, 3, 128                 # encoding: [0x2d,0x23,0x00,0x80]
+         cmpi 2, 1, 3, 128
+# CHECK: cmpd 2, 3, 4                    # encoding: [0x7d,0x23,0x20,0x00]
+         cmp 2, 1, 3, 4
+# CHECK: cmpldi 2, 3, 128                # encoding: [0x29,0x23,0x00,0x80]
+         cmpli 2, 1, 3, 128
+# CHECK: cmpld 2, 3, 4                   # encoding: [0x7d,0x23,0x20,0x40]
+         cmpl 2, 1, 3, 4
+
+# CHECK: cmpwi 2, 3, 128                 # encoding: [0x2d,0x03,0x00,0x80]
+         cmpi 2, 0, 3, 128
+# CHECK: cmpw 2, 3, 4                    # encoding: [0x7d,0x03,0x20,0x00]
+         cmp 2, 0, 3, 4
+# CHECK: cmplwi 2, 3, 128                # encoding: [0x29,0x03,0x00,0x80]
+         cmpli 2, 0, 3, 128
+# CHECK: cmplw 2, 3, 4                   # encoding: [0x7d,0x03,0x20,0x40]
+         cmpl 2, 0, 3, 4
 
 # Fixed-point trap instructions