pax_global_header00006660000000000000000000000064133441757320014523gustar00rootroot0000000000000052 comment=64cb60f754c5e1450c57cb0ec99b0117f45e9d86 jnr-a64asm-jnr-a64asm-1.0.0/000077500000000000000000000000001334417573200152635ustar00rootroot00000000000000jnr-a64asm-jnr-a64asm-1.0.0/LICENSE000066400000000000000000000010371334417573200162710ustar00rootroot00000000000000 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. jnr-a64asm-jnr-a64asm-1.0.0/README.md000066400000000000000000000002441334417573200165420ustar00rootroot00000000000000This is a pure-java port of asmjit for AARCH64 architecture (http://code.google.com/p/asmjit/) This is remote assembler for jnr-ffi to support aarch64 architecture jnr-a64asm-jnr-a64asm-1.0.0/pom.xml000066400000000000000000000047231334417573200166060ustar00rootroot00000000000000 4.0.0 org.sonatype.oss oss-parent 7 com.github.jnr jnr-a64asm jar 1.0.0 jnr-a64asm A pure-java A64 assembler The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo scm:git:git@github.com:jnr/jnr-a64asm.git scm:git:git@github.com:jnr/jnr-a64asm.git git@github.com:jnr/jnr-a64asm.git HEAD ossdev ossdev ossdev@puresoftware.com junit junit 4.8.2 test UTF-8 1.7 1.7 org.apache.maven.plugins maven-javadoc-plugin 2.9.1 attach-javadocs jar -Xdoclint:none org.apache.maven.plugins maven-source-plugin 2.2.1 attach-sources jar jnr-a64asm-jnr-a64asm-1.0.0/src/000077500000000000000000000000001334417573200160525ustar00rootroot00000000000000jnr-a64asm-jnr-a64asm-1.0.0/src/main/000077500000000000000000000000001334417573200167765ustar00rootroot00000000000000jnr-a64asm-jnr-a64asm-1.0.0/src/main/java/000077500000000000000000000000001334417573200177175ustar00rootroot00000000000000jnr-a64asm-jnr-a64asm-1.0.0/src/main/java/jnr/000077500000000000000000000000001334417573200205105ustar00rootroot00000000000000jnr-a64asm-jnr-a64asm-1.0.0/src/main/java/jnr/a64asm/000077500000000000000000000000001334417573200216035ustar00rootroot00000000000000jnr-a64asm-jnr-a64asm-1.0.0/src/main/java/jnr/a64asm/Asm.java000066400000000000000000000174321334417573200231750ustar00rootroot00000000000000/* * Copyright (C) 2018 Ossdev07 * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.a64asm; import static jnr.a64asm.REG.*; import static jnr.a64asm.SIZE.*; public final class Asm { private Asm() {} public static final CPU_A64 Aarch_64 = CPU_A64.A64; /** No register, can be used only in @c Mem operand. */ public static final Register no_reg = new Register(NO_REG, 0); /** 64 bit General purpose register. */ public static final Register x0 = Register.gpr(REG_X0); /** 64 bit General purpose register. */ public static final Register x1 = Register.gpr(REG_X1); /** 64 bit General purpose register. */ public static final Register x2 = Register.gpr(REG_X2); /** 64 bit General purpose register. */ public static final Register x3 = Register.gpr(REG_X3); /** 64 bit General purpose register. */ public static final Register x4 = Register.gpr(REG_X4); /** 64 bit General purpose register. */ public static final Register x5 = Register.gpr(REG_X5); /** 64 bit General purpose register. */ public static final Register x6 = Register.gpr(REG_X6); /** 64 bit General purpose register. */ public static final Register x7 = Register.gpr(REG_X7); /** frame pointer */ public static final Register fp = Register.gpr(REG_X29); /** link register */ public static final Register lr = Register.gpr(REG_X30); /** stack pointer */ public static final Register sp = Register.gpr(REG_X31); /** 64 bit 15 Spare General purpose register (64 bit mode only). */ public static final Register w0 = Register.gpr(REG_W0); public static final Register w1 = Register.gpr(REG_W1); public static final Register w2 = Register.gpr(REG_W2); public static final Register w3 = Register.gpr(REG_W3); public static final Register w4 = Register.gpr(REG_W4); public static final Register w5 = Register.gpr(REG_W5); public static final Register w6 = Register.gpr(REG_W6); public static final Register w7 = Register.gpr(REG_W7); public static final Register w8 = Register.gpr(REG_W8); public static final Register w9 = Register.gpr(REG_W9); public static final Register w10 = Register.gpr(REG_W10); public static final Register w11 = Register.gpr(REG_W11); public static final Register w12 = Register.gpr(REG_W12); public static final Register w13 = Register.gpr(REG_W13); public static final Register w14 = Register.gpr(REG_W14); public static final Register w15 = Register.gpr(REG_W15); static final Mem _ptr_build(Label label, long disp, int ptrSize) { return new Mem(label, disp, ptrSize); } static final Mem _ptr_build(Label label, Register index, int shift, long disp, int ptrSize) { return new Mem(label, index, shift, disp, ptrSize); } /** Absolute addressing */ static final Mem _ptr_build_abs(long target, long disp, int ptrSize) { return new Mem(target, disp, ptrSize); } static final Mem _ptr_build_abs(long target, Register index, int shift, long disp, int ptrSize) { return new Mem(target, index, shift, disp, ptrSize); } static final Mem _ptr_build(Register base, long disp, int ptrSize) { return new Mem(base, disp, ptrSize); } static final Mem _ptr_build(Register base, Register index, int shift, long disp, int ptrSize) { return new Mem(base, index, shift, disp, ptrSize); } // ============================================================================ // [AsmJit::Mem - ptr[displacement]] // ============================================================================ /** Create pointer operand with not specified size. */ public static final Mem ptr(Label label, long disp) { return _ptr_build(label, disp, 0); } /** Create pointer operand with not specified size. */ public static final Mem ptr(Label label) { return _ptr_build(label, 0, 0); } /** Create word (2 Bytes) pointer operand. */ public static final Mem word_ptr(Label label, long disp) { return _ptr_build(label, disp, SIZE_WORD); } /** Create word (2 Bytes) pointer operand. */ public static final Mem word_ptr(Label label) { return _ptr_build(label, 0, SIZE_WORD); } /** Create dword (4 Bytes) pointer operand. */ public static final Mem dword_ptr(Label label, long disp) { return _ptr_build(label, disp, SIZE_DWORD); } /** Create dword (4 Bytes) pointer operand. */ public static final Mem dword_ptr(Label label) { return _ptr_build(label, 0, SIZE_DWORD); } /** Create pointer operand with not specified size. */ public static final Mem ptr(Label label, Register index, int shift, long disp) { return _ptr_build(label, index, shift, disp, 0); } /** Create dword (4 Bytes) pointer operand. */ public static final Mem word_ptr(Label label, Register index, int shift, long disp) { return _ptr_build(label, index, shift, disp, SIZE_WORD); } /** Create qword (8 Bytes) pointer operand. */ public static final Mem dword_ptr(Label label, Register index, int shift, long disp) { return _ptr_build(label, index, shift, disp, SIZE_DWORD); } public static final Mem word_ptr_abs(long target, Register index, int shift, long disp) { return _ptr_build_abs(target, index, shift, disp, SIZE_WORD); } public static final Mem dword_ptr_abs(long target, Register index, int shift, long disp) { return _ptr_build_abs(target, index, shift, disp, SIZE_DWORD); } // ============================================================================ // [AsmJit::Mem - ptr[base + displacement]] // ============================================================================ /** Create pointer operand with not specified size. */ public static final Mem ptr(Register base, long disp) { return _ptr_build(base, disp, 0); } /** Create word (4 Bytes) pointer operand. */ public static final Mem word_ptr(Register base, long disp) { return _ptr_build(base, disp, SIZE_WORD); } /** Create dword (8 Bytes) pointer operand. */ public static final Mem dword_ptr(Register base, long disp) { return _ptr_build(base, disp, SIZE_DWORD); } // ============================================================================ // [AsmJit::Mem - ptr[base + (index << shift) + displacement]] // ============================================================================ /** Create pointer operand with not specified size. */ public static final Mem ptr(Register base, Register index, int shift, long disp) { return _ptr_build(base, index, shift, disp, 0); } /** Create word (2 Bytes) pointer operand. */ public static final Mem word_ptr(Register base, Register index, int shift, long disp) { return _ptr_build(base, index, shift, disp, SIZE_WORD); } /** Create dword (4 Bytes) pointer operand. */ public static final Mem dword_ptr(Register base, Register index, int shift, long disp) { return _ptr_build(base, index, shift, disp, SIZE_DWORD); } public static final Immediate imm(long value) { return Immediate.imm(value); } public static final Immediate uimm(long value) { return Immediate.imm(value); } } jnr-a64asm-jnr-a64asm-1.0.0/src/main/java/jnr/a64asm/Assembler_A64.java000066400000000000000000001276101334417573200250040ustar00rootroot00000000000000/* * Copyright (C) 2018 Ossdev07 * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.a64asm; import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.List; import static jnr.a64asm.INST_CODE.*; import static jnr.a64asm.InstructionGroup.*; import static jnr.a64asm.OP.*; import static jnr.a64asm.OperandFlags.*; import static jnr.a64asm.RELOC_MODE.*; import static jnr.a64asm.REG.*; import static jnr.a64asm.Util.*; import static jnr.a64asm.SIZE.*; import static jnr.a64asm.PrefOp.*; /** * Low level code generation. */ public final class Assembler_A64 extends Serializer { private final CodeBuffer _buffer = new CodeBuffer(); private final List _relocData = new LinkedList(); private final CpuInfo cpuInfo = CpuInfo.GENERIC; private int _properties = 0; private final Logger _logger = null; private final CPU_A64 cpu; @Override boolean is64() { return cpu == CPU_A64.A64; } private static final int intValue(boolean b) { return b ? 1 : 0; } public static final CPU_A64 Aarch_64 = CPU_A64.Aarch64; public Assembler_A64(CPU_A64 cpu) { this.cpu = cpu; } public final int offset() { return _buffer.offset(); } /** Gets the required size of memory required to store all the generated code */ public final int codeSize() { return _buffer.offset(); } //! @brief Set byte at position @a pos. public final byte getByteAt(int pos) { return _buffer.getByteAt(pos); } //! @brief Set word at position @a pos. public final short getWordAt(int pos) { return _buffer.getWordAt(pos); } //! @brief Set word at position @a pos. public final int getDWordAt(int pos) { return _buffer.getDWordAt(pos); } //! @brief Set word at position @a pos. public final long getQWordAt(int pos) { return _buffer.getQWordAt(pos); } //! @brief Set byte at position @a pos. public final void setByteAt(int pos, byte x) { _buffer.setByteAt(pos, x); } //! @brief Set word at position @a pos. public final void setWordAt(int pos, short x) { _buffer.setWordAt(pos, x); } //! @brief Set word at position @a pos. public final void setDWordAt(int pos, int x) { _buffer.setDWordAt(pos, x); } //! @brief Set word at position @a pos. public final void setQWordAt(int pos, long x) { _buffer.setQWordAt(pos, x); } //! @brief Set word at position @a pos. public final int getInt32At(int pos) { return (int) _buffer.getDWordAt(pos); } //! @brief Set int32 at position @a pos. public final void setInt32At(int pos, long x) { _buffer.setDWordAt(pos, (int) x); } public final void setVarAt(int pos, long i, boolean isUnsigned, int size) { switch (size) { case 1: setByteAt(pos, (byte) i); break; case 2: setWordAt(pos, (short) i); break; case 4: setDWordAt(pos, (int) i); break; case 8: setQWordAt(pos, i); default: throw new IllegalArgumentException("invalid size"); } } /** Emit Byte to internal buffer. */ final void _emitByte(int x) { _buffer.emitByte((byte) x); } /** Emit Word (2 bytes) to internal buffer. */ final void _emitWord(int x) { _buffer.emitWord((short) x); } /** Emit DWord (4 bytes) to internal buffer. */ final void _emitDWord(int x) { _buffer.emitDWord(x); } /** Emit QWord (8 bytes) to internal buffer. */ final void _emitQWord(long x) { _buffer.emitQWord(x); } /** Emit Int32 (4 bytes) to internal buffer. */ final void _emitInt32(int x) { _buffer.emitDWord(x); } /** Emit system signed integer (4 or 8 bytes) to internal buffer. */ final void _emitSysInt(long x) { if (is64()) { _buffer.emitQWord(x); } else { _buffer.emitDWord((int) x); } } //! @brief Emit single @a opCode without operands. final void _emitOpCode(int opCode) { if ((opCode & 0xFF000000) != 0) { _emitByte((byte) ((opCode & 0xFF000000) >> 24)); } if ((opCode & 0x00FF0000) != 0) { _emitByte((byte) ((opCode & 0x00FF0000) >> 16)); } if ((opCode & 0x0000FF00) != 0) { _emitByte((byte) ((opCode & 0x0000FF00) >> 8)); } _emitByte((byte) (opCode & 0x000000FF)); } void _emitImmediate(Immediate imm, int size) { switch (size) { case 1: _emitByte(imm.byteValue()); break; case 2: _emitWord(imm.shortValue()); break; case 4: _emitDWord(imm.intValue()); break; case 8: if (!is64()) { throw new IllegalArgumentException("64 bit immediate values not supported for 32bit"); } _emitQWord(imm.longValue()); break; default: throw new IllegalArgumentException("invalid immediate operand size"); } } void _emita64(INST_CODE code, Operand o1, Operand o2, Operand o3, Operand o4, Operand o5) { InstructionDescription id = InstructionDescription.find(code); switch(id.group){ case addsub_carry: case addsub_ext: { int inst_to_emit = 0; if ((o1.isReg() && o2.isReg() && o3.isReg()) || (o4 != null && o4.isExtend())){ Register regD = (Register) o1; Register regN = (Register) o2; Register regM = (Register) o3; Ext extV = null; if(o4 != _none && o4.isExtend()) extV = (Ext) o4; if(o1.size() == SIZE_DWORD){ inst_to_emit |= 1 << 31; } inst_to_emit |= regD.code & 0b11111; inst_to_emit |= (regN.code & 0b11111) << 5; inst_to_emit |= (regM.code & 0b11111) << 16; if((id.group == addsub_ext) && (extV != null)){ inst_to_emit |= (extV.value() & 0b111) << 10; inst_to_emit |= (extV.type() & 0b111) << 13; } inst_to_emit |= id.opcode; _emitInt32(inst_to_emit); } else throw new IllegalArgumentException("illegal arguments"); break; } case addsub_imm: case addsub_shift: { int inst_to_emit = 0; if ((o1 != _none && o1.isReg()) && (o2 != _none && o2.isReg())){ Register regD = (Register) o1; Register regN = (Register) o2; Immediate val = null ; if(o3 != _none && o3.isImm()) val = (Immediate) o3; Shift sft = null; if(o4 != _none) sft = (Shift) o4; Register regM = null; if(o3 != _none && o3.isReg()) regM = (Register) o3; if(o1.size() == SIZE_DWORD) inst_to_emit |= 1 << 31; inst_to_emit |= regD.code & 0b11111; inst_to_emit |= (regN.code & 0b11111) << 16; if(id.group == addsub_shift){ if(regM != null) inst_to_emit |= (regM.code & 0b11111) << 16; if (sft != null) inst_to_emit |= (sft.value() & 0b111111) << 10; } else { if (val != null) inst_to_emit |= (val.value() & 0xfff) << 10; } if(sft != null) inst_to_emit |= (sft.type() & 0b11) << 22; inst_to_emit |= id.opcode; _emitInt32(inst_to_emit); } else throw new IllegalArgumentException("illegal arguments"); break; } case bitfield: { int inst_to_emit = 0; if (o1.isReg() && o2.isReg()){ Register regD = (Register) o1; Register regN = (Register) o2; Immediate val1 = null ; if(o3.isImm()) val1 = (Immediate) o3; Immediate val2 = null; if(o4.isImm()) val2 = (Immediate) o4; if(o1.size() == SIZE_DWORD){ inst_to_emit |= 1 << 31; inst_to_emit |= 1 << 22; } inst_to_emit |= regD.code & 0b11111; inst_to_emit |= (regN.code & 0b11111) << 5; if (val1 != null) inst_to_emit |= (val1.value() & 0b111111) << 10; if (val2 != null) inst_to_emit |= (val2.value() & 0b111111) << 16; inst_to_emit |= id.opcode; _emitInt32(inst_to_emit); } else throw new IllegalArgumentException("illegal arguments"); break; } case branch_imm: { int inst_to_emit = 0; if (o1 != _none){ Immediate mem = (Immediate) o1; /*