Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-02-08 Thread Evan Cheng
> Index: lib/CodeGen/LiveIntervalAnalysis.cpp
> ===
> RCS file: /var/cvs/llvm/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp,v
> retrieving revision 1.204
> diff -u -r1.204 LiveIntervalAnalysis.cpp
> --- lib/CodeGen/LiveIntervalAnalysis.cpp  19 Dec 2006 22:41:21 -  
>  
> 1.204
> +++ lib/CodeGen/LiveIntervalAnalysis.cpp  5 Feb 2007 21:05:57 -
> -354,15 +354,26 @@
>  //
>  // Keep track of whether we replace a use and/or def  
> so that we can
>  // create the spill interval with the appropriate range.

Please update comment.

> -mop.setReg(NewVReg);
> -
> -bool HasUse = mop.isUse();
> -bool HasDef = mop.isDef();
> -for (unsigned j = i+1, e = MI->getNumOperands(); j !=  
> e; ++j) {
> +
> +bool HasUse = false;
> +bool HasDef = false;
> +int ReadLatency = InstrSlots::USE; //default read latency
> +for (unsigned j = i, e = MI->getNumOperands(); j != e;  
> ++j) {
>if (MI->getOperand(j).isReg() &&
>MI->getOperand(j).getReg() == li.reg) {
>  MI->getOperand(j).setReg(NewVReg);

Is this right? Aren't you in danger of modifying MO?


> -HasUse |= MI->getOperand(j).isUse();
> +
> +if (MI->getOperand(j).isUse()) {
> +  HasUse = true;
> +  //get the greatest read latency
> +  if (!MI->getOperand(j).isImplicit()){
> +int read_latency = MI->getInstrDescriptor()->
> +  getOperandConstraint(j,TOI::READ_LATENCY);
> +if (read_latency != -1 && read_latency >  
> ReadLatency)
> +  ReadLatency = read_latency;
> +  }
> +}
> +
>  HasDef |= MI->getOperand(j).isDef();
>}
>  }

> @@ -376,16 +387,16 @@
>  // the spill weight is now infinity as it
>  // cannot be spilled again
>  nI.weight = HUGE_VALF;
> -
> +unsigned ValNum = nI.getNextValue(~0U, 0);
>  if (HasUse) {
> -  LiveRange LR(getLoadIndex(index), getUseIndex(index),
> -   nI.getNextValue(~0U, 0));
> +  LiveRange LR(getLoadIndex(index),
> +   getBaseIndex(index) + ReadLatency + 1,  
> ValNum);
>DOUT << " +" << LR;
>nI.addRange(LR);
>  }
>  if (HasDef) {
>LiveRange LR(getDefIndex(index), getStoreIndex(index),
> -   nI.getNextValue(~0U, 0));
> +   ValNum);
>DOUT << " +" << LR;
>nI.addRange(LR);
>  }

Is this right? I think this is adding live intervals for the spill /  
restore instruction?


> @@ -441,6 +441,24 @@
>DOUT << "\t\tregister: "; DEBUG(printRegName(interval.reg));
>LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
> +  // For each kill, get the greatest read latency of the virtual  
> register.
> +  std::vector ReadLatency(vi.Kills.size());
> +  for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i){
> +const TargetInstrDescriptor *instrDescriptor =
> +  vi.Kills[i]->getInstrDescriptor();
> +ReadLatency[i] = InstrSlots::USE; //default read latency
> +//find the operands that use the virtual register
> +for (unsigned j = 0, f = vi.Kills[i]->getNumOperands(); j !=  
> f; ++j){
> +  MachineOperand op = vi.Kills[i]->getOperand(j);
> +  if (op.isRegister() && op.isUse() && (op.getReg() ==  
> interval.reg)) {
> +int read_latency =
> +  instrDescriptor->getOperandConstraint(j,  
> TOI::READ_LATENCY);
> +if (read_latency != -1 && read_latency > ReadLatency[i])
> +  ReadLatency[i] = (char) read_latency;
> +  }
> +}
> +  }

Question: is it necessary to calculate ReadLatency up front rather  
than calculated it on demand (i.e. the rest of the changes in this  
file which use ReadLatency)?

Some nit picks.

1. Please pick identifiers that are more consistent with the rest of  
the LLVM code. e.g. You'll find TID is used for TargetInstrDescriptor  
all over the place.
2. Please use getUseIndex() instead of InstrSlots::Use.
3. Please "unsigned" instead of "char" for ReadLatency to match  
getUseIndex(), etc.

