mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 12:50:00 +00:00
Add a PPC inline asm constraint type for single CR bits
Now that the PowerPC backend can track individual CR bits as first-class registers, we should also have a way of allocating them for inline asm statements. Because these registers are only one bit, if an output variable is implicitly cast to a larger integer size, we'll get an any_extend to that larger type (this is part of the existing target-independent logic). As a result, regardless of the size of the output type, only the first bit is meaningful. The constraint identifier "wc" has been chosen for this purpose. Although gcc does not currently support allocating individual CR bits, this identifier choice has been coordinated with the gcc PowerPC team, and will be marked as reserved for this purpose in the gcc constraints.md file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202657 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3de6ee1ae6
commit
5a49125fec
@ -8292,6 +8292,8 @@ PPCTargetLowering::getConstraintType(const std::string &Constraint) const {
|
|||||||
// suboptimal.
|
// suboptimal.
|
||||||
return C_Memory;
|
return C_Memory;
|
||||||
}
|
}
|
||||||
|
} else if (Constraint == "wc") { // individual CR bits.
|
||||||
|
return C_RegisterClass;
|
||||||
}
|
}
|
||||||
return TargetLowering::getConstraintType(Constraint);
|
return TargetLowering::getConstraintType(Constraint);
|
||||||
}
|
}
|
||||||
@ -8309,7 +8311,11 @@ PPCTargetLowering::getSingleConstraintMatchWeight(
|
|||||||
if (CallOperandVal == NULL)
|
if (CallOperandVal == NULL)
|
||||||
return CW_Default;
|
return CW_Default;
|
||||||
Type *type = CallOperandVal->getType();
|
Type *type = CallOperandVal->getType();
|
||||||
|
|
||||||
// Look at the constraint type.
|
// Look at the constraint type.
|
||||||
|
if (StringRef(constraint) == "wc" && type->isIntegerTy(1))
|
||||||
|
return CW_Register; // an individual CR bit.
|
||||||
|
|
||||||
switch (*constraint) {
|
switch (*constraint) {
|
||||||
default:
|
default:
|
||||||
weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
|
weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
|
||||||
@ -8365,6 +8371,8 @@ PPCTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
|
|||||||
case 'y': // crrc
|
case 'y': // crrc
|
||||||
return std::make_pair(0U, &PPC::CRRCRegClass);
|
return std::make_pair(0U, &PPC::CRRCRegClass);
|
||||||
}
|
}
|
||||||
|
} else if (Constraint == "wc") { // an individual CR bit.
|
||||||
|
return std::make_pair(0U, &PPC::CRBITRCRegClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<unsigned, const TargetRegisterClass*> R =
|
std::pair<unsigned, const TargetRegisterClass*> R =
|
||||||
|
59
test/CodeGen/PowerPC/crbit-asm.ll
Normal file
59
test/CodeGen/PowerPC/crbit-asm.ll
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
; RUN: llc -mcpu=pwr7 < %s | FileCheck %s
|
||||||
|
target datalayout = "E-m:e-i64:64-n32:64"
|
||||||
|
target triple = "powerpc64-unknown-linux-gnu"
|
||||||
|
|
||||||
|
define zeroext i1 @testi1(i1 zeroext %b1, i1 zeroext %b2) #0 {
|
||||||
|
entry:
|
||||||
|
%0 = tail call i8 asm "crand $0, $1, $2", "=^wc,^wc,^wc"(i1 %b1, i1 %b2) #0
|
||||||
|
%1 = and i8 %0, 1
|
||||||
|
%tobool3 = icmp ne i8 %1, 0
|
||||||
|
ret i1 %tobool3
|
||||||
|
|
||||||
|
; CHECK-LABEL: @testi1
|
||||||
|
; CHECK-DAG: andi. {{[0-9]+}}, 3, 1
|
||||||
|
; CHECK-DAG: li [[REG1:[0-9]+]], 0
|
||||||
|
; CHECK-DAG: cror [[REG2:[0-9]+]], 1, 1
|
||||||
|
; CHECK-DAG: andi. {{[0-9]+}}, 4, 1
|
||||||
|
; CHECK-DAG: crand [[REG3:[0-9]+]], [[REG2]], 1
|
||||||
|
; CHECK-DAG: li [[REG4:[0-9]+]], 1
|
||||||
|
; CHECK: isel 3, [[REG4]], [[REG1]], [[REG3]]
|
||||||
|
; CHECK: blr
|
||||||
|
}
|
||||||
|
|
||||||
|
define signext i32 @testi32(i32 signext %b1, i32 signext %b2) #0 {
|
||||||
|
entry:
|
||||||
|
%0 = tail call i32 asm "crand $0, $1, $2", "=^wc,^wc,^wc"(i32 %b1, i32 %b2) #0
|
||||||
|
ret i32 %0
|
||||||
|
|
||||||
|
; The ABI sign_extend should combine with the any_extend from the asm result,
|
||||||
|
; and the result will be 0 or -1. This highlights the fact that only the first
|
||||||
|
; bit is meaningful.
|
||||||
|
; CHECK-LABEL: @testi32
|
||||||
|
; CHECK-DAG: andi. {{[0-9]+}}, 3, 1
|
||||||
|
; CHECK-DAG: li [[REG1:[0-9]+]], 0
|
||||||
|
; CHECK-DAG: cror [[REG2:[0-9]+]], 1, 1
|
||||||
|
; CHECK-DAG: andi. {{[0-9]+}}, 4, 1
|
||||||
|
; CHECK-DAG: crand [[REG3:[0-9]+]], [[REG2]], 1
|
||||||
|
; CHECK-DAG: li [[REG4:[0-9]+]], -1
|
||||||
|
; CHECK: isel 3, [[REG4]], [[REG1]], [[REG3]]
|
||||||
|
; CHECK: blr
|
||||||
|
}
|
||||||
|
|
||||||
|
define zeroext i8 @testi8(i8 zeroext %b1, i8 zeroext %b2) #0 {
|
||||||
|
entry:
|
||||||
|
%0 = tail call i8 asm "crand $0, $1, $2", "=^wc,^wc,^wc"(i8 %b1, i8 %b2) #0
|
||||||
|
ret i8 %0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @testi8
|
||||||
|
; CHECK-DAG: andi. {{[0-9]+}}, 3, 1
|
||||||
|
; CHECK-DAG: li [[REG1:[0-9]+]], 0
|
||||||
|
; CHECK-DAG: cror [[REG2:[0-9]+]], 1, 1
|
||||||
|
; CHECK-DAG: andi. {{[0-9]+}}, 4, 1
|
||||||
|
; CHECK-DAG: crand [[REG3:[0-9]+]], [[REG2]], 1
|
||||||
|
; CHECK-DAG: li [[REG4:[0-9]+]], 1
|
||||||
|
; CHECK: isel 3, [[REG4]], [[REG1]], [[REG3]]
|
||||||
|
; CHECK: blr
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { nounwind }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user