Commit e0df91fe by Jan Voung

ARM: lowerSelect for integers.

No bool-folding optimization, just the straightforward compare followed by mov and conditional mov. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1211243005.
parent fdc54db7
......@@ -19,14 +19,14 @@
namespace Ice {
namespace CondX8664 {
namespace CondX8664 {
// An enum of condition codes used for branches and cmov. The enum value
// should match the value used to encode operands in binary instructions.
enum BrCond {
#define X(tag, encode, opp, dump, emit) tag encode,
ICEINSTX8664BR_TABLE
ICEINSTX8664BR_TABLE
#undef X
Br_None
Br_None
};
// An enum of condition codes relevant to the CMPPS instruction. The enum
......@@ -34,9 +34,9 @@ enum BrCond {
// instructions.
enum CmppsCond {
#define X(tag, emit) tag,
ICEINSTX8664CMPPS_TABLE
ICEINSTX8664CMPPS_TABLE
#undef X
Cmpps_Invalid
Cmpps_Invalid
};
} // end of namespace CondX8664
......
......@@ -31,8 +31,8 @@
#pragma clang diagnostic pop
#include <algorithm> // max()
#include <cctype> // isdigit(), isupper()
#include <locale> // locale
#include <cctype> // isdigit(), isupper()
#include <locale> // locale
#include <unordered_map>
namespace std {
......
......@@ -519,8 +519,9 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var,
Var.getInitializers()) {
switch (Init->getKind()) {
case VariableDeclaration::Initializer::DataInitializerKind: {
const auto &Data = llvm::cast<VariableDeclaration::DataInitializer>(
Init.get())->getContents();
const auto &Data =
llvm::cast<VariableDeclaration::DataInitializer>(Init.get())
->getContents();
for (SizeT i = 0; i < Init->getNumBytes(); ++i) {
Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
}
......
......@@ -2009,8 +2009,51 @@ void TargetARM32::lowerRet(const InstRet *Inst) {
}
void TargetARM32::lowerSelect(const InstSelect *Inst) {
(void)Inst;
UnimplementedError(Func->getContext()->getFlags());
Variable *Dest = Inst->getDest();
Type DestTy = Dest->getType();
Operand *SrcT = Inst->getTrueOperand();
Operand *SrcF = Inst->getFalseOperand();
Operand *Condition = Inst->getCondition();
if (isVectorType(DestTy)) {
UnimplementedError(Func->getContext()->getFlags());
return;
}
if (isFloatingType(DestTy)) {
UnimplementedError(Func->getContext()->getFlags());
return;
}
// TODO(jvoung): handle folding opportunities.
// cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t
Variable *CmpOpnd0 = legalizeToVar(Condition);
Operand *CmpOpnd1 = Ctx->getConstantZero(IceType_i32);
_cmp(CmpOpnd0, CmpOpnd1);
CondARM32::Cond Cond = CondARM32::NE;
if (DestTy == IceType_i64) {
// Set the low portion.
Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
Variable *TLo = nullptr;
Operand *SrcFLo = legalize(loOperand(SrcF), Legal_Reg | Legal_Flex);
_mov(TLo, SrcFLo);
Operand *SrcTLo = legalize(loOperand(SrcT), Legal_Reg | Legal_Flex);
_mov_nonkillable(TLo, SrcTLo, Cond);
_mov(DestLo, TLo);
// Set the high portion.
Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Variable *THi = nullptr;
Operand *SrcFHi = legalize(hiOperand(SrcF), Legal_Reg | Legal_Flex);
_mov(THi, SrcFHi);
Operand *SrcTHi = legalize(hiOperand(SrcT), Legal_Reg | Legal_Flex);
_mov_nonkillable(THi, SrcTHi, Cond);
_mov(DestHi, THi);
return;
}
Variable *T = nullptr;
SrcF = legalize(SrcF, Legal_Reg | Legal_Flex);
_mov(T, SrcF);
SrcT = legalize(SrcT, Legal_Reg | Legal_Flex);
_mov_nonkillable(T, SrcT, Cond);
_mov(Dest, T);
}
void TargetARM32::lowerStore(const InstStore *Inst) {
......@@ -2057,7 +2100,7 @@ void TargetARM32::lowerSwitch(const InstSwitch *Inst) {
_br(Inst->getLabelDefault());
return;
}
// 32 bit integer
Variable *Src0Var = legalizeToVar(Src0);
for (SizeT I = 0; I < NumCases; ++I) {
......
......@@ -1580,6 +1580,17 @@ entry:
; OPTM1: cmp
; OPTM1: cmovne
; ARM32-LABEL: select64VarVar
; The initial compare.
; ARM32: cmp
; ARM32: cmpeq
; ARM32: movcc
; ARM32: movcs
; The non-folded compare for the select.
; ARM32: cmp
; ARM32: movne
; ARM32: movne
define internal i64 @select64VarConst(i64 %a, i64 %b) {
entry:
%cmp = icmp ult i64 %a, %b
......@@ -1604,6 +1615,19 @@ entry:
; OPTM1: cmp
; OPTM1: cmovne
; ARM32-LABEL: select64VarConst
; ARM32: cmp
; ARM32: cmpeq
; ARM32: movcc
; ARM32: movcs
; ARM32: cmp
; ARM32: movw
; ARM32: movt
; ARM32: movne
; ARM32: movw
; ARM32: movt
; ARM32: movne
define internal i64 @select64ConstVar(i64 %a, i64 %b) {
entry:
%cmp = icmp ult i64 %a, %b
......@@ -1628,6 +1652,19 @@ entry:
; OPTM1: cmp
; OPTM1: cmove
; ARM32-LABEL: select64ConstVar
; ARM32: cmp
; ARM32: cmpeq
; ARM32: movcc
; ARM32: movcs
; ARM32: cmp
; ARM32: movw
; ARM32: movt
; ARM32: movne
; ARM32: movw
; ARM32: movt
; ARM32: movne
define internal void @icmpEq64Imm() {
entry:
%cmp = icmp eq i64 123, 234
......
......@@ -3,8 +3,23 @@
; regardless of the optimization level, so there are no special OPTM1
; match lines.
; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 | FileCheck %s
; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 | FileCheck %s
; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
; RUN: --target x8632 -i %s --args -O2 \
; RUN: | %if --need=target_X8632 --command FileCheck %s
; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
; RUN: --target x8632 -i %s --args -Om1 \
; RUN: | %if --need=target_X8632 --command FileCheck %s
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \
; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -i %s --args -Om1 --skip-unimplemented \
; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s
define void @testSelect(i32 %a, i32 %b) {
entry:
......@@ -32,6 +47,16 @@ declare void @useInt(i32 %x)
; CHECK: cmp
; CHECK: call {{.*}} R_{{.*}} useInt
; CHECK: ret
; ARM32-LABEL: testSelect
; ARM32: cmp
; ARM32: cmp
; ARM32: bl {{.*}} useInt
; ARM32: cmp
; ARM32: cmp
; ARM32: mov {{.*}}, #20
; ARM32: movne {{.*}}, #10
; ARM32: bl {{.*}} useInt
; ARM32: bx lr
; Check for valid addressing mode in the cmp instruction when the
; operand is an immediate.
......@@ -42,6 +67,8 @@ entry:
}
; CHECK-LABEL: testSelectImm32
; CHECK-NOT: cmp 0x{{[0-9a-f]+}},
; ARM32-LABEL: testSelectImm32
; ARM32-NOT: cmp #{{.*}},
; Check for valid addressing mode in the cmp instruction when the
; operand is an immediate. There is a different x86-32 lowering
......@@ -53,3 +80,5 @@ entry:
}
; CHECK-LABEL: testSelectImm64
; CHECK-NOT: cmp 0x{{[0-9a-f]+}},
; ARM32-LABEL: testSelectImm64
; ARM32-NOT: cmp #{{.*}},
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment