[llvm] e1de277 - [SystemZ] Allow specifying plain register numbers in AsmParser

Ulrich Weigand via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 29 11:43:20 PDT 2020


Author: Ulrich Weigand
Date: 2020-04-29T20:42:30+02:00
New Revision: e1de2773a534957305d7a559c6d88c4b5ac354e2

URL: https://github.com/llvm/llvm-project/commit/e1de2773a534957305d7a559c6d88c4b5ac354e2
DIFF: https://github.com/llvm/llvm-project/commit/e1de2773a534957305d7a559c6d88c4b5ac354e2.diff

LOG: [SystemZ] Allow specifying plain register numbers in AsmParser

For compatibility with other assemblers on the platform, allow
using just plain integer register numbers in all places where a
register operand is expected.

Bug: llvm.org/PR45582

Added: 
    

Modified: 
    llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
    llvm/test/MC/SystemZ/regs-bad.s
    llvm/test/MC/SystemZ/regs-good.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index b6c2f837d3eb..a3110248e8e0 100644
--- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -748,45 +748,86 @@ bool SystemZAsmParser::parseRegister(Register &Reg, bool RestoreOnFailure) {
 // Parse a register of kind Kind and add it to Operands.
 OperandMatchResultTy
 SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterKind Kind) {
-  if (Parser.getTok().isNot(AsmToken::Percent))
-    return MatchOperand_NoMatch;
+  SMLoc StartLoc, EndLoc;
+  unsigned RegNum;
 
-  Register Reg;
-  if (parseRegister(Reg))
-    return MatchOperand_ParseFail;
+  // Handle register names of the form %<prefix><number>.
+  if (Parser.getTok().is(AsmToken::Percent)) {
+    Register Reg;
+    if (parseRegister(Reg))
+      return MatchOperand_ParseFail;
 
-  // Verify that a register prefix appropriate for Kind was used.
-  bool PrefixMatch;
-  switch (Kind) {
-  case GR32Reg:
-  case GRH32Reg:
-  case GR64Reg:
-  case GR128Reg:
-    PrefixMatch = Reg.Group == RegGR;
-    break;
-  case FP32Reg:
-  case FP64Reg:
-  case FP128Reg:
-    PrefixMatch = Reg.Group == RegFP;
-    break;
-  case VR32Reg:
-  case VR64Reg:
-  case VR128Reg:
-    // It is OK to use the %f prefix with vector instructions that
-    // expect some VR..Reg kind, so accept the RegFP group as well.
-    PrefixMatch = Reg.Group == RegV || Reg.Group == RegFP;
-    break;
-  case AR32Reg:
-    PrefixMatch = Reg.Group == RegAR;
-    break;
-  case CR64Reg:
-    PrefixMatch = Reg.Group == RegCR;
-    break;
+    // Verify that a register prefix appropriate for Kind was used.
+    bool PrefixMatch;
+    switch (Kind) {
+    case GR32Reg:
+    case GRH32Reg:
+    case GR64Reg:
+    case GR128Reg:
+      PrefixMatch = Reg.Group == RegGR;
+      break;
+    case FP32Reg:
+    case FP64Reg:
+    case FP128Reg:
+      PrefixMatch = Reg.Group == RegFP;
+      break;
+    case VR32Reg:
+    case VR64Reg:
+    case VR128Reg:
+      // It is OK to use the %f prefix with vector instructions that
+      // expect some VR..Reg kind, so accept the RegFP group as well.
+      PrefixMatch = Reg.Group == RegV || Reg.Group == RegFP;
+      break;
+    case AR32Reg:
+      PrefixMatch = Reg.Group == RegAR;
+      break;
+    case CR64Reg:
+      PrefixMatch = Reg.Group == RegCR;
+      break;
+    }
+    if (!PrefixMatch) {
+      Error(Reg.StartLoc, "invalid operand for instruction");
+      return MatchOperand_ParseFail;
+    }
+
+    RegNum = Reg.Num;
+    StartLoc = Reg.StartLoc;
+    EndLoc = Reg.EndLoc;
   }
-  if (!PrefixMatch) {
-    Error(Reg.StartLoc, "invalid operand for instruction");
-    return MatchOperand_ParseFail;
+  // Also allow specifying just a plain register number as integer.
+  else if (Parser.getTok().is(AsmToken::Integer)) {
+    const MCExpr *Register;
+    StartLoc = Parser.getTok().getLoc();
+    if (Parser.parseExpression(Register))
+      return MatchOperand_ParseFail;
+
+    auto *CE = dyn_cast<MCConstantExpr>(Register);
+    if (!CE)
+      return MatchOperand_ParseFail;
+
+    int64_t MaxRegNum;
+    switch (Kind) {
+    case VR32Reg:
+    case VR64Reg:
+    case VR128Reg:
+      MaxRegNum = 31;
+      break;
+    default:
+      MaxRegNum = 15;
+      break;
+    }
+    int64_t Value = CE->getValue();
+    if (Value < 0 || Value > MaxRegNum) {
+      Error(StartLoc, "invalid register");
+      return MatchOperand_ParseFail;
+    }
+    RegNum = (unsigned) Value;
+
+    EndLoc = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
   }
+  // Otherwise we didn't match a register operand.
+  else
+    return MatchOperand_NoMatch;
 
   // Determine the LLVM register number according to Kind.
   const unsigned *Regs;
@@ -804,13 +845,13 @@ SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterKind Kind) {
   case AR32Reg:  Regs = SystemZMC::AR32Regs;  break;
   case CR64Reg:  Regs = SystemZMC::CR64Regs;  break;
   }
-  if (Regs[Reg.Num] == 0) {
-    Error(Reg.StartLoc, "invalid register pair");
+  if (Regs[RegNum] == 0) {
+    Error(StartLoc, "invalid register pair");
     return MatchOperand_ParseFail;
   }
 
-  Operands.push_back(SystemZOperand::createReg(Kind, Regs[Reg.Num],
-                                               Reg.StartLoc, Reg.EndLoc));
+  Operands.push_back(SystemZOperand::createReg(Kind, Regs[RegNum],
+                                               StartLoc, EndLoc));
   return MatchOperand_Success;
 }
 

diff  --git a/llvm/test/MC/SystemZ/regs-bad.s b/llvm/test/MC/SystemZ/regs-bad.s
index c4d16ef4cc3d..db56af96638b 100644
--- a/llvm/test/MC/SystemZ/regs-bad.s
+++ b/llvm/test/MC/SystemZ/regs-bad.s
@@ -15,9 +15,9 @@
 #CHECK: lr	%r0,%a1
 #CHECK: error: invalid operand for instruction
 #CHECK: lr	%r0,%c1
-#CHECK: error: invalid operand for instruction
-#CHECK: lr	%r0,0
-#CHECK: error: invalid operand for instruction
+#CHECK: error: invalid register
+#CHECK: lr	%r0,16
+#CHECK: error: unexpected token in argument list
 #CHECK: lr	%r0,0(%r1)
 
 	lr	%f0,%r1
@@ -26,7 +26,7 @@
 	lr	%r0,%f1
 	lr	%r0,%a1
 	lr	%r0,%c1
-	lr	%r0,0
+	lr	%r0,16
 	lr	%r0,0(%r1)
 
 # Test GR64 operands
@@ -43,9 +43,9 @@
 #CHECK: lgr	%r0,%a1
 #CHECK: error: invalid operand for instruction
 #CHECK: lgr	%r0,%c1
-#CHECK: error: invalid operand for instruction
-#CHECK: lgr	%r0,0
-#CHECK: error: invalid operand for instruction
+#CHECK: error: invalid register
+#CHECK: lgr	%r0,16
+#CHECK: error: unexpected token in argument list
 #CHECK: lgr	%r0,0(%r1)
 
 	lgr	%f0,%r1
@@ -54,7 +54,7 @@
 	lgr	%r0,%f1
 	lgr	%r0,%a1
 	lgr	%r0,%c1
-	lgr	%r0,0
+	lgr	%r0,16
 	lgr	%r0,0(%r1)
 
 # Test GR128 operands
@@ -87,9 +87,9 @@
 #CHECK: dlr	%r0,%a1
 #CHECK: error: invalid operand for instruction
 #CHECK: dlr	%r0,%c1
-#CHECK: error: invalid operand for instruction
-#CHECK: dlr	%r0,0
-#CHECK: error: invalid operand for instruction
+#CHECK: error: invalid register
+#CHECK: dlr	%r0,16
+#CHECK: error: unexpected token in argument list
 #CHECK: dlr	%r0,0(%r1)
 
 	dlr	%r1,%r0
@@ -106,7 +106,7 @@
 	dlr	%r0,%f1
 	dlr	%r0,%a1
 	dlr	%r0,%c1
-	dlr	%r0,0
+	dlr	%r0,16
 	dlr	%r0,0(%r1)
 
 # Test FP32 operands
@@ -123,9 +123,9 @@
 #CHECK: ler	%f0,%a1
 #CHECK: error: invalid operand for instruction
 #CHECK: ler	%f0,%c1
-#CHECK: error: invalid operand for instruction
-#CHECK: ler	%f0,0
-#CHECK: error: invalid operand for instruction
+#CHECK: error: invalid register
+#CHECK: ler	%f0,16
+#CHECK: error: unexpected token in argument list
 #CHECK: ler	%f0,0(%r1)
 
 	ler	%r0,%f1
@@ -134,7 +134,7 @@
 	ler	%f0,%r1
 	ler	%f0,%a1
 	ler	%f0,%c1
-	ler	%f0,0
+	ler	%f0,16
 	ler	%f0,0(%r1)
 
 # Test FP64 operands
@@ -151,9 +151,9 @@
 #CHECK: ldr	%f0,%a1
 #CHECK: error: invalid operand for instruction
 #CHECK: ldr	%f0,%c1
-#CHECK: error: invalid operand for instruction
-#CHECK: ldr	%f0,0
-#CHECK: error: invalid operand for instruction
+#CHECK: error: invalid register
+#CHECK: ldr	%f0,16
+#CHECK: error: unexpected token in argument list
 #CHECK: ldr	%f0,0(%r1)
 
 	ldr	%r0,%f1
@@ -162,7 +162,7 @@
 	ldr	%f0,%r1
 	ldr	%f0,%a1
 	ldr	%f0,%c1
-	ldr	%f0,0
+	ldr	%f0,16
 	ldr	%f0,0(%r1)
 
 # Test FP128 operands
@@ -195,9 +195,9 @@
 #CHECK: lxr	%f0,%a1
 #CHECK: error: invalid operand for instruction
 #CHECK: lxr	%f0,%c1
-#CHECK: error: invalid operand for instruction
-#CHECK: lxr	%f0,0
-#CHECK: error: invalid operand for instruction
+#CHECK: error: invalid register
+#CHECK: lxr	%f0,16
+#CHECK: error: unexpected token in argument list
 #CHECK: lxr	%f0,0(%r1)
 
 	lxr	%f2,%f0
@@ -214,7 +214,7 @@
 	lxr	%f0,%r1
 	lxr	%f0,%a1
 	lxr	%f0,%c1
-	lxr	%f0,0
+	lxr	%f0,16
 	lxr	%f0,0(%r1)
 
 # Test access register operands
@@ -225,15 +225,15 @@
 #CHECK: ear	%r0,%f0
 #CHECK: error: invalid operand for instruction
 #CHECK: ear	%r0,%c0
-#CHECK: error: invalid operand for instruction
-#CHECK: ear	%r0,0
-#CHECK: error: invalid operand for instruction
+#CHECK: error: invalid register
+#CHECK: ear	%r0,16
+#CHECK: error: unexpected token in argument list
 #CHECK: ear	%r0,0(%r1)
 
 	ear	%r0,%r0
 	ear	%r0,%f0
 	ear	%r0,%c0
-	ear	%r0,0
+	ear	%r0,16
 	ear	%r0,0(%r1)
 
 # Test control register operands
@@ -242,13 +242,13 @@
 #CHECK: lctl	%c0,%r0,0
 #CHECK: lctl	%c0,%f0,0
 #CHECK: lctl	%c0,%a0,0
-#CHECK: lctl	%c0,0,0
+#CHECK: lctl	%c0,16,0
 #CHECK: lctl	%c0,0(%r1),0
 
 	lctl	%c0,%r0,0
 	lctl	%c0,%f0,0
 	lctl	%c0,%a0,0
-	lctl	%c0,0,0
+	lctl	%c0,16,0
 	lctl	%c0,0(%r1),0
 
 	.cfi_startproc

diff  --git a/llvm/test/MC/SystemZ/regs-good.s b/llvm/test/MC/SystemZ/regs-good.s
index c20301133d87..c6157b5e2c85 100644
--- a/llvm/test/MC/SystemZ/regs-good.s
+++ b/llvm/test/MC/SystemZ/regs-good.s
@@ -8,6 +8,7 @@
 #CHECK: lr	%r10, %r11              # encoding: [0x18,0xab]
 #CHECK: lr	%r12, %r13              # encoding: [0x18,0xcd]
 #CHECK: lr	%r14, %r15              # encoding: [0x18,0xef]
+#CHECK: lr	%r0, %r15               # encoding: [0x18,0x0f]
 
 	lr	%r0,%r1
 	lr	%r2,%r3
@@ -17,6 +18,7 @@
 	lr	%r10,%r11
 	lr	%r12,%r13
 	lr	%r14,%r15
+	lr	0,15
 
 #CHECK: lgr	%r0, %r1                # encoding: [0xb9,0x04,0x00,0x01]
 #CHECK: lgr	%r2, %r3                # encoding: [0xb9,0x04,0x00,0x23]
@@ -26,6 +28,7 @@
 #CHECK: lgr	%r10, %r11              # encoding: [0xb9,0x04,0x00,0xab]
 #CHECK: lgr	%r12, %r13              # encoding: [0xb9,0x04,0x00,0xcd]
 #CHECK: lgr	%r14, %r15              # encoding: [0xb9,0x04,0x00,0xef]
+#CHECK: lgr	%r0, %r15               # encoding: [0xb9,0x04,0x00,0x0f]
 
 	lgr	%r0,%r1
 	lgr	%r2,%r3
@@ -35,6 +38,7 @@
 	lgr	%r10,%r11
 	lgr	%r12,%r13
 	lgr	%r14,%r15
+	lgr	0,15
 
 #CHECK: dlr	%r0, %r0                # encoding: [0xb9,0x97,0x00,0x00]
 #CHECK: dlr	%r2, %r0                # encoding: [0xb9,0x97,0x00,0x20]
@@ -43,6 +47,7 @@
 #CHECK: dlr	%r8, %r0                # encoding: [0xb9,0x97,0x00,0x80]
 #CHECK: dlr	%r10, %r0               # encoding: [0xb9,0x97,0x00,0xa0]
 #CHECK: dlr	%r12, %r0               # encoding: [0xb9,0x97,0x00,0xc0]
+#CHECK: dlr	%r14, %r0               # encoding: [0xb9,0x97,0x00,0xe0]
 #CHECK: dlr	%r14, %r0               # encoding: [0xb9,0x97,0x00,0xe0]
 
 	dlr	%r0,%r0
@@ -53,6 +58,7 @@
 	dlr	%r10,%r0
 	dlr	%r12,%r0
 	dlr	%r14,%r0
+	dlr	14,0
 
 #CHECK: ler	%f0, %f1                # encoding: [0x38,0x01]
 #CHECK: ler	%f2, %f3                # encoding: [0x38,0x23]
@@ -62,6 +68,7 @@
 #CHECK: ler	%f10, %f11              # encoding: [0x38,0xab]
 #CHECK: ler	%f12, %f13              # encoding: [0x38,0xcd]
 #CHECK: ler	%f14, %f15              # encoding: [0x38,0xef]
+#CHECK: ler	%f0, %f15               # encoding: [0x38,0x0f]
 
 	ler	%f0,%f1
 	ler	%f2,%f3
@@ -71,6 +78,7 @@
 	ler	%f10,%f11
 	ler	%f12,%f13
 	ler	%f14,%f15
+	ler	0,15
 
 #CHECK: ldr	%f0, %f1                # encoding: [0x28,0x01]
 #CHECK: ldr	%f2, %f3                # encoding: [0x28,0x23]
@@ -80,6 +88,7 @@
 #CHECK: ldr	%f10, %f11              # encoding: [0x28,0xab]
 #CHECK: ldr	%f12, %f13              # encoding: [0x28,0xcd]
 #CHECK: ldr	%f14, %f15              # encoding: [0x28,0xef]
+#CHECK: ldr	%f0, %f15               # encoding: [0x28,0x0f]
 
 	ldr	%f0,%f1
 	ldr	%f2,%f3
@@ -89,16 +98,19 @@
 	ldr	%f10,%f11
 	ldr	%f12,%f13
 	ldr	%f14,%f15
+	ldr	0,15
 
 #CHECK: lxr	%f0, %f1                # encoding: [0xb3,0x65,0x00,0x01]
 #CHECK: lxr	%f4, %f5                # encoding: [0xb3,0x65,0x00,0x45]
 #CHECK: lxr	%f8, %f9                # encoding: [0xb3,0x65,0x00,0x89]
 #CHECK: lxr	%f12, %f13              # encoding: [0xb3,0x65,0x00,0xcd]
+#CHECK: lxr	%f0, %f13               # encoding: [0xb3,0x65,0x00,0x0d]
 
 	lxr	%f0,%f1
 	lxr	%f4,%f5
 	lxr	%f8,%f9
 	lxr	%f12,%f13
+	lxr	0,13
 
 #CHECK: cpya	%a0, %a1                # encoding: [0xb2,0x4d,0x00,0x01]
 #CHECK: cpya	%a2, %a3                # encoding: [0xb2,0x4d,0x00,0x23]
@@ -108,6 +120,7 @@
 #CHECK: cpya	%a10, %a11              # encoding: [0xb2,0x4d,0x00,0xab]
 #CHECK: cpya	%a12, %a13              # encoding: [0xb2,0x4d,0x00,0xcd]
 #CHECK: cpya	%a14, %a15              # encoding: [0xb2,0x4d,0x00,0xef]
+#CHECK: cpya	%a0, %a15               # encoding: [0xb2,0x4d,0x00,0x0f]
 
 	cpya	%a0,%a1
 	cpya	%a2,%a3
@@ -117,6 +130,7 @@
 	cpya	%a10,%a11
 	cpya	%a12,%a13
 	cpya	%a14,%a15
+	cpya	0,15
 
 #CHECK: lctl	%c0, %c1, 0             # encoding: [0xb7,0x01,0x00,0x00]
 #CHECK: lctl	%c2, %c3, 0             # encoding: [0xb7,0x23,0x00,0x00]
@@ -126,6 +140,7 @@
 #CHECK: lctl	%c10, %c11, 0           # encoding: [0xb7,0xab,0x00,0x00]
 #CHECK: lctl	%c12, %c13, 0           # encoding: [0xb7,0xcd,0x00,0x00]
 #CHECK: lctl	%c14, %c15, 0           # encoding: [0xb7,0xef,0x00,0x00]
+#CHECK: lctl	%c0, %c15, 0            # encoding: [0xb7,0x0f,0x00,0x00]
 
 	lctl	%c0,%c1,0
 	lctl	%c2,%c3,0
@@ -135,6 +150,7 @@
 	lctl	%c10,%c11,0
 	lctl	%c12,%c13,0
 	lctl	%c14,%c15,0
+	lctl	0,15,0
 
 
 #CHECK: .cfi_offset %r0, 0


        


More information about the llvm-commits mailing list