Home | History | Annotate | Download | only in radeon
      1 //===-- AMDGPUAsmPrinter.cpp - AMDGPU Assebly printer  --------------------===//
      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 // The AMDGPUAsmPrinter is used to print both assembly string and also binary
     11 // code.  When passed an MCAsmStreamer it prints assembly and when passed
     12 // an MCObjectStreamer it outputs binary code.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 //
     16 
     17 
     18 #include "AMDGPUAsmPrinter.h"
     19 #include "AMDGPU.h"
     20 #include "SIMachineFunctionInfo.h"
     21 #include "SIRegisterInfo.h"
     22 #include "llvm/MC/MCStreamer.h"
     23 #include "llvm/Target/TargetLoweringObjectFile.h"
     24 #include "llvm/Support/TargetRegistry.h"
     25 
     26 using namespace llvm;
     27 
     28 
     29 static AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm,
     30                                               MCStreamer &Streamer) {
     31   return new AMDGPUAsmPrinter(tm, Streamer);
     32 }
     33 
     34 extern "C" void LLVMInitializeAMDGPUAsmPrinter() {
     35   TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass);
     36 }
     37 
     38 /// runOnMachineFunction - We need to override this function so we can avoid
     39 /// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle.
     40 bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     41   const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>();
     42   if (STM.dumpCode()) {
     43     MF.dump();
     44   }
     45   SetupMachineFunction(MF);
     46   if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
     47     EmitProgramInfo(MF);
     48   }
     49   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
     50   EmitFunctionBody();
     51   return false;
     52 }
     53 
     54 void AMDGPUAsmPrinter::EmitProgramInfo(MachineFunction &MF) {
     55   unsigned MaxSGPR = 0;
     56   unsigned MaxVGPR = 0;
     57   bool VCCUsed = false;
     58   const SIRegisterInfo * RI =
     59                 static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
     60 
     61   for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
     62                                                   BB != BB_E; ++BB) {
     63     MachineBasicBlock &MBB = *BB;
     64     for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
     65                                                     I != E; ++I) {
     66       MachineInstr &MI = *I;
     67 
     68       unsigned numOperands = MI.getNumOperands();
     69       for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
     70         MachineOperand & MO = MI.getOperand(op_idx);
     71         unsigned maxUsed;
     72         unsigned width = 0;
     73         bool isSGPR = false;
     74         unsigned reg;
     75         unsigned hwReg;
     76         if (!MO.isReg()) {
     77           continue;
     78         }
     79         reg = MO.getReg();
     80         if (reg == AMDGPU::VCC) {
     81           VCCUsed = true;
     82           continue;
     83         }
     84         if (reg == AMDGPU::EXEC) {
     85           continue;
     86         }
     87         if (AMDGPU::SReg_32RegClass.contains(reg)) {
     88           isSGPR = true;
     89           width = 1;
     90         } else if (AMDGPU::VReg_32RegClass.contains(reg)) {
     91           isSGPR = false;
     92           width = 1;
     93         } else if (AMDGPU::SReg_64RegClass.contains(reg)) {
     94           isSGPR = true;
     95           width = 2;
     96         } else if (AMDGPU::VReg_64RegClass.contains(reg)) {
     97           isSGPR = false;
     98           width = 2;
     99         } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
    100           isSGPR = true;
    101           width = 4;
    102         } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
    103           isSGPR = false;
    104           width = 4;
    105         } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
    106           isSGPR = true;
    107           width = 8;
    108         } else {
    109           assert("!Unknown register class");
    110         }
    111         hwReg = RI->getHWRegNum(reg);
    112         maxUsed = hwReg + width - 1;
    113         if (isSGPR) {
    114           MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
    115         } else {
    116           MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
    117         }
    118       }
    119     }
    120   }
    121   if (VCCUsed) {
    122     MaxSGPR += 2;
    123   }
    124   SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
    125   OutStreamer.EmitIntValue(MaxSGPR + 1, 4);
    126   OutStreamer.EmitIntValue(MaxVGPR + 1, 4);
    127   OutStreamer.EmitIntValue(MFI->spi_ps_input_addr, 4);
    128 }
    129