< prev index next >

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

Print this page




  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 
  25 
  26 package org.graalvm.compiler.asm.aarch64;
  27 
  28 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.BASE_REGISTER_ONLY;
  29 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.EXTENDED_REGISTER_OFFSET;
  30 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.IMMEDIATE_SCALED;
  31 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.IMMEDIATE_UNSCALED;
  32 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.REGISTER_OFFSET;
  33 import static org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.AddressGenerationPlan.WorkPlan.ADD_TO_BASE;
  34 import static org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.AddressGenerationPlan.WorkPlan.ADD_TO_INDEX;
  35 import static org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.AddressGenerationPlan.WorkPlan.NO_WORK;



  36 import static jdk.vm.ci.aarch64.AArch64.CPU;
  37 import static jdk.vm.ci.aarch64.AArch64.r8;
  38 import static jdk.vm.ci.aarch64.AArch64.r9;
  39 import static jdk.vm.ci.aarch64.AArch64.sp;
  40 import static jdk.vm.ci.aarch64.AArch64.zr;
  41 
  42 import org.graalvm.compiler.asm.Label;
  43 import org.graalvm.compiler.core.common.NumUtil;
  44 import org.graalvm.compiler.debug.GraalError;
  45 
  46 import jdk.vm.ci.aarch64.AArch64;
  47 import jdk.vm.ci.code.Register;
  48 import jdk.vm.ci.code.TargetDescription;
  49 
  50 public class AArch64MacroAssembler extends AArch64Assembler {
  51 
  52     private final ScratchRegister[] scratchRegister = new ScratchRegister[]{new ScratchRegister(r8), new ScratchRegister(r9)};
  53 
  54     // Points to the next free scratch register
  55     private int nextFreeScratchRegister = 0;


1435      */
1436     public void cbz(int size, Register cmp, Label label) {
1437         // TODO Handle case where offset is too large for a single jump instruction
1438         if (label.isBound()) {
1439             int offset = label.position() - position();
1440             super.cbz(size, cmp, offset);
1441         } else {
1442             label.addPatchAt(position());
1443             int regEncoding = cmp.encoding << (PatchLabelKind.INFORMATION_OFFSET + 1);
1444             int sizeEncoding = (size == 64 ? 1 : 0) << PatchLabelKind.INFORMATION_OFFSET;
1445             // Encode condition flag so that we know how to patch the instruction later
1446             emitInt(PatchLabelKind.BRANCH_ZERO.encoding | regEncoding | sizeEncoding);
1447         }
1448     }
1449 
1450     /**
1451      * Test a single bit and branch if the bit is nonzero.
1452      *
1453      * @param cmp general purpose register. May not be null, zero-register or stackpointer.
1454      * @param uimm6 Unsigned 6-bit bit index.
1455      * @param label Can only handle 21-bit word-aligned offsets for now. May be unbound. Non null.
1456      */
1457     public void tbnz(Register cmp, int uimm6, Label label) {
1458         assert NumUtil.isUnsignedNbit(6, uimm6);
1459         if (label.isBound()) {
1460             int offset = label.position() - position();
1461             super.tbnz(cmp, uimm6, offset);
1462         } else {
1463             label.addPatchAt(position());
1464             int indexEncoding = uimm6 << PatchLabelKind.INFORMATION_OFFSET;
1465             int regEncoding = cmp.encoding << (PatchLabelKind.INFORMATION_OFFSET + 6);
1466             emitInt(PatchLabelKind.BRANCH_BIT_NONZERO.encoding | indexEncoding | regEncoding);
1467         }
1468     }
1469 
1470     /**
1471      * Test a single bit and branch if the bit is zero.
1472      *
1473      * @param cmp general purpose register. May not be null, zero-register or stackpointer.
1474      * @param uimm6 Unsigned 6-bit bit index.
1475      * @param label Can only handle 21-bit word-aligned offsets for now. May be unbound. Non null.
1476      */
1477     public void tbz(Register cmp, int uimm6, Label label) {
1478         assert NumUtil.isUnsignedNbit(6, uimm6);
1479         if (label.isBound()) {
1480             int offset = label.position() - position();
1481             super.tbz(cmp, uimm6, offset);
1482         } else {
1483             label.addPatchAt(position());
1484             int indexEncoding = uimm6 << PatchLabelKind.INFORMATION_OFFSET;
1485             int regEncoding = cmp.encoding << (PatchLabelKind.INFORMATION_OFFSET + 6);
1486             emitInt(PatchLabelKind.BRANCH_BIT_ZERO.encoding | indexEncoding | regEncoding);
1487         }
1488     }
1489 
1490     /**
1491      * Branches to label if condition is true.
1492      *
1493      * @param condition any condition value allowed. Non null.
1494      * @param label Can only handle 21-bit word-aligned offsets for now. May be unbound. Non null.
1495      */


1664                 int regEncoding = information >>> 1;
1665                 Register reg = AArch64.cpuRegisters.get(regEncoding);
1666                 // 1 => 64; 0 => 32
1667                 int size = sizeEncoding * 32 + 32;
1668                 switch (type) {
1669                     case BRANCH_NONZERO:
1670                         super.cbnz(size, reg, branchOffset, branch);
1671                         break;
1672                     case BRANCH_ZERO:
1673                         super.cbz(size, reg, branchOffset, branch);
1674                         break;
1675                 }
1676                 break;
1677             }
1678             case BRANCH_BIT_NONZERO:
1679             case BRANCH_BIT_ZERO: {
1680                 int information = instruction >>> PatchLabelKind.INFORMATION_OFFSET;
1681                 int sizeEncoding = information & NumUtil.getNbitNumberInt(6);
1682                 int regEncoding = information >>> 6;
1683                 Register reg = AArch64.cpuRegisters.get(regEncoding);



1684                 switch (type) {
1685                     case BRANCH_BIT_NONZERO:
1686                         super.tbnz(reg, sizeEncoding, branchOffset, branch);
1687                         break;
1688                     case BRANCH_BIT_ZERO:
1689                         super.tbz(reg, sizeEncoding, branchOffset, branch);
1690                         break;
1691                 }
1692                 break;
1693             }
1694             case ADR: {
1695                 int information = instruction >>> PatchLabelKind.INFORMATION_OFFSET;
1696                 int regEncoding = information;
1697                 Register reg = AArch64.cpuRegisters.get(regEncoding);
1698                 super.adr(reg, branchOffset, branch);
1699                 break;
1700             }
1701             default:
1702                 throw GraalError.shouldNotReachHere();
1703         }




  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 
  25 
  26 package org.graalvm.compiler.asm.aarch64;
  27 
  28 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.BASE_REGISTER_ONLY;
  29 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.EXTENDED_REGISTER_OFFSET;
  30 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.IMMEDIATE_SCALED;
  31 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.IMMEDIATE_UNSCALED;
  32 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.REGISTER_OFFSET;
  33 import static org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.AddressGenerationPlan.WorkPlan.ADD_TO_BASE;
  34 import static org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.AddressGenerationPlan.WorkPlan.ADD_TO_INDEX;
  35 import static org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.AddressGenerationPlan.WorkPlan.NO_WORK;
  36 
  37 import org.graalvm.compiler.asm.BranchTargetOutOfBoundsException;
  38 
  39 import static jdk.vm.ci.aarch64.AArch64.CPU;
  40 import static jdk.vm.ci.aarch64.AArch64.r8;
  41 import static jdk.vm.ci.aarch64.AArch64.r9;
  42 import static jdk.vm.ci.aarch64.AArch64.sp;
  43 import static jdk.vm.ci.aarch64.AArch64.zr;
  44 
  45 import org.graalvm.compiler.asm.Label;
  46 import org.graalvm.compiler.core.common.NumUtil;
  47 import org.graalvm.compiler.debug.GraalError;
  48 
  49 import jdk.vm.ci.aarch64.AArch64;
  50 import jdk.vm.ci.code.Register;
  51 import jdk.vm.ci.code.TargetDescription;
  52 
  53 public class AArch64MacroAssembler extends AArch64Assembler {
  54 
  55     private final ScratchRegister[] scratchRegister = new ScratchRegister[]{new ScratchRegister(r8), new ScratchRegister(r9)};
  56 
  57     // Points to the next free scratch register
  58     private int nextFreeScratchRegister = 0;


1438      */
1439     public void cbz(int size, Register cmp, Label label) {
1440         // TODO Handle case where offset is too large for a single jump instruction
1441         if (label.isBound()) {
1442             int offset = label.position() - position();
1443             super.cbz(size, cmp, offset);
1444         } else {
1445             label.addPatchAt(position());
1446             int regEncoding = cmp.encoding << (PatchLabelKind.INFORMATION_OFFSET + 1);
1447             int sizeEncoding = (size == 64 ? 1 : 0) << PatchLabelKind.INFORMATION_OFFSET;
1448             // Encode condition flag so that we know how to patch the instruction later
1449             emitInt(PatchLabelKind.BRANCH_ZERO.encoding | regEncoding | sizeEncoding);
1450         }
1451     }
1452 
1453     /**
1454      * Test a single bit and branch if the bit is nonzero.
1455      *
1456      * @param cmp general purpose register. May not be null, zero-register or stackpointer.
1457      * @param uimm6 Unsigned 6-bit bit index.
1458      * @param label Can only handle 16-bit word-aligned offsets for now. May be unbound. Non null.
1459      */
1460     public void tbnz(Register cmp, int uimm6, Label label) {
1461         assert NumUtil.isUnsignedNbit(6, uimm6);
1462         if (label.isBound()) {
1463             int offset = label.position() - position();
1464             super.tbnz(cmp, uimm6, offset);
1465         } else {
1466             label.addPatchAt(position());
1467             int indexEncoding = uimm6 << PatchLabelKind.INFORMATION_OFFSET;
1468             int regEncoding = cmp.encoding << (PatchLabelKind.INFORMATION_OFFSET + 6);
1469             emitInt(PatchLabelKind.BRANCH_BIT_NONZERO.encoding | indexEncoding | regEncoding);
1470         }
1471     }
1472 
1473     /**
1474      * Test a single bit and branch if the bit is zero.
1475      *
1476      * @param cmp general purpose register. May not be null, zero-register or stackpointer.
1477      * @param uimm6 Unsigned 6-bit bit index.
1478      * @param label Can only handle 16-bit word-aligned offsets for now. May be unbound. Non null.
1479      */
1480     public void tbz(Register cmp, int uimm6, Label label) {
1481         assert NumUtil.isUnsignedNbit(6, uimm6);
1482         if (label.isBound()) {
1483             int offset = label.position() - position();
1484             super.tbz(cmp, uimm6, offset);
1485         } else {
1486             label.addPatchAt(position());
1487             int indexEncoding = uimm6 << PatchLabelKind.INFORMATION_OFFSET;
1488             int regEncoding = cmp.encoding << (PatchLabelKind.INFORMATION_OFFSET + 6);
1489             emitInt(PatchLabelKind.BRANCH_BIT_ZERO.encoding | indexEncoding | regEncoding);
1490         }
1491     }
1492 
1493     /**
1494      * Branches to label if condition is true.
1495      *
1496      * @param condition any condition value allowed. Non null.
1497      * @param label Can only handle 21-bit word-aligned offsets for now. May be unbound. Non null.
1498      */


1667                 int regEncoding = information >>> 1;
1668                 Register reg = AArch64.cpuRegisters.get(regEncoding);
1669                 // 1 => 64; 0 => 32
1670                 int size = sizeEncoding * 32 + 32;
1671                 switch (type) {
1672                     case BRANCH_NONZERO:
1673                         super.cbnz(size, reg, branchOffset, branch);
1674                         break;
1675                     case BRANCH_ZERO:
1676                         super.cbz(size, reg, branchOffset, branch);
1677                         break;
1678                 }
1679                 break;
1680             }
1681             case BRANCH_BIT_NONZERO:
1682             case BRANCH_BIT_ZERO: {
1683                 int information = instruction >>> PatchLabelKind.INFORMATION_OFFSET;
1684                 int sizeEncoding = information & NumUtil.getNbitNumberInt(6);
1685                 int regEncoding = information >>> 6;
1686                 Register reg = AArch64.cpuRegisters.get(regEncoding);
1687                 if (!NumUtil.isSignedNbit(16, branchOffset)) {
1688                     throw new BranchTargetOutOfBoundsException(true, "Branch target %d out of bounds", branchOffset);
1689                 }
1690                 switch (type) {
1691                     case BRANCH_BIT_NONZERO:
1692                         super.tbnz(reg, sizeEncoding, branchOffset, branch);
1693                         break;
1694                     case BRANCH_BIT_ZERO:
1695                         super.tbz(reg, sizeEncoding, branchOffset, branch);
1696                         break;
1697                 }
1698                 break;
1699             }
1700             case ADR: {
1701                 int information = instruction >>> PatchLabelKind.INFORMATION_OFFSET;
1702                 int regEncoding = information;
1703                 Register reg = AArch64.cpuRegisters.get(regEncoding);
1704                 super.adr(reg, branchOffset, branch);
1705                 break;
1706             }
1707             default:
1708                 throw GraalError.shouldNotReachHere();
1709         }


< prev index next >