r600g/llvm: Handle copies between vector registers
authorTom Stellard <thomas.stellard@amd.com>
Fri, 20 Apr 2012 13:07:37 +0000 (09:07 -0400)
committerTom Stellard <thomas.stellard@amd.com>
Mon, 23 Apr 2012 13:34:05 +0000 (09:34 -0400)
src/gallium/drivers/radeon/R600GenRegisterInfo.pl
src/gallium/drivers/radeon/R600InstrInfo.cpp

index 396a69f11f6111b838a151c58ddeaaa2bfdb0a99..cbded11576639afd53dd011f78c14d3fee3a5b9f 100644 (file)
@@ -85,6 +85,7 @@ def R600_Reg128 : RegisterClass<"AMDIL", [v4f32], 128, (add
     $t128_string)>
 {
   let SubRegClasses = [(R600_TReg32 sel_x, sel_y, sel_z, sel_w)];
+  let CopyCost = -1;
 }
 
 STRING
index 80adf8c12fa8af8689b1440567c0a39314e5cdaf..0c7ffc4334dac06660f0d209519a97089f1646d2 100644 (file)
@@ -39,8 +39,26 @@ R600InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                            unsigned DestReg, unsigned SrcReg,
                            bool KillSrc) const
 {
-  BuildMI(MBB, MI, DL, get(AMDIL::MOV), DestReg)
-    .addReg(SrcReg, getKillRegState(KillSrc));
+
+  unsigned subRegMap[4] = {AMDIL::sel_x, AMDIL::sel_y, AMDIL::sel_z, AMDIL::sel_w};
+
+  if (AMDIL::R600_Reg128RegClass.contains(DestReg)
+      && AMDIL::R600_Reg128RegClass.contains(SrcReg)) {
+    for (unsigned i = 0; i < 4; i++) {
+      BuildMI(MBB, MI, DL, get(AMDIL::MOV))
+              .addReg(RI.getSubReg(DestReg, subRegMap[i]), RegState::Define)
+              .addReg(RI.getSubReg(SrcReg, subRegMap[i]))
+              .addReg(DestReg, RegState::Define | RegState::Implicit);
+    }
+  } else {
+
+    /* We can't copy vec4 registers */
+    assert(!AMDIL::R600_Reg128RegClass.contains(DestReg)
+           && !AMDIL::R600_Reg128RegClass.contains(SrcReg));
+
+    BuildMI(MBB, MI, DL, get(AMDIL::MOV), DestReg)
+      .addReg(SrcReg, getKillRegState(KillSrc));
+  }
 }
 
 unsigned R600InstrInfo::getISAOpcode(unsigned opcode) const