llvm-6502/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp
Michel Danzer 01115b1f50 R600/SI: Fix int_SI_fs_interp_constant
The important fix is that the constant interpolation value is stored in the
parameter slot P0, which is encoded as 2.

In addition, drop the SI_INTERP_CONST pseudo instruction, pass the parameter
slot as an operand to V_INTERP_MOV_F32 instead of hardcoding it there, and
add a special operand class for the parameter slots for type checking and
pretty printing.

NOTE: This is a candidate for the Mesa stable branch.

Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175193 91177308-0d34-0410-b5e6-96231b3b80d8
2013-02-14 19:03:25 +00:00

169 lines
4.4 KiB
C++

//===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
// \file
//===----------------------------------------------------------------------===//
#include "AMDGPUInstPrinter.h"
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
#include "llvm/MC/MCInst.h"
using namespace llvm;
void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
StringRef Annot) {
printInstruction(MI, OS);
printAnnotation(OS, Annot);
}
void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
switch (Op.getReg()) {
// This is the default predicate state, so we don't need to print it.
case AMDGPU::PRED_SEL_OFF: break;
default: O << getRegisterName(Op.getReg()); break;
}
} else if (Op.isImm()) {
O << Op.getImm();
} else if (Op.isFPImm()) {
O << Op.getFPImm();
} else {
assert(!"unknown operand type in printOperand");
}
}
void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
raw_ostream &O) {
unsigned Imm = MI->getOperand(OpNum).getImm();
if (Imm == 2) {
O << "P0";
} else if (Imm == 1) {
O << "P20";
} else if (Imm == 0) {
O << "P10";
} else {
assert(!"Invalid interpolation parameter slot");
}
}
void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
printOperand(MI, OpNo, O);
O << ", ";
printOperand(MI, OpNo + 1, O);
}
void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
raw_ostream &O, StringRef Asm) {
const MCOperand &Op = MI->getOperand(OpNo);
assert(Op.isImm());
if (Op.getImm() == 1) {
O << Asm;
}
}
void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
printIfSet(MI, OpNo, O, "|");
}
void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
printIfSet(MI, OpNo, O, "_SAT");
}
void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
union Literal {
float f;
int32_t i;
} L;
L.i = MI->getOperand(OpNo).getImm();
O << L.i << "(" << L.f << ")";
}
void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
printIfSet(MI, OpNo, O, " *");
}
void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
printIfSet(MI, OpNo, O, "-");
}
void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
switch (MI->getOperand(OpNo).getImm()) {
default: break;
case 1:
O << " * 2.0";
break;
case 2:
O << " * 4.0";
break;
case 3:
O << " / 2.0";
break;
}
}
void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
printIfSet(MI, OpNo, O, "+");
}
void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
printIfSet(MI, OpNo, O, "ExecMask,");
}
void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
printIfSet(MI, OpNo, O, "Pred,");
}
void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.getImm() == 0) {
O << " (MASKED)";
}
}
void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const char * chans = "XYZW";
int sel = MI->getOperand(OpNo).getImm();
int chan = sel & 3;
sel >>= 2;
if (sel >= 512) {
sel -= 512;
int cb = sel >> 12;
sel &= 4095;
O << cb << "[" << sel << "]";
} else if (sel >= 448) {
sel -= 448;
O << sel;
} else if (sel >= 0){
O << sel;
}
if (sel >= 0)
O << "." << chans[chan];
}
#include "AMDGPUGenAsmWriter.inc"