mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-15 16:09:57 +00:00
Add bfc to armv6t2.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74868 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
edcbada3d0
commit
36a0aebac2
@ -741,6 +741,11 @@ void Emitter<CodeEmitter>::emitDataProcessingInstruction(
|
||||
unsigned ImplicitRn) {
|
||||
const TargetInstrDesc &TID = MI.getDesc();
|
||||
|
||||
if (TID.Opcode == ARM::BFC) {
|
||||
cerr << "ERROR: ARMv6t2 JIT is not yet supported.\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
// Part of binary is determined by TableGn.
|
||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||
|
||||
|
@ -170,6 +170,27 @@ def sext_16_node : PatLeaf<(i32 GPR:$a), [{
|
||||
return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
|
||||
}]>;
|
||||
|
||||
/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
|
||||
/// e.g., 0xf000ffff
|
||||
def bf_inv_mask_imm : Operand<i32>,
|
||||
PatLeaf<(imm), [{
|
||||
uint32_t v = (uint32_t)N->getZExtValue();
|
||||
if (v == 0xffffffff)
|
||||
return 0;
|
||||
// naive checker. should do better, but simple is best for now since it's
|
||||
// more likely to be correct.
|
||||
while (v & 1) v >>= 1; // shift off the leading 1's
|
||||
if (v)
|
||||
{
|
||||
while (!(v & 1)) v >>=1; // shift off the mask
|
||||
while (v & 1) v >>= 1; // shift off the trailing 1's
|
||||
}
|
||||
// if this is a mask for clearing a bitfield, what's left should be zero.
|
||||
return (v == 0);
|
||||
}] > {
|
||||
let PrintMethod = "printBitfieldInvMaskImmOperand";
|
||||
}
|
||||
|
||||
class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
|
||||
class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
|
||||
|
||||
@ -993,6 +1014,15 @@ defm EOR : AsI1_bin_irs<0b0001, "eor",
|
||||
defm BIC : AsI1_bin_irs<0b1110, "bic",
|
||||
BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
|
||||
|
||||
def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
|
||||
AddrMode1, Size4Bytes, IndexModeNone, DPFrm,
|
||||
"bfc", " $dst, $imm", "$src = $dst",
|
||||
[(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
|
||||
Requires<[IsARM, HasV6T2]> {
|
||||
let Inst{27-21} = 0b0111110;
|
||||
let Inst{6-0} = 0b0011111;
|
||||
}
|
||||
|
||||
def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm,
|
||||
"mvn", " $dst, $src",
|
||||
[(set GPR:$dst, (not GPR:$src))]>, UnaryDP;
|
||||
|
@ -89,27 +89,6 @@ def imm0_65535 : PatLeaf<(i32 imm), [{
|
||||
return (uint32_t)N->getZExtValue() < 65536;
|
||||
}]>;
|
||||
|
||||
/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
|
||||
/// e.g., 0xf000ffff
|
||||
def bf_inv_mask_imm : Operand<i32>,
|
||||
PatLeaf<(imm), [{
|
||||
uint32_t v = (uint32_t)N->getZExtValue();
|
||||
if (v == 0xffffffff)
|
||||
return 0;
|
||||
// naive checker. should do better, but simple is best for now since it's
|
||||
// more likely to be correct.
|
||||
while (v & 1) v >>= 1; // shift off the leading 1's
|
||||
if (v)
|
||||
{
|
||||
while (!(v & 1)) v >>=1; // shift off the mask
|
||||
while (v & 1) v >>= 1; // shift off the trailing 1's
|
||||
}
|
||||
// if this is a mask for clearing a bitfield, what's left should be zero.
|
||||
return (v == 0);
|
||||
}] > {
|
||||
let PrintMethod = "printBitfieldInvMaskImmOperand";
|
||||
}
|
||||
|
||||
/// Split a 32-bit immediate into two 16 bit parts.
|
||||
def t2_lo16 : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
|
||||
@ -820,23 +799,6 @@ defm t2EOR : T2I_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
|
||||
|
||||
defm t2BIC : T2I_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
|
||||
|
||||
def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
|
||||
(t2BICri GPR:$src, t2_so_imm_not:$imm)>;
|
||||
|
||||
defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
|
||||
|
||||
def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
|
||||
(t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
|
||||
|
||||
// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
|
||||
let AddedComplexity = 1 in
|
||||
defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
|
||||
|
||||
def : T2Pat<(t2_so_imm_not:$src),
|
||||
(t2MVNi t2_so_imm_not:$src)>;
|
||||
|
||||
// A8.6.17 BFC - Bitfield clear
|
||||
// FIXME: Also available in ARM mode.
|
||||
let Constraints = "$src = $dst" in
|
||||
def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
|
||||
"bfc", " $dst, $imm",
|
||||
@ -844,6 +806,22 @@ def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
|
||||
|
||||
// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
|
||||
|
||||
defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
|
||||
|
||||
// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
|
||||
let AddedComplexity = 1 in
|
||||
defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
|
||||
|
||||
|
||||
def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
|
||||
(t2BICri GPR:$src, t2_so_imm_not:$imm)>;
|
||||
|
||||
def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
|
||||
(t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
|
||||
|
||||
def : T2Pat<(t2_so_imm_not:$src),
|
||||
(t2MVNi t2_so_imm_not:$src)>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Multiply Instructions.
|
||||
//
|
||||
|
19
test/CodeGen/ARM/bfc.ll
Normal file
19
test/CodeGen/ARM/bfc.ll
Normal file
@ -0,0 +1,19 @@
|
||||
; RUN: llvm-as < %s | llc -march=arm -mattr=+v6t2 | grep "bfc " | count 3
|
||||
|
||||
; 4278190095 = 0xff00000f
|
||||
define i32 @f1(i32 %a) {
|
||||
%tmp = and i32 %a, 4278190095
|
||||
ret i32 %tmp
|
||||
}
|
||||
|
||||
; 4286578688 = 0xff800000
|
||||
define i32 @f2(i32 %a) {
|
||||
%tmp = and i32 %a, 4286578688
|
||||
ret i32 %tmp
|
||||
}
|
||||
|
||||
; 4095 = 0x00000fff
|
||||
define i32 @f3(i32 %a) {
|
||||
%tmp = and i32 %a, 4095
|
||||
ret i32 %tmp
|
||||
}
|
Loading…
Reference in New Issue
Block a user