mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-26 06:04:47 +00:00
This change handles a another case for generating the bic instruction
when a compile time constant is known. This occurs when implicitly zero extending function arguments from 16 bits to 32 bits. The 8 bit case doesn't need to be handled, as the 8 bit constants are encoded directly, thereby not needing a separate load instruction to form the constant into a register. <rdar://problem/11481151> llvm-svn: 158659
This commit is contained in:
parent
1c3df655ea
commit
3d5ae56be4
@ -62,6 +62,15 @@ def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
|
||||
}]>;
|
||||
|
||||
// so_imm_notSext_XFORM - Return a so_imm value packed into the format
|
||||
// described for so_imm_notSext def below, with sign extension from 16
|
||||
// bits.
|
||||
def t2_so_imm_notSext16_XFORM : SDNodeXForm<imm, [{
|
||||
APInt apIntN = N->getAPIntValue();
|
||||
unsigned N16bitSignExt = apIntN.trunc(16).sext(32).getZExtValue();
|
||||
return CurDAG->getTargetConstant(~N16bitSignExt, MVT::i32);
|
||||
}]>;
|
||||
|
||||
// t2_so_imm - Match a 32-bit immediate operand, which is an
|
||||
// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
|
||||
// immediate splatted into multiple bytes of the word.
|
||||
@ -86,6 +95,17 @@ def t2_so_imm_not : Operand<i32>, PatLeaf<(imm), [{
|
||||
let ParserMatchClass = t2_so_imm_not_asmoperand;
|
||||
}
|
||||
|
||||
// t2_so_imm_notSext - match an immediate that is a complement of a t2_so_imm
|
||||
// if the upper 16 bits are zero.
|
||||
def t2_so_imm_notSext : Operand<i32>, PatLeaf<(imm), [{
|
||||
APInt apIntN = N->getAPIntValue();
|
||||
if (!apIntN.isIntN(16)) return false;
|
||||
unsigned N16bitSignExt = apIntN.trunc(16).sext(32).getZExtValue();
|
||||
return ARM_AM::getT2SOImmVal(~N16bitSignExt) != -1;
|
||||
}], t2_so_imm_notSext16_XFORM> {
|
||||
let ParserMatchClass = t2_so_imm_not_asmoperand;
|
||||
}
|
||||
|
||||
// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
|
||||
def t2_so_imm_neg_asmoperand : AsmOperandClass { let Name = "T2SOImmNeg"; }
|
||||
def t2_so_imm_neg : Operand<i32>, PatLeaf<(imm), [{
|
||||
@ -2332,6 +2352,17 @@ let AddedComplexity = 1 in
|
||||
def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm),
|
||||
(t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
|
||||
|
||||
// top16Zero - answer true if the upper 16 bits of $src are 0, false otherwise
|
||||
def top16Zero: PatLeaf<(i32 rGPR:$src), [{
|
||||
return CurDAG->MaskedValueIsZero(SDValue(N,0), APInt::getHighBitsSet(32, 16));
|
||||
}]>;
|
||||
|
||||
// so_imm_notSext is needed instead of so_imm_not, as the value of imm
|
||||
// will match the extended, not the original bitWidth for $src.
|
||||
def : T2Pat<(and top16Zero:$src, t2_so_imm_notSext:$imm),
|
||||
(t2BICri rGPR:$src, t2_so_imm_notSext:$imm)>;
|
||||
|
||||
|
||||
// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
|
||||
def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm),
|
||||
(t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
|
||||
|
19
test/CodeGen/ARM/bicZext.ll
Normal file
19
test/CodeGen/ARM/bicZext.ll
Normal file
@ -0,0 +1,19 @@
|
||||
; RUN: llc %s -o - | FileCheck %s
|
||||
; ModuleID = 'bic.c'
|
||||
target triple = "thumbv7-apple-ios3.0.0"
|
||||
|
||||
define zeroext i16 @foo16(i16 zeroext %f) nounwind readnone optsize ssp {
|
||||
entry:
|
||||
; CHECK: .thumb_func _foo16
|
||||
; CHECK: {{bic[^#]*#3}}
|
||||
%and = and i16 %f, -4
|
||||
ret i16 %and
|
||||
}
|
||||
|
||||
define i32 @foo32(i32 %f) nounwind readnone optsize ssp {
|
||||
entry:
|
||||
; CHECK: .thumb_func _foo32
|
||||
; CHECK: {{bic[^#]*#3}}
|
||||
%and = and i32 %f, -4
|
||||
ret i32 %and
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user