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

Unified Diff: runtime/vm/assembler_arm64.h

Issue 227593012: Adds ldr and str 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_test.cc » ('j') | runtime/vm/assembler_arm64_test.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 34800)
+++ runtime/vm/assembler_arm64.h (working copy)
@@ -69,23 +69,83 @@
class Address : public ValueObject {
public:
Address(const Address& other)
- : ValueObject(), encoding_(other.encoding_) {
+ : ValueObject(),
+ encoding_(other.encoding_),
+ type_(other.type_),
+ base_(other.base_) {
}
Address& operator=(const Address& other) {
encoding_ = other.encoding_;
+ type_ = other.type_;
+ base_ = other.base_;
return *this;
}
- Address(Register rn, int32_t offset = 0) {
- ASSERT(Utils::IsAbsoluteUint(12, offset));
- encoding_ = -1;
+ enum AddressType {
+ Offset,
+ PreIndex,
+ PostIndex,
+ Reg,
+ };
+
+ // Offset is in bytes. We translate to number of operands for the larger
+ // unsigned imm12 case based on the OperandSize. For the smaller signed
+ // imm9 case, the offset is the number of bytes, but is unscaled.
regis 2014/04/07 23:38:19 I do not understand "We translate to number of ope
zra 2014/04/08 15:14:13 Tried to clarify. Also added an assert.
+ Address(Register rn, int32_t offset = 0, AddressType at = Offset,
+ OperandSize sz = kDoubleWord) {
+ ASSERT((rn != R31) && (rn != ZR));
+ const Register crn = ConcreteRegister(rn);
+ const int32_t scale = Log2OperandSizeBytes(sz);
+ if (Utils::IsUint(12 + scale, offset) && (at == Offset)) {
+ encoding_ =
+ B24 |
+ ((offset >> scale) << kImm12Shift) |
+ (static_cast<int32_t>(crn) << kRnShift);
+ } else {
+ ASSERT(Utils::IsInt(9, offset));
+ ASSERT((at == PreIndex) || (at == PostIndex));
+ int32_t idx = (at == PostIndex) ? B10 : (B11 | B10);
+ encoding_ =
+ idx |
+ ((offset & 0x1ff) << kImm9Shift) |
+ (static_cast<int32_t>(crn) << kRnShift);
+ }
+ type_ = at;
+ base_ = crn;
}
+ // TODO(zra): Write CanHoldOffset(int32_t off, AddressType, OperandSize).
+ // TODO(zra): Write constructor for PC-relative load address.
+
+ // Base register rn with offset rm. rm is sign-extended according to ext.
+ // If ext is UXTX, rm may be optionally scaled by the
+ // Log2OperandSize (specified by the instruction).
+ Address(Register rn, Register rm, Extend ext = UXTX, bool scaled = false) {
+ ASSERT((rn != R31) && (rn != ZR));
+ ASSERT((rm != R31) && (rm != SP));
+ ASSERT(!scaled || (ext == UXTX)); // Can only scale when ext = UXTX.
+ ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX));
+ const Register crn = ConcreteRegister(rn);
+ const Register crm = ConcreteRegister(rm);
+ const int32_t s = scaled ? B12 : 0;
+ encoding_ =
+ B21 | B11 | s |
+ (static_cast<int32_t>(crn) << kRnShift) |
+ (static_cast<int32_t>(crm) << kRmShift) |
+ (static_cast<int32_t>(ext) << kExtendTypeShift);
+ type_ = Reg;
+ base_ = crn;
+ }
+
private:
uint32_t encoding() const { return encoding_; }
+ AddressType type() const { return type_; }
+ Register base() const { return base_; }
uint32_t encoding_;
+ AddressType type_;
+ Register base_;
friend class Assembler;
};
@@ -288,6 +348,19 @@
EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord);
}
+ // Loads and Stores.
+ void ldr(Register rt, Address a) {
+ // If we are doing pre-/post-indexing, and the base and result registers
+ // are the same, then the result of the load will be clobbered by the
+ // writeback, which is unlikely to be useful.
+ ASSERT(((a.type() != Address::PreIndex) &&
+ (a.type() != Address::PostIndex)) ||
+ (rt != a.base()));
+ EmitLoadStoreReg(LDR, rt, a, kDoubleWord);
+ }
+ void str(Register rt, Address a) {
+ EmitLoadStoreReg(STR, rt, a, kDoubleWord);
+ }
// Function return.
void ret(Register rn = R30) {
@@ -383,6 +456,16 @@
Emit(encoding);
}
+ void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a,
+ OperandSize sz) {
+ const int32_t size = Log2OperandSizeBytes(sz);
+ const int32_t encoding =
+ op | (size << kSzShift) |
+ (static_cast<int32_t>(rt) << kRtShift) |
+ a.encoding();
+ Emit(encoding);
+ }
+
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(Assembler);
};
« no previous file with comments | « no previous file | runtime/vm/assembler_arm64_test.cc » ('j') | runtime/vm/assembler_arm64_test.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698