From 63cc527fbce3d1e4b47b687c404b1777fa15ffe5 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sun, 2 Aug 2009 17:39:17 +0000 Subject: [PATCH] Inline assembly support for Blackfin. We use the same constraints as GCC, including those that are slightly insane for inline assembler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77899 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Blackfin/BlackfinISelLowering.cpp | 94 +++++++++++++++++--- lib/Target/Blackfin/BlackfinRegisterInfo.td | 5 ++ lib/Target/Blackfin/README.txt | 50 +++++++++++ test/CodeGen/Blackfin/inline-asm.ll | 38 ++++++++ 4 files changed, 175 insertions(+), 12 deletions(-) create mode 100644 test/CodeGen/Blackfin/inline-asm.ll diff --git a/lib/Target/Blackfin/BlackfinISelLowering.cpp b/lib/Target/Blackfin/BlackfinISelLowering.cpp index a4af0ad9e79..4b1bd9d9244 100644 --- a/lib/Target/Blackfin/BlackfinISelLowering.cpp +++ b/lib/Target/Blackfin/BlackfinISelLowering.cpp @@ -498,34 +498,104 @@ unsigned BlackfinTargetLowering::getFunctionAlignment(const Function *F) const { /// 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 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 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 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(); + switch (Constraint[0]) { + case 'z': return make_vector(P0, P1, P2, 0); + case 'D': return make_vector(R0, R2, R4, R6, 0); + case 'W': return make_vector(R1, R3, R5, R7, 0); + case 'c': return make_vector(I0, I1, I2, I3, + B0, B1, B2, B3, + L0, L1, L2, L3, 0); + case 't': return make_vector(LT0, LT1, 0); + case 'u': return make_vector(LB0, LB1, 0); + case 'k': return make_vector(LC0, LC1, 0); + case 'y': return make_vector(RETS, RETN, RETI, RETX, RETE, + ASTAT, SEQSTAT, USP, 0); + } + return std::vector(); } diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.td b/lib/Target/Blackfin/BlackfinRegisterInfo.td index 2b06fe34964..642d10f5aa6 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.td +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.td @@ -281,6 +281,8 @@ def P : RegisterClass<"BF", [i32], 32, [P0, P1, P2, P3, P4, P5, FP, SP]> { 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 AnyCC : RegisterClass<"BF", [i32], 8, [CC, NCC]> { 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]>; diff --git a/lib/Target/Blackfin/README.txt b/lib/Target/Blackfin/README.txt index 4631c12f7e7..67c1e514bc7 100644 --- a/lib/Target/Blackfin/README.txt +++ b/lib/Target/Blackfin/README.txt @@ -41,6 +41,56 @@ should keep track of: 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<