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

Unified Diff: runtime/vm/assembler_arm64.h

Issue 701233003: Implement bigint intrinsics on arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 1 month 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 | « no previous file | runtime/vm/assembler_arm64_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_arm64.h
===================================================================
--- runtime/vm/assembler_arm64.h (revision 41529)
+++ runtime/vm/assembler_arm64.h (working copy)
@@ -675,6 +675,9 @@
void smulh(Register rd, Register rn, Register rm) {
EmitMiscDP3Source(SMULH, rd, rn, rm, R0, kDoubleWord);
}
+ void umaddl(Register rd, Register rn, Register rm, Register ra) {
+ EmitMiscDP3Source(UMADDL, rd, rn, rm, ra, kDoubleWord);
+ }
// Move wide immediate.
void movk(Register rd, const Immediate& imm, int hw_idx) {
@@ -782,7 +785,7 @@
// Conditional branch.
void b(Label* label, Condition cond = AL) {
- EmitBranch(BCOND, cond, label);
+ EmitConditionalBranch(BCOND, cond, label);
}
void b(int32_t offset) {
@@ -792,8 +795,14 @@
EmitUnconditionalBranchOp(BL, offset);
}
- // TODO(zra): cbz, cbnz.
+ void cbz(Label* label, Register rt, OperandSize sz = kDoubleWord) {
+ EmitCompareAndBranch(CBZ, rt, label, sz);
+ }
+ void cbnz(Label* label, Register rt, OperandSize sz = kDoubleWord) {
+ EmitCompareAndBranch(CBNZ, rt, label, sz);
+ }
+
// Branch, link, return.
void br(Register rn) {
EmitUnconditionalBranchRegOp(BR, rn);
@@ -1600,8 +1609,8 @@
return static_cast<int64_t>(off);
}
- void EmitCompareAndBranch(CompareAndBranchOp op, Register rt, int64_t imm,
- OperandSize sz) {
+ void EmitCompareAndBranchOp(CompareAndBranchOp op, Register rt, int64_t imm,
+ OperandSize sz) {
ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0));
ASSERT((rt != CSP) && (rt != R31));
@@ -1615,8 +1624,8 @@
Emit(encoding);
}
- void EmitConditionalBranch(ConditionalBranchOp op, Condition cond,
- int64_t imm) {
+ void EmitConditionalBranchOp(ConditionalBranchOp op, Condition cond,
+ int64_t imm) {
const int32_t off = EncodeImm19BranchOffset(imm, 0);
const int32_t encoding =
op |
@@ -1630,7 +1639,8 @@
return Utils::IsInt(21, offset);
}
- void EmitBranch(ConditionalBranchOp op, Condition cond, Label* label) {
+ void EmitConditionalBranch(ConditionalBranchOp op, Condition cond,
+ Label* label) {
if (label->IsBound()) {
const int64_t dest = label->Position() - buffer_.Size();
if (use_far_branches() && !CanEncodeImm19BranchOffset(dest)) {
@@ -1639,12 +1649,12 @@
// no need for a guard branch.
b(dest);
} else {
- EmitConditionalBranch(
+ EmitConditionalBranchOp(
op, InvertCondition(cond), 2 * Instr::kInstrSize);
b(dest);
}
} else {
- EmitConditionalBranch(op, cond, dest);
+ EmitConditionalBranchOp(op, cond, dest);
}
} else {
const int64_t position = buffer_.Size();
@@ -1652,15 +1662,40 @@
// When cond is AL, this guard branch will be rewritten as a nop when
// the label is bound. We don't write it as a nop initially because it
// makes the decoding code in Bind simpler.
- EmitConditionalBranch(op, InvertCondition(cond), 2 * Instr::kInstrSize);
+ EmitConditionalBranchOp(
+ op, InvertCondition(cond), 2 * Instr::kInstrSize);
b(label->position_);
} else {
- EmitConditionalBranch(op, cond, label->position_);
+ EmitConditionalBranchOp(op, cond, label->position_);
}
label->LinkTo(position);
}
}
+ void EmitCompareAndBranch(CompareAndBranchOp op, Register rt,
zra 2014/11/06 00:30:59 You also need to detect these instructions in Bind
+ Label* label, OperandSize sz) {
+ if (label->IsBound()) {
+ const int64_t dest = label->Position() - buffer_.Size();
+ if (use_far_branches() && !CanEncodeImm19BranchOffset(dest)) {
+ EmitCompareAndBranchOp(
+ op == CBZ ? CBNZ : CBZ, rt, 2 * Instr::kInstrSize, sz);
+ b(dest);
+ } else {
+ EmitCompareAndBranchOp(op, rt, dest, sz);
+ }
+ } else {
+ const int64_t position = buffer_.Size();
+ if (use_far_branches()) {
+ EmitCompareAndBranchOp(
+ op == CBZ ? CBNZ : CBZ, rt, 2 * Instr::kInstrSize, sz);
+ b(label->position_);
+ } else {
+ EmitCompareAndBranchOp(op, rt, label->position_, sz);
+ }
+ label->LinkTo(position);
+ }
+ }
+
bool CanEncodeImm26BranchOffset(int64_t offset) {
ASSERT(Utils::IsAligned(offset, 4));
return Utils::IsInt(26, offset);
« no previous file with comments | « no previous file | runtime/vm/assembler_arm64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698