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 @@ ...@@ -19,14 +19,14 @@
namespace Ice { namespace Ice {
namespace CondX8664 { namespace CondX8664 {
// An enum of condition codes used for branches and cmov. The enum value // An enum of condition codes used for branches and cmov. The enum value
// should match the value used to encode operands in binary instructions. // should match the value used to encode operands in binary instructions.
enum BrCond { enum BrCond {
#define X(tag, encode, opp, dump, emit) tag encode, #define X(tag, encode, opp, dump, emit) tag encode,
ICEINSTX8664BR_TABLE ICEINSTX8664BR_TABLE
#undef X #undef X
Br_None Br_None
}; };
// An enum of condition codes relevant to the CMPPS instruction. The enum // An enum of condition codes relevant to the CMPPS instruction. The enum
...@@ -34,9 +34,9 @@ enum BrCond { ...@@ -34,9 +34,9 @@ enum BrCond {
// instructions. // instructions.
enum CmppsCond { enum CmppsCond {
#define X(tag, emit) tag, #define X(tag, emit) tag,
ICEINSTX8664CMPPS_TABLE ICEINSTX8664CMPPS_TABLE
#undef X #undef X
Cmpps_Invalid Cmpps_Invalid
}; };
} // end of namespace CondX8664 } // end of namespace CondX8664
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
#pragma clang diagnostic pop #pragma clang diagnostic pop
#include <algorithm> // max() #include <algorithm> // max()
#include <cctype> // isdigit(), isupper() #include <cctype> // isdigit(), isupper()
#include <locale> // locale #include <locale> // locale
#include <unordered_map> #include <unordered_map>
namespace std { namespace std {
......
...@@ -519,8 +519,9 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var, ...@@ -519,8 +519,9 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var,
Var.getInitializers()) { Var.getInitializers()) {
switch (Init->getKind()) { switch (Init->getKind()) {
case VariableDeclaration::Initializer::DataInitializerKind: { case VariableDeclaration::Initializer::DataInitializerKind: {
const auto &Data = llvm::cast<VariableDeclaration::DataInitializer>( const auto &Data =
Init.get())->getContents(); llvm::cast<VariableDeclaration::DataInitializer>(Init.get())
->getContents();
for (SizeT i = 0; i < Init->getNumBytes(); ++i) { for (SizeT i = 0; i < Init->getNumBytes(); ++i) {
Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
} }
......
...@@ -2009,8 +2009,51 @@ void TargetARM32::lowerRet(const InstRet *Inst) { ...@@ -2009,8 +2009,51 @@ void TargetARM32::lowerRet(const InstRet *Inst) {
} }
void TargetARM32::lowerSelect(const InstSelect *Inst) { void TargetARM32::lowerSelect(const InstSelect *Inst) {
(void)Inst; Variable *Dest = Inst->getDest();
UnimplementedError(Func->getContext()->getFlags()); 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) { void TargetARM32::lowerStore(const InstStore *Inst) {
...@@ -2057,7 +2100,7 @@ void TargetARM32::lowerSwitch(const InstSwitch *Inst) { ...@@ -2057,7 +2100,7 @@ void TargetARM32::lowerSwitch(const InstSwitch *Inst) {
_br(Inst->getLabelDefault()); _br(Inst->getLabelDefault());
return; return;
} }
// 32 bit integer // 32 bit integer
Variable *Src0Var = legalizeToVar(Src0); Variable *Src0Var = legalizeToVar(Src0);
for (SizeT I = 0; I < NumCases; ++I) { for (SizeT I = 0; I < NumCases; ++I) {
......
...@@ -1580,6 +1580,17 @@ entry: ...@@ -1580,6 +1580,17 @@ entry:
; OPTM1: cmp ; OPTM1: cmp
; OPTM1: cmovne ; 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) { define internal i64 @select64VarConst(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp ult i64 %a, %b %cmp = icmp ult i64 %a, %b
...@@ -1604,6 +1615,19 @@ entry: ...@@ -1604,6 +1615,19 @@ entry:
; OPTM1: cmp ; OPTM1: cmp
; OPTM1: cmovne ; 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) { define internal i64 @select64ConstVar(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp ult i64 %a, %b %cmp = icmp ult i64 %a, %b
...@@ -1628,6 +1652,19 @@ entry: ...@@ -1628,6 +1652,19 @@ entry:
; OPTM1: cmp ; OPTM1: cmp
; OPTM1: cmove ; 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() { define internal void @icmpEq64Imm() {
entry: entry:
%cmp = icmp eq i64 123, 234 %cmp = icmp eq i64 123, 234
......
...@@ -3,8 +3,23 @@ ...@@ -3,8 +3,23 @@
; regardless of the optimization level, so there are no special OPTM1 ; regardless of the optimization level, so there are no special OPTM1
; match lines. ; match lines.
; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 | FileCheck %s ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 | FileCheck %s ; 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) { define void @testSelect(i32 %a, i32 %b) {
entry: entry:
...@@ -32,6 +47,16 @@ declare void @useInt(i32 %x) ...@@ -32,6 +47,16 @@ declare void @useInt(i32 %x)
; CHECK: cmp ; CHECK: cmp
; CHECK: call {{.*}} R_{{.*}} useInt ; CHECK: call {{.*}} R_{{.*}} useInt
; CHECK: ret ; 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 ; Check for valid addressing mode in the cmp instruction when the
; operand is an immediate. ; operand is an immediate.
...@@ -42,6 +67,8 @@ entry: ...@@ -42,6 +67,8 @@ entry:
} }
; CHECK-LABEL: testSelectImm32 ; CHECK-LABEL: testSelectImm32
; CHECK-NOT: cmp 0x{{[0-9a-f]+}}, ; CHECK-NOT: cmp 0x{{[0-9a-f]+}},
; ARM32-LABEL: testSelectImm32
; ARM32-NOT: cmp #{{.*}},
; Check for valid addressing mode in the cmp instruction when the ; Check for valid addressing mode in the cmp instruction when the
; operand is an immediate. There is a different x86-32 lowering ; operand is an immediate. There is a different x86-32 lowering
...@@ -53,3 +80,5 @@ entry: ...@@ -53,3 +80,5 @@ entry:
} }
; CHECK-LABEL: testSelectImm64 ; CHECK-LABEL: testSelectImm64
; CHECK-NOT: cmp 0x{{[0-9a-f]+}}, ; 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