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

Unified Diff: runtime/vm/assembler_arm64.h

Issue 231373003: Adds logical operations to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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 | « no previous file | runtime/vm/assembler_arm64.cc » ('j') | runtime/vm/assembler_arm64.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_arm64.h
===================================================================
--- runtime/vm/assembler_arm64.h (revision 34831)
+++ runtime/vm/assembler_arm64.h (working copy)
@@ -217,8 +217,16 @@
type_ = Immediate;
}
- // TODO(zra): Add bitfield immediate operand
- // Operand(int32_t n, int32_t imms, int32_t immr);
+ // Call Assembler::IsImmLogical to find values for these arguments.
regis 2014/04/09 20:49:49 I do not understand this comment.
zra 2014/04/09 22:14:28 Tried to clarify.
+ Operand(uint8_t n, int8_t imm_s, int8_t imm_r) {
+ ASSERT((n == 1) || (n == 0));
+ ASSERT(Utils::IsUint(6, imm_s) && Utils::IsUint(6, imm_r));
+ type_ = BitfieldImm;
+ encoding_ =
+ (static_cast<int32_t>(n) << kNShift) |
+ (static_cast<int32_t>(imm_s) << kImmSShift) |
+ (static_cast<int32_t>(imm_r) << kImmRShift);
+ }
enum OperandType {
Shifted,
@@ -326,13 +334,83 @@
void add(Register rd, Register rn, Operand o) {
AddSubHelper(kDoubleWord, false, false, rd, rn, o);
}
+ void adds(Register rd, Register rn, Operand o) {
+ AddSubHelper(kDoubleWord, true, false, rd, rn, o);
+ }
void addw(Register rd, Register rn, Operand o) {
AddSubHelper(kWord, false, false, rd, rn, o);
}
void sub(Register rd, Register rn, Operand o) {
AddSubHelper(kDoubleWord, false, true, rd, rn, o);
}
+ void subs(Register rd, Register rn, Operand o) {
+ AddSubHelper(kDoubleWord, true, true, rd, rn, o);
+ }
+ // Logical immediate operations.
+ // TODO(zra): Add macros that check IsImmLogical, and fall back on a longer
+ // sequence on failure.
+ void andi(Register rd, Register rn, uint64_t imm) {
+ uint8_t n = 0, imm_s = 0, imm_r = 0;
+ const bool immok = IsImmLogical(imm, kXRegSizeInBits, &n, &imm_s, &imm_r);
regis 2014/04/09 20:49:49 You could also use a pattern similar to ShifterOpe
zra 2014/04/09 22:14:28 Done.
+ ASSERT(immok);
+ EmitLogicalImmOp(ANDI, rd, rn, Operand(n, imm_s, imm_r), kDoubleWord);
+ }
+ void orri(Register rd, Register rn, uint64_t imm) {
+ uint8_t n = 0, imm_s = 0, imm_r = 0;
+ const bool immok = IsImmLogical(imm, kXRegSizeInBits, &n, &imm_s, &imm_r);
+ ASSERT(immok);
+ EmitLogicalImmOp(ORRI, rd, rn, Operand(n, imm_s, imm_r), kDoubleWord);
+ }
+ void eori(Register rd, Register rn, uint64_t imm) {
+ uint8_t n = 0, imm_s = 0, imm_r = 0;
+ const bool immok = IsImmLogical(imm, kXRegSizeInBits, &n, &imm_s, &imm_r);
+ ASSERT(immok);
+ EmitLogicalImmOp(EORI, rd, rn, Operand(n, imm_s, imm_r), kDoubleWord);
+ }
+ void andis(Register rd, Register rn, uint64_t imm) {
+ uint8_t n = 0, imm_s = 0, imm_r = 0;
+ const bool immok = IsImmLogical(imm, kXRegSizeInBits, &n, &imm_s, &imm_r);
+ ASSERT(immok);
+ EmitLogicalImmOp(ANDIS, rd, rn, Operand(n, imm_s, imm_r), kDoubleWord);
+ }
+
+ // Logical (shifted) register operations.
+ void and_(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(AND, rd, rn, o, kDoubleWord);
+ }
+ void bic(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(BIC, rd, rn, o, kDoubleWord);
+ }
+ void orr(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(ORR, rd, rn, o, kDoubleWord);
+ }
+ void orn(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(ORN, rd, rn, o, kDoubleWord);
+ }
+ void eor(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(EOR, rd, rn, o, kDoubleWord);
+ }
+ void eon(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(EON, rd, rn, o, kDoubleWord);
+ }
+ void ands(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(ANDS, rd, rn, o, kDoubleWord);
+ }
+ void bics(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(BICS, rd, rn, o, kDoubleWord);
+ }
+
+ // Comparison.
+ // rn cmp o.
+ void cmp(Register rn, Operand o) {
+ subs(ZR, rn, o);
+ }
+ // rn cmp -o.
+ void cmn(Register rn, Operand o) {
+ adds(ZR, rn, o);
+ }
+
// Move wide immediate.
void movk(Register rd, int32_t imm, int32_t hw_idx) {
ASSERT(rd != SP);
@@ -393,6 +471,9 @@
GrowableArray<CodeComment*> comments_;
+ bool IsImmLogical(uint64_t value, uint8_t width,
+ uint8_t* n, uint8_t* imm_s, uint8_t* imm_r);
+
void AddSubHelper(OperandSize os, bool set_flags, bool subtract,
Register rd, Register rn, Operand o) {
ASSERT((rd != R31) && (rn != R31));
@@ -412,9 +493,9 @@
}
void EmitAddSubImmOp(AddSubImmOp op, Register rd, Register rn,
- Operand o, OperandSize os, bool set_flags) {
- ASSERT((os == kDoubleWord) || (os == kWord));
- const int32_t size = (os == kDoubleWord) ? B31 : 0;
+ Operand o, OperandSize sz, bool set_flags) {
+ ASSERT((sz == kDoubleWord) || (sz == kWord));
+ const int32_t size = (sz == kDoubleWord) ? B31 : 0;
const int32_t s = set_flags ? B29 : 0;
const int32_t encoding =
op | size | s |
@@ -424,6 +505,42 @@
Emit(encoding);
}
+ void EmitLogicalImmOp(LogicalImmOp op, Register rd, Register rn,
+ Operand o, OperandSize sz) {
+ ASSERT((sz == kDoubleWord) || (sz == kWord));
+ ASSERT((rd != R31) && (rn != R31));
+ ASSERT(rn != SP);
+ ASSERT((op == ANDIS) || (rd != ZR)); // op != ANDIS => rd != ZR.
+ ASSERT((op != ANDIS) || (rd != SP)); // op == ANDIS => rd != SP.
+ ASSERT(o.type() == Operand::BitfieldImm);
+ const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+ const Register crd = ConcreteRegister(rd);
+ const Register crn = ConcreteRegister(rn);
+ const int32_t encoding =
+ op | size |
+ (static_cast<int32_t>(crd) << kRdShift) |
+ (static_cast<int32_t>(crn) << kRnShift) |
+ o.encoding();
+ Emit(encoding);
+ }
+
+ void EmitLogicalShiftOp(LogicalShiftOp op,
+ Register rd, Register rn, Operand o, OperandSize sz) {
+ ASSERT((sz == kDoubleWord) || (sz == kWord));
+ ASSERT((rd != R31) && (rn != R31));
+ ASSERT((rd != SP) && (rn != SP));
+ ASSERT(o.type() == Operand::Shifted);
+ const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+ const Register crd = ConcreteRegister(rd);
+ const Register crn = ConcreteRegister(rn);
+ const int32_t encoding =
+ op | size |
+ (static_cast<int32_t>(crd) << kRdShift) |
+ (static_cast<int32_t>(crn) << kRnShift) |
+ o.encoding();
+ Emit(encoding);
+ }
+
void EmitAddSubShiftExtOp(AddSubShiftExtOp op,
Register rd, Register rn, Operand o,
OperandSize sz, bool set_flags) {
« no previous file with comments | « no previous file | runtime/vm/assembler_arm64.cc » ('j') | runtime/vm/assembler_arm64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698