[Mesa-dev] [PATCH 5/5] R600: Add support for i8 and i16 function arguments
Tom Stellard
tom at stellard.net
Fri Dec 7 14:25:16 PST 2012
From: Tom Stellard <thomas.stellard at amd.com>
---
lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp | 5 +++
.../AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp | 2 ++
lib/Target/AMDGPU/R600ISelLowering.cpp | 25 +++++++++++---
lib/Target/AMDGPU/R600Instructions.td | 38 ++++++++++++++++------
test/CodeGen/R600/short-args.ll | 37 +++++++++++++++++++++
5 files changed, 92 insertions(+), 15 deletions(-)
create mode 100644 test/CodeGen/R600/short-args.ll
diff --git a/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp b/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp
index 5a98463..d15ed39 100644
--- a/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp
+++ b/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp
@@ -62,6 +62,7 @@ private:
static bool isCPLoad(const LoadSDNode *N);
static bool isConstantLoad(const LoadSDNode *N, int cbID);
static bool isGlobalLoad(const LoadSDNode *N);
+ static bool isParamLoad(const LoadSDNode *N);
static bool isPrivateLoad(const LoadSDNode *N);
static bool isLocalLoad(const LoadSDNode *N);
static bool isRegionLoad(const LoadSDNode *N);
@@ -349,6 +350,10 @@ bool AMDGPUDAGToDAGISel::isGlobalLoad(const LoadSDNode *N) {
return checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS);
}
+bool AMDGPUDAGToDAGISel::isParamLoad(const LoadSDNode *N) {
+ return checkType(N->getSrcValue(), AMDGPUAS::PARAM_I_ADDRESS);
+}
+
bool AMDGPUDAGToDAGISel::isLocalLoad(const LoadSDNode *N) {
return checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS);
}
diff --git a/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp b/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
index 154f05b..837bd81 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
@@ -159,6 +159,8 @@ void R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
break;
}
case AMDGPU::CONSTANT_LOAD_eg:
+ case AMDGPU::VTX_READ_PARAM_8_eg:
+ case AMDGPU::VTX_READ_PARAM_16_eg:
case AMDGPU::VTX_READ_PARAM_32_eg:
case AMDGPU::VTX_READ_GLOBAL_8_eg:
case AMDGPU::VTX_READ_GLOBAL_32_eg:
diff --git a/lib/Target/AMDGPU/R600ISelLowering.cpp b/lib/Target/AMDGPU/R600ISelLowering.cpp
index 33cd2cc..d17aa05 100644
--- a/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -17,6 +17,7 @@
#include "R600InstrInfo.h"
#include "R600MachineFunctionInfo.h"
#include "llvm/Argument.h"
+#include "llvm/Function.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
@@ -800,16 +801,30 @@ SDValue R600TargetLowering::LowerFormalArguments(
DebugLoc DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const {
unsigned ParamOffsetBytes = 36;
- for (unsigned i = 0, e = Ins.size(); i < e; ++i) {
+ Function::const_arg_iterator FuncArg =
+ DAG.getMachineFunction().getFunction()->arg_begin();
+ for (unsigned i = 0, e = Ins.size(); i < e; ++i, ++FuncArg) {
EVT VT = Ins[i].VT;
+ Type *ArgType = FuncArg->getType();
+ unsigned ArgSizeInBits = ArgType->isPointerTy() ?
+ 32 : ArgType->getPrimitiveSizeInBits();
+ unsigned ArgBytes = ArgSizeInBits >> 3;
+ EVT ArgVT;
+ if (ArgSizeInBits < VT.getSizeInBits()) {
+ assert(!ArgType->isFloatTy() &&
+ "Extending floating point arguments not supported yet");
+ ArgVT = MVT::getIntegerVT(ArgSizeInBits);
+ } else {
+ ArgVT = VT;
+ }
PointerType *PtrTy = PointerType::get(VT.getTypeForEVT(*DAG.getContext()),
AMDGPUAS::PARAM_I_ADDRESS);
- SDValue Arg = DAG.getLoad(VT, DL, DAG.getRoot(),
+ SDValue Arg = DAG.getExtLoad(ISD::ZEXTLOAD, DL, VT, DAG.getRoot(),
DAG.getConstant(ParamOffsetBytes, MVT::i32),
- MachinePointerInfo(new Argument(PtrTy)),
- false, false, false, 4);
+ MachinePointerInfo(new Argument(PtrTy)),
+ ArgVT, false, false, ArgBytes);
InVals.push_back(Arg);
- ParamOffsetBytes += (VT.getStoreSize());
+ ParamOffsetBytes += ArgBytes;
}
return Chain;
}
diff --git a/lib/Target/AMDGPU/R600Instructions.td b/lib/Target/AMDGPU/R600Instructions.td
index 41735a8..4572e7c 100644
--- a/lib/Target/AMDGPU/R600Instructions.td
+++ b/lib/Target/AMDGPU/R600Instructions.td
@@ -383,16 +383,14 @@ class EG_CF_RAT <bits <8> cf_inst, bits <6> rat_inst, bits<4> rat_id, dag outs,
let Inst{63} = BARRIER;
}
-def load_param : PatFrag<(ops node:$ptr),
- (load node:$ptr),
- [{
- const Value *Src = cast<LoadSDNode>(N)->getSrcValue();
- if (Src) {
- PointerType * PT = dyn_cast<PointerType>(Src->getType());
- return PT && PT->getAddressSpace() == AMDGPUAS::PARAM_I_ADDRESS;
- }
- return false;
- }]>;
+class LoadParamFrag <PatFrag load_type> : PatFrag <
+ (ops node:$ptr), (load_type node:$ptr),
+ [{ return isParamLoad(dyn_cast<LoadSDNode>(N)); }]
+>;
+
+def load_param : LoadParamFrag<load>;
+def load_param_zexti8 : LoadParamFrag<zextloadi8>;
+def load_param_zexti16 : LoadParamFrag<zextloadi16>;
def isR600 : Predicate<"Subtarget.device()"
"->getGeneration() == AMDGPUDeviceInfo::HD4XXX">;
@@ -1248,6 +1246,18 @@ class VTX_READ_8_eg <bits<8> buffer_id, list<dag> pattern>
let DATA_FORMAT = 1; // FMT_8
}
+class VTX_READ_16_eg <bits<8> buffer_id, list<dag> pattern>
+ : VTX_READ_eg <"VTX_READ_16", buffer_id, (outs R600_TReg32_X:$dst),
+ pattern> {
+ let MEGA_FETCH_COUNT = 2;
+ let DST_SEL_X = 0;
+ let DST_SEL_Y = 7; // Masked
+ let DST_SEL_Z = 7; // Masked
+ let DST_SEL_W = 7; // Masked
+ let DATA_FORMAT = 5; // FMT_16
+
+}
+
class VTX_READ_32_eg <bits<8> buffer_id, list<dag> pattern>
: VTX_READ_eg <"VTX_READ_32", buffer_id, (outs R600_TReg32_X:$dst),
pattern> {
@@ -1290,6 +1300,14 @@ class VTX_READ_128_eg <bits<8> buffer_id, list<dag> pattern>
// VTX Read from parameter memory space
//===----------------------------------------------------------------------===//
+def VTX_READ_PARAM_8_eg : VTX_READ_8_eg <0,
+ [(set (i32 R600_TReg32_X:$dst), (load_param_zexti8 ADDRVTX_READ:$ptr))]
+>;
+
+def VTX_READ_PARAM_16_eg : VTX_READ_16_eg <0,
+ [(set (i32 R600_TReg32_X:$dst), (load_param_zexti16 ADDRVTX_READ:$ptr))]
+>;
+
def VTX_READ_PARAM_32_eg : VTX_READ_32_eg <0,
[(set (i32 R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))]
>;
diff --git a/test/CodeGen/R600/short-args.ll b/test/CodeGen/R600/short-args.ll
new file mode 100644
index 0000000..1070250
--- /dev/null
+++ b/test/CodeGen/R600/short-args.ll
@@ -0,0 +1,37 @@
+; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s
+
+; CHECK: VTX_READ_8 T{{[0-9]+\.X, T[0-9]+\.X}}
+
+define void @i8_arg(i32 addrspace(1)* nocapture %out, i8 %in) nounwind {
+entry:
+ %0 = zext i8 %in to i32
+ store i32 %0, i32 addrspace(1)* %out, align 4
+ ret void
+}
+
+; CHECK: VTX_READ_8 T{{[0-9]+\.X, T[0-9]+\.X}}
+
+define void @i8_zext_arg(i32 addrspace(1)* nocapture %out, i8 zeroext %in) nounwind {
+entry:
+ %0 = zext i8 %in to i32
+ store i32 %0, i32 addrspace(1)* %out, align 4
+ ret void
+}
+
+; CHECK: VTX_READ_16 T{{[0-9]+\.X, T[0-9]+\.X}}
+
+define void @i16_arg(i32 addrspace(1)* nocapture %out, i16 %in) nounwind {
+entry:
+ %0 = zext i16 %in to i32
+ store i32 %0, i32 addrspace(1)* %out, align 4
+ ret void
+}
+
+; CHECK: VTX_READ_16 T{{[0-9]+\.X, T[0-9]+\.X}}
+
+define void @i16_zext_arg(i32 addrspace(1)* nocapture %out, i16 zeroext %in) nounwind {
+entry:
+ %0 = zext i16 %in to i32
+ store i32 %0, i32 addrspace(1)* %out, align 4
+ ret void
+}
--
1.7.11.4
More information about the mesa-dev
mailing list