mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-03 17:31:50 +00:00
0fc8c68b11
ARM symbol variants are written with parens instead of @ like this: .word __GLOBAL_I_a(target1) This commit adds support for parsing these symbol variants in expressions. We introduce a new flag to MCAsmInfo that indicates the parser should use parens to parse the symbol variant. The expression parser is modified to look for symbol variants using parens instead of @ when the corresponding MCAsmInfo flag is true. The MCAsmInfo parens flag is enabled only for ARM on ELF. By adding this flag to MCAsmInfo, we are able to get rid of redundant ARM-specific symbol variants and use the generic variants instead (e.g. VK_GOT instead of VK_ARM_GOT). We use the new UseParensForSymbolVariant attribute in MCAsmInfo to correctly print the symbol variants for arm. To achive this we need to keep a handle to the MCAsmInfo in the MCSymbolRefExpr class that we can check when printing the symbol variant. Updated Tests: Changed case of symbol variant to match the generic kind. test/CodeGen/ARM/tls-models.ll test/CodeGen/ARM/tls1.ll test/CodeGen/ARM/tls2.ll test/CodeGen/Thumb2/tls1.ll test/CodeGen/Thumb2/tls2.ll PR18080 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196424 91177308-0d34-0410-b5e6-96231b3b80d8
129 lines
4.2 KiB
C++
129 lines
4.2 KiB
C++
//===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains code to lower ARM MachineInstrs to their corresponding
|
|
// MCInst records.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "ARM.h"
|
|
#include "ARMAsmPrinter.h"
|
|
#include "MCTargetDesc/ARMMCExpr.h"
|
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
#include "llvm/IR/Constants.h"
|
|
#include "llvm/MC/MCExpr.h"
|
|
#include "llvm/MC/MCInst.h"
|
|
#include "llvm/Target/Mangler.h"
|
|
using namespace llvm;
|
|
|
|
|
|
MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
|
|
const MCSymbol *Symbol) {
|
|
const MCExpr *Expr;
|
|
unsigned Option = MO.getTargetFlags() & ARMII::MO_OPTION_MASK;
|
|
switch (Option) {
|
|
default: {
|
|
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
|
|
OutContext);
|
|
switch (Option) {
|
|
default: llvm_unreachable("Unknown target flag on symbol operand");
|
|
case 0:
|
|
break;
|
|
case ARMII::MO_LO16:
|
|
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
|
|
OutContext);
|
|
Expr = ARMMCExpr::CreateLower16(Expr, OutContext);
|
|
break;
|
|
case ARMII::MO_HI16:
|
|
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
|
|
OutContext);
|
|
Expr = ARMMCExpr::CreateUpper16(Expr, OutContext);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ARMII::MO_PLT:
|
|
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_PLT,
|
|
OutContext);
|
|
break;
|
|
}
|
|
|
|
if (!MO.isJTI() && MO.getOffset())
|
|
Expr = MCBinaryExpr::CreateAdd(Expr,
|
|
MCConstantExpr::Create(MO.getOffset(),
|
|
OutContext),
|
|
OutContext);
|
|
return MCOperand::CreateExpr(Expr);
|
|
|
|
}
|
|
|
|
bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO,
|
|
MCOperand &MCOp) {
|
|
switch (MO.getType()) {
|
|
default: llvm_unreachable("unknown operand type");
|
|
case MachineOperand::MO_Register:
|
|
// Ignore all non-CPSR implicit register operands.
|
|
if (MO.isImplicit() && MO.getReg() != ARM::CPSR)
|
|
return false;
|
|
assert(!MO.getSubReg() && "Subregs should be eliminated!");
|
|
MCOp = MCOperand::CreateReg(MO.getReg());
|
|
break;
|
|
case MachineOperand::MO_Immediate:
|
|
MCOp = MCOperand::CreateImm(MO.getImm());
|
|
break;
|
|
case MachineOperand::MO_MachineBasicBlock:
|
|
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
|
|
MO.getMBB()->getSymbol(), OutContext));
|
|
break;
|
|
case MachineOperand::MO_GlobalAddress: {
|
|
MCOp = GetSymbolRef(MO,
|
|
GetARMGVSymbol(MO.getGlobal(), MO.getTargetFlags()));
|
|
break;
|
|
}
|
|
case MachineOperand::MO_ExternalSymbol:
|
|
MCOp = GetSymbolRef(MO,
|
|
GetExternalSymbolSymbol(MO.getSymbolName()));
|
|
break;
|
|
case MachineOperand::MO_JumpTableIndex:
|
|
MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));
|
|
break;
|
|
case MachineOperand::MO_ConstantPoolIndex:
|
|
MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));
|
|
break;
|
|
case MachineOperand::MO_BlockAddress:
|
|
MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
|
|
break;
|
|
case MachineOperand::MO_FPImmediate: {
|
|
APFloat Val = MO.getFPImm()->getValueAPF();
|
|
bool ignored;
|
|
Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
|
|
MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
|
|
break;
|
|
}
|
|
case MachineOperand::MO_RegisterMask:
|
|
// Ignore call clobbers.
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
|
|
ARMAsmPrinter &AP) {
|
|
OutMI.setOpcode(MI->getOpcode());
|
|
|
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
|
const MachineOperand &MO = MI->getOperand(i);
|
|
|
|
MCOperand MCOp;
|
|
if (AP.lowerOperand(MO, MCOp))
|
|
OutMI.addOperand(MCOp);
|
|
}
|
|
}
|