forked from OSchip/llvm-project
[VE] global variable isel patterns
Summary: Asm expr fixups, isel patterns and tests for global variables addresses. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D73355
This commit is contained in:
parent
f5147765ba
commit
0fca35c652
|
@ -1,5 +1,6 @@
|
||||||
add_llvm_component_library(LLVMVEDesc
|
add_llvm_component_library(LLVMVEDesc
|
||||||
VEMCAsmInfo.cpp
|
VEMCAsmInfo.cpp
|
||||||
|
VEMCExpr.cpp
|
||||||
VEMCTargetDesc.cpp
|
VEMCTargetDesc.cpp
|
||||||
VETargetStreamer.cpp
|
VETargetStreamer.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
//===-- VEFixupKinds.h - VE Specific Fixup Entries --------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_LIB_TARGET_VE_MCTARGETDESC_VEFIXUPKINDS_H
|
||||||
|
#define LLVM_LIB_TARGET_VE_MCTARGETDESC_VEFIXUPKINDS_H
|
||||||
|
|
||||||
|
#include "llvm/MC/MCFixup.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace VE {
|
||||||
|
enum Fixups {
|
||||||
|
/// fixup_ve_hi32 - 32-bit fixup corresponding to foo@hi
|
||||||
|
fixup_ve_hi32 = FirstTargetFixupKind,
|
||||||
|
|
||||||
|
/// fixup_ve_lo32 - 32-bit fixup corresponding to foo@lo
|
||||||
|
fixup_ve_lo32,
|
||||||
|
|
||||||
|
// Marker
|
||||||
|
LastTargetFixupKind,
|
||||||
|
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
|
||||||
|
};
|
||||||
|
} // namespace VE
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,97 @@
|
||||||
|
//===-- VEMCExpr.cpp - VE specific MC expression classes ------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file contains the implementation of the assembly expression modifiers
|
||||||
|
// accepted by the VE architecture (e.g. "%hi", "%lo", ...).
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "VEMCExpr.h"
|
||||||
|
#include "llvm/MC/MCAssembler.h"
|
||||||
|
#include "llvm/MC/MCContext.h"
|
||||||
|
#include "llvm/MC/MCObjectStreamer.h"
|
||||||
|
#include "llvm/MC/MCSymbolELF.h"
|
||||||
|
#include "llvm/Object/ELF.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
#define DEBUG_TYPE "vemcexpr"
|
||||||
|
|
||||||
|
const VEMCExpr *VEMCExpr::create(VariantKind Kind, const MCExpr *Expr,
|
||||||
|
MCContext &Ctx) {
|
||||||
|
return new (Ctx) VEMCExpr(Kind, Expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
|
||||||
|
|
||||||
|
bool closeParen = printVariantKind(OS, Kind);
|
||||||
|
|
||||||
|
const MCExpr *Expr = getSubExpr();
|
||||||
|
Expr->print(OS, MAI);
|
||||||
|
|
||||||
|
if (closeParen)
|
||||||
|
OS << ')';
|
||||||
|
printVariantKindSuffix(OS, Kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VEMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind) {
|
||||||
|
switch (Kind) {
|
||||||
|
case VK_VE_None:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case VK_VE_HI32:
|
||||||
|
case VK_VE_LO32:
|
||||||
|
return false; // OS << "@<text>("; break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEMCExpr::printVariantKindSuffix(raw_ostream &OS, VariantKind Kind) {
|
||||||
|
switch (Kind) {
|
||||||
|
case VK_VE_None:
|
||||||
|
break;
|
||||||
|
case VK_VE_HI32:
|
||||||
|
OS << "@hi";
|
||||||
|
break;
|
||||||
|
case VK_VE_LO32:
|
||||||
|
OS << "@lo";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VEMCExpr::VariantKind VEMCExpr::parseVariantKind(StringRef name) {
|
||||||
|
return StringSwitch<VEMCExpr::VariantKind>(name)
|
||||||
|
.Case("hi", VK_VE_HI32)
|
||||||
|
.Case("lo", VK_VE_LO32)
|
||||||
|
.Default(VK_VE_None);
|
||||||
|
}
|
||||||
|
|
||||||
|
VE::Fixups VEMCExpr::getFixupKind(VEMCExpr::VariantKind Kind) {
|
||||||
|
switch (Kind) {
|
||||||
|
default:
|
||||||
|
llvm_unreachable("Unhandled VEMCExpr::VariantKind");
|
||||||
|
case VK_VE_HI32:
|
||||||
|
return VE::fixup_ve_hi32;
|
||||||
|
case VK_VE_LO32:
|
||||||
|
return VE::fixup_ve_lo32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VEMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
|
||||||
|
const MCAsmLayout *Layout,
|
||||||
|
const MCFixup *Fixup) const {
|
||||||
|
return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
|
||||||
|
Streamer.visitUsedExpr(*getSubExpr());
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
|
||||||
|
llvm_unreachable("TODO implement");
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
//====- VEMCExpr.h - VE specific MC expression classes --------*- C++ -*-=====//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file describes VE-specific MCExprs, used for modifiers like
|
||||||
|
// "%hi" or "%lo" etc.,
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_LIB_TARGET_VE_MCTARGETDESC_VEMCEXPR_H
|
||||||
|
#define LLVM_LIB_TARGET_VE_MCTARGETDESC_VEMCEXPR_H
|
||||||
|
|
||||||
|
#include "VEFixupKinds.h"
|
||||||
|
#include "llvm/MC/MCExpr.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class StringRef;
|
||||||
|
class VEMCExpr : public MCTargetExpr {
|
||||||
|
public:
|
||||||
|
enum VariantKind {
|
||||||
|
VK_VE_None,
|
||||||
|
VK_VE_HI32,
|
||||||
|
VK_VE_LO32,
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
const VariantKind Kind;
|
||||||
|
const MCExpr *Expr;
|
||||||
|
|
||||||
|
explicit VEMCExpr(VariantKind Kind, const MCExpr *Expr)
|
||||||
|
: Kind(Kind), Expr(Expr) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// @name Construction
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
static const VEMCExpr *create(VariantKind Kind, const MCExpr *Expr,
|
||||||
|
MCContext &Ctx);
|
||||||
|
/// @}
|
||||||
|
/// @name Accessors
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/// getOpcode - Get the kind of this expression.
|
||||||
|
VariantKind getKind() const { return Kind; }
|
||||||
|
|
||||||
|
/// getSubExpr - Get the child of this expression.
|
||||||
|
const MCExpr *getSubExpr() const { return Expr; }
|
||||||
|
|
||||||
|
/// getFixupKind - Get the fixup kind of this expression.
|
||||||
|
VE::Fixups getFixupKind() const { return getFixupKind(Kind); }
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
|
||||||
|
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
|
||||||
|
const MCFixup *Fixup) const override;
|
||||||
|
void visitUsedExpr(MCStreamer &Streamer) const override;
|
||||||
|
MCFragment *findAssociatedFragment() const override {
|
||||||
|
return getSubExpr()->findAssociatedFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;
|
||||||
|
|
||||||
|
static bool classof(const MCExpr *E) {
|
||||||
|
return E->getKind() == MCExpr::Target;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool classof(const VEMCExpr *) { return true; }
|
||||||
|
|
||||||
|
static VariantKind parseVariantKind(StringRef name);
|
||||||
|
static bool printVariantKind(raw_ostream &OS, VariantKind Kind);
|
||||||
|
static void printVariantKindSuffix(raw_ostream &OS, VariantKind Kind);
|
||||||
|
static VE::Fixups getFixupKind(VariantKind Kind);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,6 +12,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "VEISelLowering.h"
|
#include "VEISelLowering.h"
|
||||||
|
#include "MCTargetDesc/VEMCExpr.h"
|
||||||
#include "VERegisterInfo.h"
|
#include "VERegisterInfo.h"
|
||||||
#include "VETargetMachine.h"
|
#include "VETargetMachine.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
|
@ -222,6 +223,10 @@ VETargetLowering::VETargetLowering(const TargetMachine &TM,
|
||||||
addRegisterClass(MVT::f32, &VE::F32RegClass);
|
addRegisterClass(MVT::f32, &VE::F32RegClass);
|
||||||
addRegisterClass(MVT::f64, &VE::I64RegClass);
|
addRegisterClass(MVT::f64, &VE::I64RegClass);
|
||||||
|
|
||||||
|
// Custom legalize GlobalAddress nodes into LO/HI parts.
|
||||||
|
MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
|
||||||
|
setOperationAction(ISD::GlobalAddress, PtrVT, Custom);
|
||||||
|
|
||||||
setStackPointerRegisterToSaveRestore(VE::SX11);
|
setStackPointerRegisterToSaveRestore(VE::SX11);
|
||||||
|
|
||||||
// Set function alignment to 16 bytes
|
// Set function alignment to 16 bytes
|
||||||
|
@ -234,12 +239,17 @@ VETargetLowering::VETargetLowering(const TargetMachine &TM,
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
|
const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||||
|
#define TARGET_NODE_CASE(NAME) \
|
||||||
|
case VEISD::NAME: \
|
||||||
|
return "VEISD::" #NAME;
|
||||||
switch ((VEISD::NodeType)Opcode) {
|
switch ((VEISD::NodeType)Opcode) {
|
||||||
case VEISD::FIRST_NUMBER:
|
case VEISD::FIRST_NUMBER:
|
||||||
break;
|
break;
|
||||||
case VEISD::RET_FLAG:
|
TARGET_NODE_CASE(Lo)
|
||||||
return "VEISD::RET_FLAG";
|
TARGET_NODE_CASE(Hi)
|
||||||
|
TARGET_NODE_CASE(RET_FLAG)
|
||||||
}
|
}
|
||||||
|
#undef TARGET_NODE_CASE
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,3 +257,59 @@ EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
|
||||||
EVT VT) const {
|
EVT VT) const {
|
||||||
return MVT::i32;
|
return MVT::i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert to a target node and set target flags.
|
||||||
|
SDValue VETargetLowering::withTargetFlags(SDValue Op, unsigned TF,
|
||||||
|
SelectionDAG &DAG) const {
|
||||||
|
if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op))
|
||||||
|
return DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(GA),
|
||||||
|
GA->getValueType(0), GA->getOffset(), TF);
|
||||||
|
|
||||||
|
llvm_unreachable("Unhandled address SDNode");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split Op into high and low parts according to HiTF and LoTF.
|
||||||
|
// Return an ADD node combining the parts.
|
||||||
|
SDValue VETargetLowering::makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
|
||||||
|
SelectionDAG &DAG) const {
|
||||||
|
SDLoc DL(Op);
|
||||||
|
EVT VT = Op.getValueType();
|
||||||
|
SDValue Hi = DAG.getNode(VEISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG));
|
||||||
|
SDValue Lo = DAG.getNode(VEISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG));
|
||||||
|
return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build SDNodes for producing an address from a GlobalAddress, ConstantPool,
|
||||||
|
// or ExternalSymbol SDNode.
|
||||||
|
SDValue VETargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const {
|
||||||
|
SDLoc DL(Op);
|
||||||
|
|
||||||
|
assert(!isPositionIndependent() && "TODO implement PIC");
|
||||||
|
|
||||||
|
// This is one of the absolute code models.
|
||||||
|
switch (getTargetMachine().getCodeModel()) {
|
||||||
|
default:
|
||||||
|
llvm_unreachable("Unsupported absolute code model");
|
||||||
|
case CodeModel::Small:
|
||||||
|
case CodeModel::Medium:
|
||||||
|
case CodeModel::Large:
|
||||||
|
// abs64.
|
||||||
|
return makeHiLoPair(Op, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Custom Lower {
|
||||||
|
SDValue VETargetLowering::LowerGlobalAddress(SDValue Op,
|
||||||
|
SelectionDAG &DAG) const {
|
||||||
|
return makeAddress(Op, DAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||||
|
switch (Op.getOpcode()) {
|
||||||
|
default:
|
||||||
|
llvm_unreachable("Should not custom lower this!");
|
||||||
|
case ISD::GlobalAddress:
|
||||||
|
return LowerGlobalAddress(Op, DAG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// } Custom Lower
|
||||||
|
|
|
@ -23,6 +23,10 @@ class VESubtarget;
|
||||||
namespace VEISD {
|
namespace VEISD {
|
||||||
enum NodeType : unsigned {
|
enum NodeType : unsigned {
|
||||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||||
|
|
||||||
|
Hi,
|
||||||
|
Lo, // Hi/Lo operations, typically on a global address.
|
||||||
|
|
||||||
RET_FLAG, // Return with a flag operand.
|
RET_FLAG, // Return with a flag operand.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -60,6 +64,17 @@ public:
|
||||||
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
|
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
|
||||||
SelectionDAG &DAG) const override;
|
SelectionDAG &DAG) const override;
|
||||||
|
|
||||||
|
/// Custom Lower {
|
||||||
|
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
|
||||||
|
|
||||||
|
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
/// } Custom Lower
|
||||||
|
|
||||||
|
SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const;
|
||||||
|
SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
|
||||||
|
SelectionDAG &DAG) const;
|
||||||
|
SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
|
||||||
bool isFPImmLegal(const APFloat &Imm, EVT VT,
|
bool isFPImmLegal(const APFloat &Imm, EVT VT,
|
||||||
bool ForCodeSize) const override;
|
bool ForCodeSize) const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -178,6 +178,9 @@ def uimm6Op64 : Operand<i64> {
|
||||||
let PrintMethod = "printCCOperand" in
|
let PrintMethod = "printCCOperand" in
|
||||||
def CCOp : Operand<i32>;
|
def CCOp : Operand<i32>;
|
||||||
|
|
||||||
|
def VEhi : SDNode<"VEISD::Hi", SDTIntUnaryOp>;
|
||||||
|
def VElo : SDNode<"VEISD::Lo", SDTIntUnaryOp>;
|
||||||
|
|
||||||
// These are target-independent nodes, but have target-specific formats.
|
// These are target-independent nodes, but have target-specific formats.
|
||||||
def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,
|
def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,
|
||||||
SDTCisVT<1, i64> ]>;
|
SDTCisVT<1, i64> ]>;
|
||||||
|
@ -883,6 +886,13 @@ def : Pat<(truncstorei16 i64:$src, ADDRri:$addr),
|
||||||
def : Pat<(truncstorei32 i64:$src, ADDRri:$addr),
|
def : Pat<(truncstorei32 i64:$src, ADDRri:$addr),
|
||||||
(STLri MEMri:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
|
(STLri MEMri:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
|
||||||
|
|
||||||
|
// Address calculation and its optimization
|
||||||
|
def : Pat<(VEhi tglobaladdr:$in), (LEASLzzi tglobaladdr:$in)>;
|
||||||
|
def : Pat<(VElo tglobaladdr:$in), (ANDrm0 (LEAzzi tglobaladdr:$in), 32)>;
|
||||||
|
def : Pat<(add (VEhi tglobaladdr:$in1), (VElo tglobaladdr:$in2)),
|
||||||
|
(LEASLrzi (ANDrm0 (LEAzzi tglobaladdr:$in2), 32),
|
||||||
|
(tglobaladdr:$in1))>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Pseudo Instructions
|
// Pseudo Instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "MCTargetDesc/VEMCExpr.h"
|
||||||
#include "VE.h"
|
#include "VE.h"
|
||||||
#include "llvm/CodeGen/AsmPrinter.h"
|
#include "llvm/CodeGen/AsmPrinter.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
@ -27,9 +28,11 @@ using namespace llvm;
|
||||||
static MCOperand LowerSymbolOperand(const MachineInstr *MI,
|
static MCOperand LowerSymbolOperand(const MachineInstr *MI,
|
||||||
const MachineOperand &MO,
|
const MachineOperand &MO,
|
||||||
const MCSymbol *Symbol, AsmPrinter &AP) {
|
const MCSymbol *Symbol, AsmPrinter &AP) {
|
||||||
|
VEMCExpr::VariantKind Kind = (VEMCExpr::VariantKind)MO.getTargetFlags();
|
||||||
|
|
||||||
const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, AP.OutContext);
|
const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, AP.OutContext);
|
||||||
return MCOperand::createExpr(MCSym);
|
const VEMCExpr *expr = VEMCExpr::create(Kind, MCSym, AP.OutContext);
|
||||||
|
return MCOperand::createExpr(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MCOperand LowerOperand(const MachineInstr *MI, const MachineOperand &MO,
|
static MCOperand LowerOperand(const MachineInstr *MI, const MachineOperand &MO,
|
||||||
|
@ -43,6 +46,8 @@ static MCOperand LowerOperand(const MachineInstr *MI, const MachineOperand &MO,
|
||||||
break;
|
break;
|
||||||
return MCOperand::createReg(MO.getReg());
|
return MCOperand::createReg(MO.getReg());
|
||||||
|
|
||||||
|
case MachineOperand::MO_GlobalAddress:
|
||||||
|
return LowerSymbolOperand(MI, MO, AP.getSymbol(MO.getGlobal()), AP);
|
||||||
case MachineOperand::MO_Immediate:
|
case MachineOperand::MO_Immediate:
|
||||||
return MCOperand::createImm(MO.getImm());
|
return MCOperand::createImm(MO.getImm());
|
||||||
|
|
||||||
|
|
|
@ -191,4 +191,3 @@ define i8 @loadi8stk() {
|
||||||
%1 = load i8, i8* %addr, align 16
|
%1 = load i8, i8* %addr, align 16
|
||||||
ret i8 %1
|
ret i8 %1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
|
||||||
|
|
||||||
|
@vi8 = common dso_local local_unnamed_addr global i8 0, align 1
|
||||||
|
@vi16 = common dso_local local_unnamed_addr global i16 0, align 2
|
||||||
|
@vi32 = common dso_local local_unnamed_addr global i32 0, align 4
|
||||||
|
@vi64 = common dso_local local_unnamed_addr global i64 0, align 8
|
||||||
|
@vf32 = common dso_local local_unnamed_addr global float 0.000000e+00, align 4
|
||||||
|
@vf64 = common dso_local local_unnamed_addr global double 0.000000e+00, align 8
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define double @loadf64com() {
|
||||||
|
; CHECK-LABEL: loadf64com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s0, vf64@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, vf64@hi(%s0)
|
||||||
|
; CHECK-NEXT: ld %s0, (,%s0)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
%1 = load double, double* @vf64, align 8
|
||||||
|
ret double %1
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define float @loadf32com() {
|
||||||
|
; CHECK-LABEL: loadf32com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s0, vf32@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, vf32@hi(%s0)
|
||||||
|
; CHECK-NEXT: ldu %s0, (,%s0)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
%1 = load float, float* @vf32, align 4
|
||||||
|
ret float %1
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define i64 @loadi64com() {
|
||||||
|
; CHECK-LABEL: loadi64com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s0, vi64@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, vi64@hi(%s0)
|
||||||
|
; CHECK-NEXT: ld %s0, (,%s0)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
%1 = load i64, i64* @vi64, align 8
|
||||||
|
ret i64 %1
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define i32 @loadi32com() {
|
||||||
|
; CHECK-LABEL: loadi32com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s0, vi32@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, vi32@hi(%s0)
|
||||||
|
; CHECK-NEXT: ldl.sx %s0, (,%s0)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
%1 = load i32, i32* @vi32, align 4
|
||||||
|
ret i32 %1
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define i16 @loadi16com() {
|
||||||
|
; CHECK-LABEL: loadi16com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s0, vi16@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, vi16@hi(%s0)
|
||||||
|
; CHECK-NEXT: ld2b.zx %s0, (,%s0)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
%1 = load i16, i16* @vi16, align 2
|
||||||
|
ret i16 %1
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define i8 @loadi8com() {
|
||||||
|
; CHECK-LABEL: loadi8com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s0, vi8@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, vi8@hi(%s0)
|
||||||
|
; CHECK-NEXT: ld1b.zx %s0, (,%s0)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
%1 = load i8, i8* @vi8, align 1
|
||||||
|
ret i8 %1
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
|
||||||
|
|
||||||
|
@vi8 = common dso_local local_unnamed_addr global i8 0, align 1
|
||||||
|
@vi16 = common dso_local local_unnamed_addr global i16 0, align 2
|
||||||
|
@vi32 = common dso_local local_unnamed_addr global i32 0, align 4
|
||||||
|
@vi64 = common dso_local local_unnamed_addr global i64 0, align 8
|
||||||
|
@vf32 = common dso_local local_unnamed_addr global float 0.000000e+00, align 4
|
||||||
|
@vf64 = common dso_local local_unnamed_addr global double 0.000000e+00, align 8
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define void @storef64com(double %0) {
|
||||||
|
; CHECK-LABEL: storef64com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s1, vf64@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s1, vf64@hi(%s1)
|
||||||
|
; CHECK-NEXT: st %s0, (,%s1)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
store double %0, double* @vf64, align 8
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define void @storef32com(float %0) {
|
||||||
|
; CHECK-LABEL: storef32com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s1, vf32@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s1, vf32@hi(%s1)
|
||||||
|
; CHECK-NEXT: stu %s0, (,%s1)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
store float %0, float* @vf32, align 4
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define void @storei64com(i64 %0) {
|
||||||
|
; CHECK-LABEL: storei64com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s1, vi64@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s1, vi64@hi(%s1)
|
||||||
|
; CHECK-NEXT: st %s0, (,%s1)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
store i64 %0, i64* @vi64, align 8
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define void @storei32com(i32 %0) {
|
||||||
|
; CHECK-LABEL: storei32com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s1, vi32@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s1, vi32@hi(%s1)
|
||||||
|
; CHECK-NEXT: stl %s0, (,%s1)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
store i32 %0, i32* @vi32, align 4
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define void @storei16com(i16 %0) {
|
||||||
|
; CHECK-LABEL: storei16com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s1, vi16@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s1, vi16@hi(%s1)
|
||||||
|
; CHECK-NEXT: st2b %s0, (,%s1)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
store i16 %0, i16* @vi16, align 2
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: norecurse nounwind readonly
|
||||||
|
define void @storei8com(i8 %0) {
|
||||||
|
; CHECK-LABEL: storei8com:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s1, vi8@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s1, vi8@hi(%s1)
|
||||||
|
; CHECK-NEXT: st1b %s0, (,%s1)
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
store i8 %0, i8* @vi8, align 1
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue