mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
ARM IAS: properly handle expression operands
Operands which involved label arithemetic would previously fail to parse. This corrects that by adding the additional case for the shift operand validation. llvm-svn: 198735
This commit is contained in:
parent
869aa34c78
commit
3374bbd05c
@ -8775,12 +8775,24 @@ unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
|
||||
// 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.
|
||||
if (Kind == MCK__35_0 && Op->isImm()) {
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
|
||||
if (!CE)
|
||||
return Match_InvalidOperand;
|
||||
switch (Kind) {
|
||||
default: break;
|
||||
case MCK__35_0:
|
||||
if (Op->isImm())
|
||||
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()))
|
||||
if (CE->getValue() == 0)
|
||||
return Match_Success;
|
||||
break;
|
||||
case MCK_ARMSOImm:
|
||||
if (Op->isImm()) {
|
||||
const MCExpr *SOExpr = Op->getImm();
|
||||
int64_t Value;
|
||||
if (!SOExpr->EvaluateAsAbsolute(Value))
|
||||
return Match_Success;
|
||||
assert((Value >= INT32_MIN && Value <= INT32_MAX) &&
|
||||
"expression value must be representiable in 32 bits");
|
||||
}
|
||||
break;
|
||||
}
|
||||
return Match_InvalidOperand;
|
||||
}
|
||||
|
@ -307,17 +307,30 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
||||
<< markup(">");
|
||||
} else {
|
||||
assert(Op.isExpr() && "unknown operand kind in printOperand");
|
||||
// If a symbolic branch target was added as a constant expression then print
|
||||
// that address in hex. And only print 32 unsigned bits for the address.
|
||||
const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
|
||||
int64_t Address;
|
||||
if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
|
||||
const MCExpr *Expr = Op.getExpr();
|
||||
switch (Expr->getKind()) {
|
||||
case MCExpr::Binary:
|
||||
O << '#' << *Expr;
|
||||
break;
|
||||
case MCExpr::Constant: {
|
||||
// If a symbolic branch target was added as a constant expression then
|
||||
// print that address in hex. And only print 32 unsigned bits for the
|
||||
// address.
|
||||
const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
|
||||
int64_t TargetAddress;
|
||||
if (!Constant->EvaluateAsAbsolute(TargetAddress)) {
|
||||
O << '#' << *Expr;
|
||||
} else {
|
||||
O << "0x";
|
||||
O.write_hex((uint32_t)Address);
|
||||
O.write_hex(static_cast<uint32_t>(TargetAddress));
|
||||
}
|
||||
else {
|
||||
// Otherwise, just print the expression.
|
||||
O << *Op.getExpr();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// FIXME: Should we always treat this as if it is a constant literal and
|
||||
// prefix it with '#'?
|
||||
O << *Expr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
test/MC/ARM/complex-operands.s
Normal file
40
test/MC/ARM/complex-operands.s
Normal file
@ -0,0 +1,40 @@
|
||||
@ RUN: llvm-mc -triple armv7-eabi -filetype asm -o - %s | FileCheck %s
|
||||
|
||||
.syntax unified
|
||||
|
||||
.data
|
||||
|
||||
.type .L_table_begin,%object
|
||||
.L_table_begin:
|
||||
.rep 2
|
||||
.long 0xd15ab1ed
|
||||
.long 0x0ff1c1a1
|
||||
.endr
|
||||
.L_table_end:
|
||||
|
||||
.text
|
||||
|
||||
.type return,%function
|
||||
return:
|
||||
bx lr
|
||||
|
||||
.global arm_function
|
||||
.type arm_function,%function
|
||||
arm_function:
|
||||
mov r0, #(.L_table_end - .L_table_begin) >> 2
|
||||
blx return
|
||||
|
||||
@ CHECK-LABEL: arm_function
|
||||
@ CHECK: movw r0, #(.L_table_end-.L_table_begin)>>2
|
||||
@ CHECK: blx return
|
||||
|
||||
.global thumb_function
|
||||
.type thumb_function,%function
|
||||
thumb_function:
|
||||
mov r0, #(.L_table_end - .L_table_begin) >> 2
|
||||
blx return
|
||||
|
||||
@ CHECK-LABEL: thumb_function
|
||||
@ CHECK: movw r0, #(.L_table_end-.L_table_begin)>>2
|
||||
@ CHECK: blx return
|
||||
|
Loading…
Reference in New Issue
Block a user