SIInstrInfo.cpp revision ef8e66bc165ea2ef9987ab6406268ce195f74eb0
1//===-- SIInstrInfo.cpp - SI Instruction Information  ---------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// SI Implementation of TargetInstrInfo.
11//
12//===----------------------------------------------------------------------===//
13
14
15#include "SIInstrInfo.h"
16#include "AMDGPUTargetMachine.h"
17#include "llvm/CodeGen/MachineRegisterInfo.h"
18#include "llvm/MC/MCInstrDesc.h"
19
20#include <stdio.h>
21
22using namespace llvm;
23
24SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm)
25  : AMDGPUInstrInfo(tm),
26    RI(tm, *this),
27    TM(tm)
28    { }
29
30const SIRegisterInfo &SIInstrInfo::getRegisterInfo() const
31{
32  return RI;
33}
34
35void
36SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
37                           MachineBasicBlock::iterator MI, DebugLoc DL,
38                           unsigned DestReg, unsigned SrcReg,
39                           bool KillSrc) const
40{
41  BuildMI(MBB, MI, DL, get(AMDIL::V_MOV_B32_e32), DestReg)
42   .addReg(SrcReg, getKillRegState(KillSrc));
43}
44
45unsigned SIInstrInfo::getEncodingType(const MachineInstr &MI) const
46{
47  return get(MI.getOpcode()).TSFlags & SI_INSTR_FLAGS_ENCODING_MASK;
48}
49
50unsigned SIInstrInfo::getEncodingBytes(const MachineInstr &MI) const
51{
52
53  /* Instructions with literal constants are expanded to 64-bits, and
54   * the constant is stored in bits [63:32] */
55  for (unsigned i = 0; i < MI.getNumOperands(); i++) {
56    if (MI.getOperand(i).getType() == MachineOperand::MO_FPImmediate) {
57      return 8;
58    }
59  }
60
61  /* This instruction always has a literal */
62  if (MI.getOpcode() == AMDIL::S_MOV_IMM_I32) {
63    return 8;
64  }
65
66  unsigned encoding_type = getEncodingType(MI);
67  switch (encoding_type) {
68    case SIInstrEncodingType::EXP:
69    case SIInstrEncodingType::LDS:
70    case SIInstrEncodingType::MUBUF:
71    case SIInstrEncodingType::MTBUF:
72    case SIInstrEncodingType::MIMG:
73    case SIInstrEncodingType::VOP3:
74      return 8;
75    default:
76      return 4;
77  }
78}
79
80MachineInstr * SIInstrInfo::convertToISA(MachineInstr & MI, MachineFunction &MF,
81    DebugLoc DL) const
82{
83
84  switch (MI.getOpcode()) {
85    default: break;
86    case AMDIL::ABS_f32: return convertABS_f32(MI, MF, DL);
87    case AMDIL::CLAMP_f32: return convertCLAMP_f32(MI, MF, DL);
88  }
89
90  MachineInstr * newMI = AMDGPUInstrInfo::convertToISA(MI, MF, DL);
91  const MCInstrDesc &newDesc = get(newMI->getOpcode());
92
93  /* If this instruction was converted to a VOP3, we need to add the extra
94   * operands for abs, clamp, omod, and negate. */
95  if (getEncodingType(*newMI) == SIInstrEncodingType::VOP3
96      && newMI->getNumOperands() < newDesc.getNumOperands()) {
97    MachineInstrBuilder builder(newMI);
98    for (unsigned op_idx = newMI->getNumOperands();
99                  op_idx < newDesc.getNumOperands(); op_idx++) {
100      builder.addImm(0);
101    }
102  }
103  return newMI;
104}
105
106unsigned SIInstrInfo::getISAOpcode(unsigned AMDILopcode) const
107{
108  switch (AMDILopcode) {
109  //XXX We need a better way of detecting end of program
110  case AMDIL::RETURN: return AMDIL::S_ENDPGM;
111  default: return AMDGPUInstrInfo::getISAOpcode(AMDILopcode);
112  }
113}
114
115MachineInstr * SIInstrInfo::convertABS_f32(MachineInstr & absInstr,
116    MachineFunction &MF, DebugLoc DL) const
117{
118  MachineRegisterInfo &MRI = MF.getRegInfo();
119  MachineOperand &dst = absInstr.getOperand(0);
120
121  /* Convert the desination register to the VReg_32 class */
122  if (TargetRegisterInfo::isVirtualRegister(dst.getReg())) {
123    MRI.setRegClass(dst.getReg(), AMDIL::VReg_32RegisterClass);
124  }
125
126  return BuildMI(MF, DL, get(AMDIL::V_MOV_B32_e64))
127                 .addOperand(absInstr.getOperand(0))
128                 .addOperand(absInstr.getOperand(1))
129                /* VSRC1-2 are unused, but we still need to fill all the
130                 * operand slots, so we just reuse the VSRC0 operand */
131                 .addOperand(absInstr.getOperand(1))
132                 .addOperand(absInstr.getOperand(1))
133                 .addImm(1) // ABS
134                 .addImm(0) // CLAMP
135                 .addImm(0) // OMOD
136                 .addImm(0); // NEG
137}
138
139MachineInstr * SIInstrInfo::convertCLAMP_f32(MachineInstr & clampInstr,
140    MachineFunction &MF, DebugLoc DL) const
141{
142  MachineRegisterInfo &MRI = MF.getRegInfo();
143  /* XXX: HACK assume that low == zero and high == one for now until
144   * we have a way to propogate the immediates. */
145
146/*
147  uint32_t zero = (uint32_t)APFloat(0.0f).bitcastToAPInt().getZExtValue();
148  uint32_t one = (uint32_t)APFloat(1.0f).bitcastToAPInt().getZExtValue();
149  uint32_t low = clampInstr.getOperand(2).getImm();
150  uint32_t high = clampInstr.getOperand(3).getImm();
151*/
152//  if (low == zero && high == one) {
153
154  /* Convert the desination register to the VReg_32 class */
155  if (TargetRegisterInfo::isVirtualRegister(clampInstr.getOperand(0).getReg())) {
156    MRI.setRegClass(clampInstr.getOperand(0).getReg(),
157                    AMDIL::VReg_32RegisterClass);
158  }
159  return BuildMI(MF, DL, get(AMDIL::V_MOV_B32_e64))
160           .addOperand(clampInstr.getOperand(0))
161           .addOperand(clampInstr.getOperand(1))
162          /* VSRC1-2 are unused, but we still need to fill all the
163           * operand slots, so we just reuse the VSRC0 operand */
164           .addOperand(clampInstr.getOperand(1))
165           .addOperand(clampInstr.getOperand(1))
166           .addImm(0) // ABS
167           .addImm(1) // CLAMP
168           .addImm(0) // OMOD
169           .addImm(0); // NEG
170//  } else {
171    /* XXX: Handle other cases */
172//    abort();
173//  }
174}
175