forked from OSchip/llvm-project
[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 llvm-svn: 284485
This commit is contained in:
parent
af6ff2a91b
commit
858915f054
|
@ -4553,8 +4553,60 @@ MipsAsmParser::parseMemOperand(OperandVector &Operands) {
|
|||
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.
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue