[llvm-commits] [llvm] r169915 - in /llvm/trunk: include/llvm/ lib/Target/ lib/Target/R600/ lib/Target/R600/InstPrinter/ lib/Target/R600/MCTargetDesc/ lib/Target/R600/TargetInfo/ test/CodeGen/R600/ test/CodeGen/SI/
Daniel Dunbar
daniel at zuster.org
Thu Aug 15 17:12:08 PDT 2013
Hi Tom,
The test in test/CodeGen/SI doesn't actually get run currently, because
there is no lit.local.cfg which enables its suffix. I am about to fix this
problem globally, but this test crashes now on my machine:
--
-- Testing: 1 tests, 1 threads --
Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
FAIL: LLVM :: CodeGen/SI/sanity.ll (1 of 1)
******************** TEST 'LLVM :: CodeGen/SI/sanity.ll' FAILED
********************
Script:
--
/Volumes/OzzyData/Users/ddunbar/llvm.obj.64/Debug+Asserts/bin/llc <
/Volumes/OzzyData/Users/ddunbar/llvm/test/CodeGen/SI/sanity.ll -march=r600
-mcpu=SI |
/Volumes/OzzyData/Users/ddunbar/llvm.obj.64/Debug+Asserts/bin/FileCheck
/Volumes/OzzyData/Users/ddunbar/llvm/test/CodeGen/SI/sanity.ll
--
Exit Code: 2
Command Output (stderr):
--
0x7fe0f1034210: i64 = GlobalAddress<void (i32)* @llvm.AMDGPU.shader.type> 0
[ORD=1]
Undefined function
UNREACHABLE executed at
/Volumes/OzzyData/Users/ddunbar/llvm/lib/Target/R600/AMDGPUISelLowering.h:68!
0 llc 0x00000001091b9dfe
llvm::sys::PrintStackTrace(__sFILE*) + 46
1 llc 0x00000001091ba10b
PrintStackTraceSignalHandler(void*) + 27
2 llc 0x00000001091ba488 SignalHandler(int) + 408
3 libsystem_platform.dylib 0x00007fff94c095aa _sigtramp + 26
4 llc 0x00000001096ff2df guard variable for
llvm::system_category()::s + 621559
5 llc 0x00000001091ba13b raise + 27
6 llc 0x00000001091ba1f2 abort + 18
7 llc 0x0000000109198b86
llvm::llvm_unreachable_internal(char const*, char const*, unsigned int) +
198
8 llc 0x0000000107ec23ff
llvm::AMDGPUTargetLowering::LowerCall(llvm::TargetLowering::CallLoweringInfo&,
llvm::SmallVectorImpl<llvm::SDValue>&) const + 63
9 llc 0x00000001087af8f2
llvm::TargetLowering::LowerCallTo(llvm::TargetLowering::CallLoweringInfo&)
const + 4146
10 llc 0x0000000108794176
llvm::SelectionDAGBuilder::LowerCallTo(llvm::ImmutableCallSite,
llvm::SDValue, bool, llvm::MachineBasicBlock*) + 3494
11 llc 0x0000000108782105
llvm::SelectionDAGBuilder::visitCall(llvm::CallInst const&) + 2549
12 llc 0x0000000108779a49
llvm::SelectionDAGBuilder::visit(unsigned int, llvm::User const&) + 1097
13 llc 0x0000000108778ce3
llvm::SelectionDAGBuilder::visit(llvm::Instruction const&) + 131
14 llc 0x00000001087e876c
llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator<llvm::Instruction
const>, llvm::ilist_iterator<llvm::Instruction const>, bool&) + 140
15 llc 0x00000001087e8556
llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 4214
16 llc 0x00000001087e65a4
llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 1108
17 llc 0x0000000108a148be
llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 110
18 llc 0x00000001090f578f
llvm::FPPassManager::runOnFunction(llvm::Function&) + 431
19 llc 0x00000001090f5a78
llvm::FPPassManager::runOnModule(llvm::Module&) + 104
20 llc 0x00000001090f6146
llvm::MPPassManager::runOnModule(llvm::Module&) + 1350
21 llc 0x00000001090f6c0e
llvm::PassManagerImpl::run(llvm::Module&) + 302
22 llc 0x00000001090f6ea1
llvm::PassManager::run(llvm::Module&) + 33
23 llc 0x0000000107da8db9 compileModule(char**,
llvm::LLVMContext&) + 6185
24 llc 0x0000000107da7522 main + 226
25 libdyld.dylib 0x00007fff932d15fd start + 1
26 libdyld.dylib 0x0000000000000003 start + 1825761799
Stack dump:
0. Program arguments:
/Volumes/OzzyData/Users/ddunbar/llvm.obj.64/Debug+Asserts/bin/llc
-march=r600 -mcpu=SI
1. Running pass 'Function Pass Manager' on module '<stdin>'.
2. Running pass 'AMDGPU DAG->DAG Pattern Instruction Selection' on function
'@main'
FileCheck error: '-' is empty.
--
********************
Testing Time: 12.76s
********************
Failing Tests (1):
LLVM :: CodeGen/SI/sanity.ll
Unexpected Failures: 1
--
I will XFAIL it for the time being, but could you take a look?
Thanks,
- Daniel
On Tue, Dec 11, 2012 at 1:25 PM, Tom Stellard <thomas.stellard at amd.com>wrote:
> Author: tstellar
> Date: Tue Dec 11 15:25:42 2012
> New Revision: 169915
>
> URL: http://llvm.org/viewvc/llvm-project?rev=169915&view=rev
> Log:
> Add R600 backend
>
> A new backend supporting AMD GPUs: Radeon HD2XXX - HD7XXX
>
> Added:
> llvm/trunk/include/llvm/IntrinsicsR600.td
> llvm/trunk/lib/Target/R600/
> llvm/trunk/lib/Target/R600/AMDGPU.h
> llvm/trunk/lib/Target/R600/AMDGPU.td
> llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.cpp
> llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.h
> llvm/trunk/lib/Target/R600/AMDGPUCodeEmitter.h
> llvm/trunk/lib/Target/R600/AMDGPUConvertToISA.cpp
> llvm/trunk/lib/Target/R600/AMDGPUISelLowering.cpp
> llvm/trunk/lib/Target/R600/AMDGPUISelLowering.h
> llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.cpp
> llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.h
> llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.td
> llvm/trunk/lib/Target/R600/AMDGPUInstructions.td
> llvm/trunk/lib/Target/R600/AMDGPUIntrinsics.td
> llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.cpp
> llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.h
> llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.cpp
> llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.h
> llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.td
> llvm/trunk/lib/Target/R600/AMDGPUSubtarget.cpp
> llvm/trunk/lib/Target/R600/AMDGPUSubtarget.h
> llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp
> llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.h
> llvm/trunk/lib/Target/R600/AMDIL.h
> llvm/trunk/lib/Target/R600/AMDIL7XXDevice.cpp
> llvm/trunk/lib/Target/R600/AMDIL7XXDevice.h
> llvm/trunk/lib/Target/R600/AMDILBase.td
> llvm/trunk/lib/Target/R600/AMDILCFGStructurizer.cpp
> llvm/trunk/lib/Target/R600/AMDILDevice.cpp
> llvm/trunk/lib/Target/R600/AMDILDevice.h
> llvm/trunk/lib/Target/R600/AMDILDeviceInfo.cpp
> llvm/trunk/lib/Target/R600/AMDILDeviceInfo.h
> llvm/trunk/lib/Target/R600/AMDILDevices.h
> llvm/trunk/lib/Target/R600/AMDILEvergreenDevice.cpp
> llvm/trunk/lib/Target/R600/AMDILEvergreenDevice.h
> llvm/trunk/lib/Target/R600/AMDILFrameLowering.cpp
> llvm/trunk/lib/Target/R600/AMDILFrameLowering.h
> llvm/trunk/lib/Target/R600/AMDILISelDAGToDAG.cpp
> llvm/trunk/lib/Target/R600/AMDILISelLowering.cpp
> llvm/trunk/lib/Target/R600/AMDILInstrInfo.td
> llvm/trunk/lib/Target/R600/AMDILIntrinsicInfo.cpp
> llvm/trunk/lib/Target/R600/AMDILIntrinsicInfo.h
> llvm/trunk/lib/Target/R600/AMDILIntrinsics.td
> llvm/trunk/lib/Target/R600/AMDILNIDevice.cpp
> llvm/trunk/lib/Target/R600/AMDILNIDevice.h
> llvm/trunk/lib/Target/R600/AMDILPeepholeOptimizer.cpp
> llvm/trunk/lib/Target/R600/AMDILRegisterInfo.td
> llvm/trunk/lib/Target/R600/AMDILSIDevice.cpp
> llvm/trunk/lib/Target/R600/AMDILSIDevice.h
> llvm/trunk/lib/Target/R600/CMakeLists.txt
> llvm/trunk/lib/Target/R600/InstPrinter/
> llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp
> llvm/trunk/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.h
> llvm/trunk/lib/Target/R600/InstPrinter/CMakeLists.txt
> llvm/trunk/lib/Target/R600/InstPrinter/LLVMBuild.txt
> llvm/trunk/lib/Target/R600/InstPrinter/Makefile
> llvm/trunk/lib/Target/R600/LLVMBuild.txt
> llvm/trunk/lib/Target/R600/MCTargetDesc/
> llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp
> llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCAsmInfo.cpp
> llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCAsmInfo.h
> llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h
> llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp
> llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.h
> llvm/trunk/lib/Target/R600/MCTargetDesc/CMakeLists.txt
> llvm/trunk/lib/Target/R600/MCTargetDesc/LLVMBuild.txt
> llvm/trunk/lib/Target/R600/MCTargetDesc/Makefile
> llvm/trunk/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
> llvm/trunk/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> llvm/trunk/lib/Target/R600/Makefile
> llvm/trunk/lib/Target/R600/Processors.td
> llvm/trunk/lib/Target/R600/R600Defines.h
> llvm/trunk/lib/Target/R600/R600ExpandSpecialInstrs.cpp
> llvm/trunk/lib/Target/R600/R600ISelLowering.cpp
> llvm/trunk/lib/Target/R600/R600ISelLowering.h
> llvm/trunk/lib/Target/R600/R600InstrInfo.cpp
> llvm/trunk/lib/Target/R600/R600InstrInfo.h
> llvm/trunk/lib/Target/R600/R600Instructions.td
> llvm/trunk/lib/Target/R600/R600Intrinsics.td
> llvm/trunk/lib/Target/R600/R600MachineFunctionInfo.cpp
> llvm/trunk/lib/Target/R600/R600MachineFunctionInfo.h
> llvm/trunk/lib/Target/R600/R600RegisterInfo.cpp
> llvm/trunk/lib/Target/R600/R600RegisterInfo.h
> llvm/trunk/lib/Target/R600/R600RegisterInfo.td
> llvm/trunk/lib/Target/R600/R600Schedule.td
> llvm/trunk/lib/Target/R600/SIAssignInterpRegs.cpp
> llvm/trunk/lib/Target/R600/SIFixSGPRLiveness.cpp
> llvm/trunk/lib/Target/R600/SIISelLowering.cpp
> llvm/trunk/lib/Target/R600/SIISelLowering.h
> llvm/trunk/lib/Target/R600/SIInstrFormats.td
> llvm/trunk/lib/Target/R600/SIInstrInfo.cpp
> llvm/trunk/lib/Target/R600/SIInstrInfo.h
> llvm/trunk/lib/Target/R600/SIInstrInfo.td
> llvm/trunk/lib/Target/R600/SIInstructions.td
> llvm/trunk/lib/Target/R600/SIIntrinsics.td
> llvm/trunk/lib/Target/R600/SILowerControlFlow.cpp
> llvm/trunk/lib/Target/R600/SILowerLiteralConstants.cpp
> llvm/trunk/lib/Target/R600/SIMachineFunctionInfo.cpp
> llvm/trunk/lib/Target/R600/SIMachineFunctionInfo.h
> llvm/trunk/lib/Target/R600/SIRegisterInfo.cpp
> llvm/trunk/lib/Target/R600/SIRegisterInfo.h
> llvm/trunk/lib/Target/R600/SIRegisterInfo.td
> llvm/trunk/lib/Target/R600/SISchedule.td
> llvm/trunk/lib/Target/R600/TargetInfo/
> llvm/trunk/lib/Target/R600/TargetInfo/AMDGPUTargetInfo.cpp
> llvm/trunk/lib/Target/R600/TargetInfo/CMakeLists.txt
> llvm/trunk/lib/Target/R600/TargetInfo/LLVMBuild.txt
> llvm/trunk/lib/Target/R600/TargetInfo/Makefile
> llvm/trunk/test/CodeGen/R600/add.v4i32.ll
> llvm/trunk/test/CodeGen/R600/and.v4i32.ll
> llvm/trunk/test/CodeGen/R600/fabs.ll
> llvm/trunk/test/CodeGen/R600/fadd.ll
> llvm/trunk/test/CodeGen/R600/fadd.v4f32.ll
> llvm/trunk/test/CodeGen/R600/fcmp-cnd.ll
> llvm/trunk/test/CodeGen/R600/fcmp-cnde-int-args.ll
> llvm/trunk/test/CodeGen/R600/fcmp.ll
> llvm/trunk/test/CodeGen/R600/fdiv.v4f32.ll
> llvm/trunk/test/CodeGen/R600/floor.ll
> llvm/trunk/test/CodeGen/R600/fmax.ll
> llvm/trunk/test/CodeGen/R600/fmin.ll
> llvm/trunk/test/CodeGen/R600/fmul.ll
> llvm/trunk/test/CodeGen/R600/fmul.v4f32.ll
> llvm/trunk/test/CodeGen/R600/fsub.ll
> llvm/trunk/test/CodeGen/R600/fsub.v4f32.ll
> llvm/trunk/test/CodeGen/R600/i8_to_double_to_float.ll
> llvm/trunk/test/CodeGen/R600/icmp-select-sete-reverse-args.ll
> llvm/trunk/test/CodeGen/R600/lit.local.cfg
> llvm/trunk/test/CodeGen/R600/literals.ll
> llvm/trunk/test/CodeGen/R600/llvm.AMDGPU.mul.ll
> llvm/trunk/test/CodeGen/R600/llvm.AMDGPU.trunc.ll
> llvm/trunk/test/CodeGen/R600/llvm.cos.ll
> llvm/trunk/test/CodeGen/R600/llvm.pow.ll
> llvm/trunk/test/CodeGen/R600/llvm.sin.ll
> llvm/trunk/test/CodeGen/R600/load.constant_addrspace.f32.ll
> llvm/trunk/test/CodeGen/R600/load.i8.ll
> llvm/trunk/test/CodeGen/R600/reciprocal.ll
> llvm/trunk/test/CodeGen/R600/sdiv.ll
> llvm/trunk/test/CodeGen/R600/selectcc-icmp-select-float.ll
> llvm/trunk/test/CodeGen/R600/selectcc_cnde.ll
> llvm/trunk/test/CodeGen/R600/selectcc_cnde_int.ll
> llvm/trunk/test/CodeGen/R600/setcc.v4i32.ll
> llvm/trunk/test/CodeGen/R600/short-args.ll
> llvm/trunk/test/CodeGen/R600/store.v4f32.ll
> llvm/trunk/test/CodeGen/R600/store.v4i32.ll
> llvm/trunk/test/CodeGen/R600/udiv.v4i32.ll
> llvm/trunk/test/CodeGen/R600/urem.v4i32.ll
> llvm/trunk/test/CodeGen/SI/
> llvm/trunk/test/CodeGen/SI/sanity.ll
> Modified:
> llvm/trunk/include/llvm/Intrinsics.td
> llvm/trunk/lib/Target/LLVMBuild.txt
>
> Modified: llvm/trunk/include/llvm/Intrinsics.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=169915&r1=169914&r2=169915&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Intrinsics.td (original)
> +++ llvm/trunk/include/llvm/Intrinsics.td Tue Dec 11 15:25:42 2012
> @@ -472,3 +472,4 @@
> include "llvm/IntrinsicsHexagon.td"
> include "llvm/IntrinsicsNVVM.td"
> include "llvm/IntrinsicsMips.td"
> +include "llvm/IntrinsicsR600.td"
>
> Added: llvm/trunk/include/llvm/IntrinsicsR600.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsR600.td?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/include/llvm/IntrinsicsR600.td (added)
> +++ llvm/trunk/include/llvm/IntrinsicsR600.td Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,36 @@
> +//===- IntrinsicsR600.td - Defines R600 intrinsics ---------*- tablegen
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file defines all of the R600-specific intrinsics.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +let TargetPrefix = "r600" in {
> +
> +class R600ReadPreloadRegisterIntrinsic<string name>
> + : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
> + GCCBuiltin<name>;
> +
> +multiclass R600ReadPreloadRegisterIntrinsic_xyz<string prefix> {
> + def _x : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_x")>;
> + def _y : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_y")>;
> + def _z : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_z")>;
> +}
> +
> +defm int_r600_read_global_size : R600ReadPreloadRegisterIntrinsic_xyz <
> + "__builtin_r600_read_global_size">;
> +defm int_r600_read_local_size : R600ReadPreloadRegisterIntrinsic_xyz <
> + "__builtin_r600_read_local_size">;
> +defm int_r600_read_ngroups : R600ReadPreloadRegisterIntrinsic_xyz <
> + "__builtin_r600_read_ngroups">;
> +defm int_r600_read_tgid : R600ReadPreloadRegisterIntrinsic_xyz <
> + "__builtin_r600_read_tgid">;
> +defm int_r600_read_tidig : R600ReadPreloadRegisterIntrinsic_xyz <
> + "__builtin_r600_read_tidig">;
> +} // End TargetPrefix = "r600"
>
> Modified: llvm/trunk/lib/Target/LLVMBuild.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/LLVMBuild.txt?rev=169915&r1=169914&r2=169915&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/LLVMBuild.txt (original)
> +++ llvm/trunk/lib/Target/LLVMBuild.txt Tue Dec 11 15:25:42 2012
> @@ -16,7 +16,7 @@
>
> ;===------------------------------------------------------------------------===;
>
> [common]
> -subdirectories = ARM CppBackend Hexagon MBlaze MSP430 NVPTX Mips PowerPC
> Sparc X86 XCore
> +subdirectories = ARM CppBackend Hexagon MBlaze MSP430 NVPTX Mips PowerPC
> R600 Sparc X86 XCore
>
> ; This is a special group whose required libraries are extended (by
> llvm-build)
> ; with the best execution engine (the native JIT, if available, or the
>
> Added: llvm/trunk/lib/Target/R600/AMDGPU.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPU.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPU.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPU.h Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,48 @@
> +//===-- AMDGPU.h - MachineFunction passes hw codegen --------------*- C++
> -*-=//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +/// \file
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef AMDGPU_H
> +#define AMDGPU_H
> +
> +#include "AMDGPUTargetMachine.h"
> +#include "llvm/Support/TargetRegistry.h"
> +#include "llvm/Target/TargetMachine.h"
> +
> +namespace llvm {
> +
> +class FunctionPass;
> +class AMDGPUTargetMachine;
> +
> +// R600 Passes
> +FunctionPass* createR600KernelParametersPass(const DataLayout *TD);
> +FunctionPass *createR600ExpandSpecialInstrsPass(TargetMachine &tm);
> +
> +// SI Passes
> +FunctionPass *createSIAssignInterpRegsPass(TargetMachine &tm);
> +FunctionPass *createSILowerControlFlowPass(TargetMachine &tm);
> +FunctionPass *createSICodeEmitterPass(formatted_raw_ostream &OS);
> +FunctionPass *createSILowerLiteralConstantsPass(TargetMachine &tm);
> +FunctionPass *createSIFixSGPRLivenessPass(TargetMachine &tm);
> +
> +// Passes common to R600 and SI
> +FunctionPass *createAMDGPUConvertToISAPass(TargetMachine &tm);
> +
> +} // End namespace llvm
> +
> +namespace ShaderType {
> + enum Type {
> + PIXEL = 0,
> + VERTEX = 1,
> + GEOMETRY = 2,
> + COMPUTE = 3
> + };
> +}
> +
> +#endif // AMDGPU_H
>
> Added: llvm/trunk/lib/Target/R600/AMDGPU.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPU.td?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPU.td (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPU.td Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,40 @@
> +//===-- AMDIL.td - AMDIL Tablegen files --*- tablegen
> -*-------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//==-----------------------------------------------------------------------===//
> +
> +// Include AMDIL TD files
> +include "AMDILBase.td"
> +
> +
> +def AMDGPUInstrInfo : InstrInfo {
> + let guessInstructionProperties = 1;
> +}
> +
>
> +//===----------------------------------------------------------------------===//
> +// Declare the target which we are implementing
>
> +//===----------------------------------------------------------------------===//
> +def AMDGPUAsmWriter : AsmWriter {
> + string AsmWriterClassName = "InstPrinter";
> + int Variant = 0;
> + bit isMCAsmWriter = 1;
> +}
> +
> +def AMDGPU : Target {
> + // Pull in Instruction Info:
> + let InstructionSet = AMDGPUInstrInfo;
> + let AssemblyWriters = [AMDGPUAsmWriter];
> +}
> +
> +// Include AMDGPU TD files
> +include "R600Schedule.td"
> +include "SISchedule.td"
> +include "Processors.td"
> +include "AMDGPUInstrInfo.td"
> +include "AMDGPUIntrinsics.td"
> +include "AMDGPURegisterInfo.td"
> +include "AMDGPUInstructions.td"
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.cpp?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.cpp (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.cpp Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,138 @@
> +//===-- AMDGPUAsmPrinter.cpp - AMDGPU Assebly printer
> --------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +///
> +/// The AMDGPUAsmPrinter is used to print both assembly string and also
> binary
> +/// code. When passed an MCAsmStreamer it prints assembly and when passed
> +/// an MCObjectStreamer it outputs binary code.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +
> +
> +#include "AMDGPUAsmPrinter.h"
> +#include "AMDGPU.h"
> +#include "SIMachineFunctionInfo.h"
> +#include "SIRegisterInfo.h"
> +#include "llvm/MC/MCStreamer.h"
> +#include "llvm/Target/TargetLoweringObjectFile.h"
> +#include "llvm/Support/TargetRegistry.h"
> +
> +using namespace llvm;
> +
> +
> +static AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm,
> + MCStreamer &Streamer) {
> + return new AMDGPUAsmPrinter(tm, Streamer);
> +}
> +
> +extern "C" void LLVMInitializeR600AsmPrinter() {
> + TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget,
> createAMDGPUAsmPrinterPass);
> +}
> +
> +/// We need to override this function so we can avoid
> +/// the call to EmitFunctionHeader(), which the MCPureStreamer can't
> handle.
> +bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
> + const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>();
> + if (STM.dumpCode()) {
> +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
> + MF.dump();
> +#endif
> + }
> + SetupMachineFunction(MF);
> + OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
> + if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
> + EmitProgramInfo(MF);
> + }
> + EmitFunctionBody();
> + return false;
> +}
> +
> +void AMDGPUAsmPrinter::EmitProgramInfo(MachineFunction &MF) {
> + unsigned MaxSGPR = 0;
> + unsigned MaxVGPR = 0;
> + bool VCCUsed = false;
> + const SIRegisterInfo * RI =
> + static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
> +
> + for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
> + BB != BB_E; ++BB) {
> + MachineBasicBlock &MBB = *BB;
> + for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
> + I != E; ++I) {
> + MachineInstr &MI = *I;
> +
> + unsigned numOperands = MI.getNumOperands();
> + for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
> + MachineOperand & MO = MI.getOperand(op_idx);
> + unsigned maxUsed;
> + unsigned width = 0;
> + bool isSGPR = false;
> + unsigned reg;
> + unsigned hwReg;
> + if (!MO.isReg()) {
> + continue;
> + }
> + reg = MO.getReg();
> + if (reg == AMDGPU::VCC) {
> + VCCUsed = true;
> + continue;
> + }
> + switch (reg) {
> + default: break;
> + case AMDGPU::EXEC:
> + case AMDGPU::SI_LITERAL_CONSTANT:
> + case AMDGPU::SREG_LIT_0:
> + case AMDGPU::M0:
> + continue;
> + }
> +
> + if (AMDGPU::SReg_32RegClass.contains(reg)) {
> + isSGPR = true;
> + width = 1;
> + } else if (AMDGPU::VReg_32RegClass.contains(reg)) {
> + isSGPR = false;
> + width = 1;
> + } else if (AMDGPU::SReg_64RegClass.contains(reg)) {
> + isSGPR = true;
> + width = 2;
> + } else if (AMDGPU::VReg_64RegClass.contains(reg)) {
> + isSGPR = false;
> + width = 2;
> + } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
> + isSGPR = true;
> + width = 4;
> + } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
> + isSGPR = false;
> + width = 4;
> + } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
> + isSGPR = true;
> + width = 8;
> + } else {
> + assert(!"Unknown register class");
> + }
> + hwReg = RI->getEncodingValue(reg);
> + maxUsed = hwReg + width - 1;
> + if (isSGPR) {
> + MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
> + } else {
> + MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
> + }
> + }
> + }
> + }
> + if (VCCUsed) {
> + MaxSGPR += 2;
> + }
> + SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
> + OutStreamer.EmitIntValue(MaxSGPR + 1, 4);
> + OutStreamer.EmitIntValue(MaxVGPR + 1, 4);
> + OutStreamer.EmitIntValue(MFI->SPIPSInputAddr, 4);
> +}
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUAsmPrinter.h Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,44 @@
> +//===-- AMDGPUAsmPrinter.h - Print AMDGPU assembly code
> -------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief AMDGPU Assembly printer class.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef AMDGPU_ASMPRINTER_H
> +#define AMDGPU_ASMPRINTER_H
> +
> +#include "llvm/CodeGen/AsmPrinter.h"
> +
> +namespace llvm {
> +
> +class AMDGPUAsmPrinter : public AsmPrinter {
> +
> +public:
> + explicit AMDGPUAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
> + : AsmPrinter(TM, Streamer) { }
> +
> + virtual bool runOnMachineFunction(MachineFunction &MF);
> +
> + virtual const char *getPassName() const {
> + return "AMDGPU Assembly Printer";
> + }
> +
> + /// \brief Emit register usage information so that the GPU driver
> + /// can correctly setup the GPU state.
> + void EmitProgramInfo(MachineFunction &MF);
> +
> + /// Implemented in AMDGPUMCInstLower.cpp
> + virtual void EmitInstruction(const MachineInstr *MI);
> +};
> +
> +} // End anonymous llvm
> +
> +#endif //AMDGPU_ASMPRINTER_H
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUCodeEmitter.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUCodeEmitter.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUCodeEmitter.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUCodeEmitter.h Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,49 @@
> +//===-- AMDGPUCodeEmitter.h - AMDGPU Code Emitter interface
> -----------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief CodeEmitter interface for R600 and SI codegen.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef AMDGPUCODEEMITTER_H
> +#define AMDGPUCODEEMITTER_H
> +
> +namespace llvm {
> +
> +class AMDGPUCodeEmitter {
> +public:
> + uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;
> + virtual uint64_t getMachineOpValue(const MachineInstr &MI,
> + const MachineOperand &MO) const {
> return 0; }
> + virtual unsigned GPR4AlignEncode(const MachineInstr &MI,
> + unsigned OpNo) const {
> + return 0;
> + }
> + virtual unsigned GPR2AlignEncode(const MachineInstr &MI,
> + unsigned OpNo) const {
> + return 0;
> + }
> + virtual uint64_t VOPPostEncode(const MachineInstr &MI,
> + uint64_t Value) const {
> + return Value;
> + }
> + virtual uint64_t i32LiteralEncode(const MachineInstr &MI,
> + unsigned OpNo) const {
> + return 0;
> + }
> + virtual uint32_t SMRDmemriEncode(const MachineInstr &MI, unsigned OpNo)
> + const {
> + return 0;
> + }
> +};
> +
> +} // End namespace llvm
> +
> +#endif // AMDGPUCODEEMITTER_H
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUConvertToISA.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUConvertToISA.cpp?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUConvertToISA.cpp (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUConvertToISA.cpp Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,62 @@
> +//===-- AMDGPUConvertToISA.cpp - Lower AMDIL to HW ISA
> --------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief This pass lowers AMDIL machine instructions to the appropriate
> +/// hardware instructions.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "AMDGPU.h"
> +#include "AMDGPUInstrInfo.h"
> +#include "llvm/CodeGen/MachineFunctionPass.h"
> +
> +using namespace llvm;
> +
> +namespace {
> +
> +class AMDGPUConvertToISAPass : public MachineFunctionPass {
> +
> +private:
> + static char ID;
> + TargetMachine &TM;
> +
> +public:
> + AMDGPUConvertToISAPass(TargetMachine &tm) :
> + MachineFunctionPass(ID), TM(tm) { }
> +
> + virtual bool runOnMachineFunction(MachineFunction &MF);
> +
> + virtual const char *getPassName() const {return "AMDGPU Convert to
> ISA";}
> +
> +};
> +
> +} // End anonymous namespace
> +
> +char AMDGPUConvertToISAPass::ID = 0;
> +
> +FunctionPass *llvm::createAMDGPUConvertToISAPass(TargetMachine &tm) {
> + return new AMDGPUConvertToISAPass(tm);
> +}
> +
> +bool AMDGPUConvertToISAPass::runOnMachineFunction(MachineFunction &MF) {
> + const AMDGPUInstrInfo * TII =
> + static_cast<const
> AMDGPUInstrInfo*>(TM.getInstrInfo());
> +
> + for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
> + BB != BB_E; ++BB) {
> + MachineBasicBlock &MBB = *BB;
> + for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
> + I != E; ++I) {
> + MachineInstr &MI = *I;
> + TII->convertToISA(MI, MF, MBB.findDebugLoc(I));
> + }
> + }
> + return false;
> +}
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUISelLowering.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUISelLowering.cpp?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUISelLowering.cpp (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUISelLowering.cpp Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,417 @@
> +//===-- AMDGPUISelLowering.cpp - AMDGPU Common DAG lowering functions
> -----===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief This is the parent TargetLowering class for hardware code gen
> +/// targets.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "AMDGPUISelLowering.h"
> +#include "AMDILIntrinsicInfo.h"
> +#include "llvm/CodeGen/MachineFunction.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/CodeGen/SelectionDAG.h"
> +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
> +
> +using namespace llvm;
> +
> +AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
> + TargetLowering(TM, new TargetLoweringObjectFileELF()) {
> +
> + // Initialize target lowering borrowed from AMDIL
> + InitAMDILLowering();
> +
> + // We need to custom lower some of the intrinsics
> + setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
> +
> + // Library functions. These default to Expand, but we have instructions
> + // for them.
> + setOperationAction(ISD::FCEIL, MVT::f32, Legal);
> + setOperationAction(ISD::FEXP2, MVT::f32, Legal);
> + setOperationAction(ISD::FPOW, MVT::f32, Legal);
> + setOperationAction(ISD::FLOG2, MVT::f32, Legal);
> + setOperationAction(ISD::FABS, MVT::f32, Legal);
> + setOperationAction(ISD::FFLOOR, MVT::f32, Legal);
> + setOperationAction(ISD::FRINT, MVT::f32, Legal);
> +
> + // Lower floating point store/load to integer store/load to reduce the
> number
> + // of patterns in tablegen.
> + setOperationAction(ISD::STORE, MVT::f32, Promote);
> + AddPromotedToType(ISD::STORE, MVT::f32, MVT::i32);
> +
> + setOperationAction(ISD::STORE, MVT::v4f32, Promote);
> + AddPromotedToType(ISD::STORE, MVT::v4f32, MVT::v4i32);
> +
> + setOperationAction(ISD::LOAD, MVT::f32, Promote);
> + AddPromotedToType(ISD::LOAD, MVT::f32, MVT::i32);
> +
> + setOperationAction(ISD::LOAD, MVT::v4f32, Promote);
> + AddPromotedToType(ISD::LOAD, MVT::v4f32, MVT::v4i32);
> +
> + setOperationAction(ISD::UDIV, MVT::i32, Expand);
> + setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
> + setOperationAction(ISD::UREM, MVT::i32, Expand);
> +}
> +
>
> +//===---------------------------------------------------------------------===//
> +// TargetLowering Callbacks
>
> +//===---------------------------------------------------------------------===//
> +
> +SDValue AMDGPUTargetLowering::LowerFormalArguments(
> + SDValue Chain,
> + CallingConv::ID CallConv,
> + bool isVarArg,
> + const
> SmallVectorImpl<ISD::InputArg> &Ins,
> + DebugLoc DL, SelectionDAG &DAG,
> + SmallVectorImpl<SDValue> &InVals)
> const {
> + for (unsigned i = 0, e = Ins.size(); i < e; ++i) {
> + InVals.push_back(SDValue());
> + }
> + return Chain;
> +}
> +
> +SDValue AMDGPUTargetLowering::LowerReturn(
> + SDValue Chain,
> + CallingConv::ID CallConv,
> + bool isVarArg,
> + const
> SmallVectorImpl<ISD::OutputArg> &Outs,
> + const SmallVectorImpl<SDValue>
> &OutVals,
> + DebugLoc DL, SelectionDAG &DAG)
> const {
> + return DAG.getNode(AMDGPUISD::RET_FLAG, DL, MVT::Other, Chain);
> +}
> +
>
> +//===---------------------------------------------------------------------===//
> +// Target specific lowering
>
> +//===---------------------------------------------------------------------===//
> +
> +SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG
> &DAG)
> + const {
> + switch (Op.getOpcode()) {
> + default:
> + Op.getNode()->dump();
> + assert(0 && "Custom lowering code for this"
> + "instruction is not implemented yet!");
> + break;
> + // AMDIL DAG lowering
> + case ISD::SDIV: return LowerSDIV(Op, DAG);
> + case ISD::SREM: return LowerSREM(Op, DAG);
> + case ISD::SIGN_EXTEND_INREG: return LowerSIGN_EXTEND_INREG(Op, DAG);
> + case ISD::BRCOND: return LowerBRCOND(Op, DAG);
> + // AMDGPU DAG lowering
> + case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
> + case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
> + }
> + return Op;
> +}
> +
> +SDValue AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
> + SelectionDAG &DAG) const {
> + unsigned IntrinsicID =
> cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
> + DebugLoc DL = Op.getDebugLoc();
> + EVT VT = Op.getValueType();
> +
> + switch (IntrinsicID) {
> + default: return Op;
> + case AMDGPUIntrinsic::AMDIL_abs:
> + return LowerIntrinsicIABS(Op, DAG);
> + case AMDGPUIntrinsic::AMDIL_exp:
> + return DAG.getNode(ISD::FEXP2, DL, VT, Op.getOperand(1));
> + case AMDGPUIntrinsic::AMDGPU_lrp:
> + return LowerIntrinsicLRP(Op, DAG);
> + case AMDGPUIntrinsic::AMDIL_fraction:
> + return DAG.getNode(AMDGPUISD::FRACT, DL, VT, Op.getOperand(1));
> + case AMDGPUIntrinsic::AMDIL_mad:
> + return DAG.getNode(AMDGPUISD::MAD, DL, VT, Op.getOperand(1),
> + Op.getOperand(2), Op.getOperand(3));
> + case AMDGPUIntrinsic::AMDIL_max:
> + return DAG.getNode(AMDGPUISD::FMAX, DL, VT, Op.getOperand(1),
> + Op.getOperand(2));
> + case AMDGPUIntrinsic::AMDGPU_imax:
> + return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Op.getOperand(1),
> + Op.getOperand(2));
> + case AMDGPUIntrinsic::AMDGPU_umax:
> + return DAG.getNode(AMDGPUISD::UMAX, DL, VT, Op.getOperand(1),
> + Op.getOperand(2));
> + case AMDGPUIntrinsic::AMDIL_min:
> + return DAG.getNode(AMDGPUISD::FMIN, DL, VT, Op.getOperand(1),
> + Op.getOperand(2));
> + case AMDGPUIntrinsic::AMDGPU_imin:
> + return DAG.getNode(AMDGPUISD::SMIN, DL, VT, Op.getOperand(1),
> + Op.getOperand(2));
> + case AMDGPUIntrinsic::AMDGPU_umin:
> + return DAG.getNode(AMDGPUISD::UMIN, DL, VT, Op.getOperand(1),
> + Op.getOperand(2));
> + case AMDGPUIntrinsic::AMDIL_round_nearest:
> + return DAG.getNode(ISD::FRINT, DL, VT, Op.getOperand(1));
> + }
> +}
> +
> +///IABS(a) = SMAX(sub(0, a), a)
> +SDValue AMDGPUTargetLowering::LowerIntrinsicIABS(SDValue Op,
> + SelectionDAG &DAG) const {
> +
> + DebugLoc DL = Op.getDebugLoc();
> + EVT VT = Op.getValueType();
> + SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, VT),
> + Op.getOperand(1));
> +
> + return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Neg, Op.getOperand(1));
> +}
> +
> +/// Linear Interpolation
> +/// LRP(a, b, c) = muladd(a, b, (1 - a) * c)
> +SDValue AMDGPUTargetLowering::LowerIntrinsicLRP(SDValue Op,
> + SelectionDAG &DAG) const {
> + DebugLoc DL = Op.getDebugLoc();
> + EVT VT = Op.getValueType();
> + SDValue OneSubA = DAG.getNode(ISD::FSUB, DL, VT,
> + DAG.getConstantFP(1.0f, MVT::f32),
> + Op.getOperand(1));
> + SDValue OneSubAC = DAG.getNode(ISD::FMUL, DL, VT, OneSubA,
> + Op.getOperand(3));
> + return DAG.getNode(AMDGPUISD::MAD, DL, VT, Op.getOperand(1),
> + Op.getOperand(2),
> + OneSubAC);
> +}
> +
> +/// \brief Generate Min/Max node
> +SDValue AMDGPUTargetLowering::LowerMinMax(SDValue Op,
> + SelectionDAG &DAG) const {
> + DebugLoc DL = Op.getDebugLoc();
> + EVT VT = Op.getValueType();
> +
> + SDValue LHS = Op.getOperand(0);
> + SDValue RHS = Op.getOperand(1);
> + SDValue True = Op.getOperand(2);
> + SDValue False = Op.getOperand(3);
> + SDValue CC = Op.getOperand(4);
> +
> + if (VT != MVT::f32 ||
> + !((LHS == True && RHS == False) || (LHS == False && RHS == True))) {
> + return SDValue();
> + }
> +
> + ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
> + switch (CCOpcode) {
> + case ISD::SETOEQ:
> + case ISD::SETONE:
> + case ISD::SETUNE:
> + case ISD::SETNE:
> + case ISD::SETUEQ:
> + case ISD::SETEQ:
> + case ISD::SETFALSE:
> + case ISD::SETFALSE2:
> + case ISD::SETTRUE:
> + case ISD::SETTRUE2:
> + case ISD::SETUO:
> + case ISD::SETO:
> + assert(0 && "Operation should already be optimised !");
> + case ISD::SETULE:
> + case ISD::SETULT:
> + case ISD::SETOLE:
> + case ISD::SETOLT:
> + case ISD::SETLE:
> + case ISD::SETLT: {
> + if (LHS == True)
> + return DAG.getNode(AMDGPUISD::FMIN, DL, VT, LHS, RHS);
> + else
> + return DAG.getNode(AMDGPUISD::FMAX, DL, VT, LHS, RHS);
> + }
> + case ISD::SETGT:
> + case ISD::SETGE:
> + case ISD::SETUGE:
> + case ISD::SETOGE:
> + case ISD::SETUGT:
> + case ISD::SETOGT: {
> + if (LHS == True)
> + return DAG.getNode(AMDGPUISD::FMAX, DL, VT, LHS, RHS);
> + else
> + return DAG.getNode(AMDGPUISD::FMIN, DL, VT, LHS, RHS);
> + }
> + case ISD::SETCC_INVALID:
> + assert(0 && "Invalid setcc condcode !");
> + }
> + return Op;
> +}
> +
> +
> +
> +SDValue AMDGPUTargetLowering::LowerUDIVREM(SDValue Op,
> + SelectionDAG &DAG) const {
> + DebugLoc DL = Op.getDebugLoc();
> + EVT VT = Op.getValueType();
> +
> + SDValue Num = Op.getOperand(0);
> + SDValue Den = Op.getOperand(1);
> +
> + SmallVector<SDValue, 8> Results;
> +
> + // RCP = URECIP(Den) = 2^32 / Den + e
> + // e is rounding error.
> + SDValue RCP = DAG.getNode(AMDGPUISD::URECIP, DL, VT, Den);
> +
> + // RCP_LO = umulo(RCP, Den) */
> + SDValue RCP_LO = DAG.getNode(ISD::UMULO, DL, VT, RCP, Den);
> +
> + // RCP_HI = mulhu (RCP, Den) */
> + SDValue RCP_HI = DAG.getNode(ISD::MULHU, DL, VT, RCP, Den);
> +
> + // NEG_RCP_LO = -RCP_LO
> + SDValue NEG_RCP_LO = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0,
> VT),
> + RCP_LO);
> +
> + // ABS_RCP_LO = (RCP_HI == 0 ? NEG_RCP_LO : RCP_LO)
> + SDValue ABS_RCP_LO = DAG.getSelectCC(DL, RCP_HI, DAG.getConstant(0, VT),
> + NEG_RCP_LO, RCP_LO,
> + ISD::SETEQ);
> + // Calculate the rounding error from the URECIP instruction
> + // E = mulhu(ABS_RCP_LO, RCP)
> + SDValue E = DAG.getNode(ISD::MULHU, DL, VT, ABS_RCP_LO, RCP);
> +
> + // RCP_A_E = RCP + E
> + SDValue RCP_A_E = DAG.getNode(ISD::ADD, DL, VT, RCP, E);
> +
> + // RCP_S_E = RCP - E
> + SDValue RCP_S_E = DAG.getNode(ISD::SUB, DL, VT, RCP, E);
> +
> + // Tmp0 = (RCP_HI == 0 ? RCP_A_E : RCP_SUB_E)
> + SDValue Tmp0 = DAG.getSelectCC(DL, RCP_HI, DAG.getConstant(0, VT),
> + RCP_A_E, RCP_S_E,
> + ISD::SETEQ);
> + // Quotient = mulhu(Tmp0, Num)
> + SDValue Quotient = DAG.getNode(ISD::MULHU, DL, VT, Tmp0, Num);
> +
> + // Num_S_Remainder = Quotient * Den
> + SDValue Num_S_Remainder = DAG.getNode(ISD::UMULO, DL, VT, Quotient,
> Den);
> +
> + // Remainder = Num - Num_S_Remainder
> + SDValue Remainder = DAG.getNode(ISD::SUB, DL, VT, Num, Num_S_Remainder);
> +
> + // Remainder_GE_Den = (Remainder >= Den ? -1 : 0)
> + SDValue Remainder_GE_Den = DAG.getSelectCC(DL, Remainder, Den,
> + DAG.getConstant(-1, VT),
> + DAG.getConstant(0, VT),
> + ISD::SETGE);
> + // Remainder_GE_Zero = (Remainder >= 0 ? -1 : 0)
> + SDValue Remainder_GE_Zero = DAG.getSelectCC(DL, Remainder,
> + DAG.getConstant(0, VT),
> + DAG.getConstant(-1, VT),
> + DAG.getConstant(0, VT),
> + ISD::SETGE);
> + // Tmp1 = Remainder_GE_Den & Remainder_GE_Zero
> + SDValue Tmp1 = DAG.getNode(ISD::AND, DL, VT, Remainder_GE_Den,
> + Remainder_GE_Zero);
> +
> + // Calculate Division result:
> +
> + // Quotient_A_One = Quotient + 1
> + SDValue Quotient_A_One = DAG.getNode(ISD::ADD, DL, VT, Quotient,
> +
> DAG.getConstant(1, VT));
> +
> + // Quotient_S_One = Quotient - 1
> + SDValue Quotient_S_One = DAG.getNode(ISD::SUB, DL, VT, Quotient,
> +
> DAG.getConstant(1, VT));
> +
> + // Div = (Tmp1 == 0 ? Quotient : Quotient_A_One)
> + SDValue Div = DAG.getSelectCC(DL, Tmp1, DAG.getConstant(0, VT),
> + Quotient, Quotient_A_One,
> ISD::SETEQ);
> +
> + // Div = (Remainder_GE_Zero == 0 ? Quotient_S_One : Div)
> + Div = DAG.getSelectCC(DL, Remainder_GE_Zero, DAG.getConstant(0, VT),
> + Quotient_S_One, Div, ISD::SETEQ);
> +
> + // Calculate Rem result:
> +
> + // Remainder_S_Den = Remainder - Den
> + SDValue Remainder_S_Den = DAG.getNode(ISD::SUB, DL, VT, Remainder, Den);
> +
> + // Remainder_A_Den = Remainder + Den
> + SDValue Remainder_A_Den = DAG.getNode(ISD::ADD, DL, VT, Remainder, Den);
> +
> + // Rem = (Tmp1 == 0 ? Remainder : Remainder_S_Den)
> + SDValue Rem = DAG.getSelectCC(DL, Tmp1, DAG.getConstant(0, VT),
> + Remainder, Remainder_S_Den,
> ISD::SETEQ);
> +
> + // Rem = (Remainder_GE_Zero == 0 ? Remainder_A_Den : Rem)
> + Rem = DAG.getSelectCC(DL, Remainder_GE_Zero, DAG.getConstant(0, VT),
> + Remainder_A_Den, Rem, ISD::SETEQ);
> + SDValue Ops[2];
> + Ops[0] = Div;
> + Ops[1] = Rem;
> + return DAG.getMergeValues(Ops, 2, DL);
> +}
> +
>
> +//===----------------------------------------------------------------------===//
> +// Helper functions
>
> +//===----------------------------------------------------------------------===//
> +
> +bool AMDGPUTargetLowering::isHWTrueValue(SDValue Op) const {
> + if (ConstantFPSDNode * CFP = dyn_cast<ConstantFPSDNode>(Op)) {
> + return CFP->isExactlyValue(1.0);
> + }
> + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
> + return C->isAllOnesValue();
> + }
> + return false;
> +}
> +
> +bool AMDGPUTargetLowering::isHWFalseValue(SDValue Op) const {
> + if (ConstantFPSDNode * CFP = dyn_cast<ConstantFPSDNode>(Op)) {
> + return CFP->getValueAPF().isZero();
> + }
> + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
> + return C->isNullValue();
> + }
> + return false;
> +}
> +
> +SDValue AMDGPUTargetLowering::CreateLiveInRegister(SelectionDAG &DAG,
> + const
> TargetRegisterClass *RC,
> + unsigned Reg, EVT VT)
> const {
> + MachineFunction &MF = DAG.getMachineFunction();
> + MachineRegisterInfo &MRI = MF.getRegInfo();
> + unsigned VirtualRegister;
> + if (!MRI.isLiveIn(Reg)) {
> + VirtualRegister = MRI.createVirtualRegister(RC);
> + MRI.addLiveIn(Reg, VirtualRegister);
> + } else {
> + VirtualRegister = MRI.getLiveInVirtReg(Reg);
> + }
> + return DAG.getRegister(VirtualRegister, VT);
> +}
> +
> +#define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node;
> +
> +const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode)
> const {
> + switch (Opcode) {
> + default: return 0;
> + // AMDIL DAG nodes
> + NODE_NAME_CASE(MAD);
> + NODE_NAME_CASE(CALL);
> + NODE_NAME_CASE(UMUL);
> + NODE_NAME_CASE(DIV_INF);
> + NODE_NAME_CASE(RET_FLAG);
> + NODE_NAME_CASE(BRANCH_COND);
> +
> + // AMDGPU DAG nodes
> + NODE_NAME_CASE(DWORDADDR)
> + NODE_NAME_CASE(FRACT)
> + NODE_NAME_CASE(FMAX)
> + NODE_NAME_CASE(SMAX)
> + NODE_NAME_CASE(UMAX)
> + NODE_NAME_CASE(FMIN)
> + NODE_NAME_CASE(SMIN)
> + NODE_NAME_CASE(UMIN)
> + NODE_NAME_CASE(URECIP)
> + NODE_NAME_CASE(INTERP)
> + NODE_NAME_CASE(INTERP_P0)
> + NODE_NAME_CASE(EXPORT)
> + }
> +}
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUISelLowering.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUISelLowering.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUISelLowering.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUISelLowering.h Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,144 @@
> +//===-- AMDGPUISelLowering.h - AMDGPU Lowering Interface --------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief Interface definition of the TargetLowering class that is common
> +/// to all AMD GPUs.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef AMDGPUISELLOWERING_H
> +#define AMDGPUISELLOWERING_H
> +
> +#include "llvm/Target/TargetLowering.h"
> +
> +namespace llvm {
> +
> +class MachineRegisterInfo;
> +
> +class AMDGPUTargetLowering : public TargetLowering {
> +private:
> + SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
> +
> +protected:
> +
> + /// \brief Helper function that adds Reg to the LiveIn list of the DAG's
> + /// MachineFunction.
> + ///
> + /// \returns a RegisterSDNode representing Reg.
> + SDValue CreateLiveInRegister(SelectionDAG &DAG, const
> TargetRegisterClass *RC,
> + unsigned Reg, EVT VT)
> const;
> +
> + bool isHWTrueValue(SDValue Op) const;
> + bool isHWFalseValue(SDValue Op) const;
> +
> +public:
> + AMDGPUTargetLowering(TargetMachine &TM);
> +
> + virtual SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID
> CallConv,
> + bool isVarArg,
> + const SmallVectorImpl<ISD::InputArg> &Ins,
> + DebugLoc DL, SelectionDAG &DAG,
> + SmallVectorImpl<SDValue> &InVals) const;
> +
> + virtual SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv,
> + bool isVarArg,
> + const SmallVectorImpl<ISD::OutputArg> &Outs,
> + const SmallVectorImpl<SDValue> &OutVals,
> + DebugLoc DL, SelectionDAG &DAG) const;
> +
> + virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerIntrinsicIABS(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerIntrinsicLRP(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerMinMax(SDValue Op, SelectionDAG &DAG) const;
> + virtual const char* getTargetNodeName(unsigned Opcode) const;
> +
> +// Functions defined in AMDILISelLowering.cpp
> +public:
> +
> + /// \brief Determine which of the bits specified in \p Mask are known
> to be
> + /// either zero or one and return them in the \p KnownZero and \p
> KnownOne
> + /// bitsets.
> + virtual void computeMaskedBitsForTargetNode(const SDValue Op,
> + APInt &KnownZero,
> + APInt &KnownOne,
> + const SelectionDAG &DAG,
> + unsigned Depth = 0) const;
> +
> + virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info,
> + const CallInst &I, unsigned Intrinsic)
> const;
> +
> + /// We want to mark f32/f64 floating point values as legal.
> + bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
> +
> + /// We don't want to shrink f64/f32 constants.
> + bool ShouldShrinkFPConstant(EVT VT) const;
> +
> +private:
> + void InitAMDILLowering();
> + SDValue LowerSREM(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSREM8(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSREM16(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSREM32(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSREM64(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSDIV(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSDIV24(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSDIV32(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSDIV64(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const;
> + EVT genIntType(uint32_t size = 32, uint32_t numEle = 1) const;
> + SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
> +};
> +
> +namespace AMDGPUISD {
> +
> +enum {
> + // AMDIL ISD Opcodes
> + FIRST_NUMBER = ISD::BUILTIN_OP_END,
> + MAD, // 32bit Fused Multiply Add instruction
> + CALL, // Function call based on a single integer
> + UMUL, // 32bit unsigned multiplication
> + DIV_INF, // Divide with infinity returned on zero divisor
> + RET_FLAG,
> + BRANCH_COND,
> + // End AMDIL ISD Opcodes
> + BITALIGN,
> + DWORDADDR,
> + FRACT,
> + FMAX,
> + SMAX,
> + UMAX,
> + FMIN,
> + SMIN,
> + UMIN,
> + URECIP,
> + INTERP,
> + INTERP_P0,
> + EXPORT,
> + LAST_AMDGPU_ISD_NUMBER
> +};
> +
> +
> +} // End namespace AMDGPUISD
> +
> +namespace SIISD {
> +
> +enum {
> + SI_FIRST = AMDGPUISD::LAST_AMDGPU_ISD_NUMBER,
> + VCC_AND,
> + VCC_BITCAST
> +};
> +
> +} // End namespace SIISD
> +
> +} // End namespace llvm
> +
> +#endif // AMDGPUISELLOWERING_H
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.cpp?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.cpp (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.cpp Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,257 @@
> +//===-- AMDGPUInstrInfo.cpp - Base class for AMD GPU InstrInfo
> ------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief Implementation of the TargetInstrInfo class that is common to
> all
> +/// AMD GPUs.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "AMDGPUInstrInfo.h"
> +#include "AMDGPURegisterInfo.h"
> +#include "AMDGPUTargetMachine.h"
> +#include "AMDIL.h"
> +#include "llvm/CodeGen/MachineFrameInfo.h"
> +#include "llvm/CodeGen/MachineInstrBuilder.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +
> +#define GET_INSTRINFO_CTOR
> +#include "AMDGPUGenInstrInfo.inc"
> +
> +using namespace llvm;
> +
> +AMDGPUInstrInfo::AMDGPUInstrInfo(TargetMachine &tm)
> + : AMDGPUGenInstrInfo(0,0), RI(tm, *this), TM(tm) { }
> +
> +const AMDGPURegisterInfo &AMDGPUInstrInfo::getRegisterInfo() const {
> + return RI;
> +}
> +
> +bool AMDGPUInstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
> + unsigned &SrcReg, unsigned
> &DstReg,
> + unsigned &SubIdx) const {
> +// TODO: Implement this function
> + return false;
> +}
> +
> +unsigned AMDGPUInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
> + int &FrameIndex) const {
> +// TODO: Implement this function
> + return 0;
> +}
> +
> +unsigned AMDGPUInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr
> *MI,
> + int &FrameIndex) const
> {
> +// TODO: Implement this function
> + return 0;
> +}
> +
> +bool AMDGPUInstrInfo::hasLoadFromStackSlot(const MachineInstr *MI,
> + const MachineMemOperand *&MMO,
> + int &FrameIndex) const {
> +// TODO: Implement this function
> + return false;
> +}
> +unsigned AMDGPUInstrInfo::isStoreFromStackSlot(const MachineInstr *MI,
> + int &FrameIndex) const {
> +// TODO: Implement this function
> + return 0;
> +}
> +unsigned AMDGPUInstrInfo::isStoreFromStackSlotPostFE(const MachineInstr
> *MI,
> + int &FrameIndex)
> const {
> +// TODO: Implement this function
> + return 0;
> +}
> +bool AMDGPUInstrInfo::hasStoreFromStackSlot(const MachineInstr *MI,
> + const MachineMemOperand *&MMO,
> + int &FrameIndex) const {
> +// TODO: Implement this function
> + return false;
> +}
> +
> +MachineInstr *
> +AMDGPUInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
> + MachineBasicBlock::iterator &MBBI,
> + LiveVariables *LV) const {
> +// TODO: Implement this function
> + return NULL;
> +}
> +bool AMDGPUInstrInfo::getNextBranchInstr(MachineBasicBlock::iterator
> &iter,
> + MachineBasicBlock &MBB) const {
> + while (iter != MBB.end()) {
> + switch (iter->getOpcode()) {
> + default:
> + break;
> + case AMDGPU::BRANCH_COND_i32:
> + case AMDGPU::BRANCH_COND_f32:
> + case AMDGPU::BRANCH:
> + return true;
> + };
> + ++iter;
> + }
> + return false;
> +}
> +
> +MachineBasicBlock::iterator skipFlowControl(MachineBasicBlock *MBB) {
> + MachineBasicBlock::iterator tmp = MBB->end();
> + if (!MBB->size()) {
> + return MBB->end();
> + }
> + while (--tmp) {
> + if (tmp->getOpcode() == AMDGPU::ENDLOOP
> + || tmp->getOpcode() == AMDGPU::ENDIF
> + || tmp->getOpcode() == AMDGPU::ELSE) {
> + if (tmp == MBB->begin()) {
> + return tmp;
> + } else {
> + continue;
> + }
> + } else {
> + return ++tmp;
> + }
> + }
> + return MBB->end();
> +}
> +
> +void
> +AMDGPUInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
> + MachineBasicBlock::iterator MI,
> + unsigned SrcReg, bool isKill,
> + int FrameIndex,
> + const TargetRegisterClass *RC,
> + const TargetRegisterInfo *TRI) const {
> + assert(!"Not Implemented");
> +}
> +
> +void
> +AMDGPUInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
> + MachineBasicBlock::iterator MI,
> + unsigned DestReg, int FrameIndex,
> + const TargetRegisterClass *RC,
> + const TargetRegisterInfo *TRI) const
> {
> + assert(!"Not Implemented");
> +}
> +
> +MachineInstr *
> +AMDGPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
> + MachineInstr *MI,
> + const SmallVectorImpl<unsigned>
> &Ops,
> + int FrameIndex) const {
> +// TODO: Implement this function
> + return 0;
> +}
> +MachineInstr*
> +AMDGPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
> + MachineInstr *MI,
> + const SmallVectorImpl<unsigned>
> &Ops,
> + MachineInstr *LoadMI) const {
> + // TODO: Implement this function
> + return 0;
> +}
> +bool
> +AMDGPUInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
> + const SmallVectorImpl<unsigned>
> &Ops) const {
> + // TODO: Implement this function
> + return false;
> +}
> +bool
> +AMDGPUInstrInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr
> *MI,
> + unsigned Reg, bool UnfoldLoad,
> + bool UnfoldStore,
> + SmallVectorImpl<MachineInstr*> &NewMIs)
> const {
> + // TODO: Implement this function
> + return false;
> +}
> +
> +bool
> +AMDGPUInstrInfo::unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,
> + SmallVectorImpl<SDNode*> &NewNodes)
> const {
> + // TODO: Implement this function
> + return false;
> +}
> +
> +unsigned
> +AMDGPUInstrInfo::getOpcodeAfterMemoryUnfold(unsigned Opc,
> + bool UnfoldLoad, bool
> UnfoldStore,
> + unsigned *LoadRegIndex) const {
> + // TODO: Implement this function
> + return 0;
> +}
> +
> +bool AMDGPUInstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode
> *Load2,
> + int64_t Offset1, int64_t
> Offset2,
> + unsigned NumLoads) const {
> + assert(Offset2 > Offset1
> + && "Second offset should be larger than first offset!");
> + // If we have less than 16 loads in a row, and the offsets are within
> 16,
> + // then schedule together.
> + // TODO: Make the loads schedule near if it fits in a cacheline
> + return (NumLoads < 16 && (Offset2 - Offset1) < 16);
> +}
> +
> +bool
> +AMDGPUInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand>
> &Cond)
> + const {
> + // TODO: Implement this function
> + return true;
> +}
> +void AMDGPUInstrInfo::insertNoop(MachineBasicBlock &MBB,
> + MachineBasicBlock::iterator MI) const {
> + // TODO: Implement this function
> +}
> +
> +bool AMDGPUInstrInfo::isPredicated(const MachineInstr *MI) const {
> + // TODO: Implement this function
> + return false;
> +}
> +bool
> +AMDGPUInstrInfo::SubsumesPredicate(const SmallVectorImpl<MachineOperand>
> &Pred1,
> + const SmallVectorImpl<MachineOperand>
> &Pred2)
> + const {
> + // TODO: Implement this function
> + return false;
> +}
> +
> +bool AMDGPUInstrInfo::DefinesPredicate(MachineInstr *MI,
> + std::vector<MachineOperand> &Pred)
> const {
> + // TODO: Implement this function
> + return false;
> +}
> +
> +bool AMDGPUInstrInfo::isPredicable(MachineInstr *MI) const {
> + // TODO: Implement this function
> + return MI->getDesc().isPredicable();
> +}
> +
> +bool
> +AMDGPUInstrInfo::isSafeToMoveRegClassDefs(const TargetRegisterClass *RC)
> const {
> + // TODO: Implement this function
> + return true;
> +}
> +
> +void AMDGPUInstrInfo::convertToISA(MachineInstr & MI, MachineFunction &MF,
> + DebugLoc DL) const {
> + MachineRegisterInfo &MRI = MF.getRegInfo();
> + const AMDGPURegisterInfo & RI = getRegisterInfo();
> +
> + for (unsigned i = 0; i < MI.getNumOperands(); i++) {
> + MachineOperand &MO = MI.getOperand(i);
> + // Convert dst regclass to one that is supported by the ISA
> + if (MO.isReg() && MO.isDef()) {
> + if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
> + const TargetRegisterClass * oldRegClass =
> MRI.getRegClass(MO.getReg());
> + const TargetRegisterClass * newRegClass =
> RI.getISARegClass(oldRegClass);
> +
> + assert(newRegClass);
> +
> + MRI.setRegClass(MO.getReg(), newRegClass);
> + }
> + }
> + }
> +}
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.h Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,149 @@
> +//===-- AMDGPUInstrInfo.h - AMDGPU Instruction Information ------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief Contains the definition of a TargetInstrInfo class that is
> common
> +/// to all AMD GPUs.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef AMDGPUINSTRUCTIONINFO_H
> +#define AMDGPUINSTRUCTIONINFO_H
> +
> +#include "AMDGPURegisterInfo.h"
> +#include "AMDGPUInstrInfo.h"
> +#include "llvm/Target/TargetInstrInfo.h"
> +
> +#include <map>
> +
> +#define GET_INSTRINFO_HEADER
> +#define GET_INSTRINFO_ENUM
> +#include "AMDGPUGenInstrInfo.inc"
> +
> +#define OPCODE_IS_ZERO_INT AMDGPU::PRED_SETE_INT
> +#define OPCODE_IS_NOT_ZERO_INT AMDGPU::PRED_SETNE_INT
> +#define OPCODE_IS_ZERO AMDGPU::PRED_SETE
> +#define OPCODE_IS_NOT_ZERO AMDGPU::PRED_SETNE
> +
> +namespace llvm {
> +
> +class AMDGPUTargetMachine;
> +class MachineFunction;
> +class MachineInstr;
> +class MachineInstrBuilder;
> +
> +class AMDGPUInstrInfo : public AMDGPUGenInstrInfo {
> +private:
> + const AMDGPURegisterInfo RI;
> + TargetMachine &TM;
> + bool getNextBranchInstr(MachineBasicBlock::iterator &iter,
> + MachineBasicBlock &MBB) const;
> +public:
> + explicit AMDGPUInstrInfo(TargetMachine &tm);
> +
> + virtual const AMDGPURegisterInfo &getRegisterInfo() const = 0;
> +
> + bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg,
> + unsigned &DstReg, unsigned &SubIdx) const;
> +
> + unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex)
> const;
> + unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI,
> + int &FrameIndex) const;
> + bool hasLoadFromStackSlot(const MachineInstr *MI,
> + const MachineMemOperand *&MMO,
> + int &FrameIndex) const;
> + unsigned isStoreFromStackSlot(const MachineInstr *MI, int &FrameIndex)
> const;
> + unsigned isStoreFromStackSlotPostFE(const MachineInstr *MI,
> + int &FrameIndex) const;
> + bool hasStoreFromStackSlot(const MachineInstr *MI,
> + const MachineMemOperand *&MMO,
> + int &FrameIndex) const;
> +
> + MachineInstr *
> + convertToThreeAddress(MachineFunction::iterator &MFI,
> + MachineBasicBlock::iterator &MBBI,
> + LiveVariables *LV) const;
> +
> +
> + virtual void copyPhysReg(MachineBasicBlock &MBB,
> + MachineBasicBlock::iterator MI, DebugLoc DL,
> + unsigned DestReg, unsigned SrcReg,
> + bool KillSrc) const = 0;
> +
> + void storeRegToStackSlot(MachineBasicBlock &MBB,
> + MachineBasicBlock::iterator MI,
> + unsigned SrcReg, bool isKill, int FrameIndex,
> + const TargetRegisterClass *RC,
> + const TargetRegisterInfo *TRI) const;
> + void loadRegFromStackSlot(MachineBasicBlock &MBB,
> + MachineBasicBlock::iterator MI,
> + unsigned DestReg, int FrameIndex,
> + const TargetRegisterClass *RC,
> + const TargetRegisterInfo *TRI) const;
> +
> +protected:
> + MachineInstr *foldMemoryOperandImpl(MachineFunction &MF,
> + MachineInstr *MI,
> + const SmallVectorImpl<unsigned>
> &Ops,
> + int FrameIndex) const;
> + MachineInstr *foldMemoryOperandImpl(MachineFunction &MF,
> + MachineInstr *MI,
> + const SmallVectorImpl<unsigned>
> &Ops,
> + MachineInstr *LoadMI) const;
> +public:
> + bool canFoldMemoryOperand(const MachineInstr *MI,
> + const SmallVectorImpl<unsigned> &Ops) const;
> + bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
> + unsigned Reg, bool UnfoldLoad, bool
> UnfoldStore,
> + SmallVectorImpl<MachineInstr *> &NewMIs) const;
> + bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,
> + SmallVectorImpl<SDNode *> &NewNodes) const;
> + unsigned getOpcodeAfterMemoryUnfold(unsigned Opc,
> + bool UnfoldLoad, bool UnfoldStore,
> + unsigned *LoadRegIndex = 0) const;
> + bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
> + int64_t Offset1, int64_t Offset2,
> + unsigned NumLoads) const;
> +
> + bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond)
> const;
> + void insertNoop(MachineBasicBlock &MBB,
> + MachineBasicBlock::iterator MI) const;
> + bool isPredicated(const MachineInstr *MI) const;
> + bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
> + const SmallVectorImpl<MachineOperand> &Pred2)
> const;
> + bool DefinesPredicate(MachineInstr *MI,
> + std::vector<MachineOperand> &Pred) const;
> + bool isPredicable(MachineInstr *MI) const;
> + bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const;
> +
> + // Helper functions that check the opcode for status information
> + bool isLoadInst(llvm::MachineInstr *MI) const;
> + bool isExtLoadInst(llvm::MachineInstr *MI) const;
> + bool isSWSExtLoadInst(llvm::MachineInstr *MI) const;
> + bool isSExtLoadInst(llvm::MachineInstr *MI) const;
> + bool isZExtLoadInst(llvm::MachineInstr *MI) const;
> + bool isAExtLoadInst(llvm::MachineInstr *MI) const;
> + bool isStoreInst(llvm::MachineInstr *MI) const;
> + bool isTruncStoreInst(llvm::MachineInstr *MI) const;
> +
> + virtual MachineInstr* getMovImmInstr(MachineFunction *MF, unsigned
> DstReg,
> + int64_t Imm) const = 0;
> + virtual unsigned getIEQOpcode() const = 0;
> + virtual bool isMov(unsigned opcode) const = 0;
> +
> + /// \brief Convert the AMDIL MachineInstr to a supported ISA
> + /// MachineInstr
> + virtual void convertToISA(MachineInstr & MI, MachineFunction &MF,
> + DebugLoc DL) const;
> +
> +};
> +
> +} // End llvm namespace
> +
> +#endif // AMDGPUINSTRINFO_H
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.td?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.td (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUInstrInfo.td Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,74 @@
> +//===-- AMDGPUInstrInfo.td - AMDGPU DAG nodes --------------*- tablegen
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file contains DAG node defintions for the AMDGPU target.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
>
> +//===----------------------------------------------------------------------===//
> +// AMDGPU DAG Profiles
>
> +//===----------------------------------------------------------------------===//
> +
> +def AMDGPUDTIntTernaryOp : SDTypeProfile<1, 3, [
> + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3>
> +]>;
> +
>
> +//===----------------------------------------------------------------------===//
> +// AMDGPU DAG Nodes
> +//
> +
> +// out = ((a << 32) | b) >> c)
> +//
> +// Can be used to optimize rtol:
> +// rotl(a, b) = bitalign(a, a, 32 - b)
> +def AMDGPUbitalign : SDNode<"AMDGPUISD::BITALIGN", AMDGPUDTIntTernaryOp>;
> +
> +// This argument to this node is a dword address.
> +def AMDGPUdwordaddr : SDNode<"AMDGPUISD::DWORDADDR", SDTIntUnaryOp>;
> +
> +// out = a - floor(a)
> +def AMDGPUfract : SDNode<"AMDGPUISD::FRACT", SDTFPUnaryOp>;
> +
> +// out = max(a, b) a and b are floats
> +def AMDGPUfmax : SDNode<"AMDGPUISD::FMAX", SDTFPBinOp,
> + [SDNPCommutative, SDNPAssociative]
> +>;
> +
> +// out = max(a, b) a and b are signed ints
> +def AMDGPUsmax : SDNode<"AMDGPUISD::SMAX", SDTIntBinOp,
> + [SDNPCommutative, SDNPAssociative]
> +>;
> +
> +// out = max(a, b) a and b are unsigned ints
> +def AMDGPUumax : SDNode<"AMDGPUISD::UMAX", SDTIntBinOp,
> + [SDNPCommutative, SDNPAssociative]
> +>;
> +
> +// out = min(a, b) a and b are floats
> +def AMDGPUfmin : SDNode<"AMDGPUISD::FMIN", SDTFPBinOp,
> + [SDNPCommutative, SDNPAssociative]
> +>;
> +
> +// out = min(a, b) a snd b are signed ints
> +def AMDGPUsmin : SDNode<"AMDGPUISD::SMIN", SDTIntBinOp,
> + [SDNPCommutative, SDNPAssociative]
> +>;
> +
> +// out = min(a, b) a and b are unsigned ints
> +def AMDGPUumin : SDNode<"AMDGPUISD::UMIN", SDTIntBinOp,
> + [SDNPCommutative, SDNPAssociative]
> +>;
> +
> +// urecip - This operation is a helper for integer division, it returns
> the
> +// result of 1 / a as a fractional unsigned integer.
> +// out = (2^32 / a) + e
> +// e is rounding error
> +def AMDGPUurecip : SDNode<"AMDGPUISD::URECIP", SDTIntUnaryOp>;
> +
> +def fpow : SDNode<"ISD::FPOW", SDTFPBinOp>;
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUInstructions.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUInstructions.td?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUInstructions.td (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUInstructions.td Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,190 @@
> +//===-- AMDGPUInstructions.td - Common instruction defs ---*- tablegen
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file contains instruction defs that are common to all hw codegen
> +// targets.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +class AMDGPUInst <dag outs, dag ins, string asm, list<dag> pattern> :
> Instruction {
> + field bits<16> AMDILOp = 0;
> + field bits<3> Gen = 0;
> +
> + let Namespace = "AMDGPU";
> + let OutOperandList = outs;
> + let InOperandList = ins;
> + let AsmString = asm;
> + let Pattern = pattern;
> + let Itinerary = NullALU;
> + let TSFlags{42-40} = Gen;
> + let TSFlags{63-48} = AMDILOp;
> +}
> +
> +class AMDGPUShaderInst <dag outs, dag ins, string asm, list<dag> pattern>
> + : AMDGPUInst<outs, ins, asm, pattern> {
> +
> + field bits<32> Inst = 0xffffffff;
> +
> +}
> +
> +def InstFlag : OperandWithDefaultOps <i32, (ops (i32 0))>;
> +
> +def COND_EQ : PatLeaf <
> + (cond),
> + [{switch(N->get()){{default: return false;
> + case ISD::SETOEQ: case ISD::SETUEQ:
> + case ISD::SETEQ: return true;}}}]
> +>;
> +
> +def COND_NE : PatLeaf <
> + (cond),
> + [{switch(N->get()){{default: return false;
> + case ISD::SETONE: case ISD::SETUNE:
> + case ISD::SETNE: return true;}}}]
> +>;
> +def COND_GT : PatLeaf <
> + (cond),
> + [{switch(N->get()){{default: return false;
> + case ISD::SETOGT: case ISD::SETUGT:
> + case ISD::SETGT: return true;}}}]
> +>;
> +
> +def COND_GE : PatLeaf <
> + (cond),
> + [{switch(N->get()){{default: return false;
> + case ISD::SETOGE: case ISD::SETUGE:
> + case ISD::SETGE: return true;}}}]
> +>;
> +
> +def COND_LT : PatLeaf <
> + (cond),
> + [{switch(N->get()){{default: return false;
> + case ISD::SETOLT: case ISD::SETULT:
> + case ISD::SETLT: return true;}}}]
> +>;
> +
> +def COND_LE : PatLeaf <
> + (cond),
> + [{switch(N->get()){{default: return false;
> + case ISD::SETOLE: case ISD::SETULE:
> + case ISD::SETLE: return true;}}}]
> +>;
> +
>
> +//===----------------------------------------------------------------------===//
> +// Load/Store Pattern Fragments
>
> +//===----------------------------------------------------------------------===//
> +
> +def zextloadi8_global : PatFrag<(ops node:$ptr), (zextloadi8 node:$ptr),
> [{
> + return isGlobalLoad(dyn_cast<LoadSDNode>(N));
> +}]>;
> +
> +class Constants {
> +int TWO_PI = 0x40c90fdb;
> +int PI = 0x40490fdb;
> +int TWO_PI_INV = 0x3e22f983;
> +}
> +def CONST : Constants;
> +
> +def FP_ZERO : PatLeaf <
> + (fpimm),
> + [{return N->getValueAPF().isZero();}]
> +>;
> +
> +def FP_ONE : PatLeaf <
> + (fpimm),
> + [{return N->isExactlyValue(1.0);}]
> +>;
> +
> +let isCodeGenOnly = 1, isPseudo = 1, usesCustomInserter = 1 in {
> +
> +class CLAMP <RegisterClass rc> : AMDGPUShaderInst <
> + (outs rc:$dst),
> + (ins rc:$src0),
> + "CLAMP $dst, $src0",
> + [(set rc:$dst, (int_AMDIL_clamp rc:$src0, (f32 FP_ZERO), (f32 FP_ONE)))]
> +>;
> +
> +class FABS <RegisterClass rc> : AMDGPUShaderInst <
> + (outs rc:$dst),
> + (ins rc:$src0),
> + "FABS $dst, $src0",
> + [(set rc:$dst, (fabs rc:$src0))]
> +>;
> +
> +class FNEG <RegisterClass rc> : AMDGPUShaderInst <
> + (outs rc:$dst),
> + (ins rc:$src0),
> + "FNEG $dst, $src0",
> + [(set rc:$dst, (fneg rc:$src0))]
> +>;
> +
> +def SHADER_TYPE : AMDGPUShaderInst <
> + (outs),
> + (ins i32imm:$type),
> + "SHADER_TYPE $type",
> + [(int_AMDGPU_shader_type imm:$type)]
> +>;
> +
> +} // End isCodeGenOnly = 1, isPseudo = 1, hasCustomInserter = 1
> +
> +/* Generic helper patterns for intrinsics */
> +/* -------------------------------------- */
> +
> +class POW_Common <AMDGPUInst log_ieee, AMDGPUInst exp_ieee, AMDGPUInst
> mul,
> + RegisterClass rc> : Pat <
> + (fpow rc:$src0, rc:$src1),
> + (exp_ieee (mul rc:$src1, (log_ieee rc:$src0)))
> +>;
> +
> +/* Other helper patterns */
> +/* --------------------- */
> +
> +/* Extract element pattern */
> +class Extract_Element <ValueType sub_type, ValueType vec_type,
> + RegisterClass vec_class, int sub_idx,
> + SubRegIndex sub_reg>: Pat<
> + (sub_type (vector_extract (vec_type vec_class:$src), sub_idx)),
> + (EXTRACT_SUBREG vec_class:$src, sub_reg)
> +>;
> +
> +/* Insert element pattern */
> +class Insert_Element <ValueType elem_type, ValueType vec_type,
> + RegisterClass elem_class, RegisterClass vec_class,
> + int sub_idx, SubRegIndex sub_reg> : Pat <
> +
> + (vec_type (vector_insert (vec_type vec_class:$vec),
> + (elem_type elem_class:$elem), sub_idx)),
> + (INSERT_SUBREG vec_class:$vec, elem_class:$elem, sub_reg)
> +>;
> +
> +// Vector Build pattern
> +class Vector_Build <ValueType vecType, RegisterClass vectorClass,
> + ValueType elemType, RegisterClass elemClass> : Pat <
> + (vecType (build_vector (elemType elemClass:$x), (elemType elemClass:$y),
> + (elemType elemClass:$z), (elemType
> elemClass:$w))),
> + (INSERT_SUBREG (INSERT_SUBREG (INSERT_SUBREG (INSERT_SUBREG
> + (vecType (IMPLICIT_DEF)), elemClass:$x, sel_x), elemClass:$y, sel_y),
> + elemClass:$z, sel_z), elemClass:$w, sel_w)
> +>;
> +
> +// bitconvert pattern
> +class BitConvert <ValueType dt, ValueType st, RegisterClass rc> : Pat <
> + (dt (bitconvert (st rc:$src0))),
> + (dt rc:$src0)
> +>;
> +
> +class DwordAddrPat<ValueType vt, RegisterClass rc> : Pat <
> + (vt (AMDGPUdwordaddr (vt rc:$addr))),
> + (vt rc:$addr)
> +>;
> +
> +include "R600Instructions.td"
> +
> +include "SIInstrInfo.td"
> +
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUIntrinsics.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUIntrinsics.td?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUIntrinsics.td (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUIntrinsics.td Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,62 @@
> +//===-- AMDGPUIntrinsics.td - Common intrinsics -*- tablegen
> -*-----------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file defines intrinsics that are used by all hw codegen targets.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +let TargetPrefix = "AMDGPU", isTarget = 1 in {
> +
> + def int_AMDGPU_load_const : Intrinsic<[llvm_float_ty], [llvm_i32_ty],
> [IntrNoMem]>;
> + def int_AMDGPU_load_imm : Intrinsic<[llvm_v4f32_ty], [llvm_i32_ty],
> [IntrNoMem]>;
> + def int_AMDGPU_reserve_reg : Intrinsic<[], [llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_store_output : Intrinsic<[], [llvm_float_ty,
> llvm_i32_ty], []>;
> + def int_AMDGPU_swizzle : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
> llvm_i32_ty], [IntrNoMem]>;
> +
> + def int_AMDGPU_arl : Intrinsic<[llvm_i32_ty], [llvm_float_ty],
> [IntrNoMem]>;
> + def int_AMDGPU_cndlt : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty, llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_div : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_dp4 : Intrinsic<[llvm_float_ty], [llvm_v4f32_ty,
> llvm_v4f32_ty], [IntrNoMem]>;
> + def int_AMDGPU_kill : Intrinsic<[], [llvm_float_ty], []>;
> + def int_AMDGPU_kilp : Intrinsic<[], [], []>;
> + def int_AMDGPU_lrp : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty, llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_mul : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_pow : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_rcp : Intrinsic<[llvm_float_ty], [llvm_float_ty],
> [IntrNoMem]>;
> + def int_AMDGPU_rsq : Intrinsic<[llvm_float_ty], [llvm_float_ty],
> [IntrNoMem]>;
> + def int_AMDGPU_seq : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_sgt : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_sge : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_sle : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_sne : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_mullit : Intrinsic<[llvm_v4f32_ty], [llvm_float_ty,
> llvm_float_ty, llvm_float_ty], [IntrNoMem]>;
> + def int_AMDGPU_tex : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
> llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_txb : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
> llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_txf : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
> llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
> llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_txq : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
> llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_txd : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
> llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
> [IntrNoMem]>;
> + def int_AMDGPU_txl : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
> llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_trunc : Intrinsic<[llvm_float_ty], [llvm_float_ty],
> [IntrNoMem]>;
> + def int_AMDGPU_ddx : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
> llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_ddy : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
> llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_imax : Intrinsic<[llvm_i32_ty], [llvm_i32_ty,
> llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_imin : Intrinsic<[llvm_i32_ty], [llvm_i32_ty,
> llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_umax : Intrinsic<[llvm_i32_ty], [llvm_i32_ty,
> llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_umin : Intrinsic<[llvm_i32_ty], [llvm_i32_ty,
> llvm_i32_ty], [IntrNoMem]>;
> + def int_AMDGPU_cube : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
> [IntrNoMem]>;
> +
> + def int_AMDGPU_shader_type : Intrinsic<[], [llvm_i32_ty], []>;
> +}
> +
> +let TargetPrefix = "TGSI", isTarget = 1 in {
> +
> + def int_TGSI_lit_z : Intrinsic<[llvm_float_ty], [llvm_float_ty,
> llvm_float_ty, llvm_float_ty],[IntrNoMem]>;
> +}
> +
> +include "SIIntrinsics.td"
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.cpp?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.cpp (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.cpp Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,77 @@
> +//===- AMDGPUMCInstLower.cpp - Lower AMDGPU MachineInstr to an MCInst
> -----===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief Code to lower AMDGPU MachineInstrs to their corresponding
> MCInst.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +
> +#include "AMDGPUMCInstLower.h"
> +#include "AMDGPUAsmPrinter.h"
> +#include "R600InstrInfo.h"
> +#include "llvm/CodeGen/MachineBasicBlock.h"
> +#include "llvm/CodeGen/MachineInstr.h"
> +#include "llvm/Constants.h"
> +#include "llvm/MC/MCInst.h"
> +#include "llvm/MC/MCStreamer.h"
> +#include "llvm/Support/ErrorHandling.h"
> +
> +using namespace llvm;
> +
> +AMDGPUMCInstLower::AMDGPUMCInstLower() { }
> +
> +void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI)
> const {
> + OutMI.setOpcode(MI->getOpcode());
> +
> + for (unsigned i = 0, e = MI->getNumExplicitOperands(); i != e; ++i) {
> + const MachineOperand &MO = MI->getOperand(i);
> +
> + MCOperand MCOp;
> + switch (MO.getType()) {
> + default:
> + llvm_unreachable("unknown operand type");
> + case MachineOperand::MO_FPImmediate: {
> + const APFloat &FloatValue = MO.getFPImm()->getValueAPF();
> + assert(&FloatValue.getSemantics() == &APFloat::IEEEsingle &&
> + "Only floating point immediates are supported at the
> moment.");
> + MCOp = MCOperand::CreateFPImm(FloatValue.convertToFloat());
> + break;
> + }
> + case MachineOperand::MO_Immediate:
> + MCOp = MCOperand::CreateImm(MO.getImm());
> + break;
> + case MachineOperand::MO_Register:
> + MCOp = MCOperand::CreateReg(MO.getReg());
> + break;
> + }
> + OutMI.addOperand(MCOp);
> + }
> +}
> +
> +void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
> + AMDGPUMCInstLower MCInstLowering;
> +
> + if (MI->isBundle()) {
> + const MachineBasicBlock *MBB = MI->getParent();
> + MachineBasicBlock::const_instr_iterator I = MI;
> + ++I;
> + while (I != MBB->end() && I->isInsideBundle()) {
> + MCInst MCBundleInst;
> + const MachineInstr *BundledInst = I;
> + MCInstLowering.lower(BundledInst, MCBundleInst);
> + OutStreamer.EmitInstruction(MCBundleInst);
> + ++I;
> + }
> + } else {
> + MCInst TmpInst;
> + MCInstLowering.lower(MI, TmpInst);
> + OutStreamer.EmitInstruction(TmpInst);
> + }
> +}
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUMCInstLower.h Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,31 @@
> +//===- AMDGPUMCInstLower.h MachineInstr Lowering Interface ------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +/// \file
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef AMDGPU_MCINSTLOWER_H
> +#define AMDGPU_MCINSTLOWER_H
> +
> +namespace llvm {
> +
> +class MCInst;
> +class MachineInstr;
> +
> +class AMDGPUMCInstLower {
> +
> +public:
> + AMDGPUMCInstLower();
> +
> + /// \brief Lower a MachineInstr to an MCInst
> + void lower(const MachineInstr *MI, MCInst &OutMI) const;
> +
> +};
> +
> +} // End namespace llvm
> +
> +#endif //AMDGPU_MCINSTLOWER_H
>
> Added: llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.cpp?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.cpp (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.cpp Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,51 @@
> +//===-- AMDGPURegisterInfo.cpp - AMDGPU Register Information
> -------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief Parent TargetRegisterInfo class common to all hw codegen
> targets.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "AMDGPURegisterInfo.h"
> +#include "AMDGPUTargetMachine.h"
> +
> +using namespace llvm;
> +
> +AMDGPURegisterInfo::AMDGPURegisterInfo(TargetMachine &tm,
> + const TargetInstrInfo &tii)
> +: AMDGPUGenRegisterInfo(0),
> + TM(tm),
> + TII(tii)
> + { }
> +
>
> +//===----------------------------------------------------------------------===//
> +// Function handling callbacks - Functions are a seldom used feature of
> GPUS, so
> +// they are not supported at this time.
>
> +//===----------------------------------------------------------------------===//
> +
> +const uint16_t AMDGPURegisterInfo::CalleeSavedReg = AMDGPU::NoRegister;
> +
> +const uint16_t* AMDGPURegisterInfo::getCalleeSavedRegs(const
> MachineFunction *MF)
> +
> const {
> + return &CalleeSavedReg;
> +}
> +
> +void AMDGPURegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator
> MI,
> + int SPAdj,
> + RegScavenger *RS) const {
> + assert(!"Subroutines not supported yet");
> +}
> +
> +unsigned AMDGPURegisterInfo::getFrameRegister(const MachineFunction &MF)
> const {
> + assert(!"Subroutines not supported yet");
> + return 0;
> +}
> +
> +#define GET_REGINFO_TARGET_DESC
> +#include "AMDGPUGenRegisterInfo.inc"
>
> Added: llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.h Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,63 @@
> +//===-- AMDGPURegisterInfo.h - AMDGPURegisterInfo Interface -*- C++
> -*-----===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief TargetRegisterInfo interface that is implemented by all hw
> codegen
> +/// targets.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef AMDGPUREGISTERINFO_H
> +#define AMDGPUREGISTERINFO_H
> +
> +#include "llvm/ADT/BitVector.h"
> +#include "llvm/Target/TargetRegisterInfo.h"
> +
> +#define GET_REGINFO_HEADER
> +#define GET_REGINFO_ENUM
> +#include "AMDGPUGenRegisterInfo.inc"
> +
> +namespace llvm {
> +
> +class AMDGPUTargetMachine;
> +class TargetInstrInfo;
> +
> +struct AMDGPURegisterInfo : public AMDGPUGenRegisterInfo {
> + TargetMachine &TM;
> + const TargetInstrInfo &TII;
> + static const uint16_t CalleeSavedReg;
> +
> + AMDGPURegisterInfo(TargetMachine &tm, const TargetInstrInfo &tii);
> +
> + virtual BitVector getReservedRegs(const MachineFunction &MF) const {
> + assert(!"Unimplemented"); return BitVector();
> + }
> +
> + /// \param RC is an AMDIL reg class.
> + ///
> + /// \returns The ISA reg class that is equivalent to \p RC.
> + virtual const TargetRegisterClass * getISARegClass(
> + const TargetRegisterClass * RC)
> const {
> + assert(!"Unimplemented"); return NULL;
> + }
> +
> + virtual const TargetRegisterClass* getCFGStructurizerRegClass(MVT VT)
> const {
> + assert(!"Unimplemented"); return NULL;
> + }
> +
> + const uint16_t* getCalleeSavedRegs(const MachineFunction *MF) const;
> + void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
> + RegScavenger *RS) const;
> + unsigned getFrameRegister(const MachineFunction &MF) const;
> +
> +};
> +
> +} // End namespace llvm
> +
> +#endif // AMDIDSAREGISTERINFO_H
>
> Added: llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.td?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.td (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPURegisterInfo.td Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,22 @@
> +//===-- AMDGPURegisterInfo.td - AMDGPU register info -------*- tablegen
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// Tablegen register definitions common to all hw codegen targets.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +let Namespace = "AMDGPU" in {
> + def sel_x : SubRegIndex;
> + def sel_y : SubRegIndex;
> + def sel_z : SubRegIndex;
> + def sel_w : SubRegIndex;
> +}
> +
> +include "R600RegisterInfo.td"
> +include "SIRegisterInfo.td"
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUSubtarget.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUSubtarget.cpp?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUSubtarget.cpp (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUSubtarget.cpp Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,87 @@
> +//===-- AMDGPUSubtarget.cpp - AMDGPU Subtarget Information
> ----------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief Implements the AMDGPU specific subclass of TargetSubtarget.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "AMDGPUSubtarget.h"
> +
> +using namespace llvm;
> +
> +#define GET_SUBTARGETINFO_ENUM
> +#define GET_SUBTARGETINFO_TARGET_DESC
> +#define GET_SUBTARGETINFO_CTOR
> +#include "AMDGPUGenSubtargetInfo.inc"
> +
> +AMDGPUSubtarget::AMDGPUSubtarget(StringRef TT, StringRef CPU, StringRef
> FS) :
> + AMDGPUGenSubtargetInfo(TT, CPU, FS), DumpCode(false) {
> + InstrItins = getInstrItineraryForCPU(CPU);
> +
> + memset(CapsOverride, 0, sizeof(*CapsOverride)
> + * AMDGPUDeviceInfo::MaxNumberCapabilities);
> + // Default card
> + StringRef GPU = CPU;
> + Is64bit = false;
> + DefaultSize[0] = 64;
> + DefaultSize[1] = 1;
> + DefaultSize[2] = 1;
> + ParseSubtargetFeatures(GPU, FS);
> + DevName = GPU;
> + Device = AMDGPUDeviceInfo::getDeviceFromName(DevName, this, Is64bit);
> +}
> +
> +AMDGPUSubtarget::~AMDGPUSubtarget() {
> + delete Device;
> +}
> +
> +bool
> +AMDGPUSubtarget::isOverride(AMDGPUDeviceInfo::Caps caps) const {
> + assert(caps < AMDGPUDeviceInfo::MaxNumberCapabilities &&
> + "Caps index is out of bounds!");
> + return CapsOverride[caps];
> +}
> +bool
> +AMDGPUSubtarget::is64bit() const {
> + return Is64bit;
> +}
> +bool
> +AMDGPUSubtarget::isTargetELF() const {
> + return false;
> +}
> +size_t
> +AMDGPUSubtarget::getDefaultSize(uint32_t dim) const {
> + if (dim > 3) {
> + return 1;
> + } else {
> + return DefaultSize[dim];
> + }
> +}
> +
> +std::string
> +AMDGPUSubtarget::getDataLayout() const {
> + if (!Device) {
> + return std::string("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16"
> + "-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:32:32"
> + "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64"
> + "-v96:128:128-v128:128:128-v192:256:256-v256:256:256"
> + "-v512:512:512-v1024:1024:1024-v2048:2048:2048-a0:0:64");
> + }
> + return Device->getDataLayout();
> +}
> +
> +std::string
> +AMDGPUSubtarget::getDeviceName() const {
> + return DevName;
> +}
> +const AMDGPUDevice *
> +AMDGPUSubtarget::device() const {
> + return Device;
> +}
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUSubtarget.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUSubtarget.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUSubtarget.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUSubtarget.h Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,65 @@
> +//=====-- AMDGPUSubtarget.h - Define Subtarget for the AMDIL ---*- C++
> -*-====//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//==-----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief AMDGPU specific subclass of TargetSubtarget.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef AMDGPUSUBTARGET_H
> +#define AMDGPUSUBTARGET_H
> +#include "AMDILDevice.h"
> +#include "llvm/ADT/StringExtras.h"
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/Target/TargetSubtargetInfo.h"
> +
> +#define GET_SUBTARGETINFO_HEADER
> +#include "AMDGPUGenSubtargetInfo.inc"
> +
> +#define MAX_CB_SIZE (1 << 16)
> +
> +namespace llvm {
> +
> +class AMDGPUSubtarget : public AMDGPUGenSubtargetInfo {
> +private:
> + bool CapsOverride[AMDGPUDeviceInfo::MaxNumberCapabilities];
> + const AMDGPUDevice *Device;
> + size_t DefaultSize[3];
> + std::string DevName;
> + bool Is64bit;
> + bool Is32on64bit;
> + bool DumpCode;
> + bool R600ALUInst;
> +
> + InstrItineraryData InstrItins;
> +
> +public:
> + AMDGPUSubtarget(StringRef TT, StringRef CPU, StringRef FS);
> + virtual ~AMDGPUSubtarget();
> +
> + const InstrItineraryData &getInstrItineraryData() const { return
> InstrItins; }
> + virtual void ParseSubtargetFeatures(llvm::StringRef CPU,
> llvm::StringRef FS);
> +
> + bool isOverride(AMDGPUDeviceInfo::Caps) const;
> + bool is64bit() const;
> +
> + // Helper functions to simplify if statements
> + bool isTargetELF() const;
> + const AMDGPUDevice* device() const;
> + std::string getDataLayout() const;
> + std::string getDeviceName() const;
> + virtual size_t getDefaultSize(uint32_t dim) const;
> + bool dumpCode() const { return DumpCode; }
> + bool r600ALUEncoding() const { return R600ALUInst; }
> +
> +};
> +
> +} // End namespace llvm
> +
> +#endif // AMDGPUSUBTARGET_H
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,141 @@
> +//===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen
> targets-----===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief The AMDGPU target machine contains all of the hardware specific
> +/// information needed to emit code for R600 and SI GPUs.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "AMDGPUTargetMachine.h"
> +#include "AMDGPU.h"
> +#include "R600ISelLowering.h"
> +#include "R600InstrInfo.h"
> +#include "SIISelLowering.h"
> +#include "SIInstrInfo.h"
> +#include "llvm/Analysis/Passes.h"
> +#include "llvm/Analysis/Verifier.h"
> +#include "llvm/CodeGen/MachineFunctionAnalysis.h"
> +#include "llvm/CodeGen/MachineModuleInfo.h"
> +#include "llvm/CodeGen/Passes.h"
> +#include "llvm/MC/MCAsmInfo.h"
> +#include "llvm/PassManager.h"
> +#include "llvm/Support/TargetRegistry.h"
> +#include "llvm/Support/raw_os_ostream.h"
> +#include "llvm/Transforms/IPO.h"
> +#include "llvm/Transforms/Scalar.h"
> +#include <llvm/CodeGen/Passes.h>
> +
> +using namespace llvm;
> +
> +extern "C" void LLVMInitializeR600Target() {
> + // Register the target
> + RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget);
> +}
> +
> +AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT,
> + StringRef CPU, StringRef FS,
> + TargetOptions Options,
> + Reloc::Model RM, CodeModel::Model CM,
> + CodeGenOpt::Level OptLevel
> +)
> +:
> + LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel),
> + Subtarget(TT, CPU, FS),
> + Layout(Subtarget.getDataLayout()),
> + FrameLowering(TargetFrameLowering::StackGrowsUp,
> + Subtarget.device()->getStackAlignment(), 0),
> + IntrinsicInfo(this),
> + InstrItins(&Subtarget.getInstrItineraryData()) {
> + // TLInfo uses InstrInfo so it must be initialized after.
> + if (Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
> + InstrInfo = new R600InstrInfo(*this);
> + TLInfo = new R600TargetLowering(*this);
> + } else {
> + InstrInfo = new SIInstrInfo(*this);
> + TLInfo = new SITargetLowering(*this);
> + }
> +}
> +
> +AMDGPUTargetMachine::~AMDGPUTargetMachine() {
> +}
> +
> +namespace {
> +class AMDGPUPassConfig : public TargetPassConfig {
> +public:
> + AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM)
> + : TargetPassConfig(TM, PM) {}
> +
> + AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
> + return getTM<AMDGPUTargetMachine>();
> + }
> +
> + virtual bool addPreISel();
> + virtual bool addInstSelector();
> + virtual bool addPreRegAlloc();
> + virtual bool addPostRegAlloc();
> + virtual bool addPreSched2();
> + virtual bool addPreEmitPass();
> +};
> +} // End of anonymous namespace
> +
> +TargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase
> &PM) {
> + return new AMDGPUPassConfig(this, PM);
> +}
> +
> +bool
> +AMDGPUPassConfig::addPreISel() {
> + return false;
> +}
> +
> +bool AMDGPUPassConfig::addInstSelector() {
> + addPass(createAMDGPUPeepholeOpt(*TM));
> + addPass(createAMDGPUISelDag(getAMDGPUTargetMachine()));
> + return false;
> +}
> +
> +bool AMDGPUPassConfig::addPreRegAlloc() {
> + const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
> +
> + if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
> + addPass(createSIAssignInterpRegsPass(*TM));
> + }
> + addPass(createAMDGPUConvertToISAPass(*TM));
> + if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
> + addPass(createSIFixSGPRLivenessPass(*TM));
> + }
> + return false;
> +}
> +
> +bool AMDGPUPassConfig::addPostRegAlloc() {
> + return false;
> +}
> +
> +bool AMDGPUPassConfig::addPreSched2() {
> +
> + addPass(&IfConverterID);
> + return false;
> +}
> +
> +bool AMDGPUPassConfig::addPreEmitPass() {
> + addPass(createAMDGPUCFGPreparationPass(*TM));
> + addPass(createAMDGPUCFGStructurizerPass(*TM));
> +
> + const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
> + if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
> + addPass(createR600ExpandSpecialInstrsPass(*TM));
> + addPass(&FinalizeMachineBundlesID);
> + } else {
> + addPass(createSILowerLiteralConstantsPass(*TM));
> + addPass(createSILowerControlFlowPass(*TM));
> + }
> +
> + return false;
> +}
> +
>
> Added: llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.h Tue Dec 11 15:25:42
> 2012
> @@ -0,0 +1,70 @@
> +//===-- AMDGPUTargetMachine.h - AMDGPU TargetMachine Interface --*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +/// \file
> +/// \brief The AMDGPU TargetMachine interface definition for hw codgen
> targets.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef AMDGPU_TARGET_MACHINE_H
> +#define AMDGPU_TARGET_MACHINE_H
> +
> +#include "AMDGPUInstrInfo.h"
> +#include "AMDGPUSubtarget.h"
> +#include "AMDILFrameLowering.h"
> +#include "AMDILIntrinsicInfo.h"
> +#include "R600ISelLowering.h"
> +#include "llvm/ADT/OwningPtr.h"
> +#include "llvm/DataLayout.h"
> +
> +namespace llvm {
> +
> +MCAsmInfo* createMCAsmInfo(const Target &T, StringRef TT);
> +
> +class AMDGPUTargetMachine : public LLVMTargetMachine {
> +
> + AMDGPUSubtarget Subtarget;
> + const DataLayout Layout;
> + AMDGPUFrameLowering FrameLowering;
> + AMDGPUIntrinsicInfo IntrinsicInfo;
> + const AMDGPUInstrInfo * InstrInfo;
> + AMDGPUTargetLowering * TLInfo;
> + const InstrItineraryData* InstrItins;
> +
> +public:
> + AMDGPUTargetMachine(const Target &T, StringRef TT, StringRef FS,
> + StringRef CPU,
> + TargetOptions Options,
> + Reloc::Model RM, CodeModel::Model CM,
> + CodeGenOpt::Level OL);
> + ~AMDGPUTargetMachine();
> + virtual const AMDGPUFrameLowering* getFrameLowering() const {
> + return &FrameLowering;
> + }
> + virtual const AMDGPUIntrinsicInfo* getIntrinsicInfo() const {
> + return &IntrinsicInfo;
> + }
> + virtual const AMDGPUInstrInfo *getInstrInfo() const {return InstrInfo;}
> + virtual const AMDGPUSubtarget *getSubtargetImpl() const {return
> &Subtarget; }
> + virtual const AMDGPURegisterInfo *getRegisterInfo() const {
> + return &InstrInfo->getRegisterInfo();
> + }
> + virtual AMDGPUTargetLowering * getTargetLowering() const {
> + return TLInfo;
> + }
> + virtual const InstrItineraryData* getInstrItineraryData() const {
> + return InstrItins;
> + }
> + virtual const DataLayout* getDataLayout() const { return &Layout; }
> + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
> +};
> +
> +} // End namespace llvm
> +
> +#endif // AMDGPU_TARGET_MACHINE_H
>
> Added: llvm/trunk/lib/Target/R600/AMDIL.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDIL.h?rev=169915&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/AMDIL.h (added)
> +++ llvm/trunk/lib/Target/R600/AMDIL.h Tue Dec 11 15:25:42 2012
> @@ -0,0 +1,106 @@
> +//===-- AMDIL.h - Top-level interface for AMDIL representation --*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This ...
>
> [Message clipped]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130815/a813bf5c/attachment.html>
More information about the llvm-commits
mailing list