[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