#define GET_INSTRINFO_ENUM
#include "AMDGPUGenInstrInfo.inc"
+#define MO_FLAG_CLAMP (1 << 0)
+#define MO_FLAG_NEG (1 << 1)
+#define MO_FLAG_ABS (1 << 2)
+#define MO_FLAG_MASK (1 << 3)
+
namespace llvm {
class AMDGPUTargetMachine;
using namespace llvm;
-// Some instructions act as place holders to emulate operations that the GPU
-// hardware does automatically. This function can be used to check if
-// an opcode falls into this category.
-bool AMDGPU::isPlaceHolderOpcode(unsigned opcode)
-{
- switch (opcode) {
- default: return false;
- case AMDGPU::RETURN:
- case AMDGPU::LAST:
- case AMDGPU::MASK_WRITE:
- case AMDGPU::RESERVE_REG:
- return true;
- }
-}
-
-bool AMDGPU::isTransOp(unsigned opcode)
-{
- switch(opcode) {
- default: return false;
-
- case AMDGPU::COS_r600:
- case AMDGPU::COS_eg:
- case AMDGPU::MULLIT:
- case AMDGPU::MUL_LIT_r600:
- case AMDGPU::MUL_LIT_eg:
- case AMDGPU::EXP_IEEE_r600:
- case AMDGPU::EXP_IEEE_eg:
- case AMDGPU::LOG_CLAMPED_r600:
- case AMDGPU::LOG_IEEE_r600:
- case AMDGPU::LOG_CLAMPED_eg:
- case AMDGPU::LOG_IEEE_eg:
- return true;
- }
-}
-
-bool AMDGPU::isTexOp(unsigned opcode)
-{
- switch(opcode) {
- default: return false;
- case AMDGPU::TEX_LD:
- case AMDGPU::TEX_GET_TEXTURE_RESINFO:
- case AMDGPU::TEX_SAMPLE:
- case AMDGPU::TEX_SAMPLE_C:
- case AMDGPU::TEX_SAMPLE_L:
- case AMDGPU::TEX_SAMPLE_C_L:
- case AMDGPU::TEX_SAMPLE_LB:
- case AMDGPU::TEX_SAMPLE_C_LB:
- case AMDGPU::TEX_SAMPLE_G:
- case AMDGPU::TEX_SAMPLE_C_G:
- case AMDGPU::TEX_GET_GRADIENTS_H:
- case AMDGPU::TEX_GET_GRADIENTS_V:
- case AMDGPU::TEX_SET_GRADIENTS_H:
- case AMDGPU::TEX_SET_GRADIENTS_V:
- return true;
- }
-}
-
-bool AMDGPU::isReductionOp(unsigned opcode)
-{
- switch(opcode) {
- default: return false;
- case AMDGPU::DOT4_r600:
- case AMDGPU::DOT4_eg:
- return true;
- }
-}
-
-bool AMDGPU::isCubeOp(unsigned opcode)
-{
- switch(opcode) {
- default: return false;
- case AMDGPU::CUBE_r600:
- case AMDGPU::CUBE_eg:
- return true;
- }
-}
-
-
-bool AMDGPU::isFCOp(unsigned opcode)
-{
- switch(opcode) {
- default: return false;
- case AMDGPU::BREAK_LOGICALZ_f32:
- case AMDGPU::BREAK_LOGICALNZ_i32:
- case AMDGPU::BREAK_LOGICALZ_i32:
- case AMDGPU::BREAK_LOGICALNZ_f32:
- case AMDGPU::CONTINUE_LOGICALNZ_f32:
- case AMDGPU::IF_LOGICALNZ_i32:
- case AMDGPU::IF_LOGICALZ_f32:
- case AMDGPU::ELSE:
- case AMDGPU::ENDIF:
- case AMDGPU::ENDLOOP:
- case AMDGPU::IF_LOGICALNZ_f32:
- case AMDGPU::WHILELOOP:
- return true;
- }
-}
-
void AMDGPU::utilAddLiveIn(MachineFunction * MF,
MachineRegisterInfo & MRI,
const TargetInstrInfo * TII,
namespace AMDGPU {
-bool isPlaceHolderOpcode(unsigned opcode);
-
-bool isTransOp(unsigned opcode);
-bool isTexOp(unsigned opcode);
-bool isReductionOp(unsigned opcode);
-bool isCubeOp(unsigned opcode);
-bool isFCOp(unsigned opcode);
-
-// XXX: Move these to AMDGPUInstrInfo.h
-#define MO_FLAG_CLAMP (1 << 0)
-#define MO_FLAG_NEG (1 << 1)
-#define MO_FLAG_ABS (1 << 2)
-#define MO_FLAG_MASK (1 << 3)
-
void utilAddLiveIn(MachineFunction * MF, MachineRegisterInfo & MRI,
const TargetInstrInfo * TII, unsigned physReg, unsigned virtReg);
#include "AMDGPU.h"
#include "AMDGPUCodeEmitter.h"
-#include "AMDGPUUtil.h"
#include "AMDGPUInstrInfo.h"
#include "AMDILUtilityFunctions.h"
#include "R600InstrInfo.h"
const TargetMachine * TM;
const MachineRegisterInfo * MRI;
const R600RegisterInfo * TRI;
+ const R600InstrInfo * TII;
bool IsCube;
bool IsReduction;
TM = &MF.getTarget();
MRI = &MF.getRegInfo();
TRI = static_cast<const R600RegisterInfo *>(TM->getRegisterInfo());
- const R600InstrInfo * TII = static_cast<const R600InstrInfo *>(TM->getInstrInfo());
+ TII = static_cast<const R600InstrInfo *>(TM->getInstrInfo());
const AMDGPUSubtarget &STM = TM->getSubtarget<AMDGPUSubtarget>();
std::string gpu = STM.getDeviceName();
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
I != E; ++I) {
MachineInstr &MI = *I;
- IsReduction = AMDGPU::isReductionOp(MI.getOpcode());
+ IsReduction = TII->isReductionOp(MI.getOpcode());
IsVector = TII->isVector(MI);
- IsCube = AMDGPU::isCubeOp(MI.getOpcode());
+ IsCube = TII->isCubeOp(MI.getOpcode());
if (MI.getNumOperands() > 1 && MI.getOperand(0).isReg() && MI.getOperand(0).isDead()) {
continue;
}
- if (AMDGPU::isTexOp(MI.getOpcode())) {
+ if (TII->isTexOp(MI.getOpcode())) {
EmitTexInstr(MI);
- } else if (AMDGPU::isFCOp(MI.getOpcode())){
+ } else if (TII->isFCOp(MI.getOpcode())){
EmitFCInstr(MI);
} else if (IsReduction || IsVector || IsCube) {
IsLast = false;
// Some instructions are just place holder instructions that represent
// operations that the GPU does automatically. They should be ignored.
- if (AMDGPU::isPlaceHolderOpcode(MI.getOpcode())) {
+ if (TII->isPlaceHolderOpcode(MI.getOpcode())) {
return;
}
}
}
+// Some instructions act as place holders to emulate operations that the GPU
+// hardware does automatically. This function can be used to check if
+// an opcode falls into this category.
+bool R600InstrInfo::isPlaceHolderOpcode(unsigned opcode) const
+{
+ switch (opcode) {
+ default: return false;
+ case AMDGPU::RETURN:
+ case AMDGPU::LAST:
+ case AMDGPU::MASK_WRITE:
+ case AMDGPU::RESERVE_REG:
+ return true;
+ }
+}
+
+bool R600InstrInfo::isTexOp(unsigned opcode) const
+{
+ switch(opcode) {
+ default: return false;
+ case AMDGPU::TEX_LD:
+ case AMDGPU::TEX_GET_TEXTURE_RESINFO:
+ case AMDGPU::TEX_SAMPLE:
+ case AMDGPU::TEX_SAMPLE_C:
+ case AMDGPU::TEX_SAMPLE_L:
+ case AMDGPU::TEX_SAMPLE_C_L:
+ case AMDGPU::TEX_SAMPLE_LB:
+ case AMDGPU::TEX_SAMPLE_C_LB:
+ case AMDGPU::TEX_SAMPLE_G:
+ case AMDGPU::TEX_SAMPLE_C_G:
+ case AMDGPU::TEX_GET_GRADIENTS_H:
+ case AMDGPU::TEX_GET_GRADIENTS_V:
+ case AMDGPU::TEX_SET_GRADIENTS_H:
+ case AMDGPU::TEX_SET_GRADIENTS_V:
+ return true;
+ }
+}
+
+bool R600InstrInfo::isReductionOp(unsigned opcode) const
+{
+ switch(opcode) {
+ default: return false;
+ case AMDGPU::DOT4_r600:
+ case AMDGPU::DOT4_eg:
+ return true;
+ }
+}
+
+bool R600InstrInfo::isCubeOp(unsigned opcode) const
+{
+ switch(opcode) {
+ default: return false;
+ case AMDGPU::CUBE_r600:
+ case AMDGPU::CUBE_eg:
+ return true;
+ }
+}
+
+
+bool R600InstrInfo::isFCOp(unsigned opcode) const
+{
+ switch(opcode) {
+ default: return false;
+ case AMDGPU::BREAK_LOGICALZ_f32:
+ case AMDGPU::BREAK_LOGICALNZ_i32:
+ case AMDGPU::BREAK_LOGICALZ_i32:
+ case AMDGPU::BREAK_LOGICALNZ_f32:
+ case AMDGPU::CONTINUE_LOGICALNZ_f32:
+ case AMDGPU::IF_LOGICALNZ_i32:
+ case AMDGPU::IF_LOGICALZ_f32:
+ case AMDGPU::ELSE:
+ case AMDGPU::ENDIF:
+ case AMDGPU::ENDLOOP:
+ case AMDGPU::IF_LOGICALNZ_f32:
+ case AMDGPU::WHILELOOP:
+ return true;
+ }
+}
+
DFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM,
const ScheduleDAG *DAG) const
{
bool KillSrc) const;
bool isTrig(const MachineInstr &MI) const;
+ bool isPlaceHolderOpcode(unsigned opcode) const;
+ bool isTexOp(unsigned opcode) const;
+ bool isReductionOp(unsigned opcode) const;
+ bool isCubeOp(unsigned opcode) const;
+ bool isFCOp(unsigned opcode) const;
/// isVector - Vector instructions are instructions that must fill all
/// instruction slots within an instruction group.