mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-04 10:30:01 +00:00
Added a size field to the stack map record to handle subregister spills.
Implementing this on bigendian platforms could get strange. I added a target hook, getStackSlotRange, per Jakob's recommendation to make this as explicit as possible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194942 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b7dabccbce
commit
bb756ca244
@ -26,18 +26,19 @@ public:
|
||||
enum LocationType { Unprocessed, Register, Direct, Indirect, Constant,
|
||||
ConstantIndex };
|
||||
LocationType LocType;
|
||||
unsigned Size;
|
||||
unsigned Reg;
|
||||
int64_t Offset;
|
||||
Location() : LocType(Unprocessed), Reg(0), Offset(0) {}
|
||||
Location(LocationType LocType, unsigned Reg, int64_t Offset)
|
||||
: LocType(LocType), Reg(Reg), Offset(Offset) {}
|
||||
Location() : LocType(Unprocessed), Size(0), Reg(0), Offset(0) {}
|
||||
Location(LocationType LocType, unsigned Size, unsigned Reg, int64_t Offset)
|
||||
: LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {}
|
||||
};
|
||||
|
||||
// Typedef a function pointer for functions that parse sequences of operands
|
||||
// and return a Location, plus a new "next" operand iterator.
|
||||
typedef std::pair<Location, MachineInstr::const_mop_iterator>
|
||||
(*OperandParser)(MachineInstr::const_mop_iterator,
|
||||
MachineInstr::const_mop_iterator);
|
||||
MachineInstr::const_mop_iterator, const TargetMachine&);
|
||||
|
||||
// OpTypes are used to encode information about the following logical
|
||||
// operand (which may consist of several MachineOperands) for the
|
||||
|
@ -181,6 +181,23 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Compute the size in bytes and offset within a stack slot of a spilled
|
||||
/// register or subregister.
|
||||
///
|
||||
/// \param [out] Size in bytes of the spilled value.
|
||||
/// \param [out] Offset in bytes within the stack slot.
|
||||
/// \returns true if both Size and Offset are successfully computed.
|
||||
///
|
||||
/// Not all subregisters have computable spill slots. For example,
|
||||
/// subregisters registers may not be byte-sized, and a pair of discontiguous
|
||||
/// subregisters has no single offset.
|
||||
///
|
||||
/// Targets with nontrivial bigendian implementations may need to override
|
||||
/// this, particularly to support spilled vector registers.
|
||||
virtual bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx,
|
||||
unsigned &Size, unsigned &Offset,
|
||||
const TargetMachine *TM) const;
|
||||
|
||||
/// reMaterialize - Re-issue the specified 'original' instruction at the
|
||||
/// specific location targeting a new destination register.
|
||||
/// The register in Orig->getOperand(0).getReg() will be substituted by
|
||||
|
@ -1057,6 +1057,9 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr*, unsigned> > Ops,
|
||||
bool WasCopy = MI->isCopy();
|
||||
unsigned ImpReg = 0;
|
||||
|
||||
bool SpillSubRegs = (MI->getOpcode() == TargetOpcode::PATCHPOINT ||
|
||||
MI->getOpcode() == TargetOpcode::STACKMAP);
|
||||
|
||||
// TargetInstrInfo::foldMemoryOperand only expects explicit, non-tied
|
||||
// operands.
|
||||
SmallVector<unsigned, 8> FoldOps;
|
||||
@ -1068,7 +1071,7 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr*, unsigned> > Ops,
|
||||
continue;
|
||||
}
|
||||
// FIXME: Teach targets to deal with subregs.
|
||||
if (MO.getSubReg())
|
||||
if (!SpillSubRegs && MO.getSubReg())
|
||||
return false;
|
||||
// We cannot fold a load instruction into a def.
|
||||
if (LoadMI && MO.isDef())
|
||||
|
@ -41,7 +41,7 @@ void StackMaps::recordStackMap(const MachineInstr &MI, uint32_t ID,
|
||||
|
||||
if (recordResult) {
|
||||
std::pair<Location, MachineInstr::const_mop_iterator> ParseResult =
|
||||
OpParser(MI.operands_begin(), llvm::next(MI.operands_begin(), 1));
|
||||
OpParser(MI.operands_begin(), llvm::next(MI.operands_begin()), AP.TM);
|
||||
|
||||
Location &Loc = ParseResult.first;
|
||||
assert(Loc.LocType == Location::Register &&
|
||||
@ -51,7 +51,7 @@ void StackMaps::recordStackMap(const MachineInstr &MI, uint32_t ID,
|
||||
|
||||
while (MOI != MOE) {
|
||||
std::pair<Location, MachineInstr::const_mop_iterator> ParseResult =
|
||||
OpParser(MOI, MOE);
|
||||
OpParser(MOI, MOE, AP.TM);
|
||||
|
||||
Location &Loc = ParseResult.first;
|
||||
|
||||
@ -86,7 +86,7 @@ void StackMaps::recordStackMap(const MachineInstr &MI, uint32_t ID,
|
||||
/// uint16 : NumLocations
|
||||
/// Location[NumLocations] {
|
||||
/// uint8 : Register | Direct | Indirect | Constant | ConstantIndex
|
||||
/// uint8 : Reserved (location flags)
|
||||
/// uint8 : Size in Bytes
|
||||
/// uint16 : Dwarf RegNum
|
||||
/// int32 : Offset
|
||||
/// }
|
||||
@ -200,12 +200,22 @@ void StackMaps::serializeToStackMapSection() {
|
||||
);
|
||||
|
||||
unsigned RegNo = 0;
|
||||
int Offset = Loc.Offset;
|
||||
if(Loc.Reg) {
|
||||
RegNo = MCRI.getDwarfRegNum(Loc.Reg, false);
|
||||
for (MCSuperRegIterator SR(Loc.Reg, TRI);
|
||||
SR.isValid() && (int)RegNo < 0; ++SR) {
|
||||
RegNo = TRI->getDwarfRegNum(*SR, false);
|
||||
}
|
||||
// If this is a register location, put the subregister byte offset in
|
||||
// the location offset.
|
||||
if (Loc.LocType == Location::Register) {
|
||||
assert(!Loc.Offset && "Register location should have zero offset");
|
||||
unsigned LLVMRegNo = MCRI.getLLVMRegNum(RegNo, false);
|
||||
unsigned SubRegIdx = MCRI.getSubRegIndex(LLVMRegNo, Loc.Reg);
|
||||
if (SubRegIdx)
|
||||
Offset = MCRI.getSubRegIdxOffset(SubRegIdx);
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert((Loc.LocType != Location::Register
|
||||
@ -213,9 +223,9 @@ void StackMaps::serializeToStackMapSection() {
|
||||
"Missing location register");
|
||||
}
|
||||
AP.OutStreamer.EmitIntValue(Loc.LocType, 1);
|
||||
AP.OutStreamer.EmitIntValue(0, 1); // Reserved location flags.
|
||||
AP.OutStreamer.EmitIntValue(Loc.Size, 1);
|
||||
AP.OutStreamer.EmitIntValue(RegNo, 2);
|
||||
AP.OutStreamer.EmitIntValue(Loc.Offset, 4);
|
||||
AP.OutStreamer.EmitIntValue(Offset, 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
#include "llvm/CodeGen/ScoreboardHazardRecognizer.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCInstrItineraries.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
@ -276,6 +277,36 @@ bool TargetInstrInfo::hasStoreToStackSlot(const MachineInstr *MI,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TargetInstrInfo::getStackSlotRange(const TargetRegisterClass *RC,
|
||||
unsigned SubIdx, unsigned &Size,
|
||||
unsigned &Offset,
|
||||
const TargetMachine *TM) const {
|
||||
if (!SubIdx) {
|
||||
Size = RC->getSize();
|
||||
Offset = 0;
|
||||
return true;
|
||||
}
|
||||
unsigned BitSize = TM->getRegisterInfo()->getSubRegIdxSize(SubIdx);
|
||||
// Convert bit size to byte size to be consistent with
|
||||
// MCRegisterClass::getSize().
|
||||
if (BitSize % 8)
|
||||
return false;
|
||||
|
||||
int BitOffset = TM->getRegisterInfo()->getSubRegIdxOffset(SubIdx);
|
||||
if (BitOffset < 0 || BitOffset % 8)
|
||||
return false;
|
||||
|
||||
Size = BitSize /= 8;
|
||||
Offset = (unsigned)BitOffset / 8;
|
||||
|
||||
assert(RC->getSize() >= (Offset + Size) && "bad subregister range");
|
||||
|
||||
if (!TM->getDataLayout()->isLittleEndian()) {
|
||||
Offset = RC->getSize() - (Offset + Size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TargetInstrInfo::reMaterialize(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
unsigned DestReg,
|
||||
|
@ -34,7 +34,8 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
|
||||
// This method is implemented in X86MCInstLower.cpp.
|
||||
static std::pair<StackMaps::Location, MachineInstr::const_mop_iterator>
|
||||
stackmapOperandParser(MachineInstr::const_mop_iterator MOI,
|
||||
MachineInstr::const_mop_iterator MOE);
|
||||
MachineInstr::const_mop_iterator MOE,
|
||||
const TargetMachine &TM);
|
||||
|
||||
public:
|
||||
explicit X86AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
|
||||
|
@ -4239,9 +4239,20 @@ static MachineInstr* foldPatchpoint(MachineFunction &MF,
|
||||
for (unsigned i = StartIdx; i < MI->getNumOperands(); ++i) {
|
||||
MachineOperand &MO = MI->getOperand(i);
|
||||
if (std::find(Ops.begin(), Ops.end(), i) != Ops.end()) {
|
||||
assert(MO.getReg() && "patchpoint can only fold a vreg operand");
|
||||
// Compute the spill slot size and offset.
|
||||
const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(MO.getReg());
|
||||
unsigned SpillSize;
|
||||
unsigned SpillOffset;
|
||||
bool Valid = TII.getStackSlotRange(RC, MO.getSubReg(), SpillSize,
|
||||
SpillOffset, &MF.getTarget());
|
||||
if (!Valid)
|
||||
report_fatal_error("cannot spill patchpoint subregister operand");
|
||||
|
||||
MIB.addOperand(MachineOperand::CreateImm(StackMaps::IndirectMemRefOp));
|
||||
MIB.addOperand(MachineOperand::CreateImm(SpillSize));
|
||||
MIB.addOperand(MachineOperand::CreateFI(FrameIndex));
|
||||
addOffset(MIB, 0);
|
||||
addOffset(MIB, SpillOffset);
|
||||
}
|
||||
else
|
||||
MIB.addOperand(MO);
|
||||
|
@ -676,7 +676,7 @@ static void LowerTlsAddr(MCStreamer &OutStreamer,
|
||||
}
|
||||
|
||||
static std::pair<StackMaps::Location, MachineInstr::const_mop_iterator>
|
||||
parseMemoryOperand(StackMaps::Location::LocationType LocTy,
|
||||
parseMemoryOperand(StackMaps::Location::LocationType LocTy, unsigned Size,
|
||||
MachineInstr::const_mop_iterator MOI,
|
||||
MachineInstr::const_mop_iterator MOE) {
|
||||
|
||||
@ -701,12 +701,13 @@ parseMemoryOperand(StackMaps::Location::LocationType LocTy,
|
||||
(void)ZeroReg;
|
||||
|
||||
return std::make_pair(
|
||||
Location(LocTy, Base.getReg(), Disp.getImm()), ++MOI);
|
||||
Location(LocTy, Size, Base.getReg(), Disp.getImm()), ++MOI);
|
||||
}
|
||||
|
||||
std::pair<StackMaps::Location, MachineInstr::const_mop_iterator>
|
||||
X86AsmPrinter::stackmapOperandParser(MachineInstr::const_mop_iterator MOI,
|
||||
MachineInstr::const_mop_iterator MOE) {
|
||||
MachineInstr::const_mop_iterator MOE,
|
||||
const TargetMachine &TM) {
|
||||
|
||||
typedef StackMaps::Location Location;
|
||||
|
||||
@ -717,26 +718,42 @@ X86AsmPrinter::stackmapOperandParser(MachineInstr::const_mop_iterator MOI,
|
||||
if (MOP.isImm()) {
|
||||
switch (MOP.getImm()) {
|
||||
default: llvm_unreachable("Unrecognized operand type.");
|
||||
case StackMaps::DirectMemRefOp:
|
||||
return parseMemoryOperand(StackMaps::Location::Direct,
|
||||
case StackMaps::DirectMemRefOp: {
|
||||
unsigned Size = TM.getDataLayout()->getPointerSizeInBits();
|
||||
assert((Size % 8) == 0 && "Need pointer size in bytes.");
|
||||
Size /= 8;
|
||||
return parseMemoryOperand(StackMaps::Location::Direct, Size,
|
||||
llvm::next(MOI), MOE);
|
||||
case StackMaps::IndirectMemRefOp:
|
||||
return parseMemoryOperand(StackMaps::Location::Indirect,
|
||||
}
|
||||
case StackMaps::IndirectMemRefOp: {
|
||||
++MOI;
|
||||
int64_t Size = MOI->getImm();
|
||||
assert(Size > 0 && "Need a valid size for indirect memory locations.");
|
||||
return parseMemoryOperand(StackMaps::Location::Indirect, Size,
|
||||
llvm::next(MOI), MOE);
|
||||
}
|
||||
case StackMaps::ConstantOp: {
|
||||
++MOI;
|
||||
assert(MOI->isImm() && "Expected constant operand.");
|
||||
int64_t Imm = MOI->getImm();
|
||||
return std::make_pair(Location(Location::Constant, 0, Imm), ++MOI);
|
||||
return std::make_pair(
|
||||
Location(Location::Constant, sizeof(int64_t), 0, Imm), ++MOI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise this is a reg operand.
|
||||
// Otherwise this is a reg operand. The physical register number will
|
||||
// ultimately be encoded as a DWARF regno. The stack map also records the size
|
||||
// of a spill slot that can hold the register content. (The runtime can
|
||||
// track the actual size of the data type if it needs to.)
|
||||
assert(MOP.isReg() && "Expected register operand here.");
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(MOP.getReg()) &&
|
||||
"Virtreg operands should have been rewritten before now.");
|
||||
return std::make_pair(Location(Location::Register, MOP.getReg(), 0), ++MOI);
|
||||
const TargetRegisterClass *RC =
|
||||
TM.getRegisterInfo()->getMinimalPhysRegClass(MOP.getReg());
|
||||
assert(!MOP.getSubReg() && "Physical subreg still around.");
|
||||
return std::make_pair(
|
||||
Location(Location::Register, RC->getSize(), MOP.getReg(), 0), ++MOI);
|
||||
}
|
||||
|
||||
static MachineInstr::const_mop_iterator
|
||||
|
@ -18,17 +18,17 @@
|
||||
; CHECK-NEXT: .short 3
|
||||
; Loc 0: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 1: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 2: Constant 3
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 3
|
||||
define i64 @test() nounwind ssp uwtable {
|
||||
@ -45,12 +45,12 @@ entry:
|
||||
; CHECK-NEXT: .short 2
|
||||
; Loc 0: Register <-- this is the return register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 1: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
define i64 @property_access1(i8* %obj) nounwind ssp uwtable {
|
||||
@ -68,12 +68,12 @@ entry:
|
||||
; CHECK-NEXT: .short 2
|
||||
; Loc 0: Register <-- this is the return register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 1: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
define i64 @property_access2() nounwind ssp uwtable {
|
||||
@ -92,12 +92,12 @@ entry:
|
||||
; CHECK-NEXT: .short 2
|
||||
; Loc 0: Register <-- this is the return register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 1: Register <-- this will be folded once folding for FI is implemented
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
define i64 @property_access3() nounwind ssp uwtable {
|
||||
@ -116,72 +116,72 @@ entry:
|
||||
; CHECK-NEXT: .short 14
|
||||
; Loc 0: Register <-- this is the return register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 1: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 2: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 3: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 4: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 5: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 6: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 7: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 8: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 9: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 10: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 11: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 12: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 13: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
define i64 @anyreg_test1(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable {
|
||||
@ -199,72 +199,72 @@ entry:
|
||||
; CHECK-NEXT: .short 14
|
||||
; Loc 0: Register <-- this is the return register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 1: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 2: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 3: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 4: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 5: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 6: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 7: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 8: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 9: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 10: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 11: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 12: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 13: Register
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
define i64 @anyreg_test2(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable {
|
||||
@ -284,17 +284,17 @@ entry:
|
||||
; CHECK-NEXT: .short 3
|
||||
; Loc 0: Register (some register that will be spilled to the stack)
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 1: Register RDI
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short 5
|
||||
; CHECK-NEXT: .long 0
|
||||
; Loc 1: Register RSI
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short 4
|
||||
; CHECK-NEXT: .long 0
|
||||
define i64 @patchpoint_spilldef(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
; CHECK-NEXT: .long 1
|
||||
; CHECK-NEXT: .quad 4294967296
|
||||
; Num Callsites
|
||||
; CHECK-NEXT: .long 9
|
||||
; CHECK-NEXT: .long 11
|
||||
|
||||
; Constant arguments
|
||||
;
|
||||
@ -19,22 +19,22 @@
|
||||
; CHECK-NEXT: .short 4
|
||||
; SmallConstant
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 65535
|
||||
; SmallConstant
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 65536
|
||||
; SmallConstant
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 4294967295
|
||||
; CHECK-NEXT: .long -1
|
||||
; LargeConstant at index 0
|
||||
; CHECK-NEXT: .byte 5
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
|
||||
@ -52,11 +52,11 @@ entry:
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .short 2
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
define void @osrinline(i64 %a, i64 %b) {
|
||||
@ -77,11 +77,11 @@ entry:
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .short 2
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
define void @osrcold(i64 %a, i64 %b) {
|
||||
@ -137,11 +137,11 @@ entry:
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .short 2
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
define void @jsVoidCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) {
|
||||
@ -160,11 +160,11 @@ entry:
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .short 2
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short {{[0-9]+}}
|
||||
; CHECK-NEXT: .long 0
|
||||
define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) {
|
||||
@ -186,9 +186,9 @@ entry:
|
||||
;
|
||||
; Check that at least one is a spilled entry from RBP.
|
||||
; Location: Indirect RBP + ...
|
||||
; CHECK: .byte 3
|
||||
; CHECK: .byte 0
|
||||
; CHECK: .short 6
|
||||
; CHECK: .byte 3
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short 6
|
||||
define void @spilledValue(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) {
|
||||
entry:
|
||||
call void (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i32 11, i32 15, i8* null, i32 5, i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16)
|
||||
@ -206,15 +206,87 @@ entry:
|
||||
;
|
||||
; Check that at least one is a spilled entry from RBP.
|
||||
; Location: Indirect RBP + ...
|
||||
; CHECK: .byte 3
|
||||
; CHECK: .byte 0
|
||||
; CHECK: .short 6
|
||||
; CHECK: .byte 3
|
||||
; CHECK-NEXT: .byte 8
|
||||
; CHECK-NEXT: .short 6
|
||||
define webkit_jscc void @spilledStackMapValue(i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) {
|
||||
entry:
|
||||
call void (i32, i32, ...)* @llvm.experimental.stackmap(i32 12, i32 15, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Spill a subregister stackmap operand.
|
||||
;
|
||||
; CHECK: .long 13
|
||||
; CHECK-LABEL: .long L{{.*}}-_spillSubReg
|
||||
; CHECK-NEXT: .short 0
|
||||
; 4 locations
|
||||
; CHECK-NEXT: .short 1
|
||||
;
|
||||
; Check that the subregister operand is a 4-byte spill.
|
||||
; Location: Indirect, 4-byte, RBP + ...
|
||||
; CHECK: .byte 3
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .short 6
|
||||
define void @spillSubReg(i64 %arg) #0 {
|
||||
bb:
|
||||
br i1 undef, label %bb1, label %bb2
|
||||
|
||||
bb1:
|
||||
unreachable
|
||||
|
||||
bb2:
|
||||
%tmp = load i64* inttoptr (i64 140685446136880 to i64*)
|
||||
br i1 undef, label %bb16, label %bb17
|
||||
|
||||
bb16:
|
||||
unreachable
|
||||
|
||||
bb17:
|
||||
%tmp32 = trunc i64 %tmp to i32
|
||||
br i1 undef, label %bb60, label %bb61
|
||||
|
||||
bb60:
|
||||
tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind
|
||||
tail call void (i32, i32, ...)* @llvm.experimental.stackmap(i32 13, i32 5, i32 %tmp32)
|
||||
unreachable
|
||||
|
||||
bb61:
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Map a single byte subregister. There is no DWARF register number, so
|
||||
; we expect the register to be encoded with the proper size and spill offset. We don't know which
|
||||
;
|
||||
; CHECK: .long 14
|
||||
; CHECK-LABEL: .long L{{.*}}-_subRegOffset
|
||||
; CHECK-NEXT: .short 0
|
||||
; 2 locations
|
||||
; CHECK-NEXT: .short 2
|
||||
;
|
||||
; Check that the subregister operands are 1-byte spills.
|
||||
; Location 0: Register, 4-byte, AL
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
;
|
||||
; Location 1: Register, 4-byte, BL
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .short 3
|
||||
; CHECK-NEXT: .long 0
|
||||
define void @subRegOffset(i16 %arg) {
|
||||
%v = mul i16 %arg, 5
|
||||
%a0 = trunc i16 %v to i8
|
||||
tail call void asm sideeffect "nop", "~{bx}"() nounwind
|
||||
%arghi = lshr i16 %v, 8
|
||||
%a1 = trunc i16 %arghi to i8
|
||||
tail call void asm sideeffect "nop", "~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind
|
||||
tail call void (i32, i32, ...)* @llvm.experimental.stackmap(i32 14, i32 5, i8 %a0, i8 %a1)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.experimental.stackmap(i32, i32, ...)
|
||||
declare void @llvm.experimental.patchpoint.void(i32, i32, i8*, i32, ...)
|
||||
declare i64 @llvm.experimental.patchpoint.i64(i32, i32, i8*, i32, ...)
|
||||
|
Loading…
x
Reference in New Issue
Block a user