Revision: 19497
Author:   [email protected]
Date:     Wed Feb 19 16:13:09 2014 UTC
Log: A64: Introduce 'branch types' that extend the architectural conditions.

The branch types include 'always' and 'never', and types like reg_zero (CBZ) and
reg_bit_clear (TBZ).
This will be used by incoming improvements to the code generated for
deoptimization exit points.

[email protected]

Review URL: https://codereview.chromium.org/170783002
http://code.google.com/p/v8/source/detail?r=19497

Modified:
 /branches/bleeding_edge/src/a64/macro-assembler-a64.cc
 /branches/bleeding_edge/src/a64/macro-assembler-a64.h
 /branches/bleeding_edge/test/cctest/test-assembler-a64.cc

=======================================
--- /branches/bleeding_edge/src/a64/macro-assembler-a64.cc Wed Feb 19 14:37:18 2014 UTC +++ /branches/bleeding_edge/src/a64/macro-assembler-a64.cc Wed Feb 19 16:13:09 2014 UTC
@@ -664,6 +664,26 @@
   }
   return need_longer_range;
 }
+
+
+void MacroAssembler::B(Label* label, BranchType type, Register reg, int bit) {
+  ASSERT((reg.Is(NoReg) || type >= kBranchTypeFirstUsingReg) &&
+         (bit == -1 || type >= kBranchTypeFirstUsingBit));
+ if (kBranchTypeFirstCondition <= type && type <= kBranchTypeLastCondition) {
+    B(static_cast<Condition>(type), label);
+  } else {
+    switch (type) {
+      case always:        B(label);              break;
+      case never:         break;
+      case reg_zero:      Cbz(reg, label);       break;
+      case reg_not_zero:  Cbnz(reg, label);      break;
+      case reg_bit_clear: Tbz(reg, bit, label);  break;
+      case reg_bit_set:   Tbnz(reg, bit, label); break;
+      default:
+        UNREACHABLE();
+    }
+  }
+}


 void MacroAssembler::B(Label* label, Condition cond) {
=======================================
--- /branches/bleeding_edge/src/a64/macro-assembler-a64.h Wed Feb 19 15:20:15 2014 UTC +++ /branches/bleeding_edge/src/a64/macro-assembler-a64.h Wed Feb 19 16:13:09 2014 UTC
@@ -64,6 +64,53 @@
// ----------------------------------------------------------------------------
 // MacroAssembler

+enum BranchType {
+  // Copies of architectural conditions.
+  // The associated conditions can be used in place of those, the code will
+  // take care of reinterpreting them with the correct type.
+  integer_eq = eq,
+  integer_ne = ne,
+  integer_hs = hs,
+  integer_lo = lo,
+  integer_mi = mi,
+  integer_pl = pl,
+  integer_vs = vs,
+  integer_vc = vc,
+  integer_hi = hi,
+  integer_ls = ls,
+  integer_ge = ge,
+  integer_lt = lt,
+  integer_gt = gt,
+  integer_le = le,
+  integer_al = al,
+  integer_nv = nv,
+
+  // These two are *different* from the architectural codes al and nv.
+  // 'always' is used to generate unconditional branches.
+  // 'never' is used to not generate a branch (generally as the inverse
+  // branch type of 'always).
+  always, never,
+  // cbz and cbnz
+  reg_zero, reg_not_zero,
+  // tbz and tbnz
+  reg_bit_clear, reg_bit_set,
+
+  // Aliases.
+  kBranchTypeFirstCondition = eq,
+  kBranchTypeLastCondition = nv,
+  kBranchTypeFirstUsingReg = reg_zero,
+  kBranchTypeFirstUsingBit = reg_bit_clear
+};
+
+inline BranchType InvertBranchType(BranchType type) {
+ if (kBranchTypeFirstCondition <= type && type <= kBranchTypeLastCondition) {
+    return static_cast<BranchType>(
+        InvertCondition(static_cast<Condition>(type)));
+  } else {
+    return static_cast<BranchType>(type ^ 1);
+  }
+}
+
 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
 enum LinkRegisterStatus { kLRHasNotBeenSaved, kLRHasBeenSaved };
@@ -212,6 +259,14 @@
   inline void Adr(const Register& rd, Label* label);
   inline void Asr(const Register& rd, const Register& rn, unsigned shift);
inline void Asr(const Register& rd, const Register& rn, const Register& rm);
+
+  // Branch type inversion relies on these relations.
+  STATIC_ASSERT((reg_zero      == (reg_not_zero ^ 1)) &&
+                (reg_bit_clear == (reg_bit_set ^ 1)) &&
+                (always        == (never ^ 1)));
+
+ void B(Label* label, BranchType type, Register reg = NoReg, int bit = -1);
+
   inline void B(Label* label);
   inline void B(Condition cond, Label* label);
   void B(Label* label, Condition cond);
=======================================
--- /branches/bleeding_edge/test/cctest/test-assembler-a64.cc Wed Feb 19 09:43:45 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-assembler-a64.cc Wed Feb 19 16:13:09 2014 UTC
@@ -2274,6 +2274,63 @@

   TEARDOWN();
 }
+
+
+TEST(branch_type) {
+  INIT_V8();
+
+  SETUP();
+
+  Label fail, done;
+
+  START();
+  __ Mov(x0, 0x0);
+  __ Mov(x10, 0x7);
+  __ Mov(x11, 0x0);
+
+  // Test non taken branches.
+  __ Cmp(x10, 0x7);
+  __ B(&fail, ne);
+  __ B(&fail, never);
+  __ B(&fail, reg_zero, x10);
+  __ B(&fail, reg_not_zero, x11);
+  __ B(&fail, reg_bit_clear, x10, 0);
+  __ B(&fail, reg_bit_set, x10, 3);
+
+  // Test taken branches.
+  Label l1, l2, l3, l4, l5;
+  __ Cmp(x10, 0x7);
+  __ B(&l1, eq);
+  __ B(&fail);
+  __ Bind(&l1);
+  __ B(&l2, always);
+  __ B(&fail);
+  __ Bind(&l2);
+  __ B(&l3, reg_not_zero, x10);
+  __ B(&fail);
+  __ Bind(&l3);
+  __ B(&l4, reg_bit_clear, x10, 15);
+  __ B(&fail);
+  __ Bind(&l4);
+  __ B(&l5, reg_bit_set, x10, 1);
+  __ B(&fail);
+  __ Bind(&l5);
+
+  __ B(&done);
+
+  __ Bind(&fail);
+  __ Mov(x0, 0x1);
+
+  __ Bind(&done);
+
+  END();
+
+  RUN();
+
+  ASSERT_EQUAL_64(0x0, x0);
+
+  TEARDOWN();
+}


 TEST(ldr_str_offset) {

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to