Skip to content

Commit

Permalink
[VE] i64 arguments, return values and constants
Browse files Browse the repository at this point in the history
Summary: Support for i64 arguments (in register), return values and constants along with tests.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D72776
  • Loading branch information
kaz7 authored and simoll committed Jan 16, 2020
1 parent 4f244bb commit 773ae62
Show file tree
Hide file tree
Showing 10 changed files with 417 additions and 22 deletions.
1 change: 0 additions & 1 deletion llvm/lib/Target/VE/InstPrinter/VEInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ void VEInstPrinter::printOperand(const MCInst *MI, int opNum,
switch (MI->getOpcode()) {
default:
// Expects signed 32bit literals
assert(isInt<32>(MO.getImm()) && "Immediate too large");
int32_t TruncatedImm = static_cast<int32_t>(MO.getImm());
O << TruncatedImm;
return;
Expand Down
11 changes: 0 additions & 11 deletions llvm/lib/Target/VE/VE.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,5 @@ inline static const char *VECondCodeToString(VECC::CondCodes CC) {
llvm_unreachable("Invalid cond code");
}

// Different to Hi_32/Lo_32 the HI32 and LO32 functions
// preserve the correct numerical value
// on the LLVM data type for MC immediates (int64_t).
inline static int64_t HI32(int64_t imm) {
return (int32_t)(imm >> 32);
}

inline static int64_t LO32(int64_t imm) {
return (int32_t)(imm);
}

} // namespace llvm
#endif
14 changes: 14 additions & 0 deletions llvm/lib/Target/VE/VECallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@
// Aurora VE
//===----------------------------------------------------------------------===//

def CC_VE : CallingConv<[
// All arguments get passed in generic registers if there is space.

// long long/double --> generic 64 bit registers
CCIfType<[i64],
CCAssignToReg<[SX0, SX1, SX2, SX3, SX4, SX5, SX6, SX7]>>,
]>;

def RetCC_VE : CallingConv<[
// long long/double --> generic 64 bit registers
CCIfType<[i64],
CCAssignToReg<[SX0, SX1, SX2, SX3, SX4, SX5, SX6, SX7]>>,
]>;

// Callee-saved registers
def CSR : CalleeSavedRegs<(add (sequence "SX%u", 18, 33))>;
def CSR_NoRegs : CalleeSavedRegs<(add)>;
4 changes: 2 additions & 2 deletions llvm/lib/Target/VE/VEFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,14 @@ void VEFrameLowering::emitSPAdjustment(MachineFunction &MF,
// and %s13,%s13,(32)0
// lea.sl %sp,%hi(NumBytes)(%sp, %s13)
BuildMI(MBB, MBBI, dl, TII.get(VE::LEAzzi), VE::SX13)
.addImm(LO32(NumBytes));
.addImm(Lo_32(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(VE::ANDrm0), VE::SX13)
.addReg(VE::SX13)
.addImm(32);
BuildMI(MBB, MBBI, dl, TII.get(VE::LEASLrri), VE::SX11)
.addReg(VE::SX11)
.addReg(VE::SX13)
.addImm(HI32(NumBytes));
.addImm(Hi_32(NumBytes));
}

void VEFrameLowering::emitSPExtend(MachineFunction &MF, MachineBasicBlock &MBB,
Expand Down
111 changes: 104 additions & 7 deletions llvm/lib/Target/VE/VEISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ using namespace llvm;
bool VETargetLowering::CanLowerReturn(
CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
assert(!IsVarArg && "TODO implement var args");
assert(Outs.empty() && "TODO implement return values");
return true; // TODO support more than 'ret void'
CCAssignFn *RetCC = RetCC_VE;
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, RetCC);
}

SDValue
Expand All @@ -52,21 +53,117 @@ VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
assert(!IsVarArg && "TODO implement var args");
assert(Outs.empty() && "TODO implement return values");
assert(OutVals.empty() && "TODO implement return values");
// CCValAssign - represent the assignment of the return value to locations.
SmallVector<CCValAssign, 16> RVLocs;

// CCState - Info about the registers and stack slot.
CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
*DAG.getContext());

// Analyze return values.
CCInfo.AnalyzeReturn(Outs, RetCC_VE);

SDValue Flag;
SmallVector<SDValue, 4> RetOps(1, Chain);

// Copy the result values into the output registers.
for (unsigned i = 0; i != RVLocs.size(); ++i) {
CCValAssign &VA = RVLocs[i];
assert(VA.isRegLoc() && "Can only return in registers!");
SDValue OutVal = OutVals[i];

// Integer return values must be sign or zero extended by the callee.
switch (VA.getLocInfo()) {
case CCValAssign::Full:
break;
case CCValAssign::SExt:
OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal);
break;
case CCValAssign::ZExt:
OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal);
break;
case CCValAssign::AExt:
OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal);
break;
default:
llvm_unreachable("Unknown loc info!");
}

Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag);

