radeon/llvm: Add pseudo-support for 64-bit immediate types on SI
authorTom Stellard <thomas.stellard@amd.com>
Tue, 31 Jul 2012 20:05:54 +0000 (20:05 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Tue, 31 Jul 2012 20:19:21 +0000 (20:19 +0000)
SI does not support 64-bit immediates natively, but llvm will generate
i64 immediates when indexing loads and stores (since SI has 64-bit
pointers).  The i64 indices will always be small enough to fit into
32-bits (i.e. the high 32 bits will always be all zeros), so we can
treat these index values as 32-bits.

src/gallium/drivers/radeon/SIInstrInfo.td
src/gallium/drivers/radeon/SIInstructions.td

index 36496f0cc73cca55f5ab2223f5acc8acb2479e0c..81df55d135efba65f1ee7f94cb660f09fa24649e 100644 (file)
@@ -71,6 +71,11 @@ def IMM12bit : ImmLeaf <
   [{return (int16_t)Imm >= 0 && (int16_t)Imm <= 0xfff;}]
 >;
 
+def IMM32bitIn64bit : ImmLeaf <
+  i64,
+  [{return isInt<32>(Imm);}]
+>;
+
 class GPR4Align <RegisterClass rc> : Operand <vAny> {
   let EncoderMethod = "GPR4AlignEncode";
   let MIOperandInfo = (ops rc:$reg); 
@@ -85,6 +90,12 @@ def i32Literal : Operand <i32> {
   let EncoderMethod = "i32LiteralEncode";
 }
 
+// i64Literal uses the same encoder method as i32 literal, because an
+// i64Literal is really a i32 literal with the top 32-bits all set to zero.
+def i64Literal : Operand <i64> {
+  let EncoderMethod = "i32LiteralEncode";
+}
+
 def SMRDmemrr : Operand<iPTR> {
   let MIOperandInfo = (ops SReg_64, SReg_32);
   let EncoderMethod = "GPR2AlignEncode";
index 42bb449f2ee6475747e45cb0a22f17e1327dace0..94748b6725985759e5c09c62312ea5fe7c4d5fec 100644 (file)
@@ -884,6 +884,18 @@ def S_MOV_IMM_I32 : SOP1 <
   [(set SReg_32:$dst, (imm:$src0))]
 >;
 
+// i64 immediates aren't really supported in hardware, but LLVM will use the i64
+// type for indices on load and store instructions.  The pattern for
+// S_MOV_IMM_I64 will only match i64 immediates that can fit into 32-bits,
+// which the hardware can handle.
+def S_MOV_IMM_I64 : SOP1 <
+  0x3,
+  (outs SReg_64:$dst),
+  (ins i64Literal:$src0),
+  "S_MOV_IMM_I64 $dst, $src0",
+  [(set SReg_64:$dst, (IMM32bitIn64bit:$src0))]
+>;
+
 let isCodeGenOnly = 1, isPseudo = 1 in {
 
 def SET_M0 : InstSI <