| Index: runtime/vm/assembler_arm64.h
|
| ===================================================================
|
| --- runtime/vm/assembler_arm64.h (revision 36576)
|
| +++ runtime/vm/assembler_arm64.h (working copy)
|
| @@ -442,8 +442,6 @@
|
| }
|
|
|
| // 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) {
|
| Operand imm_op;
|
| const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op);
|
| @@ -734,6 +732,27 @@
|
| }
|
|
|
| // SIMD operations.
|
| + void vand(VRegister vd, VRegister vn, VRegister vm) {
|
| + EmitSIMDThreeSameOp(VAND, vd, vn, vm);
|
| + }
|
| + void vorr(VRegister vd, VRegister vn, VRegister vm) {
|
| + EmitSIMDThreeSameOp(VORR, vd, vn, vm);
|
| + }
|
| + void veor(VRegister vd, VRegister vn, VRegister vm) {
|
| + EmitSIMDThreeSameOp(VEOR, vd, vn, vm);
|
| + }
|
| + void vaddw(VRegister vd, VRegister vn, VRegister vm) {
|
| + EmitSIMDThreeSameOp(VADDW, vd, vn, vm);
|
| + }
|
| + void vaddx(VRegister vd, VRegister vn, VRegister vm) {
|
| + EmitSIMDThreeSameOp(VADDX, vd, vn, vm);
|
| + }
|
| + void vsubw(VRegister vd, VRegister vn, VRegister vm) {
|
| + EmitSIMDThreeSameOp(VSUBW, vd, vn, vm);
|
| + }
|
| + void vsubx(VRegister vd, VRegister vn, VRegister vm) {
|
| + EmitSIMDThreeSameOp(VSUBX, vd, vn, vm);
|
| + }
|
| void vadds(VRegister vd, VRegister vn, VRegister vm) {
|
| EmitSIMDThreeSameOp(VADDS, vd, vn, vm);
|
| }
|
| @@ -758,18 +777,57 @@
|
| void vdivd(VRegister vd, VRegister vn, VRegister vm) {
|
| EmitSIMDThreeSameOp(VDIVD, vd, vn, vm);
|
| }
|
| + void vnot(VRegister vd, VRegister vn) {
|
| + EmitSIMDTwoRegOp(VNOT, vd, vn);
|
| + }
|
| + void vabss(VRegister vd, VRegister vn) {
|
| + EmitSIMDTwoRegOp(VABSS, vd, vn);
|
| + }
|
| + void vabsd(VRegister vd, VRegister vn) {
|
| + EmitSIMDTwoRegOp(VABSD, vd, vn);
|
| + }
|
| + void vnegs(VRegister vd, VRegister vn) {
|
| + EmitSIMDTwoRegOp(VNEGS, vd, vn);
|
| + }
|
| + void vnegd(VRegister vd, VRegister vn) {
|
| + EmitSIMDTwoRegOp(VNEGD, vd, vn);
|
| + }
|
| + void vdupw(VRegister vd, Register rn) {
|
| + const VRegister vn = static_cast<VRegister>(rn);
|
| + EmitSIMDCopyOp(VDUPI, vd, vn, kWord, 0, 0);
|
| + }
|
| + void vdupx(VRegister vd, Register rn) {
|
| + const VRegister vn = static_cast<VRegister>(rn);
|
| + EmitSIMDCopyOp(VDUPI, vd, vn, kDoubleWord, 0, 0);
|
| + }
|
| void vdups(VRegister vd, VRegister vn, int32_t idx) {
|
| EmitSIMDCopyOp(VDUP, vd, vn, kSWord, 0, idx);
|
| }
|
| void vdupd(VRegister vd, VRegister vn, int32_t idx) {
|
| EmitSIMDCopyOp(VDUP, vd, vn, kDWord, 0, idx);
|
| }
|
| + void vinsw(VRegister vd, int32_t didx, Register rn) {
|
| + const VRegister vn = static_cast<VRegister>(rn);
|
| + EmitSIMDCopyOp(VINSI, vd, vn, kWord, 0, didx);
|
| + }
|
| + void vinsx(VRegister vd, int32_t didx, Register rn) {
|
| + const VRegister vn = static_cast<VRegister>(rn);
|
| + EmitSIMDCopyOp(VINSI, vd, vn, kDoubleWord, 0, didx);
|
| + }
|
| void vinss(VRegister vd, int32_t didx, VRegister vn, int32_t sidx) {
|
| EmitSIMDCopyOp(VINS, vd, vn, kSWord, sidx, didx);
|
| }
|
| void vinsd(VRegister vd, int32_t didx, VRegister vn, int32_t sidx) {
|
| EmitSIMDCopyOp(VINS, vd, vn, kDWord, sidx, didx);
|
| }
|
| + void vmovrs(Register rd, VRegister vn, int32_t sidx) {
|
| + const VRegister vd = static_cast<VRegister>(rd);
|
| + EmitSIMDCopyOp(VMOVW, vd, vn, kWord, 0, sidx);
|
| + }
|
| + void vmovrd(Register rd, VRegister vn, int32_t sidx) {
|
| + const VRegister vd = static_cast<VRegister>(rd);
|
| + EmitSIMDCopyOp(VMOVX, vd, vn, kDoubleWord, 0, sidx);
|
| + }
|
|
|
| // Aliases.
|
| void mov(Register rd, Register rn) {
|
| @@ -779,6 +837,9 @@
|
| orr(rd, ZR, Operand(rn));
|
| }
|
| }
|
| + void vmov(VRegister vd, VRegister vn) {
|
| + vorr(vd, vn, vn);
|
| + }
|
| void mvn(Register rd, Register rm) {
|
| orn(rd, ZR, Operand(rm));
|
| }
|
| @@ -799,12 +860,24 @@
|
| ASSERT(reg != PP); // Only pop PP with PopAndUntagPP().
|
| ldr(reg, Address(SP, 1 * kWordSize, Address::PostIndex));
|
| }
|
| + void PushFloat(VRegister reg) {
|
| + fstrs(reg, Address(SP, -1 * kFloatSize, Address::PreIndex));
|
| + }
|
| void PushDouble(VRegister reg) {
|
| - fstrd(reg, Address(SP, -1 * kWordSize, Address::PreIndex));
|
| + fstrd(reg, Address(SP, -1 * kDoubleSize, Address::PreIndex));
|
| }
|
| + void PushQuad(VRegister reg) {
|
| + fstrq(reg, Address(SP, -1 * kQuadSize, Address::PreIndex));
|
| + }
|
| + void PopFloat(VRegister reg) {
|
| + fldrs(reg, Address(SP, 1 * kFloatSize, Address::PostIndex));
|
| + }
|
| void PopDouble(VRegister reg) {
|
| - fldrd(reg, Address(SP, 1 * kWordSize, Address::PostIndex));
|
| + fldrd(reg, Address(SP, 1 * kDoubleSize, Address::PostIndex));
|
| }
|
| + void PopQuad(VRegister reg) {
|
| + fldrq(reg, Address(SP, 1 * kQuadSize, Address::PostIndex));
|
| + }
|
| void TagAndPushPP() {
|
| // Add the heap object tag back to PP before putting it on the stack.
|
| add(TMP, PP, Operand(kHeapObjectTag));
|
| @@ -1464,6 +1537,14 @@
|
| Emit(encoding);
|
| }
|
|
|
| + void EmitSIMDTwoRegOp(SIMDTwoRegOp op, VRegister vd, VRegister vn) {
|
| + const int32_t encoding =
|
| + op |
|
| + (static_cast<int32_t>(vd) << kVdShift) |
|
| + (static_cast<int32_t>(vn) << kVnShift);
|
| + Emit(encoding);
|
| + }
|
| +
|
| void StoreIntoObjectFilter(Register object, Register value, Label* no_update);
|
|
|
| // Shorter filtering sequence that assumes that value is not a smi.
|
|
|