forked from OSchip/llvm-project
279 lines
11 KiB
TableGen
279 lines
11 KiB
TableGen
//===- PTXInstrLoadStore.td - PTX Load/Store Instruction Defs -*- tblgen-*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file describes the PTX load/store instructions in TableGen format.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
// Addressing Predicates
|
|
// We have to differentiate between 32- and 64-bit pointer types
|
|
def Use32BitAddresses : Predicate<"!getSubtarget().is64Bit()">;
|
|
def Use64BitAddresses : Predicate<"getSubtarget().is64Bit()">;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Pattern Fragments for Loads/Stores
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
def load_global : PatFrag<(ops node:$ptr), (load node:$ptr), [{
|
|
const Value *Src;
|
|
const PointerType *PT;
|
|
if ((Src = cast<LoadSDNode>(N)->getSrcValue()) &&
|
|
(PT = dyn_cast<PointerType>(Src->getType())))
|
|
return PT->getAddressSpace() == PTXStateSpace::Global;
|
|
return false;
|
|
}]>;
|
|
|
|
def load_constant : PatFrag<(ops node:$ptr), (load node:$ptr), [{
|
|
const Value *Src;
|
|
const PointerType *PT;
|
|
if ((Src = cast<LoadSDNode>(N)->getSrcValue()) &&
|
|
(PT = dyn_cast<PointerType>(Src->getType())))
|
|
return PT->getAddressSpace() == PTXStateSpace::Constant;
|
|
return false;
|
|
}]>;
|
|
|
|
def load_shared : PatFrag<(ops node:$ptr), (load node:$ptr), [{
|
|
const Value *Src;
|
|
const PointerType *PT;
|
|
if ((Src = cast<LoadSDNode>(N)->getSrcValue()) &&
|
|
(PT = dyn_cast<PointerType>(Src->getType())))
|
|
return PT->getAddressSpace() == PTXStateSpace::Shared;
|
|
return false;
|
|
}]>;
|
|
|
|
def store_global
|
|
: PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{
|
|
const Value *Src;
|
|
const PointerType *PT;
|
|
if ((Src = cast<StoreSDNode>(N)->getSrcValue()) &&
|
|
(PT = dyn_cast<PointerType>(Src->getType())))
|
|
return PT->getAddressSpace() == PTXStateSpace::Global;
|
|
return false;
|
|
}]>;
|
|
|
|
def store_shared
|
|
: PatFrag<(ops node:$d, node:$ptr), (store node:$d, node:$ptr), [{
|
|
const Value *Src;
|
|
const PointerType *PT;
|
|
if ((Src = cast<StoreSDNode>(N)->getSrcValue()) &&
|
|
(PT = dyn_cast<PointerType>(Src->getType())))
|
|
return PT->getAddressSpace() == PTXStateSpace::Shared;
|
|
return false;
|
|
}]>;
|
|
|
|
// Addressing modes.
|
|
def ADDRrr32 : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
|
|
def ADDRrr64 : ComplexPattern<i64, 2, "SelectADDRrr", [], []>;
|
|
def ADDRri32 : ComplexPattern<i32, 2, "SelectADDRri", [], []>;
|
|
def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri", [], []>;
|
|
def ADDRii32 : ComplexPattern<i32, 2, "SelectADDRii", [], []>;
|
|
def ADDRii64 : ComplexPattern<i64, 2, "SelectADDRii", [], []>;
|
|
def ADDRlocal32 : ComplexPattern<i32, 2, "SelectADDRlocal", [], []>;
|
|
def ADDRlocal64 : ComplexPattern<i64, 2, "SelectADDRlocal", [], []>;
|
|
|
|
// Address operands
|
|
def MEMri32 : Operand<i32> {
|
|
let PrintMethod = "printMemOperand";
|
|
let MIOperandInfo = (ops RegI32, i32imm);
|
|
}
|
|
def MEMri64 : Operand<i64> {
|
|
let PrintMethod = "printMemOperand";
|
|
let MIOperandInfo = (ops RegI64, i64imm);
|
|
}
|
|
def LOCALri32 : Operand<i32> {
|
|
let PrintMethod = "printMemOperand";
|
|
let MIOperandInfo = (ops i32imm, i32imm);
|
|
}
|
|
def LOCALri64 : Operand<i64> {
|
|
let PrintMethod = "printMemOperand";
|
|
let MIOperandInfo = (ops i64imm, i64imm);
|
|
}
|
|
def MEMii32 : Operand<i32> {
|
|
let PrintMethod = "printMemOperand";
|
|
let MIOperandInfo = (ops i32imm, i32imm);
|
|
}
|
|
def MEMii64 : Operand<i64> {
|
|
let PrintMethod = "printMemOperand";
|
|
let MIOperandInfo = (ops i64imm, i64imm);
|
|
}
|
|
// The operand here does not correspond to an actual address, so we
|
|
// can use i32 in 64-bit address modes.
|
|
def MEMpi : Operand<i32> {
|
|
let PrintMethod = "printParamOperand";
|
|
let MIOperandInfo = (ops i32imm);
|
|
}
|
|
def MEMret : Operand<i32> {
|
|
let PrintMethod = "printReturnOperand";
|
|
let MIOperandInfo = (ops i32imm);
|
|
}
|
|
|
|
|
|
// Load/store .param space
|
|
def PTXloadparam
|
|
: SDNode<"PTXISD::LOAD_PARAM", SDTypeProfile<1, 1, [SDTCisPtrTy<1>]>,
|
|
[SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
|
|
def PTXstoreparam
|
|
: SDNode<"PTXISD::STORE_PARAM", SDTypeProfile<0, 2, [SDTCisVT<0, i32>]>,
|
|
[SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
|
|
|
|
def PTXreadparam
|
|
: SDNode<"PTXISD::READ_PARAM", SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>,
|
|
[SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
|
|
def PTXwriteparam
|
|
: SDNode<"PTXISD::WRITE_PARAM", SDTypeProfile<0, 1, []>,
|
|
[SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Classes for loads/stores
|
|
//===----------------------------------------------------------------------===//
|
|
multiclass PTX_LD<string opstr, string typestr,
|
|
RegisterClass RC, PatFrag pat_load> {
|
|
def rr32 : InstPTX<(outs RC:$d),
|
|
(ins MEMri32:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
|
[(set RC:$d, (pat_load ADDRrr32:$a))]>,
|
|
Requires<[Use32BitAddresses]>;
|
|
def rr64 : InstPTX<(outs RC:$d),
|
|
(ins MEMri64:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
|
[(set RC:$d, (pat_load ADDRrr64:$a))]>,
|
|
Requires<[Use64BitAddresses]>;
|
|
def ri32 : InstPTX<(outs RC:$d),
|
|
(ins MEMri32:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
|
[(set RC:$d, (pat_load ADDRri32:$a))]>,
|
|
Requires<[Use32BitAddresses]>;
|
|
def ri64 : InstPTX<(outs RC:$d),
|
|
(ins MEMri64:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
|
[(set RC:$d, (pat_load ADDRri64:$a))]>,
|
|
Requires<[Use64BitAddresses]>;
|
|
def ii32 : InstPTX<(outs RC:$d),
|
|
(ins MEMii32:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
|
[(set RC:$d, (pat_load ADDRii32:$a))]>,
|
|
Requires<[Use32BitAddresses]>;
|
|
def ii64 : InstPTX<(outs RC:$d),
|
|
(ins MEMii64:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
|
[(set RC:$d, (pat_load ADDRii64:$a))]>,
|
|
Requires<[Use64BitAddresses]>;
|
|
}
|
|
|
|
multiclass PTX_ST<string opstr, string typestr, RegisterClass RC,
|
|
PatFrag pat_store> {
|
|
def rr32 : InstPTX<(outs),
|
|
(ins RC:$d, MEMri32:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
|
[(pat_store RC:$d, ADDRrr32:$a)]>,
|
|
Requires<[Use32BitAddresses]>;
|
|
def rr64 : InstPTX<(outs),
|
|
(ins RC:$d, MEMri64:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
|
[(pat_store RC:$d, ADDRrr64:$a)]>,
|
|
Requires<[Use64BitAddresses]>;
|
|
def ri32 : InstPTX<(outs),
|
|
(ins RC:$d, MEMri32:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
|
[(pat_store RC:$d, ADDRri32:$a)]>,
|
|
Requires<[Use32BitAddresses]>;
|
|
def ri64 : InstPTX<(outs),
|
|
(ins RC:$d, MEMri64:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
|
[(pat_store RC:$d, ADDRri64:$a)]>,
|
|
Requires<[Use64BitAddresses]>;
|
|
def ii32 : InstPTX<(outs),
|
|
(ins RC:$d, MEMii32:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
|
[(pat_store RC:$d, ADDRii32:$a)]>,
|
|
Requires<[Use32BitAddresses]>;
|
|
def ii64 : InstPTX<(outs),
|
|
(ins RC:$d, MEMii64:$a),
|
|
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
|
[(pat_store RC:$d, ADDRii64:$a)]>,
|
|
Requires<[Use64BitAddresses]>;
|
|
}
|
|
|
|
multiclass PTX_LOCAL_LD_ST<string typestr, RegisterClass RC> {
|
|
def LDri32 : InstPTX<(outs RC:$d), (ins LOCALri32:$a),
|
|
!strconcat("ld.local", !strconcat(typestr, "\t$d, [$a]")),
|
|
[(set RC:$d, (load_global ADDRlocal32:$a))]>;
|
|
def LDri64 : InstPTX<(outs RC:$d), (ins LOCALri64:$a),
|
|
!strconcat("ld.local", !strconcat(typestr, "\t$d, [$a]")),
|
|
[(set RC:$d, (load_global ADDRlocal64:$a))]>;
|
|
def STri32 : InstPTX<(outs), (ins RC:$d, LOCALri32:$a),
|
|
!strconcat("st.local", !strconcat(typestr, "\t[$a], $d")),
|
|
[(store_global RC:$d, ADDRlocal32:$a)]>;
|
|
def STri64 : InstPTX<(outs), (ins RC:$d, LOCALri64:$a),
|
|
!strconcat("st.local", !strconcat(typestr, "\t[$a], $d")),
|
|
[(store_global RC:$d, ADDRlocal64:$a)]>;
|
|
}
|
|
|
|
multiclass PTX_PARAM_LD_ST<string typestr, RegisterClass RC> {
|
|
let hasSideEffects = 1 in {
|
|
def LDpi : InstPTX<(outs RC:$d), (ins i32imm:$a),
|
|
!strconcat("ld.param", !strconcat(typestr, "\t$d, [$a]")),
|
|
[(set RC:$d, (PTXloadparam texternalsym:$a))]>;
|
|
def STpi : InstPTX<(outs), (ins i32imm:$d, RC:$a),
|
|
!strconcat("st.param", !strconcat(typestr, "\t[$d], $a")),
|
|
[(PTXstoreparam texternalsym:$d, RC:$a)]>;
|
|
}
|
|
}
|
|
|
|
multiclass PTX_LD_ALL<string opstr, PatFrag pat_load> {
|
|
defm u16 : PTX_LD<opstr, ".u16", RegI16, pat_load>;
|
|
defm u32 : PTX_LD<opstr, ".u32", RegI32, pat_load>;
|
|
defm u64 : PTX_LD<opstr, ".u64", RegI64, pat_load>;
|
|
defm f32 : PTX_LD<opstr, ".f32", RegF32, pat_load>;
|
|
defm f64 : PTX_LD<opstr, ".f64", RegF64, pat_load>;
|
|
}
|
|
|
|
multiclass PTX_ST_ALL<string opstr, PatFrag pat_store> {
|
|
defm u16 : PTX_ST<opstr, ".u16", RegI16, pat_store>;
|
|
defm u32 : PTX_ST<opstr, ".u32", RegI32, pat_store>;
|
|
defm u64 : PTX_ST<opstr, ".u64", RegI64, pat_store>;
|
|
defm f32 : PTX_ST<opstr, ".f32", RegF32, pat_store>;
|
|
defm f64 : PTX_ST<opstr, ".f64", RegF64, pat_store>;
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Instruction definitions for loads/stores
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Global/shared stores
|
|
defm STg : PTX_ST_ALL<"st.global", store_global>;
|
|
defm STs : PTX_ST_ALL<"st.shared", store_shared>;
|
|
|
|
// Global/shared/constant loads
|
|
defm LDg : PTX_LD_ALL<"ld.global", load_global>;
|
|
defm LDc : PTX_LD_ALL<"ld.const", load_constant>;
|
|
defm LDs : PTX_LD_ALL<"ld.shared", load_shared>;
|
|
|
|
// Param loads/stores
|
|
defm PARAMPRED : PTX_PARAM_LD_ST<".pred", RegPred>;
|
|
defm PARAMU16 : PTX_PARAM_LD_ST<".u16", RegI16>;
|
|
defm PARAMU32 : PTX_PARAM_LD_ST<".u32", RegI32>;
|
|
defm PARAMU64 : PTX_PARAM_LD_ST<".u64", RegI64>;
|
|
defm PARAMF32 : PTX_PARAM_LD_ST<".f32", RegF32>;
|
|
defm PARAMF64 : PTX_PARAM_LD_ST<".f64", RegF64>;
|
|
|
|
// Local loads/stores
|
|
defm LOCALPRED : PTX_LOCAL_LD_ST<".pred", RegPred>;
|
|
defm LOCALU16 : PTX_LOCAL_LD_ST<".u16", RegI16>;
|
|
defm LOCALU32 : PTX_LOCAL_LD_ST<".u32", RegI32>;
|
|
defm LOCALU64 : PTX_LOCAL_LD_ST<".u64", RegI64>;
|
|
defm LOCALF32 : PTX_LOCAL_LD_ST<".f32", RegF32>;
|
|
defm LOCALF64 : PTX_LOCAL_LD_ST<".f64", RegF64>;
|
|
|