[llvm] r284485 - [mips][ias] Handle more complicated expressions for memory operands

Simon Dardis via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 18 08:17:17 PDT 2016


Author: sdardis
Date: Tue Oct 18 10:17:17 2016
New Revision: 284485

URL: http://llvm.org/viewvc/llvm-project?rev=284485&view=rev
Log:
[mips][ias] Handle more complicated expressions for memory operands

This patch teaches ias for mips to handle expressions such as
(8*4)+(8*31)($sp). Such expression typically occur from the expansion
of multiple macro definitions.

This partially resolves PR/30383.

Thanks to Sean Bruno for reporting the issue!

Reviewers: zoran.jovanovic, vkalintiris

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

Added:
    llvm/trunk/test/MC/Mips/memory-offsets.s
Modified:
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

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=284485&r1=284484&r2=284485&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Tue Oct 18 10:17:17 2016
@@ -4553,8 +4553,60 @@ MipsAsmParser::parseMemOperand(OperandVe
             MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
         return MatchOperand_Success;
       }
-      Error(Parser.getTok().getLoc(), "'(' expected");
-      return MatchOperand_ParseFail;
+      MCBinaryExpr::Opcode Opcode;
+      // GAS and LLVM treat comparison operators different. GAS will generate -1
+      // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
+      // highly unlikely to be found in a memory offset expression, we don't
+      // handle them.
+      switch (Tok.getKind()) {
+      case AsmToken::Plus:
+        Opcode = MCBinaryExpr::Add;
+        Parser.Lex();
+        break;
+      case AsmToken::Minus:
+        Opcode = MCBinaryExpr::Sub;
+        Parser.Lex();
+        break;
+      case AsmToken::Star:
+        Opcode = MCBinaryExpr::Mul;
+        Parser.Lex();
+        break;
+      case AsmToken::Pipe:
+        Opcode = MCBinaryExpr::Or;
+        Parser.Lex();
+        break;
+      case AsmToken::Amp:
+        Opcode = MCBinaryExpr::And;
+        Parser.Lex();
+        break;
+      case AsmToken::LessLess:
+        Opcode = MCBinaryExpr::Shl;
+        Parser.Lex();
+        break;
+      case AsmToken::GreaterGreater:
+        Opcode = MCBinaryExpr::LShr;
+        Parser.Lex();
+        break;
+      case AsmToken::Caret:
+        Opcode = MCBinaryExpr::Xor;
+        Parser.Lex();
+        break;
+      case AsmToken::Slash:
+        Opcode = MCBinaryExpr::Div;
+        Parser.Lex();
+        break;
+      case AsmToken::Percent:
+        Opcode = MCBinaryExpr::Mod;
+        Parser.Lex();
+        break;
+      default:
+        Error(Parser.getTok().getLoc(), "'(' or expression expected");
+        return MatchOperand_ParseFail;
+      }
+      const MCExpr * NextExpr;
+      if (getParser().parseExpression(NextExpr))
+        return MatchOperand_ParseFail;
+      IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
     }
 
     Parser.Lex(); // Eat the '(' token.

Added: llvm/trunk/test/MC/Mips/memory-offsets.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/memory-offsets.s?rev=284485&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/memory-offsets.s (added)
+++ llvm/trunk/test/MC/Mips/memory-offsets.s Tue Oct 18 10:17:17 2016
@@ -0,0 +1,33 @@
+# RUN: llvm-mc -arch=mips -mcpu=mips32 -show-encoding %s | FileCheck %s
+
+# Check that parseMemOperand handles expressions such as <int>, (<int>),
+# <expr>, <expr> op <expr>, (<expr>) op (<expr>).
+
+    .global __start
+    .ent    __start
+__start:
+    lw $31, ($29)                       # CHECK: lw  $ra, 0($sp)      # encoding: [0x8f,0xbf,0x00,0x00]
+    lw $31, 0($29)                      # CHECK: lw  $ra, 0($sp)      # encoding: [0x8f,0xbf,0x00,0x00]
+    lw $31, (8)($29)                    # CHECK: lw  $ra, 8($sp)      # encoding: [0x8f,0xbf,0x00,0x08]
+    lw $31, 3 + (4 * 8)($29)            # CHECK: lw  $ra, 35($sp)     # encoding: [0x8f,0xbf,0x00,0x23]
+    lw $31, (8 + 8)($29)                # CHECK: lw  $ra, 16($sp)     # encoding: [0x8f,0xbf,0x00,0x10]
+    lw $31, (8 << 4)($29)               # CHECK: lw  $ra, 128($sp)    # encoding: [0x8f,0xbf,0x00,0x80]
+    lw $31, (32768 >> 2)($29)           # CHECK: lw  $ra, 8192($sp)   # encoding: [0x8f,0xbf,0x20,0x00]
+    lw $31, 32768 >> 2($29)             # CHECK: lw  $ra, 8192($sp)   # encoding: [0x8f,0xbf,0x20,0x00]
+    lw $31, 2 << 3($29)                 # CHECK: lw  $ra, 16($sp)     # encoding: [0x8f,0xbf,0x00,0x10]
+    lw $31, (2 << 3)($29)               # CHECK: lw  $ra, 16($sp)     # encoding: [0x8f,0xbf,0x00,0x10]
+    lw $31, 4 - (4 * 8)($29)            # CHECK: lw  $ra, -28($sp)    # encoding: [0x8f,0xbf,0xff,0xe4]
+    lw $31, 4 | 8 ($29)                 # CHECK: lw  $ra, 12($sp)     # encoding: [0x8f,0xbf,0x00,0x0c]
+    lw $31, 4 || 8 ($29)                # CHECK: lw  $ra, 1($sp)      # encoding: [0x8f,0xbf,0x00,0x01]
+    lw $31, 8 & 8 ($29)                 # CHECK: lw  $ra, 8($sp)      # encoding: [0x8f,0xbf,0x00,0x08]
+    lw $31, (8 * 4) ^ (8 * 31)($29)     # CHECK: lw  $ra, 216($sp)    # encoding: [0x8f,0xbf,0x00,0xd8]
+    lw $31, (8 * 4) / (8 * 31)($29)     # CHECK: lw  $ra, 0($sp)      # encoding: [0x8f,0xbf,0x00,0x00]
+    lw $31, (8 * 4) % (8 * 31)($29)     # CHECK: lw  $ra, 32($sp)     # encoding: [0x8f,0xbf,0x00,0x20]
+    lw $31, (8 * 4) % (8)($29)          # CHECK: lw  $ra, 0($sp)      # encoding: [0x8f,0xbf,0x00,0x00]
+    lw $31, (8 * 4) + (8 * 31) ($29)    # CHECK: lw  $ra, 280($sp)    # encoding: [0x8f,0xbf,0x01,0x18]
+    lw $31, (8*4) + (8*31) + (8*32 + __start) ($29) # CHECK:  lui $ra, %hi((248+((8*32)+__start))+32) # encoding: [0x3c,0x1f,A,A]
+                                                    # CHECK:                                #   fixup A - offset: 0, value: %hi((248+((8*32)+__start))+32), kind: fixup_Mips_HI16
+                                                    # CHECK:  addu  $ra, $ra, $sp           # encoding: [0x03,0xfd,0xf8,0x21]
+                                                    # CHECK:  lw  $ra, %lo((248+((8*32)+__start))+32)($ra) # encoding: [0x8f,0xff,A,A]
+                                                    # CHECK:                                #   fixup A - offset: 0, value: %lo((248+((8*32)+__start))+32), kind: fixup_Mips_LO16
+    .end __start




More information about the llvm-commits mailing list