R600/SI: add proper 64bit immediate support v2
authorTom Stellard <thomas.stellard@amd.com>
Thu, 7 Feb 2013 19:39:38 +0000 (19:39 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 7 Feb 2013 19:39:38 +0000 (19:39 +0000)
v2: rebased on current upstream

Patch by: Christian König

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174652 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/R600/SIInstrInfo.td
lib/Target/R600/SIInstructions.td
lib/Target/R600/SILowerLiteralConstants.cpp

index 9d9f5f6e1e8082a925d8d3b8f4bd1084d558a727..83ee2cffb4a4ccc635dcf2c4e60dea3bac246513 100644 (file)
@@ -38,6 +38,16 @@ def SIvcc_bitcast : SDNode<"SIISD::VCC_BITCAST",
   SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>
 >;
 
+// Transformation function, extract the lower 32bit of a 64bit immediate
+def LO32 : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
+}]>;
+
+// Transformation function, extract the upper 32bit of a 64bit immediate
+def HI32 : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
+}]>;
+
 class InstSI <dag outs, dag ins, string asm, list<dag> pattern> :
     AMDGPUInst<outs, ins, asm, pattern> {
 
index dd5bb42aa4a70ae4e7946bd635b72c286055ec17..7d35561e9b8af28fa6c920be8438314e6aaecba4 100644 (file)
@@ -1019,19 +1019,16 @@ def S_MOV_IMM_I32 : InstSI <
   [(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 : InstSI <
-  (outs SReg_64:$dst),
-  (ins i64imm:$src0),
-  "S_MOV_IMM_I64 $dst, $src0",
-  [(set SReg_64:$dst, (IMM32bitIn64bit:$src0))]
->;
-
 } // End isCodeGenOnly, isPseudo = 1
 
+// i64 immediates aren't supported in hardware, split it into two 32bit values
+def : Pat <
+  (i64 imm:$imm),
+  (INSERT_SUBREG (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+    (S_MOV_IMM_I32 (LO32 imm:$imm)), sub0),
+    (S_MOV_IMM_I32 (HI32 imm:$imm)), sub1)
+>;
+
 class SI_LOAD_LITERAL<Operand ImmType> :
     Enc32 <(outs), (ins ImmType:$imm), "LOAD_LITERAL $imm", []> {
 
index c0411e9b4d5b074a8821dc941039dba5657a2589..6f5fd36396b681d0232562bd946b6f67ae3a095c 100644 (file)
@@ -73,7 +73,6 @@ bool SILowerLiteralConstantsPass::runOnMachineFunction(MachineFunction &MF) {
       switch (MI.getOpcode()) {
       default: break;
       case AMDGPU::S_MOV_IMM_I32:
-      case AMDGPU::S_MOV_IMM_I64:
       case AMDGPU::V_MOV_IMM_F32:
       case AMDGPU::V_MOV_IMM_I32: {
           unsigned MovOpcode;