[llvm-commits] [llvm] r77899 - in /llvm/trunk: lib/Target/Blackfin/BlackfinISelLowering.cpp lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/Blackfin/README.txt test/CodeGen/Blackfin/inline-asm.ll

Jakob Stoklund Olesen stoklund at 2pi.dk
Sun Aug 2 10:39:18 PDT 2009


Author: stoklund
Date: Sun Aug  2 12:39:17 2009
New Revision: 77899

URL: http://llvm.org/viewvc/llvm-project?rev=77899&view=rev
Log:
Inline assembly support for Blackfin.

We use the same constraints as GCC, including those that are slightly insane for inline assembler.

Added:
    llvm/trunk/test/CodeGen/Blackfin/inline-asm.ll
Modified:
    llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp
    llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td
    llvm/trunk/lib/Target/Blackfin/README.txt

Modified: llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp?rev=77899&r1=77898&r2=77899&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp Sun Aug  2 12:39:17 2009
@@ -498,34 +498,104 @@
 /// constraint it is for this target.
 BlackfinTargetLowering::ConstraintType
 BlackfinTargetLowering::getConstraintType(const std::string &Constraint) const {
-  if (Constraint.size() == 1) {
-    switch (Constraint[0]) {
-    default:  break;
-    case 'r': return C_RegisterClass;
-    }
+  if (Constraint.size() != 1)
+    return TargetLowering::getConstraintType(Constraint);
+
+  switch (Constraint[0]) {
+    // Standard constraints
+  case 'r':
+    return C_RegisterClass;
+
+    // Blackfin-specific constraints
+  case 'a':
+  case 'd':
+  case 'z':
+  case 'D':
+  case 'W':
+  case 'e':
+  case 'b':
+  case 'v':
+  case 'f':
+  case 'c':
+  case 't':
+  case 'u':
+  case 'k':
+  case 'x':
+  case 'y':
+  case 'w':
+    return C_RegisterClass;
+  case 'A':
+  case 'B':
+  case 'C':
+  case 'Z':
+  case 'Y':
+    return C_Register;
   }
 
+  // Not implemented: q0-q7, qA. Use {R2} etc instead
+
   return TargetLowering::getConstraintType(Constraint);
 }
 
+/// getRegForInlineAsmConstraint - Return register no and class for a C_Register
+/// constraint.
 std::pair<unsigned, const TargetRegisterClass*> BlackfinTargetLowering::
 getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const {
-  if (Constraint.size() == 1) {
-    switch (Constraint[0]) {
-    case 'r':
-      return std::make_pair(0U, BF::DRegisterClass);
-    }
+  typedef std::pair<unsigned, const TargetRegisterClass*> Pair;
+  using namespace BF;
+
+  if (Constraint.size() != 1)
+    return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
+
+  switch (Constraint[0]) {
+    // Standard constraints
+  case 'r':
+    return Pair(0U, VT == MVT::i16 ? D16RegisterClass : DPRegisterClass);
+
+    // Blackfin-specific constraints
+  case 'a': return Pair(0U, PRegisterClass);
+  case 'd': return Pair(0U, DRegisterClass);
+  case 'e': return Pair(0U, AccuRegisterClass);
+  case 'A': return Pair(A0, AccuRegisterClass);
+  case 'B': return Pair(A1, AccuRegisterClass);
+  case 'b': return Pair(0U, IRegisterClass);
+  case 'v': return Pair(0U, BRegisterClass);
+  case 'f': return Pair(0U, MRegisterClass);
+  case 'C': return Pair(CC, JustCCRegisterClass);
+  case 'x': return Pair(0U, GRRegisterClass);
+  case 'w': return Pair(0U, ALLRegisterClass);
+  case 'Z': return Pair(P3, PRegisterClass);
+  case 'Y': return Pair(P1, PRegisterClass);
   }
 
+  // Not implemented: q0-q7, qA. Use {R2} etc instead.
+  // Constraints z, D, W, c, t, u, k, and y use non-existing classes, defer to
+  // getRegClassForInlineAsmConstraint()
+
   return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
 }
 
 std::vector<unsigned> BlackfinTargetLowering::
-getRegClassForInlineAsmConstraint(const std::string &Constraint,
-                                  MVT VT) const {
+getRegClassForInlineAsmConstraint(const std::string &Constraint, MVT VT) const {
+  using namespace BF;
+
   if (Constraint.size() != 1)
     return std::vector<unsigned>();
 
+  switch (Constraint[0]) {
+  case 'z': return make_vector<unsigned>(P0, P1, P2, 0);
+  case 'D': return make_vector<unsigned>(R0, R2, R4, R6, 0);
+  case 'W': return make_vector<unsigned>(R1, R3, R5, R7, 0);
+  case 'c': return make_vector<unsigned>(I0, I1, I2, I3,
+                                         B0, B1, B2, B3,
+                                         L0, L1, L2, L3, 0);
+  case 't': return make_vector<unsigned>(LT0, LT1, 0);
+  case 'u': return make_vector<unsigned>(LB0, LB1, 0);
+  case 'k': return make_vector<unsigned>(LC0, LC1, 0);
+  case 'y': return make_vector<unsigned>(RETS, RETN, RETI, RETX, RETE,
+                                         ASTAT, SEQSTAT, USP, 0);
+  }
+
   return std::vector<unsigned>();
 }
 

Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td?rev=77899&r1=77898&r2=77899&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td Sun Aug  2 12:39:17 2009
@@ -281,6 +281,8 @@
 
 def I : RegisterClass<"BF", [i32], 32, [I0, I1, I2, I3]>;
 def M : RegisterClass<"BF", [i32], 32, [M0, M1, M2, M3]>;
+def B : RegisterClass<"BF", [i32], 32, [B0, B1, B2, B3]>;
+def L : RegisterClass<"BF", [i32], 32, [L0, L1, L2, L3]>;
 
 def DP : RegisterClass<"BF", [i32], 32,
     [R0, R1, R2, R3, R4, R5, R6, R7,
@@ -378,3 +380,6 @@
 def StatBit : RegisterClass<"BF", [i1], 8,
     [AZ, AN, CC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS]>;
 }
+
+// Should be i40, but that isn't defined. It is not a legal type yet anyway.
+def Accu : RegisterClass<"BF", [i64], 64, [A0, A1]>;

Modified: llvm/trunk/lib/Target/Blackfin/README.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/README.txt?rev=77899&r1=77898&r2=77899&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Blackfin/README.txt (original)
+++ llvm/trunk/lib/Target/Blackfin/README.txt Sun Aug  2 12:39:17 2009
@@ -41,6 +41,56 @@
 It's a hack combining two instructions by concatenation.
 
 * Inline Assembly
+
+These are the GCC constraints from bfin/constraints.md:
+
+| Code  | Register class                            | LLVM |
+|-------+-------------------------------------------+------|
+| a     | P                                         | C    |
+| d     | D                                         | C    |
+| z     | Call clobbered P (P0, P1, P2)             | X    |
+| D     | EvenD                                     | X    |
+| W     | OddD                                      | X    |
+| e     | Accu                                      | C    |
+| A     | A0                                        | S    |
+| B     | A1                                        | S    |
+| b     | I                                         | C    |
+| v     | B                                         | C    |
+| f     | M                                         | C    |
+| c     | Circular I, B, L                          | X    |
+| C     | JustCC                                    | S    |
+| t     | LoopTop                                   | X    |
+| u     | LoopBottom                                | X    |
+| k     | LoopCount                                 | X    |
+| x     | GR                                        | C    |
+| y     | RET*, ASTAT, SEQSTAT, USP                 | X    |
+| w     | ALL                                       | C    |
+| Z     | The FD-PIC GOT pointer (P3)               | S    |
+| Y     | The FD-PIC function pointer register (P1) | S    |
+| q0-q7 | R0-R7 individually                        |      |
+| qA    | P0                                        |      |
+|-------+-------------------------------------------+------|
+| Code  | Constant                                  |      |
+|-------+-------------------------------------------+------|
+| J     | 1<<N, N<32                                |      |
+| Ks3   | imm3                                      |      |
+| Ku3   | uimm3                                     |      |
+| Ks4   | imm4                                      |      |
+| Ku4   | uimm4                                     |      |
+| Ks5   | imm5                                      |      |
+| Ku5   | uimm5                                     |      |
+| Ks7   | imm7                                      |      |
+| KN7   | -imm7                                     |      |
+| Ksh   | imm16                                     |      |
+| Kuh   | uimm16                                    |      |
+| L     | ~(1<<N)                                   |      |
+| M1    | 0xff                                      |      |
+| M2    | 0xffff                                    |      |
+| P0-P4 | 0-4                                       |      |
+| PA    | Macflag, not M                            |      |
+| PB    | Macflag, only M                           |      |
+| Q     | Symbol                                    |      |
+
 ** TODO Support all register classes
 * DAG combiner
 ** Create test case for each Illegal SETCC case

Added: llvm/trunk/test/CodeGen/Blackfin/inline-asm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Blackfin/inline-asm.ll?rev=77899&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/Blackfin/inline-asm.ll (added)
+++ llvm/trunk/test/CodeGen/Blackfin/inline-asm.ll Sun Aug  2 12:39:17 2009
@@ -0,0 +1,38 @@
+; RUN: llvm-as < %s | llc -march=bfin | FileCheck %s
+
+; Standard "r"
+; CHECK: r0 = r0 + r1;
+define i32 @add_r(i32 %A, i32 %B) {
+	%R = call i32 asm "$0 = $1 + $2;", "=r,r,r"( i32 %A, i32 %B ) nounwind
+	ret i32 %R
+}
+
+; Target "d"
+; CHECK: r0 = r0 - r1;
+define i32 @add_d(i32 %A, i32 %B) {
+	%R = call i32 asm "$0 = $1 - $2;", "=d,d,d"( i32 %A, i32 %B ) nounwind
+	ret i32 %R
+}
+
+; Target "a" for P-regs
+; CHECK: p0 = (p0 + p1) << 1;
+define i32 @add_a(i32 %A, i32 %B) {
+	%R = call i32 asm "$0 = ($1 + $2) << 1;", "=a,a,a"( i32 %A, i32 %B ) nounwind
+	ret i32 %R
+}
+
+; Target "z" for P0, P1, P2. This is not a real regclass
+; CHECK: p0 = (p0 + p1) << 2;
+define i32 @add_Z(i32 %A, i32 %B) {
+	%R = call i32 asm "$0 = ($1 + $2) << 2;", "=z,z,z"( i32 %A, i32 %B ) nounwind
+	ret i32 %R
+}
+
+; Target "C" for CC. This is a single register
+; CHECK: cc = p0 < p1;
+; CHECK: r0 = cc;
+define i32 @add_C(i32 %A, i32 %B) {
+	%R = call i32 asm "$0 = $1 < $2;", "=C,z,z"( i32 %A, i32 %B ) nounwind
+	ret i32 %R
+}
+





More information about the llvm-commits mailing list