>// Virtual registers may be defined multiple times (due to phi
>// elimination and 2-addr elimination).  Much of what we do only  
> has to be
>// done once for the vreg.  We use an empty interval to detect  
> the first
> @@ -467,7 +485,7 @@
>// FIXME: what about dead vars?
>unsigned killIdx;
>if (vi.Kills[0] != mi)
> -killIdx = getUseIndex(getInstructionIndex(vi.Kills[0]))+1;
> +killIdx = getInstructionIndex(vi.Kills[0]) + ReadLatency 
> [0] + 1;
>  

Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-02-06 Thread Lauro Ramos Venancio

The read_latency.patch is incomplete. I forgot to deal with spill live
intervals.

Lauro

2007/2/6, Lauro Ramos Venancio <[EMAIL PROTECTED]>:

READ_LATENCY patch for review.

Sample of use:
class RegConstraint {
 string Constraints = C;
}

// AI_orr - Defines a (op r, r) pattern.
class AI_orr
 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
  !strconcat(opc, " $dst, $a, $b"),
  [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
   RegConstraint<"$a lat 2">;


Lauro

2007/1/26, Evan Cheng <[EMAIL PROTECTED]>:
>
> On Jan 26, 2007, at 1:07 PM, Lauro Ramos Venancio wrote:
>
> >> The facility does that have to be that general. There are 4 cycles
> >> between every two instructions.  See LiveIntervalAnalysis:
> >>
> >>  struct InstrSlots {
> >>enum {
> >>  LOAD  = 0,
> >>  USE   = 1,
> >>  DEF   = 2,
> >>  STORE = 3,
> >>  NUM   = 4
> >>};
> >>  };
> >>
> >> We can restrict the constraint range to 1 - 3. This ensures the last
> >> use is always the kill while retaining its flexibility.
> >>
> >> Evan
> >
> > I will try to implement this. Do you have any suggestion for
> > constraint name and syntax?
>
> I don't have any great ideas. Perhaps READ_LATENCY for constraint and
> something like
>
> $src +lat 2
>
> for syntax?
>
> Feel free to choose something else if you have better ideas.
>
> Thanks,
>
> Evan
>
> >
> > Lauro
>
>


Index: include/llvm/Target/TargetInstrInfo.h
===
RCS file: /var/cvs/llvm/llvm/include/llvm/Target/TargetInstrInfo.h,v
retrieving revision 1.111
diff -u -r1.111 TargetInstrInfo.h
--- include/llvm/Target/TargetInstrInfo.h	26 Jan 2007 14:34:51 -	1.111
+++ include/llvm/Target/TargetInstrInfo.h	6 Feb 2007 21:09:44 -
@@ -94,9 +94,10 @@
 const unsigned M_PREDICATE_OPERAND = 1 << 1;
 
 namespace TOI {
-  // Operand constraints: only "tied_to" for now.
+  // Operand constraints: only "tied_to" and read_latency for now.
   enum OperandConstraint {
-TIED_TO = 0  // Must be allocated the same register as.
+TIED_TO = 0,  // Must be allocated the same register as.
+READ_LATENCY  // Number of cycles needed for read operand.
   };
 }
 
Index: lib/CodeGen/LiveIntervalAnalysis.cpp
===
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp,v
retrieving revision 1.204
diff -u -r1.204 LiveIntervalAnalysis.cpp
--- lib/CodeGen/LiveIntervalAnalysis.cpp	19 Dec 2006 22:41:21 -	1.204
+++ lib/CodeGen/LiveIntervalAnalysis.cpp	6 Feb 2007 21:09:44 -
@@ -354,15 +354,26 @@
 //
 // Keep track of whether we replace a use and/or def so that we can
 // create the spill interval with the appropriate range. 
-mop.setReg(NewVReg);
-
-bool HasUse = mop.isUse();
-bool HasDef = mop.isDef();
-for (unsigned j = i+1, e = MI->getNumOperands(); j != e; ++j) {
+
+bool HasUse = false;
+bool HasDef = false;
+int ReadLatency = InstrSlots::USE; //default read latency
+for (unsigned j = i, e = MI->getNumOperands(); j != e; ++j) {
   if (MI->getOperand(j).isReg() &&
   MI->getOperand(j).getReg() == li.reg) {
 MI->getOperand(j).setReg(NewVReg);
-HasUse |= MI->getOperand(j).isUse();
+
+if (MI->getOperand(j).isUse()) {
+  HasUse = true;
+  //get the greatest read latency
+  if (!MI->getOperand(j).isImplicit()){
+int read_latency = MI->getInstrDescriptor()->
+  getOperandConstraint(j,TOI::READ_LATENCY);
+if (read_latency != -1 && read_latency > ReadLatency)
+  ReadLatency = read_latency;
+  }
+}
+
 HasDef |= MI->getOperand(j).isDef();
   }
 }
@@ -376,16 +387,16 @@
 // the spill weight is now infinity as it
 // cannot be spilled again
 nI.weight = HUGE_VALF;
-
+unsigned ValNum = nI.getNextValue(~0U, 0);
 if (HasUse) {
-  LiveRange LR(getLoadIndex(index), getUseIndex(index),
-   nI.getNextValue(~0U, 0));
+  LiveRange LR(getLoadIndex(index),
+   getBaseIndex(index) + ReadLatency + 1, ValNum);
   DOUT << " +" << LR;
   nI.addRange(LR);
 }
 if (HasDef) {
   LiveRange LR(getDefIndex(index), getStoreIndex(index),
-   nI.getNextValue(~0U, 0));
+   ValNum);
   DOUT << " +" << LR;
   nI.addRange(LR);
 }
@@ -441,6 +452,24 @@
   DOUT << "\t\tregister: "; DEBUG(printRegName(interval.reg));
   LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
 
+  

Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-02-06 Thread Lauro Ramos Venancio

READ_LATENCY patch for review.

Sample of use:
class RegConstraint {
string Constraints = C;
}

// AI_orr - Defines a (op r, r) pattern.
class AI_orr
: AI<(ops GPR:$dst, GPR:$a, GPR:$b),
 !strconcat(opc, " $dst, $a, $b"),
 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
  RegConstraint<"$a lat 2">;


Lauro

2007/1/26, Evan Cheng <[EMAIL PROTECTED]>:


On Jan 26, 2007, at 1:07 PM, Lauro Ramos Venancio wrote:

>> The facility does that have to be that general. There are 4 cycles
>> between every two instructions.  See LiveIntervalAnalysis:
>>
>>  struct InstrSlots {
>>enum {
>>  LOAD  = 0,
>>  USE   = 1,
>>  DEF   = 2,
>>  STORE = 3,
>>  NUM   = 4
>>};
>>  };
>>
>> We can restrict the constraint range to 1 - 3. This ensures the last
>> use is always the kill while retaining its flexibility.
>>
>> Evan
>
> I will try to implement this. Do you have any suggestion for
> constraint name and syntax?

I don't have any great ideas. Perhaps READ_LATENCY for constraint and
something like

$src +lat 2

for syntax?

Feel free to choose something else if you have better ideas.

Thanks,

Evan

>
> Lauro


Index: include/llvm/Target/TargetInstrInfo.h
===
RCS file: /var/cvs/llvm/llvm/include/llvm/Target/TargetInstrInfo.h,v
retrieving revision 1.111
diff -u -r1.111 TargetInstrInfo.h
--- include/llvm/Target/TargetInstrInfo.h	26 Jan 2007 14:34:51 -	1.111
+++ include/llvm/Target/TargetInstrInfo.h	5 Feb 2007 21:05:56 -
@@ -94,9 +94,10 @@
 const unsigned M_PREDICATE_OPERAND = 1 << 1;
 
 namespace TOI {
-  // Operand constraints: only "tied_to" for now.
+  // Operand constraints: only "tied_to" and read_latency for now.
   enum OperandConstraint {
-TIED_TO = 0  // Must be allocated the same register as.
+TIED_TO = 0,  // Must be allocated the same register as.
+READ_LATENCY  // Number of cycles needed for read operand.
   };
 }
 
Index: lib/CodeGen/LiveIntervalAnalysis.cpp
===
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp,v
retrieving revision 1.204
diff -u -r1.204 LiveIntervalAnalysis.cpp
--- lib/CodeGen/LiveIntervalAnalysis.cpp	19 Dec 2006 22:41:21 -	1.204
+++ lib/CodeGen/LiveIntervalAnalysis.cpp	5 Feb 2007 21:05:57 -
@@ -441,6 +441,24 @@
   DOUT << "\t\tregister: "; DEBUG(printRegName(interval.reg));
   LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
 
+  // For each kill, get the greatest read latency of the virtual register.
+  std::vector ReadLatency(vi.Kills.size());
+  for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i){
+const TargetInstrDescriptor *instrDescriptor =
+  vi.Kills[i]->getInstrDescriptor();
+ReadLatency[i] = InstrSlots::USE; //default read latency
+//find the operands that use the virtual register
+for (unsigned j = 0, f = vi.Kills[i]->getNumOperands(); j != f; ++j){
+  MachineOperand op = vi.Kills[i]->getOperand(j);
+  if (op.isRegister() && op.isUse() && (op.getReg() == interval.reg)) {
+int read_latency =
+  instrDescriptor->getOperandConstraint(j, TOI::READ_LATENCY);
+if (read_latency != -1 && read_latency > ReadLatency[i])
+  ReadLatency[i] = (char) read_latency;
+  }
+}
+  }
+
   // Virtual registers may be defined multiple times (due to phi
   // elimination and 2-addr elimination).  Much of what we do only has to be
   // done once for the vreg.  We use an empty interval to detect the first