// Guarantee that all emitted copies are stuck together with flags.
Flag = Chain.getValue(1);
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
}

RetOps[0] = Chain; // Update chain.

// Add the flag if we have it.
if (Flag.getNode())
RetOps.push_back(Flag);

return DAG.getNode(VEISD::RET_FLAG, DL, MVT::Other, RetOps);
}

SDValue VETargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();

// Get the size of the preserved arguments area
unsigned ArgsPreserved = 64;

// Analyze arguments according to CC_VE.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
*DAG.getContext());
// Allocate the preserved area first.
CCInfo.AllocateStack(ArgsPreserved, 8);
// We already allocated the preserved area, so the stack offset computed
// by CC_VE would be correct now.
CCInfo.AnalyzeFormalArguments(Ins, CC_VE);

for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
CCValAssign &VA = ArgLocs[i];
assert(VA.isRegLoc() && "TODO implement argument passing on stack");
if (VA.isRegLoc()) {
// This argument is passed in a register.
// All integer register arguments are promoted by the caller to i64.

// Create a virtual register for the promoted live-in value.
unsigned VReg =
MF.addLiveIn(VA.getLocReg(), getRegClassFor(VA.getLocVT()));
SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT());

assert((VA.getValVT() == MVT::i64) &&
"TODO implement other argument types than i64");

// The caller promoted the argument, so insert an Assert?ext SDNode so we
// won't promote the value again in this function.
switch (VA.getLocInfo()) {
case CCValAssign::SExt:
Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg,
DAG.getValueType(VA.getValVT()));
break;
case CCValAssign::ZExt:
Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg,
DAG.getValueType(VA.getValVT()));
break;
default:
break;
}

// Truncate the register down to the argument type.
if (VA.isExtInLoc())
Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg);

InVals.push_back(Arg);
continue;
}
}

assert(!IsVarArg && "TODO implement var args");
assert(Ins.empty() && "TODO implement input arguments");
return Chain;
}

Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/VE/VEInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ VEInstrInfo::VEInstrInfo(VESubtarget &ST)
: VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(),
Subtarget(ST) {}

void VEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, const DebugLoc &DL,
MCRegister DestReg, MCRegister SrcReg,
bool KillSrc) const {

if (VE::I64RegClass.contains(SrcReg) && VE::I64RegClass.contains(DestReg)) {
BuildMI(MBB, I, DL, get(VE::ORri), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc))
.addImm(0);
} else {
const TargetRegisterInfo *TRI = &getRegisterInfo();
dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg, TRI)
<< " to " << printReg(DestReg, TRI) << "\n";
llvm_unreachable("Impossible reg-to-reg copy");
}
}

bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
switch (MI.getOpcode()) {
case VE::EXTEND_STACK: {
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/VE/VEInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class VEInstrInfo : public VEGenInstrInfo {
///
const VERegisterInfo &getRegisterInfo() const { return RI; }

void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
bool KillSrc) const override;

// Lower pseudo instructions after register allocation.
bool expandPostRAPseudo(MachineInstr &MI) const override;

Expand Down
57 changes: 56 additions & 1 deletion llvm/lib/Target/VE/VEInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,23 @@ include "VEInstrFormats.td"

def simm7 : PatLeaf<(imm), [{ return isInt<7>(N->getSExtValue()); }]>;
def simm32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
def uimm32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
def uimm6 : PatLeaf<(imm), [{ return isUInt<6>(N->getZExtValue()); }]>;
def lomsbzero : PatLeaf<(imm), [{ return (N->getZExtValue() & 0x80000000)
== 0; }]>;
def lozero : PatLeaf<(imm), [{ return (N->getZExtValue() & 0xffffffff)
== 0; }]>;

def LO32 : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(Lo_32(N->getZExtValue()),
SDLoc(N), MVT::i64);
}]>;

def HI32 : SDNodeXForm<imm, [{
// Transformation function: shift the immediate value down into the low bits.
return CurDAG->getTargetConstant(Hi_32(N->getZExtValue()),
SDLoc(N), MVT::i32);
}]>;

// ASX format of memory address
def MEMri : Operand<iPTR> {
Expand Down Expand Up @@ -119,6 +135,14 @@ multiclass RMm<string opcStr, bits<8>opc,
let cz = 1;
let hasSideEffects = 0;
}
def rzi : RM<
opc, (outs RC:$sx), (ins RC:$sz, immOp2:$imm32),
!strconcat(opcStr, " $sx, ${imm32}(${sz})")> {
let cy = 0;
let sy = 0;
let cz = 1;
let hasSideEffects = 0;
}
def zzi : RM<
opc, (outs RC:$sx), (ins immOp2:$imm32),
!strconcat(opcStr, " $sx, $imm32")> {
Expand Down Expand Up @@ -172,6 +196,18 @@ multiclass RRNDmrm<string opcStr, bits<8>opc,
}
}

multiclass RRNDmim<string opcStr, bits<8>opc,
RegisterClass RCo, ValueType Tyo,
RegisterClass RCi, ValueType Tyi,
Operand immOp, Operand immOp2> {
def im1 : RR<opc, (outs RCo:$sx), (ins immOp:$sy, immOp2:$sz),
!strconcat(opcStr, " $sx, $sy, (${sz})1")> {
let cy = 0;
let cz = 0;
let hasSideEffects = 0;
}
}

// Used by add, mul, div, and similar commutative instructions
// The order of operands are "$sx, $sy, $sz"

Expand All @@ -180,7 +216,8 @@ multiclass RRm<string opcStr, bits<8>opc,
RRmrr<opcStr, opc, RC, Ty, RC, Ty>,
RRmri<opcStr, opc, RC, Ty, RC, Ty, immOp>,
RRmiz<opcStr, opc, RC, Ty, RC, Ty, immOp>,
RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, immOp2>;
RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, immOp2>,
RRNDmim<opcStr, opc, RC, Ty, RC, Ty, immOp, immOp2>;

// Branch multiclass
let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in
Expand Down Expand Up @@ -265,6 +302,24 @@ def MONC : RR<
0x3F, (outs), (ins),
"monc">;

//===----------------------------------------------------------------------===//
// Pattern Matchings
//===----------------------------------------------------------------------===//

// Small immediates.
def : Pat<(i64 simm7:$val), (ORim1 imm:$val, 0)>;
// Medium immediates.
def : Pat<(i64 simm32:$val), (LEAzzi imm:$val)>;
def : Pat<(i64 uimm32:$val), (ANDrm0 (LEAzzi imm:$val), 32)>;
// Arbitrary immediates.
def : Pat<(i64 lozero:$val),
(LEASLzzi (HI32 imm:$val))>;
def : Pat<(i64 lomsbzero:$val),
(LEASLrzi (LEAzzi (LO32 imm:$val)), (HI32 imm:$val))>;
def : Pat<(i64 imm:$val),
(LEASLrzi (ANDrm0 (LEAzzi (LO32 imm:$val)), 32),
(HI32 imm:$val))>;

//===----------------------------------------------------------------------===//
// Pseudo Instructions
//===----------------------------------------------------------------------===//
Expand Down
Loading

0 comments on commit 773ae62

Please sign in to comment.