[llvm] r330983 - [mips] Accept 32-bit offsets for lb and lbu commands

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 26 12:55:28 PDT 2018


Author: atanasyan
Date: Thu Apr 26 12:55:28 2018
New Revision: 330983

URL: http://llvm.org/viewvc/llvm-project?rev=330983&view=rev
Log:
[mips] Accept 32-bit offsets for lb and lbu commands

`lb` and `lbu` commands accepts 16-bit signed offsets. But GAS accepts
larger offsets for these commands. If an offset does not fit in 16-bit
range, `lb` command is translated into lui/lb or lui/addu/lb series.
It's interesting that initially LLVM assembler supported this feature,
but later it was broken.

This patch restores support for 32-bit offsets. It replaces `mem_simm16`
operand for `LB` and `LBu` definitions by the new `mem_simmptr` operand.
This operand is intended to check that offset fits to the same size as
using for pointers. Later we will be able to extend this rule and
accepts 64-bit offsets when it is possible.

Some issues remain:
- The regression also affects LD, SD, LH, LHU commands. I'm going
  to fix them by a separate patch.

- GAS accepts any 32-bit values as an offset. Now LLVM accepts signed
  16-bit values and this patch extends the range to signed 32-bit offsets.
  In other words, the following code accepted by GAS and still triggers
  an error by LLVM:
```
  lb      $4, 0x80000004

  # gas
  lui     a0, 0x8000
    lb      a0, 4(a0)
```

- In case of 64-bit pointers GAS accepts a 64-bit offset and translates
  it to the li/dsll/lb series of commands. LLVM still rejects it.
  Probably this feature has never been implemented in LLVM. This issue
  is for a separate patch.
```
  lb      $4, 0x800000001

  # gas
  li      a0, 0x8000
  dsll    a0, a0, 0x14
  lb      a0, 4(a0)
```

Differential Revision: https://reviews.llvm.org/D45020

Modified:
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
    llvm/trunk/test/MC/Mips/micromips/invalid.s
    llvm/trunk/test/MC/Mips/micromips32r6/invalid.s
    llvm/trunk/test/MC/Mips/mips-expansions.s
    llvm/trunk/test/MC/Mips/mips32r5/invalid.s
    llvm/trunk/test/MC/Mips/mips32r6/invalid.s
    llvm/trunk/test/MC/Mips/mips64r5/invalid.s
    llvm/trunk/test/MC/Mips/mips64r6/invalid.s

Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=330983&r1=330982&r2=330983&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Thu Apr 26 12:55:28 2018
@@ -1303,6 +1303,20 @@ public:
     return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
   }
 
+  bool isMemWithPtrSizeOffset() const {
+    if (!isMem())
+      return false;
+    if (!getMemBase()->isGPRAsmReg())
+      return false;
+    const unsigned PtrBits = 32;
+    if (isa<MCTargetExpr>(getMemOff()) ||
+        (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
+      return true;
+    MCValue Res;
+    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
+    return IsReloc && isIntN(PtrBits, Res.getConstant());
+  }
+
   bool isMemWithGRPMM16Base() const {
     return isMem() && getMemBase()->isMM16AsmReg();
   }
@@ -5452,6 +5466,9 @@ bool MipsAsmParser::MatchAndEmitInstruct
   case Match_MemSImm16:
     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
                  "expected memory with 16-bit signed offset");
+  case Match_MemSImmPtr:
+    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+                 "expected memory with 32-bit signed offset");
   case Match_RequiresPosSizeRange0_32: {
     SMLoc ErrorStart = Operands[3]->getStartLoc();
     SMLoc ErrorEnd = Operands[4]->getEndLoc();

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=330983&r1=330982&r2=330983&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Thu Apr 26 12:55:28 2018
@@ -1108,6 +1108,15 @@ def MipsMemSimm16AsmOperand : AsmOperand
   let DiagnosticType = "MemSImm16";
 }
 
