src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java

Print this page

        

*** 37,47 **** import static jdk.vm.ci.aarch64.AArch64.sp; import static jdk.vm.ci.aarch64.AArch64.zr; import org.graalvm.compiler.asm.AbstractAddress; import org.graalvm.compiler.asm.Label; ! import org.graalvm.compiler.asm.NumUtil; import org.graalvm.compiler.debug.GraalError; import jdk.vm.ci.aarch64.AArch64; import jdk.vm.ci.code.Register; import jdk.vm.ci.code.TargetDescription; --- 37,47 ---- import static jdk.vm.ci.aarch64.AArch64.sp; import static jdk.vm.ci.aarch64.AArch64.zr; import org.graalvm.compiler.asm.AbstractAddress; import org.graalvm.compiler.asm.Label; ! import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.debug.GraalError; import jdk.vm.ci.aarch64.AArch64; import jdk.vm.ci.code.Register; import jdk.vm.ci.code.TargetDescription;
*** 194,213 **** --- 194,215 ---- immediate = (int) displacement; } break; case ADD_TO_INDEX: newIndex = allowOverwrite ? index : additionalReg; + assert !newIndex.equals(sp) && !newIndex.equals(zr); if (plan.needsScratch) { mov(additionalReg, scaledDisplacement); add(signExtendIndex ? 32 : 64, newIndex, index, additionalReg); } else { add(signExtendIndex ? 32 : 64, newIndex, index, (int) scaledDisplacement); } immediate = 0; break; case ADD_TO_BASE: newBase = allowOverwrite ? base : additionalReg; + assert !newBase.equals(sp) && !newBase.equals(zr); if (plan.needsScratch) { mov(additionalReg, displacement); add(64, newBase, base, additionalReg); } else { add(64, newBase, base, (int) displacement);
*** 410,419 **** --- 412,434 ---- } assert !firstMove; } /** + * Generates a 32-bit immediate move code sequence. The immediate may later be updated by + * HotSpot. + * + * @param dst general purpose register. May not be null, stackpointer or zero-register. + * @param imm + */ + public void movNarrowAddress(Register dst, long imm) { + assert (imm & 0xFFFF_FFFF_0000_0000L) == 0; + movz(64, dst, (int) (imm >>> 16), 16); + movk(64, dst, (int) (imm & 0xffff), 0); + } + + /** * @return Number of instructions necessary to load immediate into register. */ public static int nrInstructionsToMoveImmediate(long imm) { if (imm == 0L || LogicalImmediateTable.isRepresentable(true, imm) != LogicalImmediateTable.Representable.NO) { return 1;
*** 454,463 **** --- 469,491 ---- super.ldrs(targetSize, srcSize, rt, address); } } /** + * Loads a srcSize value from address into rt zero-extending it if necessary. + * + * @param srcSize size of memory read in bits. Must be 8, 16 or 32 and smaller or equal to + * targetSize. + * @param rt general purpose register. May not be null or stackpointer. + * @param address all addressing modes allowed. May not be null. + */ + @Override + public void ldr(int srcSize, Register rt, AArch64Address address) { + super.ldr(srcSize, rt, address); + } + + /** * Conditional move. dst = src1 if condition else src2. * * @param size register size. Has to be 32 or 64. * @param result general purpose register. May not be null or the stackpointer. * @param trueValue general purpose register. May not be null or the stackpointer.
*** 480,549 **** /** * dst = src1 + src2. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null or stackpointer. ! * @param src1 general purpose register. May not be null or stackpointer. * @param src2 general purpose register. May not be null or stackpointer. */ public void add(int size, Register dst, Register src1, Register src2) { super.add(size, dst, src1, src2, ShiftType.LSL, 0); } /** * dst = src1 + src2 and sets condition flags. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null or stackpointer. ! * @param src1 general purpose register. May not be null or stackpointer. * @param src2 general purpose register. May not be null or stackpointer. */ public void adds(int size, Register dst, Register src1, Register src2) { ! super.adds(size, dst, src1, src2, getNopExtendType(size), 0); } /** * dst = src1 - src2 and sets condition flags. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null or stackpointer. ! * @param src1 general purpose register. May not be null or stackpointer. * @param src2 general purpose register. May not be null or stackpointer. */ public void subs(int size, Register dst, Register src1, Register src2) { ! super.subs(size, dst, src1, src2, getNopExtendType(size), 0); ! } ! ! /** ! * Returns the ExtendType for the given size that corresponds to a no-op. ! * ! * I.e. when doing add X0, X1, X2, the actual instruction has the form add X0, X1, X2 UXTX. ! * ! * @param size ! */ ! private static ExtendType getNopExtendType(int size) { ! if (size == 64) { ! return ExtendType.UXTX; ! } else if (size == 32) { ! return ExtendType.UXTW; } else { ! throw GraalError.shouldNotReachHere("No-op "); } } /** * dst = src1 - src2. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null or stackpointer. ! * @param src1 general purpose register. May not be null or stackpointer. * @param src2 general purpose register. May not be null or stackpointer. */ public void sub(int size, Register dst, Register src1, Register src2) { super.sub(size, dst, src1, src2, ShiftType.LSL, 0); } /** * dst = src1 + shiftType(src2, shiftAmt & (size - 1)). * * @param size register size. Has to be 32 or 64. --- 508,576 ---- /** * dst = src1 + src2. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null. ! * @param src1 general purpose register. May not be null. * @param src2 general purpose register. May not be null or stackpointer. */ public void add(int size, Register dst, Register src1, Register src2) { + if (dst.equals(sp) || src1.equals(sp)) { + super.add(size, dst, src1, src2, ExtendType.UXTX, 0); + } else { super.add(size, dst, src1, src2, ShiftType.LSL, 0); } + } /** * dst = src1 + src2 and sets condition flags. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null. ! * @param src1 general purpose register. May not be null. * @param src2 general purpose register. May not be null or stackpointer. */ public void adds(int size, Register dst, Register src1, Register src2) { ! if (dst.equals(sp) || src1.equals(sp)) { ! super.adds(size, dst, src1, src2, ExtendType.UXTX, 0); ! } else { ! super.adds(size, dst, src1, src2, ShiftType.LSL, 0); ! } } /** * dst = src1 - src2 and sets condition flags. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null. ! * @param src1 general purpose register. May not be null. * @param src2 general purpose register. May not be null or stackpointer. */ public void subs(int size, Register dst, Register src1, Register src2) { ! if (dst.equals(sp) || src1.equals(sp)) { ! super.subs(size, dst, src1, src2, ExtendType.UXTX, 0); } else { ! super.subs(size, dst, src1, src2, ShiftType.LSL, 0); } } /** * dst = src1 - src2. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null. ! * @param src1 general purpose register. May not be null. * @param src2 general purpose register. May not be null or stackpointer. */ public void sub(int size, Register dst, Register src1, Register src2) { + if (dst.equals(sp) || src1.equals(sp)) { + super.sub(size, dst, src1, src2, ExtendType.UXTX, 0); + } else { super.sub(size, dst, src1, src2, ShiftType.LSL, 0); } + } /** * dst = src1 + shiftType(src2, shiftAmt & (size - 1)). * * @param size register size. Has to be 32 or 64.
*** 588,608 **** /** * dst = src + immediate. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null or stackpointer. ! * @param src general purpose register. May not be null or stackpointer. ! * @param immediate arithmetic immediate */ @Override public void add(int size, Register dst, Register src, int immediate) { if (immediate < 0) { sub(size, dst, src, -immediate); ! } else if (!(dst.equals(src) && immediate == 0)) { super.add(size, dst, src, immediate); } } /** * dst = src + aimm and sets condition flags. * --- 615,645 ---- /** * dst = src + immediate. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null or zero-register. ! * @param src general purpose register. May not be null or zero-register. ! * @param immediate 32-bit signed int */ @Override public void add(int size, Register dst, Register src, int immediate) { + assert (!dst.equals(zr) && !src.equals(zr)); if (immediate < 0) { sub(size, dst, src, -immediate); ! } else if (isAimm(immediate)) { ! if (!(dst.equals(src) && immediate == 0)) { super.add(size, dst, src, immediate); } + } else if (immediate >= -(1 << 24) && immediate < (1 << 24)) { + super.add(size, dst, src, immediate & -(1 << 12)); + super.add(size, dst, dst, immediate & ((1 << 12) - 1)); + } else { + assert !dst.equals(src); + mov(dst, immediate); + add(size, src, dst, dst); + } } /** * dst = src + aimm and sets condition flags. *
*** 611,620 **** --- 648,658 ---- * @param src general purpose register. May not be null or zero-register. * @param immediate arithmetic immediate. */ @Override public void adds(int size, Register dst, Register src, int immediate) { + assert (!dst.equals(sp) && !src.equals(zr)); if (immediate < 0) { subs(size, dst, src, -immediate); } else if (!(dst.equals(src) && immediate == 0)) { super.adds(size, dst, src, immediate); }
*** 622,642 **** /** * dst = src - immediate. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null or stackpointer. ! * @param src general purpose register. May not be null or stackpointer. ! * @param immediate arithmetic immediate */ @Override public void sub(int size, Register dst, Register src, int immediate) { if (immediate < 0) { add(size, dst, src, -immediate); ! } else if (!dst.equals(src) || immediate != 0) { super.sub(size, dst, src, immediate); } } /** * dst = src - aimm and sets condition flags. * --- 660,690 ---- /** * dst = src - immediate. * * @param size register size. Has to be 32 or 64. ! * @param dst general purpose register. May not be null or zero-register. ! * @param src general purpose register. May not be null or zero-register. ! * @param immediate 32-bit signed int */ @Override public void sub(int size, Register dst, Register src, int immediate) { + assert (!dst.equals(zr) && !src.equals(zr)); if (immediate < 0) { add(size, dst, src, -immediate); ! } else if (isAimm(immediate)) { ! if (!(dst.equals(src) && immediate == 0)) { super.sub(size, dst, src, immediate); } + } else if (immediate >= -(1 << 24) && immediate < (1 << 24)) { + super.sub(size, dst, src, immediate & -(1 << 12)); + super.sub(size, dst, dst, immediate & ((1 << 12) - 1)); + } else { + assert !dst.equals(src); + mov(dst, immediate); + sub(size, src, dst, dst); + } } /** * dst = src - aimm and sets condition flags. *
*** 645,658 **** * @param src general purpose register. May not be null or zero-register. * @param immediate arithmetic immediate. */ @Override public void subs(int size, Register dst, Register src, int immediate) { if (immediate < 0) { adds(size, dst, src, -immediate); } else if (!dst.equals(src) || immediate != 0) { ! super.sub(size, dst, src, immediate); } } /** * dst = src1 * src2. --- 693,707 ---- * @param src general purpose register. May not be null or zero-register. * @param immediate arithmetic immediate. */ @Override public void subs(int size, Register dst, Register src, int immediate) { + assert (!dst.equals(sp) && !src.equals(zr)); if (immediate < 0) { adds(size, dst, src, -immediate); } else if (!dst.equals(src) || immediate != 0) { ! super.subs(size, dst, src, immediate); } } /** * dst = src1 * src2.
*** 673,682 **** --- 722,732 ---- * @param dst general purpose register. May not be null or the stackpointer. * @param src1 general purpose register. May not be null or the stackpointer. * @param src2 general purpose register. May not be null or the stackpointer. */ public void umulh(int size, Register dst, Register src1, Register src2) { + assert (!dst.equals(sp) && !src1.equals(sp) && !src2.equals(sp)); assert size == 32 || size == 64; if (size == 64) { super.umulh(dst, src1, src2); } else { // xDst = wSrc1 * wSrc2
*** 693,702 **** --- 743,753 ---- * @param dst general purpose register. May not be null or the stackpointer. * @param src1 general purpose register. May not be null or the stackpointer. * @param src2 general purpose register. May not be null or the stackpointer. */ public void smulh(int size, Register dst, Register src1, Register src2) { + assert (!dst.equals(sp) && !src1.equals(sp) && !src2.equals(sp)); assert size == 32 || size == 64; if (size == 64) { super.smulh(dst, src1, src2); } else { // xDst = wSrc1 * wSrc2
*** 713,722 **** --- 764,774 ---- * @param dst general purpose register. May not be null or the stackpointer. * @param n numerator. General purpose register. May not be null or the stackpointer. * @param d denominator. General purpose register. Divisor May not be null or the stackpointer. */ public void rem(int size, Register dst, Register n, Register d) { + assert (!dst.equals(sp) && !n.equals(sp) && !d.equals(sp)); // There is no irem or similar instruction. Instead we use the relation: // n % d = n - Floor(n / d) * d if nd >= 0 // n % d = n - Ceil(n / d) * d else // Which is equivalent to n - TruncatingDivision(n, d) * d super.sdiv(size, dst, n, d);
*** 938,957 **** } /** * Sign-extend value from src into dst. * ! * @param destSize destination register size. Has to be 32 or 64. ! * @param srcSize source register size. May be 8, 16 or 32 and smaller than destSize. * @param dst general purpose register. May not be null, stackpointer or zero-register. * @param src general purpose register. May not be null, stackpointer or zero-register. */ public void sxt(int destSize, int srcSize, Register dst, Register src) { ! assert (destSize == 32 || destSize == 64) && srcSize < destSize; ! assert srcSize == 8 || srcSize == 16 || srcSize == 32; ! int[] srcSizeValues = {7, 15, 31}; ! super.sbfm(destSize, dst, src, 0, srcSizeValues[NumUtil.log2Ceil(srcSize / 8)]); } /** * dst = src if condition else -src. * --- 990,1007 ---- } /** * Sign-extend value from src into dst. * ! * @param destSize destination register size. Must be 32 or 64. ! * @param srcSize source register size. Must be smaller than destSize. * @param dst general purpose register. May not be null, stackpointer or zero-register. * @param src general purpose register. May not be null, stackpointer or zero-register. */ public void sxt(int destSize, int srcSize, Register dst, Register src) { ! assert (srcSize < destSize && srcSize > 0); ! super.sbfm(destSize, dst, src, 0, srcSize - 1); } /** * dst = src if condition else -src. *
*** 1076,1085 **** --- 1126,1136 ---- * @param size register size. Has to be 32 or 64. * @param x general purpose register. May not be null or stackpointer. * @param y general purpose register. May not be null or stackpointer. */ public void cmp(int size, Register x, Register y) { + assert size == 32 || size == 64; super.subs(size, zr, x, y, ShiftType.LSL, 0); } /** * Compares x to y and sets condition flags.
*** 1087,1096 **** --- 1138,1148 ---- * @param size register size. Has to be 32 or 64. * @param x general purpose register. May not be null or stackpointer. * @param y comparison immediate, {@link #isComparisonImmediate(long)} has to be true for it. */ public void cmp(int size, Register x, int y) { + assert size == 32 || size == 64; if (y < 0) { super.adds(size, zr, x, -y); } else { super.subs(size, zr, x, y); }
*** 1107,1116 **** --- 1159,1216 ---- public void ands(int size, Register dst, Register x, Register y) { super.ands(size, dst, x, y, ShiftType.LSL, 0); } /** + * Sets overflow flag according to result of x * y. + * + * @param size register size. Has to be 32 or 64. + * @param dst general purpose register. May not be null or stack-pointer. + * @param x general purpose register. May not be null or stackpointer. + * @param y general purpose register. May not be null or stackpointer. + */ + public void mulvs(int size, Register dst, Register x, Register y) { + try (ScratchRegister sc1 = getScratchRegister(); + ScratchRegister sc2 = getScratchRegister()) { + switch (size) { + case 64: { + // Be careful with registers: it's possible that x, y, and dst are the same + // register. + Register rscratch1 = sc1.getRegister(); + Register rscratch2 = sc2.getRegister(); + mul(64, rscratch1, x, y); // Result bits 0..63 + smulh(64, rscratch2, x, y); // Result bits 64..127 + // Top is pure sign ext + subs(64, zr, rscratch2, rscratch1, ShiftType.ASR, 63); + // Copy all 64 bits of the result into dst + mov(64, dst, rscratch1); + mov(rscratch1, 0x80000000); + // Develop 0 (EQ), or 0x80000000 (NE) + cmov(32, rscratch1, rscratch1, zr, ConditionFlag.NE); + cmp(32, rscratch1, 1); + // 0x80000000 - 1 => VS + break; + } + case 32: { + Register rscratch1 = sc1.getRegister(); + smaddl(rscratch1, x, y, zr); + // Copy the low 32 bits of the result into dst + mov(32, dst, rscratch1); + subs(64, zr, rscratch1, rscratch1, ExtendType.SXTW, 0); + // NE => overflow + mov(rscratch1, 0x80000000); + // Develop 0 (EQ), or 0x80000000 (NE) + cmov(32, rscratch1, rscratch1, zr, ConditionFlag.NE); + cmp(32, rscratch1, 1); + // 0x80000000 - 1 => VS + break; + } + } + } + } + + /** * When patching up Labels we have to know what kind of code to generate. */ public enum PatchLabelKind { BRANCH_CONDITIONALLY(0x0), BRANCH_UNCONDITIONALLY(0x1),
*** 1351,1361 **** break; case BRANCH_UNCONDITIONALLY: super.b(branchOffset, branch); break; case JUMP_ADDRESS: ! emitInt(jumpTarget, branch); break; case BRANCH_NONZERO: case BRANCH_ZERO: { int information = instruction >>> PatchLabelKind.INFORMATION_OFFSET; int sizeEncoding = information & 1; --- 1451,1462 ---- break; case BRANCH_UNCONDITIONALLY: super.b(branchOffset, branch); break; case JUMP_ADDRESS: ! int offset = instruction >>> PatchLabelKind.INFORMATION_OFFSET; ! emitInt(jumpTarget - offset, branch); break; case BRANCH_NONZERO: case BRANCH_ZERO: { int information = instruction >>> PatchLabelKind.INFORMATION_OFFSET; int sizeEncoding = information & 1;
*** 1402,1407 **** --- 1503,1518 ---- @Override public AbstractAddress getPlaceholder(int instructionStartPosition) { return AArch64Address.PLACEHOLDER; } + + /** + * Loads an address into Register d. + * + * @param d general purpose register. May not be null. + * @param a AArch64Address the address of an operand. + */ + public void lea(Register d, AArch64Address a) { + a.lea(this, d); + } }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File