mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Make first substantial checkin of my port of ARM constant islands code to Mips.
Before I just ported the shell of the pass. I've tried to keep everything nearly identical to the ARM version. I think it will be very easy to eventually merge these two and create a new more general pass that other targets can use. I have some improvements I would like to make to allow pools to be shared across functions and some other things. When I'm all done we can think about making a more general pass. More to be ported but the basic mechanism works now almost as good as gcc mips16. llvm-svn: 193509
This commit is contained in:
parent
faa5d33982
commit
9f4f45f079
@ -172,6 +172,11 @@ class FEXT_RI16_B_ins<bits<5> _op, string asmstr,
|
||||
FEXT_RI16<_op, (outs), (ins CPU16Regs:$rx, brtarget:$imm),
|
||||
!strconcat(asmstr, "\t$rx, $imm"), [], itin>;
|
||||
|
||||
class FEXT_RI16_TCP_ins<bits<5> _op, string asmstr,
|
||||
InstrItinClass itin>:
|
||||
FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm),
|
||||
!strconcat(asmstr, "\t$rx, $imm"), [], itin>;
|
||||
|
||||
class FEXT_2RI16_ins<bits<5> _op, string asmstr,
|
||||
InstrItinClass itin>:
|
||||
FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm),
|
||||
@ -455,7 +460,7 @@ def Constant32:
|
||||
MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>;
|
||||
|
||||
def LwConstant32:
|
||||
MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm),
|
||||
MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm, imm32:$constid),
|
||||
"lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>;
|
||||
|
||||
|
||||
@ -793,10 +798,11 @@ def LwRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, IILoad>, MayLoad{
|
||||
// Purpose: Load Word (SP-Relative, Extended)
|
||||
// To load an SP-relative word from memory as a signed value.
|
||||
//
|
||||
def LwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b10110, "lw", IILoad>, MayLoad{
|
||||
def LwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b10010, "lw", IILoad>, MayLoad{
|
||||
let Uses = [SP];
|
||||
}
|
||||
|
||||
def LwRxPcTcpX16: FEXT_RI16_TCP_ins<0b10110, "lw", IILoad>, MayLoad;
|
||||
//
|
||||
// Format: MOVE r32, rz MIPS16e
|
||||
// Purpose: Move
|
||||
@ -1355,7 +1361,7 @@ def: Mips16Pat<(i32 addr16:$addr),
|
||||
|
||||
|
||||
// Large (>16 bit) immediate loads
|
||||
def : Mips16Pat<(i32 imm:$imm), (LwConstant32 imm:$imm)>;
|
||||
def : Mips16Pat<(i32 imm:$imm), (LwConstant32 imm:$imm, -1)>;
|
||||
|
||||
// Carry MipsPatterns
|
||||
def : Mips16Pat<(subc CPU16Regs:$lhs, CPU16Regs:$rhs),
|
||||
@ -1848,3 +1854,19 @@ def GotPrologue16:
|
||||
(outs CPU16Regs:$rh, CPU16Regs:$rl),
|
||||
(ins simm16:$immHi, simm16:$immLo),
|
||||
".align 2\n\tli\t$rh, $immHi\n\taddiu\t$rl, $$pc, $immLo\n ",[]> ;
|
||||
|
||||
// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
|
||||
def cpinst_operand : Operand<i32> {
|
||||
// let PrintMethod = "printCPInstOperand";
|
||||
}
|
||||
|
||||
// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
|
||||
// the function. The first operand is the ID# for this instruction, the second
|
||||
// is the index into the MachineConstantPool that this is, the third is the
|
||||
// size in bytes of this constant pool entry.
|
||||
//
|
||||
let neverHasSideEffects = 1, isNotDuplicable = 1 in
|
||||
def CONSTPOOL_ENTRY :
|
||||
MipsPseudo16<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
|
||||
i32imm:$size), "foo", []>;
|
||||
|
||||
|
@ -55,6 +55,7 @@ bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
|
||||
.Initialize(OutContext, TM);
|
||||
MipsFI = MF.getInfo<MipsFunctionInfo>();
|
||||
MCP = MF.getConstantPool();
|
||||
AsmPrinter::runOnMachineFunction(MF);
|
||||
return true;
|
||||
}
|
||||
@ -75,6 +76,39 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we just ended a constant pool, mark it as such.
|
||||
if (InConstantPool && MI->getOpcode() != Mips::CONSTPOOL_ENTRY) {
|
||||
OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
|
||||
InConstantPool = false;
|
||||
}
|
||||
if (MI->getOpcode() == Mips::CONSTPOOL_ENTRY) {
|
||||
// CONSTPOOL_ENTRY - This instruction represents a floating
|
||||
//constant pool in the function. The first operand is the ID#
|
||||
// for this instruction, the second is the index into the
|
||||
// MachineConstantPool that this is, the third is the size in
|
||||
// bytes of this constant pool entry.
|
||||
// The required alignment is specified on the basic block holding this MI.
|
||||
//
|
||||
unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
|
||||
unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
|
||||
|
||||
// If this is the first entry of the pool, mark it.
|
||||
if (!InConstantPool) {
|
||||
OutStreamer.EmitDataRegion(MCDR_DataRegion);
|
||||
InConstantPool = true;
|
||||
}
|
||||
|
||||
OutStreamer.EmitLabel(GetCPISymbol(LabelId));
|
||||
|
||||
const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
|
||||
if (MCPE.isMachineConstantPoolEntry())
|
||||
EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
|
||||
else
|
||||
EmitGlobalConstant(MCPE.Val.ConstVal);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MachineBasicBlock::const_instr_iterator I = MI;
|
||||
MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
|
||||
|
||||
@ -287,6 +321,12 @@ void MipsAsmPrinter::EmitFunctionBodyEnd() {
|
||||
}
|
||||
OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
|
||||
}
|
||||
// Make sure to terminate any constant pools that were at the end
|
||||
// of the function.
|
||||
if (!InConstantPool)
|
||||
return;
|
||||
InConstantPool = false;
|
||||
OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
|
||||
}
|
||||
|
||||
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
|
||||
|
@ -42,6 +42,16 @@ private:
|
||||
// lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
|
||||
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
|
||||
|
||||
/// MCP - Keep a pointer to constantpool entries of the current
|
||||
/// MachineFunction.
|
||||
const MachineConstantPool *MCP;
|
||||
|
||||
/// InConstantPool - Maintain state when emitting a sequence of constant
|
||||
/// pool entries so we can properly mark them as data regions.
|
||||
bool InConstantPool;
|
||||
|
||||
bool UsingConstantPools;
|
||||
|
||||
public:
|
||||
|
||||
const MipsSubtarget *Subtarget;
|
||||
@ -49,8 +59,11 @@ public:
|
||||
MipsMCInstLower MCInstLowering;
|
||||
|
||||
explicit MipsAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
|
||||
: AsmPrinter(TM, Streamer), MCInstLowering(*this) {
|
||||
: AsmPrinter(TM, Streamer), MCP(0), InConstantPool(false),
|
||||
MCInstLowering(*this) {
|
||||
Subtarget = &TM.getSubtarget<MipsSubtarget>();
|
||||
UsingConstantPools =
|
||||
(Subtarget->inMips16Mode() && Subtarget->useConstantIslands());
|
||||
}
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
@ -59,6 +72,12 @@ public:
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &MF);
|
||||
|
||||
virtual void EmitConstantPool() LLVM_OVERRIDE {
|
||||
if (!UsingConstantPools)
|
||||
AsmPrinter::EmitConstantPool();
|
||||
// we emit constant pools customly!
|
||||
}
|
||||
|
||||
void EmitInstruction(const MachineInstr *MI);
|
||||
void printSavedRegsBitmask(raw_ostream &O);
|
||||
void printHex32(unsigned int Value, raw_ostream &O);
|
||||
|
@ -29,29 +29,69 @@
|
||||
#include "MCTargetDesc/MipsBaseInfo.h"
|
||||
#include "MipsTargetMachine.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/InstIterator.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
STATISTIC(NumCPEs, "Number of constpool entries");
|
||||
|
||||
// FIXME: This option should be removed once it has received sufficient testing.
|
||||
static cl::opt<bool>
|
||||
AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true),
|
||||
cl::desc("Align constant islands in code"));
|
||||
|
||||
namespace {
|
||||
typedef MachineBasicBlock::iterator Iter;
|
||||
typedef MachineBasicBlock::reverse_iterator ReverseIter;
|
||||
|
||||
class MipsConstantIslands : public MachineFunctionPass {
|
||||
|
||||
const TargetMachine &TM;
|
||||
bool IsPIC;
|
||||
unsigned ABI;
|
||||
const MipsSubtarget *STI;
|
||||
const MipsInstrInfo *TII;
|
||||
MachineFunction *MF;
|
||||
MachineConstantPool *MCP;
|
||||
|
||||
/// CPEntry - One per constant pool entry, keeping the machine instruction
|
||||
/// pointer, the constpool index, and the number of CPUser's which
|
||||
/// reference this entry.
|
||||
struct CPEntry {
|
||||
MachineInstr *CPEMI;
|
||||
unsigned CPI;
|
||||
unsigned RefCount;
|
||||
CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0)
|
||||
: CPEMI(cpemi), CPI(cpi), RefCount(rc) {}
|
||||
};
|
||||
|
||||
/// CPEntries - Keep track of all of the constant pool entry machine
|
||||
/// instructions. For each original constpool index (i.e. those that
|
||||
/// existed upon entry to this pass), it keeps a vector of entries.
|
||||
/// Original elements are cloned as we go along; the clones are
|
||||
/// put in the vector of the original element, but have distinct CPIs.
|
||||
std::vector<std::vector<CPEntry> > CPEntries;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
MipsConstantIslands(TargetMachine &tm)
|
||||
: MachineFunctionPass(ID), TM(tm),
|
||||
IsPIC(TM.getRelocationModel() == Reloc::PIC_),
|
||||
ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()) {}
|
||||
ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()),
|
||||
STI(&TM.getSubtarget<MipsSubtarget>()), MF(0), MCP(0){}
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "Mips Constant Islands";
|
||||
@ -59,10 +99,12 @@ namespace {
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
|
||||
void doInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
|
||||
|
||||
void prescanForConstants();
|
||||
|
||||
private:
|
||||
const TargetMachine &TM;
|
||||
bool IsPIC;
|
||||
unsigned ABI;
|
||||
|
||||
};
|
||||
|
||||
char MipsConstantIslands::ID = 0;
|
||||
@ -74,11 +116,138 @@ FunctionPass *llvm::createMipsConstantIslandPass(MipsTargetMachine &tm) {
|
||||
return new MipsConstantIslands(tm);
|
||||
}
|
||||
|
||||
bool MipsConstantIslands::runOnMachineFunction(MachineFunction &F) {
|
||||
bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) {
|
||||
// The intention is for this to be a mips16 only pass for now
|
||||
// FIXME:
|
||||
// if (!TM.getSubtarget<MipsSubtarget>().inMips16Mode())
|
||||
// return false;
|
||||
return false;
|
||||
MF = &mf;
|
||||
MCP = mf.getConstantPool();
|
||||
DEBUG(dbgs() << "constant island machine function " << "\n");
|
||||
if (!TM.getSubtarget<MipsSubtarget>().inMips16Mode() ||
|
||||
!MipsSubtarget::useConstantIslands()) {
|
||||
return false;
|
||||
}
|
||||
TII = (const MipsInstrInfo*)MF->getTarget().getInstrInfo();
|
||||
DEBUG(dbgs() << "constant island processing " << "\n");
|
||||
//
|
||||
// will need to make predermination if there is any constants we need to
|
||||
// put in constant islands. TBD.
|
||||
//
|
||||
prescanForConstants();
|
||||
|
||||
// This pass invalidates liveness information when it splits basic blocks.
|
||||
MF->getRegInfo().invalidateLiveness();
|
||||
|
||||
// Renumber all of the machine basic blocks in the function, guaranteeing that
|
||||
// the numbers agree with the position of the block in the function.
|
||||
MF->RenumberBlocks();
|
||||
|
||||
// Perform the initial placement of the constant pool entries. To start with,
|
||||
// we put them all at the end of the function.
|
||||
std::vector<MachineInstr*> CPEMIs;
|
||||
if (!MCP->isEmpty())
|
||||
doInitialPlacement(CPEMIs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// doInitialPlacement - Perform the initial placement of the constant pool
|
||||
/// entries. To start with, we put them all at the end of the function.
|
||||
void
|
||||
MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
|
||||
// Create the basic block to hold the CPE's.
|
||||
MachineBasicBlock *BB = MF->CreateMachineBasicBlock();
|
||||
MF->push_back(BB);
|
||||
|
||||
|
||||
// MachineConstantPool measures alignment in bytes. We measure in log2(bytes).
|
||||
unsigned MaxAlign = Log2_32(MCP->getConstantPoolAlignment());
|
||||
|
||||
// Mark the basic block as required by the const-pool.
|
||||
// If AlignConstantIslands isn't set, use 4-byte alignment for everything.
|
||||
BB->setAlignment(AlignConstantIslands ? MaxAlign : 2);
|
||||
|
||||
// The function needs to be as aligned as the basic blocks. The linker may
|
||||
// move functions around based on their alignment.
|
||||
MF->ensureAlignment(BB->getAlignment());
|
||||
|
||||
// Order the entries in BB by descending alignment. That ensures correct
|
||||
// alignment of all entries as long as BB is sufficiently aligned. Keep
|
||||
// track of the insertion point for each alignment. We are going to bucket
|
||||
// sort the entries as they are created.
|
||||
SmallVector<MachineBasicBlock::iterator, 8> InsPoint(MaxAlign + 1, BB->end());
|
||||
|
||||
// Add all of the constants from the constant pool to the end block, use an
|
||||
// identity mapping of CPI's to CPE's.
|
||||
const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
|
||||
|
||||
const DataLayout &TD = *MF->getTarget().getDataLayout();
|
||||
for (unsigned i = 0, e = CPs.size(); i != e; ++i) {
|
||||
unsigned Size = TD.getTypeAllocSize(CPs[i].getType());
|
||||
assert(Size >= 4 && "Too small constant pool entry");
|
||||
unsigned Align = CPs[i].getAlignment();
|
||||
assert(isPowerOf2_32(Align) && "Invalid alignment");
|
||||
// Verify that all constant pool entries are a multiple of their alignment.
|
||||
// If not, we would have to pad them out so that instructions stay aligned.
|
||||
assert((Size % Align) == 0 && "CP Entry not multiple of 4 bytes!");
|
||||
|
||||
// Insert CONSTPOOL_ENTRY before entries with a smaller alignment.
|
||||
unsigned LogAlign = Log2_32(Align);
|
||||
MachineBasicBlock::iterator InsAt = InsPoint[LogAlign];
|
||||
|
||||
MachineInstr *CPEMI =
|
||||
BuildMI(*BB, InsAt, DebugLoc(), TII->get(Mips::CONSTPOOL_ENTRY))
|
||||
.addImm(i).addConstantPoolIndex(i).addImm(Size);
|
||||
|
||||
CPEMIs.push_back(CPEMI);
|
||||
|
||||
// Ensure that future entries with higher alignment get inserted before
|
||||
// CPEMI. This is bucket sort with iterators.
|
||||
for (unsigned a = LogAlign + 1; a <= MaxAlign; ++a)
|
||||
if (InsPoint[a] == InsAt)
|
||||
InsPoint[a] = CPEMI;
|
||||
// Add a new CPEntry, but no corresponding CPUser yet.
|
||||
std::vector<CPEntry> CPEs;
|
||||
CPEs.push_back(CPEntry(CPEMI, i));
|
||||
CPEntries.push_back(CPEs);
|
||||
++NumCPEs;
|
||||
DEBUG(dbgs() << "Moved CPI#" << i << " to end of function, size = "
|
||||
<< Size << ", align = " << Align <<'\n');
|
||||
}
|
||||
DEBUG(BB->dump());
|
||||
}
|
||||
|
||||
|
||||
void MipsConstantIslands::prescanForConstants() {
|
||||
unsigned int J;
|
||||
for (MachineFunction::iterator B =
|
||||
MF->begin(), E = MF->end(); B != E; ++B) {
|
||||
for (MachineBasicBlock::instr_iterator I =
|
||||
B->instr_begin(), EB = B->instr_end(); I != EB; ++I) {
|
||||
switch(I->getDesc().getOpcode()) {
|
||||
case Mips::LwConstant32: {
|
||||
DEBUG(dbgs() << "constant island constant " << *I << "\n");
|
||||
J = I->getNumOperands();
|
||||
DEBUG(dbgs() << "num operands " << J << "\n");
|
||||
MachineOperand& Literal = I->getOperand(1);
|
||||
if (Literal.isImm()) {
|
||||
int64_t V = Literal.getImm();
|
||||
DEBUG(dbgs() << "literal " << V << "\n");
|
||||
Type *Int32Ty =
|
||||
Type::getInt32Ty(MF->getFunction()->getContext());
|
||||
const Constant *C = ConstantInt::get(Int32Ty, V);
|
||||
unsigned index = MCP->getConstantPoolIndex(C, 4);
|
||||
I->getOperand(2).ChangeToImmediate(index);
|
||||
DEBUG(dbgs() << "constant island constant " << *I << "\n");
|
||||
I->setDesc(TII->get(Mips::LwRxPcTcpX16));
|
||||
I->RemoveOperand(1);
|
||||
I->RemoveOperand(1);
|
||||
I->addOperand(MachineOperand::CreateCPI(index, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,6 +271,10 @@ unsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
|
||||
const char *AsmStr = MI->getOperand(0).getSymbolName();
|
||||
return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
|
||||
}
|
||||
case Mips::CONSTPOOL_ENTRY:
|
||||
// If this machine instr is a constant pool entry, its size is recorded as
|
||||
// operand #2.
|
||||
return MI->getOperand(2).getImm();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,6 +278,9 @@ def uimm16 : Operand<i32> {
|
||||
let PrintMethod = "printUnsignedImm";
|
||||
}
|
||||
|
||||
def pcrel16 : Operand<i32> {
|
||||
}
|
||||
|
||||
def MipsMemAsmOperand : AsmOperandClass {
|
||||
let Name = "Mem";
|
||||
let ParserMethod = "parseMemOperand";
|
||||
|
@ -53,6 +53,12 @@ Mips16HardFloat("mips16-hard-float", cl::NotHidden,
|
||||
cl::desc("MIPS: mips16 hard float enable."),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
Mips16ConstantIslands(
|
||||
"mips16-constant-islands", cl::Hidden,
|
||||
cl::desc("MIPS: mips16 constant islands enable. experimental feature"),
|
||||
cl::init(false));
|
||||
|
||||
void MipsSubtarget::anchor() { }
|
||||
|
||||
MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
|
||||
@ -163,3 +169,8 @@ void MipsSubtarget::resetSubtarget(MachineFunction *MF) {
|
||||
bool MipsSubtarget::mipsSEUsesSoftFloat() const {
|
||||
return TM->Options.UseSoftFloat && !InMips16HardFloat;
|
||||
}
|
||||
|
||||
bool MipsSubtarget::useConstantIslands() {
|
||||
DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands << "\n");
|
||||
return Mips16ConstantIslands;
|
||||
}
|
||||
|
@ -212,6 +212,10 @@ public:
|
||||
|
||||
bool os16() const { return Os16;};
|
||||
|
||||
// for now constant islands are on for the whole compilation unit but we only
|
||||
// really use them if in addition we are in mips16 mode
|
||||
//
|
||||
static bool useConstantIslands();
|
||||
// Grab MipsRegInfo object
|
||||
const MipsReginfo &getMReginfo() const { return MRI; }
|
||||
|
||||
|
35
test/CodeGen/Mips/const1.ll
Normal file
35
test/CodeGen/Mips/const1.ll
Normal file
@ -0,0 +1,35 @@
|
||||
; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static -mips16-constant-islands < %s | FileCheck %s
|
||||
|
||||
; ModuleID = 'const1.c'
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64"
|
||||
target triple = "mipsel-unknown-linux"
|
||||
|
||||
@i = common global i32 0, align 4
|
||||
@j = common global i32 0, align 4
|
||||
@k = common global i32 0, align 4
|
||||
@l = common global i32 0, align 4
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @t() #0 {
|
||||
entry:
|
||||
store i32 -559023410, i32* @i, align 4
|
||||
store i32 -559023410, i32* @j, align 4
|
||||
store i32 -87105875, i32* @k, align 4
|
||||
store i32 262991277, i32* @l, align 4
|
||||
ret void
|
||||
; CHECK: lw ${{[0-9]+}}, $CPI0_0
|
||||
; CHECK: lw ${{[0-9]+}}, $CPI0_1
|
||||
; CHECK: lw ${{[0-9]+}}, $CPI0_2
|
||||
; CHECK: $CPI0_0:
|
||||
; CHECK: .4byte 3735943886
|
||||
; CHECK: $CPI0_1:
|
||||
; CHECK: .4byte 4207861421
|
||||
; CHECK: $CPI0_2:
|
||||
; CHECK: .4byte 262991277
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = metadata !{metadata !"clang version 3.4 (gitosis@dmz-portal.mips.com:clang.git b754974ec32ab712ea7d8b52cd8037b24e7d6ed3) (gitosis@dmz-portal.mips.com:llvm.git 8e211187b501bc73edb938fde0019c9a20bcffd5)"}
|
Loading…
Reference in New Issue
Block a user