summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon/SIInstrInfo.cpp
blob: 058c772e620a80d9a48f7a49c04d274a18241feb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//===-- SIInstrInfo.cpp - SI Instruction Information  ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// SI Implementation of TargetInstrInfo.
//
//===----------------------------------------------------------------------===//


#include "SIInstrInfo.h"
#include "AMDGPUTargetMachine.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/MC/MCInstrDesc.h"

#include <stdio.h>

using namespace llvm;

SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm)
  : AMDGPUInstrInfo(tm),
    RI(tm, *this),
    TM(tm)
    { }

const SIRegisterInfo &SIInstrInfo::getRegisterInfo() const
{
  return RI;
}

void
SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                           MachineBasicBlock::iterator MI, DebugLoc DL,
                           unsigned DestReg, unsigned SrcReg,
                           bool KillSrc) const
{
  BuildMI(MBB, MI, DL, get(AMDIL::V_MOV_B32_e32), DestReg)
   .addReg(SrcReg, getKillRegState(KillSrc));
}

unsigned SIInstrInfo::getEncodingType(const MachineInstr &MI) const
{
  return get(MI.getOpcode()).TSFlags & SI_INSTR_FLAGS_ENCODING_MASK;
}

unsigned SIInstrInfo::getEncodingBytes(const MachineInstr &MI) const
{

  /* Instructions with literal constants are expanded to 64-bits, and
   * the constant is stored in bits [63:32] */
  for (unsigned i = 0; i < MI.getNumOperands(); i++) {
    if (MI.getOperand(i).getType() == MachineOperand::MO_FPImmediate) {
      return 8;
    }
  }

  /* This instruction always has a literal */
  if (MI.getOpcode() == AMDIL::S_MOV_IMM_I32) {
    return 8;
  }

  unsigned encoding_type = getEncodingType(MI);
  switch (encoding_type) {
    case SIInstrEncodingType::EXP:
    case SIInstrEncodingType::LDS:
    case SIInstrEncodingType::MUBUF:
    case SIInstrEncodingType::MTBUF:
    case SIInstrEncodingType::MIMG:
    case SIInstrEncodingType::VOP3:
      return 8;
    default:
      return 4;
  }
}

MachineInstr * SIInstrInfo::convertToISA(MachineInstr & MI, MachineFunction &MF,
    DebugLoc DL) const
{
  MachineInstr * newMI = AMDGPUInstrInfo::convertToISA(MI, MF, DL);
  const MCInstrDesc &newDesc = get(newMI->getOpcode());

  /* If this instruction was converted to a VOP3, we need to add the extra
   * operands for abs, clamp, omod, and negate. */
  if (getEncodingType(*newMI) == SIInstrEncodingType::VOP3
      && newMI->getNumOperands() < newDesc.getNumOperands()) {
    MachineInstrBuilder builder(newMI);
    for (unsigned op_idx = newMI->getNumOperands();
                  op_idx < newDesc.getNumOperands(); op_idx++) {
      builder.addImm(0);
    }
  }
  return newMI;
}

unsigned SIInstrInfo::getISAOpcode(unsigned AMDILopcode) const
{
  switch (AMDILopcode) {
  //XXX We need a better way of detecting end of program
  case AMDIL::MOVE_f32: return AMDIL::V_MOV_B32_e32;
  default: return AMDILopcode;
  }
}

MachineInstr * SIInstrInfo::getMovImmInstr(MachineFunction *MF, unsigned DstReg,
                                           int64_t Imm) const
{
  MachineInstr * MI = MF->CreateMachineInstr(get(AMDIL::V_MOV_IMM_I32), DebugLoc());
  MachineInstrBuilder(MI).addReg(DstReg, RegState::Define);
  MachineInstrBuilder(MI).addImm(Imm);

  return MI;

}

bool SIInstrInfo::isMov(unsigned Opcode) const
{
  switch(Opcode) {
  default: return false;
  case AMDIL::S_MOV_B32:
  case AMDIL::S_MOV_B64:
  case AMDIL::V_MOV_B32_e32:
  case AMDIL::V_MOV_B32_e64:
  case AMDIL::V_MOV_IMM_F32:
  case AMDIL::V_MOV_IMM_I32:
  case AMDIL::S_MOV_IMM_I32:
    return true;
  }
}