@@ -467,7 +485,7 @@
   // FIXME: what about dead vars?
   unsigned killIdx;
   if (vi.Kills[0] != mi)
-killIdx = getUseIndex(getInstructionIndex(vi.Kills[0]))+1;
+killIdx = getInstructionIndex(vi.Kills[0]) + ReadLatency[0] + 1;
   else
 killIdx = defIndex+1;
 
@@ -514,7 +532,7 @@
 for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) {
   MachineInstr *Kill = vi.Kills[i];
   LiveRange LR(getMBBStartIdx(Kill->getParent()),
-   getUseIndex(getInstructionIndex(Kill))+1,
+   getInstructionIndex(Kill)+ ReadLatency[i] + 1,
ValNum);
   interval.addRange(LR);
   DOUT << " +" << LR;
@@ -574,7 +592,7 @@
 // Remove the old range that we now know has an incorrect number.
 MachineInstr *Killer = vi.Kills[0];
 unsigned Start = getMBBStartIdx(Killer->getParent());
-unsigned End = getUseIndex(getInstructionIndex(Killer))+1;
+unsigned End = getInstructionIndex(Killer) + ReadLatency[0] + 1;
 DOUT << "Removing [" << Start << "," << End << "] from: ";
 interval.print(DOUT, mri_); DOUT << "\n";
 interval.removeRange(Start, End);
Index: lib/CodeGen/RegAllocLocal.cpp
===
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/RegAllocLocal.cpp,v
retrieving revision 1.100
diff -u -r1.100 R

Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-01-26 Thread Evan Cheng

On Jan 26, 2007, at 1:07 PM, Lauro Ramos Venancio wrote:

>> The facility does that have to be that general. There are 4 cycles
>> between every two instructions.  See LiveIntervalAnalysis:
>>
>>  struct InstrSlots {
>>enum {
>>  LOAD  = 0,
>>  USE   = 1,
>>  DEF   = 2,
>>  STORE = 3,
>>  NUM   = 4
>>};
>>  };
>>
>> We can restrict the constraint range to 1 - 3. This ensures the last
>> use is always the kill while retaining its flexibility.
>>
>> Evan
>
> I will try to implement this. Do you have any suggestion for
> constraint name and syntax?

I don't have any great ideas. Perhaps READ_LATENCY for constraint and  
something like

$src +lat 2

for syntax?

Feel free to choose something else if you have better ideas.

Thanks,

Evan

>
> Lauro

___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-01-26 Thread Chris Lattner

On Jan 26, 2007, at 1:08 PM, Lauro Ramos Venancio wrote:

> Hi Chris,
>
> In ARM v4/v5 specification, mul %r0, %r0, %r1 (r0 = r0*r1) is invalid,
> but mul %r0, %r1, %r0 is valid. With early-clobber constraint, ARM
> backend wouldn't emit the the mul %r0, %r1, %r0. We need a constraint
> only for the first source register.

Yep, makes sense.  It would be nice if the mechanism you guys invent  
can *also* handle early-clobber, even if it's not a one-to-one  
mapping.  For example, use of early clobber could translate into a  
bunch of != constraints.

-Chris

___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-01-26 Thread Lauro Ramos Venancio
> The facility does that have to be that general. There are 4 cycles
> between every two instructions.  See LiveIntervalAnalysis:
>
>  struct InstrSlots {
>enum {
>  LOAD  = 0,
>  USE   = 1,
>  DEF   = 2,
>  STORE = 3,
>  NUM   = 4
>};
>  };
>
> We can restrict the constraint range to 1 - 3. This ensures the last
> use is always the kill while retaining its flexibility.
>
> Evan

I will try to implement this. Do you have any suggestion for
constraint name and syntax?

Lauro
___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-01-26 Thread Evan Cheng

On Jan 26, 2007, at 6:09 AM, Lauro Ramos Venancio wrote:

> Hi Evan,
>
> Tanks for your review.
>
>> 1. I think rather than adding a constraint that says a source operand
>> must not be assigned the same register as another. It would be better
>> if you add a constraint that says a source operand "can be killed at
>> issue cycle + n". The live range analysis current assumes every
>> source operand read is completed at issue cycle + 0 and write back
>> happens at issue cycle + 2. By changing the read latency to 2 you can
>> force a source operand to conflict with a destination operand.
>
> Currently, kill moment of a temporary is determined by the last use of
> it. With the constraint proposed by you, an intermediary use could
> determine kill moment of a temporary. For example, in an use (with
> read latency 5) of a temporary followed by other use of it (with read
> latency 0), the kill moment would be determined by first use. This
> would complicate liveness algorithm. Does any backend need this
> constraint?

The facility does that have to be that general. There are 4 cycles  
between every two instructions.  See LiveIntervalAnalysis:

 struct InstrSlots {
   enum {
 LOAD  = 0,
 USE   = 1,
 DEF   = 2,
 STORE = 3,
 NUM   = 4
   };
 };

We can restrict the constraint range to 1 - 3. This ensures the last  
use is always the kill while retaining its flexibility.

Evan

>
> Maybe, it would be better a constraint that changes the kill moment
> from default (can kill at issue cycle + 0) to "can kill after
> instruction execution". What do you think?
>
> Lauro

___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-01-26 Thread Chris Lattner
On Jan 26, 2007, at 6:09 AM, Lauro Ramos Venancio wrote:
>> 1. I think rather than adding a constraint that says a source operand
>> must not be assigned the same register as another. It would be better
>> if you add a constraint that says a source operand "can be killed at
>> issue cycle + n". The live range analysis current assumes every
>> source operand read is completed at issue cycle + 0 and write back
>> happens at issue cycle + 2. By changing the read latency to 2 you can
>> force a source operand to conflict with a destination operand.
>
> Currently, kill moment of a temporary is determined by the last use of
> it. With the constraint proposed by you, an intermediary use could
> determine kill moment of a temporary. For example, in an use (with
> read latency 5) of a temporary followed by other use of it (with read
> latency 0), the kill moment would be determined by first use. This
> would complicate liveness algorithm. Does any backend need this
> constraint?
>
> Maybe, it would be better a constraint that changes the kill moment
> from default (can kill at issue cycle + 0) to "can kill after
> instruction execution". What do you think?

I don't have any useful technical input to provide, but this feature  
is quite similar to the GCC "&" early-clobber constraint modifier:

http://gcc.gnu.org/onlinedocs/gcc/Modifiers.html#Modifiers

It would be nice if the facility we end up with is at least as  
general as it is.

-Chris
___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-01-26 Thread Lauro Ramos Venancio
Hi Evan,

Tanks for your review.

> 1. I think rather than adding a constraint that says a source operand
> must not be assigned the same register as another. It would be better
> if you add a constraint that says a source operand "can be killed at
> issue cycle + n". The live range analysis current assumes every
> source operand read is completed at issue cycle + 0 and write back
> happens at issue cycle + 2. By changing the read latency to 2 you can
> force a source operand to conflict with a destination operand.

Currently, kill moment of a temporary is determined by the last use of
it. With the constraint proposed by you, an intermediary use could
determine kill moment of a temporary. For example, in an use (with
read latency 5) of a temporary followed by other use of it (with read
latency 0), the kill moment would be determined by first use. This
would complicate liveness algorithm. Does any backend need this
constraint?

Maybe, it would be better a constraint that changes the kill moment
from default (can kill at issue cycle + 0) to "can kill after
instruction execution". What do you think?

Lauro
___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


Re: [llvm-commits] [patch] Intruction Constraint DestReg!=SrcReg (for review)

2007-01-25 Thread Evan Cheng
Hi Lauro,

Thanks for taking a crack at this! Your work is much appreciated.

However, I have some comments. :-)

1. I think rather than adding a constraint that says a source operand  
must not be assigned the same register as another. It would be better  
if you add a constraint that says a source operand "can be killed at  
issue cycle + n". The live range analysis current assumes every  
source operand read is completed at issue cycle + 0 and write back  
happens at issue cycle + 2. By changing the read latency to 2 you can  
force a source operand to conflict with a destination operand.

2. Please write more comments. :-)

Thanks,

Evan

On Jan 25, 2007, at 1:54 PM, Lauro Ramos Venancio wrote:

> This patch implements the instruction constraint DestReg!=SrcReg. It
> is needed by ARM backend.
>
> A sample of use of this constraint is following:
>
> class RegConstraint {
>  string Constraints = C;
> }
>
> // AI_orr - Defines a (op r, r) pattern.
> class AI_orr
>  : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
>   !strconcat(opc, " $dst, $a, $b"),
>   [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
>RegConstraint<"$dst != $a">;
>
>
> Lauro
> 
> ___
> llvm-commits mailing list
> llvm-commits@cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits