Skip to content

Commit

Permalink
[VM] Reland Support some 32bit instructions in 64bit assemblers.
Browse files Browse the repository at this point in the history
These instructions will soon be used for for smaller (32 bit) Smis.
Also fix broken ubfiz instruction in ARM64 assembler.

This reland fixes the disassembler test that used Stop
instructions which disassemble differently on Mac
because constants have higher addresses.

Originally reviewed at
https://dart-review.googlesource.com/c/sdk/+/43668

Fix assembler test on Mac

[email protected]

Change-Id: I61f8626184af495f18a74b5fef07bad02b6615e9
Reviewed-on: https://dart-review.googlesource.com/45240
Reviewed-by: Martin Kustermann <[email protected]>
Commit-Queue: Erik Corry <[email protected]>
  • Loading branch information
ErikCorryGoogle authored and [email protected] committed Mar 6, 2018
1 parent 17d5c44 commit 235e622
Show file tree
Hide file tree
Showing 10 changed files with 706 additions and 68 deletions.
49 changes: 41 additions & 8 deletions runtime/vm/compiler/assembler/assembler_arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ bool Assembler::CanLoadFromObjectPool(const Object& object) const {
// TODO(zra, kmillikin): Also load other large immediates from the object
// pool
if (object.IsSmi()) {
ASSERT(Smi::IsValid(Smi::Value(reinterpret_cast<RawSmi*>(object.raw()))));
// If the raw smi does not fit into a 32-bit signed int, then we'll keep
// the raw value in the object pool.
return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw()));
Expand Down Expand Up @@ -680,37 +681,69 @@ void Assembler::AddImmediate(Register dest, Register rn, int64_t imm) {
}
}

void Assembler::AddImmediateSetFlags(Register dest, Register rn, int64_t imm) {
void Assembler::AddImmediateSetFlags(Register dest,
Register rn,
int64_t imm,
OperandSize sz) {
ASSERT(sz == kDoubleWord || sz == kWord);
Operand op;
if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
// Handles imm == kMinInt64.
adds(dest, rn, op);
if (sz == kDoubleWord) {
adds(dest, rn, op);
} else {
addsw(dest, rn, op);
}
} else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) ==
Operand::Immediate) {
ASSERT(imm != kMinInt64); // Would cause erroneous overflow detection.
subs(dest, rn, op);
if (sz == kDoubleWord) {
subs(dest, rn, op);
} else {
subsw(dest, rn, op);
}
} else {
// TODO(zra): Try adding top 12 bits, then bottom 12 bits.
ASSERT(rn != TMP2);
LoadImmediate(TMP2, imm);
adds(dest, rn, Operand(TMP2));
if (sz == kDoubleWord) {
adds(dest, rn, Operand(TMP2));
} else {
addsw(dest, rn, Operand(TMP2));
}
}
}

void Assembler::SubImmediateSetFlags(Register dest, Register rn, int64_t imm) {
void Assembler::SubImmediateSetFlags(Register dest,
Register rn,
int64_t imm,
OperandSize sz) {
Operand op;
ASSERT(sz == kDoubleWord || sz == kWord);
if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
// Handles imm == kMinInt64.
subs(dest, rn, op);
if (sz == kDoubleWord) {
subs(dest, rn, op);
} else {
subsw(dest, rn, op);
}
} else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) ==
Operand::Immediate) {
ASSERT(imm != kMinInt64); // Would cause erroneous overflow detection.
adds(dest, rn, op);
if (sz == kDoubleWord) {
adds(dest, rn, op);
} else {
addsw(dest, rn, op);
}
} else {
// TODO(zra): Try subtracting top 12 bits, then bottom 12 bits.
ASSERT(rn != TMP2);
LoadImmediate(TMP2, imm);
subs(dest, rn, Operand(TMP2));
if (sz == kDoubleWord) {
subs(dest, rn, Operand(TMP2));
} else {
subsw(dest, rn, Operand(TMP2));
}
}
}

Expand Down
110 changes: 93 additions & 17 deletions runtime/vm/compiler/assembler/assembler_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -649,8 +649,9 @@ class Assembler : public ValueObject {
int width,
OperandSize size = kDoubleWord) {
int wordsize = size == kDoubleWord ? 64 : 32;
EmitBitfieldOp(UBFM, rd, rn, (width - low_bit) & (wordsize - 1),
wordsize - 1, size);
ASSERT(width > 0);
ASSERT(low_bit < wordsize);
EmitBitfieldOp(UBFM, rd, rn, (-low_bit) & (wordsize - 1), width - 1, size);
}

// Unsigned bitfield extract. Takes the width bits, starting at low_bit and
Expand Down Expand Up @@ -688,6 +689,11 @@ class Assembler : public ValueObject {
EmitBitfieldOp(UBFM, rd, rn, 0, 15, kDoubleWord);
}

// Zero/unsigned extend word->64 bit.
void uxtw(Register rd, Register rn) {
EmitBitfieldOp(UBFM, rd, rn, 0, 31, kDoubleWord);
}

// Logical immediate operations.
void andi(Register rd, Register rn, const Immediate& imm) {
Operand imm_op;
Expand Down Expand Up @@ -737,6 +743,9 @@ class Assembler : public ValueObject {
void orn(Register rd, Register rn, Operand o) {
EmitLogicalShiftOp(ORN, rd, rn, o, kDoubleWord);
}
void ornw(Register rd, Register rn, Operand o) {
EmitLogicalShiftOp(ORN, rd, rn, o, kWord);
}
void eor(Register rd, Register rn, Operand o) {
EmitLogicalShiftOp(EOR, rd, rn, o, kDoubleWord);
}
Expand Down Expand Up @@ -774,20 +783,66 @@ class Assembler : public ValueObject {
void asrv(Register rd, Register rn, Register rm) {
EmitMiscDP2Source(ASRV, rd, rn, rm, kDoubleWord);
}
void madd(Register rd, Register rn, Register rm, Register ra) {
EmitMiscDP3Source(MADD, rd, rn, rm, ra, kDoubleWord);
void lslvw(Register rd, Register rn, Register rm) {
EmitMiscDP2Source(LSLV, rd, rn, rm, kWord);
}
void msub(Register rd, Register rn, Register rm, Register ra) {
EmitMiscDP3Source(MSUB, rd, rn, rm, ra, kDoubleWord);
void lsrvw(Register rd, Register rn, Register rm) {
EmitMiscDP2Source(LSRV, rd, rn, rm, kWord);
}
void smulh(Register rd, Register rn, Register rm) {
EmitMiscDP3Source(SMULH, rd, rn, rm, R31, kDoubleWord);
void asrvw(Register rd, Register rn, Register rm) {
EmitMiscDP2Source(ASRV, rd, rn, rm, kWord);
}
void umulh(Register rd, Register rn, Register rm) {
EmitMiscDP3Source(UMULH, rd, rn, rm, R31, kDoubleWord);
void madd(Register rd,
Register rn,
Register rm,
Register ra,
OperandSize sz = kDoubleWord) {
EmitMiscDP3Source(MADD, rd, rn, rm, ra, sz);
}
void umaddl(Register rd, Register rn, Register rm, Register ra) {
EmitMiscDP3Source(UMADDL, rd, rn, rm, ra, kDoubleWord);
void msub(Register rd,
Register rn,
Register rm,
Register ra,
OperandSize sz = kDoubleWord) {
EmitMiscDP3Source(MSUB, rd, rn, rm, ra, sz);
}
void smulh(Register rd,
Register rn,
Register rm,
OperandSize sz = kDoubleWord) {
EmitMiscDP3Source(SMULH, rd, rn, rm, R31, sz);
}
void umulh(Register rd,
Register rn,
Register rm,
OperandSize sz = kDoubleWord) {
EmitMiscDP3Source(UMULH, rd, rn, rm, R31, sz);
}
void umaddl(Register rd,
Register rn,
Register rm,
Register ra,
OperandSize sz = kDoubleWord) {
EmitMiscDP3Source(UMADDL, rd, rn, rm, ra, sz);
}
void umull(Register rd,
Register rn,
Register rm,
OperandSize sz = kDoubleWord) {
EmitMiscDP3Source(UMADDL, rd, rn, rm, ZR, sz);
}
void smaddl(Register rd,
Register rn,
Register rm,
Register ra,
OperandSize sz = kDoubleWord) {
EmitMiscDP3Source(SMADDL, rd, rn, rm, ra, sz);
}
void smull(Register rd,
Register rn,
Register rm,
OperandSize sz = kDoubleWord) {
EmitMiscDP3Source(SMADDL, rd, rn, rm, ZR, sz);
}

// Move wide immediate.
Expand Down Expand Up @@ -903,6 +958,7 @@ class Assembler : public ValueObject {
// For add and sub, to use CSP for rn, o must be of type Operand::Extend.
// For an unmodified rm in this case, use Operand(rm, UXTX, 0);
void cmp(Register rn, Operand o) { subs(ZR, rn, o); }
void cmpw(Register rn, Operand o) { subsw(ZR, rn, o); }
// rn cmp -o.
void cmn(Register rn, Operand o) { adds(ZR, rn, o); }

Expand Down Expand Up @@ -1199,9 +1255,16 @@ class Assembler : public ValueObject {
}
void vmov(VRegister vd, VRegister vn) { vorr(vd, vn, vn); }
void mvn(Register rd, Register rm) { orn(rd, ZR, Operand(rm)); }
void mvnw(Register rd, Register rm) { ornw(rd, ZR, Operand(rm)); }
void neg(Register rd, Register rm) { sub(rd, ZR, Operand(rm)); }
void negs(Register rd, Register rm) { subs(rd, ZR, Operand(rm)); }
void mul(Register rd, Register rn, Register rm) { madd(rd, rn, rm, ZR); }
void negsw(Register rd, Register rm) { subsw(rd, ZR, Operand(rm)); }
void mul(Register rd, Register rn, Register rm) {
madd(rd, rn, rm, ZR, kDoubleWord);
}
void mulw(Register rd, Register rn, Register rm) {
madd(rd, rn, rm, ZR, kWord);
}
void Push(Register reg) {
ASSERT(reg != PP); // Only push PP with TagAndPushPP().
str(reg, Address(SP, -1 * kWordSize, Address::PreIndex));
Expand Down Expand Up @@ -1257,8 +1320,15 @@ class Assembler : public ValueObject {
void tsti(Register rn, const Immediate& imm) { andis(ZR, rn, imm); }

// We use an alias of add, where ARM recommends an alias of ubfm.
void LslImmediate(Register rd, Register rn, int shift) {
add(rd, ZR, Operand(rn, LSL, shift));
void LslImmediate(Register rd,
Register rn,
int shift,
OperandSize sz = kDoubleWord) {
if (sz == kDoubleWord) {
add(rd, ZR, Operand(rn, LSL, shift));
} else {
addw(rd, ZR, Operand(rn, LSL, shift));
}
}
// We use an alias of add, where ARM recommends an alias of ubfm.
void LsrImmediate(Register rd, Register rn, int shift) {
Expand Down Expand Up @@ -1310,8 +1380,14 @@ class Assembler : public ValueObject {
// pool pointer is in another register, or that it is not available at all,
// PP should be passed for pp.
void AddImmediate(Register dest, Register rn, int64_t imm);
void AddImmediateSetFlags(Register dest, Register rn, int64_t imm);
void SubImmediateSetFlags(Register dest, Register rn, int64_t imm);
void AddImmediateSetFlags(Register dest,
Register rn,
int64_t imm,
OperandSize sz = kDoubleWord);
void SubImmediateSetFlags(Register dest,
Register rn,
int64_t imm,
OperandSize sz = kDoubleWord);
void AndImmediate(Register rd, Register rn, int64_t imm);
void OrImmediate(Register rd, Register rn, int64_t imm);
void XorImmediate(Register rd, Register rn, int64_t imm);
Expand Down
Loading

0 comments on commit 235e622

Please sign in to comment.