+def MipsMemSimmPtrAsmOperand : AsmOperandClass {
+  let Name = "MemOffsetSimmPtr";
+  let SuperClasses = [MipsMemAsmOperand];
+  let RenderMethod = "addMemOperands";
+  let ParserMethod = "parseMemOperand";
+  let PredicateMethod = "isMemWithPtrSizeOffset";
+  let DiagnosticType = "MemSImmPtr";
+}
+
 def MipsInvertedImmoperand : AsmOperandClass {
   let Name = "InvNum";
   let RenderMethod = "addImmOperands";
@@ -1181,6 +1190,10 @@ def mem_simm16 : mem_generic {
   let ParserMatchClass = MipsMemSimm16AsmOperand;
 }
 
+def mem_simmptr : mem_generic {
+  let ParserMatchClass = MipsMemSimmPtrAsmOperand;
+}
+
 def mem_ea : Operand<iPTR> {
   let PrintMethod = "printMemOperandEA";
   let MIOperandInfo = (ops ptr_rc, simm16);
@@ -1997,9 +2010,9 @@ let AdditionalPredicates = [NotInMicroMi
 
 /// Load and Store Instructions
 ///  aligned
-def LB  : LoadMemory<"lb", GPR32Opnd, mem_simm16, sextloadi8, II_LB>, MMRel,
+def LB  : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
           LW_FM<0x20>;
-def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simm16, zextloadi8, II_LBU,
+def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
                      addrDefault>, MMRel, LW_FM<0x24>;
 let AdditionalPredicates = [NotInMicroMips] in {
   def LH  : LoadMemory<"lh", GPR32Opnd, mem_simm16, sextloadi16, II_LH,

Modified: llvm/trunk/test/MC/Mips/micromips/invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/micromips/invalid.s?rev=330983&r1=330982&r2=330983&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/micromips/invalid.s (original)
+++ llvm/trunk/test/MC/Mips/micromips/invalid.s Thu Apr 26 12:55:28 2018
@@ -121,10 +121,10 @@
   xori $3, 65536      # CHECK: :[[@LINE]]:12: error: expected 16-bit unsigned immediate
   not $3, 4           # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
   lb $32, 8($5)       # CHECK: :[[@LINE]]:6: error: invalid register number
-  lb $4, -32769($5)   # CHECK: :[[@LINE]]:10: error: expected memory with 16-bit signed offset
-  lb $4, 32768($5)    # CHECK: :[[@LINE]]:10: error: expected memory with 16-bit signed offset
+  lb $4, -2147483649($5)  # CHECK: :[[@LINE]]:10: error: expected memory with 32-bit signed offset
+  lb $4, 2147483648($5)   # CHECK: :[[@LINE]]:10: error: expected memory with 32-bit signed offset
   lb $4, 8($32)       # CHECK: :[[@LINE]]:12: error: invalid register number
   lbu $32, 8($5)      # CHECK: :[[@LINE]]:7: error: invalid register number
-  lbu $4, -32769($5)  # CHECK: :[[@LINE]]:11: error: expected memory with 16-bit signed offset
-  lbu $4, 32768($5)   # CHECK: :[[@LINE]]:11: error: expected memory with 16-bit signed offset
+  lbu $4, -2147483649($5) # CHECK: :[[@LINE]]:11: error: expected memory with 32-bit signed offset
+  lbu $4, 2147483648($5)  # CHECK: :[[@LINE]]:11: error: expected memory with 32-bit signed offset
   lbu $4, 8($32)      # CHECK: :[[@LINE]]:13: error: invalid register number

Modified: llvm/trunk/test/MC/Mips/micromips32r6/invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/micromips32r6/invalid.s?rev=330983&r1=330982&r2=330983&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/micromips32r6/invalid.s (original)
+++ llvm/trunk/test/MC/Mips/micromips32r6/invalid.s Thu Apr 26 12:55:28 2018
@@ -253,12 +253,12 @@
   xori $3, 65536           # CHECK: :[[@LINE]]:12: error: expected 16-bit unsigned immediate
   not $3, 4                # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
   lb $32, 8($5)            # CHECK: :[[@LINE]]:6: error: invalid register number
-  lb $4, -32769($5)        # CHECK: :[[@LINE]]:10: error: expected memory with 16-bit signed offset
-  lb $4, 32768($5)         # CHECK: :[[@LINE]]:10: error: expected memory with 16-bit signed offset
+  lb $4, -2147483649($5)   # CHECK: :[[@LINE]]:10: error: expected memory with 32-bit signed offset
+  lb $4, 2147483648($5)    # CHECK: :[[@LINE]]:10: error: expected memory with 32-bit signed offset
   lb $4, 8($32)            # CHECK: :[[@LINE]]:12: error: invalid register number
   lbu $32, 8($5)           # CHECK: :[[@LINE]]:7: error: invalid register number
-  lbu $4, -32769($5)       # CHECK: :[[@LINE]]:11: error: expected memory with 16-bit signed offset
-  lbu $4, 32768($5)        # CHECK: :[[@LINE]]:11: error: expected memory with 16-bit signed offset
+  lbu $4, -2147483649($5)  # CHECK: :[[@LINE]]:11: error: expected memory with 32-bit signed offset
+  lbu $4, 2147483648($5)   # CHECK: :[[@LINE]]:11: error: expected memory with 32-bit signed offset
   lbu $4, 8($32)           # CHECK: :[[@LINE]]:13: error: invalid register number
   ldc1 $f32, 300($10)      # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
   ldc1 $f7, -32769($10)    # CHECK: :[[@LINE]]:13: error: expected memory with 16-bit signed offset

Modified: llvm/trunk/test/MC/Mips/mips-expansions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips-expansions.s?rev=330983&r1=330982&r2=330983&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips-expansions.s (original)
+++ llvm/trunk/test/MC/Mips/mips-expansions.s Thu Apr 26 12:55:28 2018
@@ -13,6 +13,24 @@
 # CHECK-LE: addiu   $8, $8, %lo($tmp0)    # encoding: [A,A,0x08,0x25]
 # CHECK-LE:                               #   fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16
 
+  lb $4, 0x8000
+# CHECK-LE: lui     $4, 1                   # encoding: [0x01,0x00,0x04,0x3c]
+# CHECK-LE: lb      $4, -32768($4)          # encoding: [0x00,0x80,0x84,0x80]
+
+  lb  $4, 0x20004($3)
+# CHECK-LE: lui     $4, 2                   # encoding: [0x02,0x00,0x04,0x3c]
+# CHECK-LE: addu    $4, $4, $3              # encoding: [0x21,0x20,0x83,0x00]
+# CHECK-LE: lb      $4, 4($4)               # encoding: [0x04,0x00,0x84,0x80]
+
+  lbu $4, 0x8000
+# CHECK-LE: lui     $4, 1                   # encoding: [0x01,0x00,0x04,0x3c]
+# CHECK-LE: lbu     $4, -32768($4)          # encoding: [0x00,0x80,0x84,0x90]
+
+  lbu  $4, 0x20004($3)
+# CHECK-LE: lui     $4, 2                   # encoding: [0x02,0x00,0x04,0x3c]
+# CHECK-LE: addu    $4, $4, $3              # encoding: [0x21,0x20,0x83,0x00]
+# CHECK-LE: lbu     $4, 4($4)               # encoding: [0x04,0x00,0x84,0x90]
+
 # LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst():
   .set noat
   lw $10, symbol($4)

Modified: llvm/trunk/test/MC/Mips/mips32r5/invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips32r5/invalid.s?rev=330983&r1=330982&r2=330983&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips32r5/invalid.s (original)
+++ llvm/trunk/test/MC/Mips/mips32r5/invalid.s Thu Apr 26 12:55:28 2018
@@ -21,12 +21,12 @@
         mfc2  $4, $3, -1     # CHECK: :[[@LINE]]:23: error: expected 3-bit unsigned immediate
         mfc2  $4, $3, 8      # CHECK: :[[@LINE]]:23: error: expected 3-bit unsigned immediate
         lb $32, 8($5)        # CHECK: :[[@LINE]]:12: error: invalid register number
-        lb $4, -32769($5)    # CHECK: :[[@LINE]]:16: error: expected memory with 16-bit signed offset
-        lb $4, 32768($5)     # CHECK: :[[@LINE]]:16: error: expected memory with 16-bit signed offset
+        lb $4, -2147483649($5)  # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset
+        lb $4, 2147483648($5)   # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset
         lb $4, 8($32)        # CHECK: :[[@LINE]]:18: error: invalid register number
         lbu $32, 8($5)       # CHECK: :[[@LINE]]:13: error: invalid register number
-        lbu $4, -32769($5)   # CHECK: :[[@LINE]]:17: error: expected memory with 16-bit signed offset
-        lbu $4, 32768($5)    # CHECK: :[[@LINE]]:17: error: expected memory with 16-bit signed offset
+        lbu $4, -2147483649($5) # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset
+        lbu $4, 2147483648($5)  # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset
         lbu $4, 8($32)       # CHECK: :[[@LINE]]:19: error: invalid register number
         ldc1 $f32, 300($10)   # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
         ldc1 $f7, -32769($10) # CHECK: :[[@LINE]]:19: error: expected memory with 16-bit signed offset

Modified: llvm/trunk/test/MC/Mips/mips32r6/invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips32r6/invalid.s?rev=330983&r1=330982&r2=330983&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips32r6/invalid.s (original)
+++ llvm/trunk/test/MC/Mips/mips32r6/invalid.s Thu Apr 26 12:55:28 2018
@@ -146,12 +146,12 @@ local_label:
         sync -1              # CHECK: :[[@LINE]]:14: error: expected 5-bit unsigned immediate
         sync 32              # CHECK: :[[@LINE]]:14: error: expected 5-bit unsigned immediate
         lb $32, 8($5)        # CHECK: :[[@LINE]]:12: error: invalid register number
-        lb $4, -32769($5)    # CHECK: :[[@LINE]]:16: error: expected memory with 16-bit signed offset
-        lb $4, 32768($5)     # CHECK: :[[@LINE]]:16: error: expected memory with 16-bit signed offset
+        lb $4, -2147483649($5)  # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset
+        lb $4, 2147483648($5)   # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset
         lb $4, 8($32)        # CHECK: :[[@LINE]]:18: error: invalid register number
         lbu $32, 8($5)       # CHECK: :[[@LINE]]:13: error: invalid register number
-        lbu $4, -32769($5)   # CHECK: :[[@LINE]]:17: error: expected memory with 16-bit signed offset
-        lbu $4, 32768($5)    # CHECK: :[[@LINE]]:17: error: expected memory with 16-bit signed offset
+        lbu $4, -2147483649($5) # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset
+        lbu $4, 2147483648($5)  # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset
         lbu $4, 8($32)       # CHECK: :[[@LINE]]:19: error: invalid register number
         ldc1 $f32, 300($10)   # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
         ldc1 $f7, -32769($10) # CHECK: :[[@LINE]]:19: error: expected memory with 16-bit signed offset

Modified: llvm/trunk/test/MC/Mips/mips64r5/invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips64r5/invalid.s?rev=330983&r1=330982&r2=330983&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips64r5/invalid.s (original)
+++ llvm/trunk/test/MC/Mips/mips64r5/invalid.s Thu Apr 26 12:55:28 2018
@@ -20,12 +20,12 @@
         dmfc0  $4, $3, 8     # CHECK: :[[@LINE]]:24: error: expected 3-bit unsigned immediate
         sd $32, 65536($32)   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number
         lb $32, 8($5)        # CHECK: :[[@LINE]]:12: error: invalid register number
-        lb $4, -32769($5)    # CHECK: :[[@LINE]]:16: error: expected memory with 16-bit signed offset
-        lb $4, 32768($5)     # CHECK: :[[@LINE]]:16: error: expected memory with 16-bit signed offset
+        lb $4, -2147483649($5)    # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset
+        lb $4, 2147483648($5)     # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset
         lb $4, 8($32)        # CHECK: :[[@LINE]]:18: error: invalid register number
         lbu $32, 8($5)       # CHECK: :[[@LINE]]:13: error: invalid register number
-        lbu $4, -32769($5)   # CHECK: :[[@LINE]]:17: error: expected memory with 16-bit signed offset
-        lbu $4, 32768($5)    # CHECK: :[[@LINE]]:17: error: expected memory with 16-bit signed offset
+        lbu $4, -2147483649($5)   # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset
+        lbu $4, 2147483648($5)    # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset
         lbu $4, 8($32)       # CHECK: :[[@LINE]]:19: error: invalid register number
         ldc1 $f32, 300($10)   # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
         ldc1 $f7, -32769($10) # CHECK: :[[@LINE]]:19: error: expected memory with 16-bit signed offset

Modified: llvm/trunk/test/MC/Mips/mips64r6/invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips64r6/invalid.s?rev=330983&r1=330982&r2=330983&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips64r6/invalid.s (original)
+++ llvm/trunk/test/MC/Mips/mips64r6/invalid.s Thu Apr 26 12:55:28 2018
@@ -195,12 +195,12 @@ local_label:
         dsrlv $2, $4, 2      # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
         dsrlv $32, $32, $32  # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number
         lb $32, 8($5)        # CHECK: :[[@LINE]]:12: error: invalid register number
-        lb $4, -32769($5)    # CHECK: :[[@LINE]]:16: error: expected memory with 16-bit signed offset
-        lb $4, 32768($5)     # CHECK: :[[@LINE]]:16: error: expected memory with 16-bit signed offset
+        lb $4, -2147483649($5)    # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset
+        lb $4, 2147483648($5)     # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset
         lb $4, 8($32)        # CHECK: :[[@LINE]]:18: error: invalid register number
         lbu $32, 8($5)       # CHECK: :[[@LINE]]:13: error: invalid register number
-        lbu $4, -32769($5)   # CHECK: :[[@LINE]]:17: error: expected memory with 16-bit signed offset
-        lbu $4, 32768($5)    # CHECK: :[[@LINE]]:17: error: expected memory with 16-bit signed offset
+        lbu $4, -2147483649($5)   # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset
+        lbu $4, 2147483648($5)    # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset
         lbu $4, 8($32)       # CHECK: :[[@LINE]]:19: error: invalid register number
         ldc1 $f32, 300($10)   # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
         ldc1 $f7, -32769($10) # CHECK: :[[@LINE]]:19: error: expected memory with 16-bit signed offset




More information about the llvm-commits mailing list