forked from OSchip/llvm-project
Inline assembly support for Blackfin.
We use the same constraints as GCC, including those that are slightly insane for inline assembler. llvm-svn: 77899
This commit is contained in:
parent
526e803f6a
commit
b052972a58
|
@ -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<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>();
|
||||
}
|
||||
|
||||
|
|
|
@ -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]>;
|
||||
|
|
|
@ -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<<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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue