Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: src/IceTargetLoweringARM32.cpp

Issue 1356763004: Subzero. ARM32 Fcmp lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: git pull && addresses comments Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringARM32.def » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTargetLoweringARM32.cpp
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 3fb5efc1e3caebbfe4ca21a752c74e77695984a6..d61d93cf0430b57ff316dd2ab95ce07b48f33acf 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -87,40 +87,39 @@ CondARM32::Cond getIcmp32Mapping(InstIcmp::ICond Cond) {
// instructions/operands that use the same enum key value. The tables are kept
// separate to maintain a proper separation between abstraction layers. There
// is a risk that the tables could get out of sync if enum values are reordered
-// or if entries are added or deleted. The following dummy namespaces use
+// or if entries are added or deleted. The following anonymous namespaces use
// static_asserts to ensure everything is kept in sync.
// Validate the enum values in ICMPARM32_TABLE.
-namespace dummy1 {
+namespace {
// Define a temporary set of enum values based on low-level table entries.
-enum _tmp_enum {
-#define X(val, signed, swapped64, C_32, C1_64, C2_64) _tmp_##val,
+enum _icmp_ll_enum {
+#define X(val, signed, swapped64, C_32, C1_64, C2_64) _icmp_ll_##val,
ICMPARM32_TABLE
#undef X
_num
};
// Define a set of constants based on high-level table entries.
-#define X(tag, str) static const int _table1_##tag = InstIcmp::tag;
+#define X(tag, str) static constexpr int _icmp_hl_##tag = InstIcmp::tag;
ICEINSTICMP_TABLE
#undef X
// Define a set of constants based on low-level table entries, and ensure the
// table entry keys are consistent.
#define X(val, signed, swapped64, C_32, C1_64, C2_64) \
- static const int _table2_##val = _tmp_##val; \
static_assert( \
- _table1_##val == _table2_##val, \
- "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE");
+ _icmp_ll_##val == _icmp_hl_##val, \
+ "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE: " #val);
ICMPARM32_TABLE
#undef X
// Repeat the static asserts with respect to the high-level table entries in
// case the high-level table has extra entries.
#define X(tag, str) \
static_assert( \
- _table1_##tag == _table2_##tag, \
- "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE");
+ _icmp_hl_##tag == _icmp_ll_##tag, \
+ "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE: " #tag);
ICEINSTICMP_TABLE
#undef X
-} // end of namespace dummy1
+} // end of anonymous namespace
// Stack alignment
const uint32_t ARM32_STACK_ALIGNMENT_BYTES = 16;
@@ -2229,9 +2228,76 @@ void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) {
UnimplementedError(Func->getContext()->getFlags());
}
+namespace {
+// Validates FCMPARM32_TABLE's declaration w.r.t. InstFcmp::FCondition ordering
+// (and naming).
+enum {
+#define X(val, CC0, CC1) _fcmp_ll_##val,
+ FCMPARM32_TABLE
+#undef X
+ _fcmp_ll_NUM
+};
+
+enum {
+#define X(tag, str) _fcmp_hl_##tag = InstFcmp::tag,
+ ICEINSTFCMP_TABLE
+#undef X
+ _fcmp_hl_NUM
+};
+
+static_assert(_fcmp_hl_NUM == _fcmp_ll_NUM,
+ "Inconsistency between high-level and low-level fcmp tags.");
+#define X(tag, str) \
+ static_assert( \
+ _fcmp_hl_##tag == _fcmp_ll_##tag, \
+ "Inconsistency between high-level and low-level fcmp tag " #tag);
+ICEINSTFCMP_TABLE
+#undef X
+
+struct {
+ CondARM32::Cond CC0;
+ CondARM32::Cond CC1;
+} TableFcmp[] = {
+#define X(val, CC0, CC1) \
+ { CondARM32::CC0, CondARM32::CC1 } \
+ ,
+ FCMPARM32_TABLE
+#undef X
+};
+} // end of anonymous namespace
+
void TargetARM32::lowerFcmp(const InstFcmp *Inst) {
- (void)Inst;
- UnimplementedError(Func->getContext()->getFlags());
+ Variable *Dest = Inst->getDest();
+ if (isVectorType(Dest->getType())) {
+ UnimplementedError(Func->getContext()->getFlags());
+ return;
+ }
+
+ Variable *Src0R = legalizeToReg(Inst->getSrc(0));
+ Variable *Src1R = legalizeToReg(Inst->getSrc(1));
+ Variable *T = makeReg(IceType_i32);
+ _vcmp(Src0R, Src1R);
+ _mov(T, Ctx->getConstantZero(IceType_i32));
+ _vmrs();
+ Operand *One = Ctx->getConstantInt32(1);
+ InstFcmp::FCond Condition = Inst->getCondition();
+ assert(Condition < llvm::array_lengthof(TableFcmp));
+ CondARM32::Cond CC0 = TableFcmp[Condition].CC0;
+ CondARM32::Cond CC1 = TableFcmp[Condition].CC1;
+ if (CC0 != CondARM32::kNone) {
+ _mov(T, One, CC0);
+ // If this mov is not a maybe mov, but an actual mov (i.e., CC0 == AL), we
+ // don't want to set_dest_nonkillable so that liveness + dead-code
+ // elimination will get rid of the previous assignment (i.e., T = 0) above.
+ if (CC0 != CondARM32::AL)
+ _set_dest_nonkillable();
+ }
+ if (CC1 != CondARM32::kNone) {
+ assert(CC0 != CondARM32::kNone);
+ assert(CC1 != CondARM32::AL);
+ _mov_nonkillable(T, One, CC1);
+ }
+ _mov(Dest, T);
}
void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
@@ -2695,16 +2761,12 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
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 = legalizeToReg(Condition);
Operand *CmpOpnd1 = Ctx->getConstantZero(IceType_i32);
_cmp(CmpOpnd0, CmpOpnd1);
- CondARM32::Cond Cond = CondARM32::NE;
+ static constexpr CondARM32::Cond Cond = CondARM32::NE;
if (DestTy == IceType_i64) {
SrcT = legalizeUndef(SrcT);
SrcF = legalizeUndef(SrcF);
@@ -2726,6 +2788,20 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
_mov(DestHi, THi);
return;
}
+
+ if (isFloatingType(DestTy)) {
+ Variable *T = makeReg(DestTy);
+ SrcF = legalizeToReg(SrcF);
+ assert(DestTy == SrcF->getType());
+ _vmov(T, SrcF);
+ SrcT = legalizeToReg(SrcT);
+ assert(DestTy == SrcT->getType());
+ _vmov(T, SrcT, Cond);
+ _set_dest_nonkillable();
+ _vmov(Dest, T);
+ return;
+ }
+
Variable *T = nullptr;
SrcF = legalize(SrcF, Legal_Reg | Legal_Flex);
_mov(T, SrcF);
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringARM32.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698