9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
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 package org.graalvm.compiler.asm.aarch64;
24
25 import static jdk.vm.ci.aarch64.AArch64.cpuRegisters;
26 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADD;
27 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADDS;
28 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADR;
29 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.AND;
30 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ANDS;
31 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ASRV;
32 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BFM;
33 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BIC;
34 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BICS;
35 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BLR;
36 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BR;
37 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BRK;
38 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLREX;
39 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLS;
40 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLZ;
41 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSEL;
42 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSINC;
43 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSNEG;
44 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.DMB;
45 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EON;
46 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EOR;
47 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EXTR;
48 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.FABS;
1299 *
1300 * @param rs general purpose register into which the exclusive access status is written. May not
1301 * be null.
1302 * @param rt general purpose register containing data to be written to memory at address. May
1303 * not be null
1304 * @param rn general purpose register containing the address specifying where rt is written to.
1305 * @param log2TransferSize log2Ceil of memory transfer size.
1306 */
1307 private void exclusiveStoreInstruction(Instruction instr, Register rs, Register rt, Register rn, int log2TransferSize) {
1308 assert log2TransferSize >= 0 && log2TransferSize < 4;
1309 assert rt.getRegisterCategory().equals(CPU) && rs.getRegisterCategory().equals(CPU) && !rs.equals(rt);
1310 int transferSizeEncoding = log2TransferSize << LoadStoreTransferSizeOffset;
1311 emitInt(transferSizeEncoding | instr.encoding | rs2(rs) | rn(rn) | rt(rt));
1312 }
1313
1314 /* PC-relative Address Calculation (5.4.4) */
1315
1316 /**
1317 * Address of page: sign extends 21-bit offset, shifts if left by 12 and adds it to the value of
1318 * the PC with its bottom 12-bits cleared, writing the result to dst.
1319 *
1320 * @param dst general purpose register. May not be null, zero-register or stackpointer.
1321 * @param imm Signed 33-bit offset with lower 12bits clear.
1322 */
1323 // protected void adrp(Register dst, long imm) {
1324 // assert (imm & NumUtil.getNbitNumberInt(12)) == 0 : "Lower 12-bit of immediate must be zero.";
1325 // assert NumUtil.isSignedNbit(33, imm);
1326 // addressCalculationInstruction(dst, (int) (imm >>> 12), Instruction.ADRP);
1327 // }
1328
1329 /**
1330 * Adds a 21-bit signed offset to the program counter and writes the result to dst.
1331 *
1332 * @param dst general purpose register. May not be null, zero-register or stackpointer.
1333 * @param imm21 Signed 21-bit offset.
1334 */
1335 public void adr(Register dst, int imm21) {
1336 emitInt(ADR.encoding | PcRelImmOp | rd(dst) | getPcRelativeImmEncoding(imm21));
1337 }
1338
1339 public void adr(Register dst, int imm21, int pos) {
1340 emitInt(ADR.encoding | PcRelImmOp | rd(dst) | getPcRelativeImmEncoding(imm21), pos);
1341 }
1342
1343 private static int getPcRelativeImmEncoding(int imm21) {
1344 assert NumUtil.isSignedNbit(21, imm21);
1345 int imm = imm21 & NumUtil.getNbitNumberInt(21);
1346 // higher 19 bit
1347 int immHi = (imm >> 2) << PcRelImmHiOffset;
1348 // lower 2 bit
1349 int immLo = (imm & 0x3) << PcRelImmLoOffset;
1350 return immHi | immLo;
1351 }
1352
1353 /* Arithmetic (Immediate) (5.4.1) */
1354
1355 /**
1356 * dst = src + aimm.
1357 *
1358 * @param size register size. Has to be 32 or 64.
1359 * @param dst general purpose register. May not be null or zero-register.
1360 * @param src general purpose register. May not be null or zero-register.
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
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 package org.graalvm.compiler.asm.aarch64;
24
25 import static jdk.vm.ci.aarch64.AArch64.cpuRegisters;
26 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADD;
27 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADDS;
28 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADR;
29 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADRP;
30 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.AND;
31 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ANDS;
32 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ASRV;
33 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BFM;
34 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BIC;
35 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BICS;
36 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BLR;
37 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BR;
38 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BRK;
39 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLREX;
40 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLS;
41 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLZ;
42 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSEL;
43 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSINC;
44 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSNEG;
45 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.DMB;
46 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EON;
47 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EOR;
48 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EXTR;
49 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.FABS;
1300 *
1301 * @param rs general purpose register into which the exclusive access status is written. May not
1302 * be null.
1303 * @param rt general purpose register containing data to be written to memory at address. May
1304 * not be null
1305 * @param rn general purpose register containing the address specifying where rt is written to.
1306 * @param log2TransferSize log2Ceil of memory transfer size.
1307 */
1308 private void exclusiveStoreInstruction(Instruction instr, Register rs, Register rt, Register rn, int log2TransferSize) {
1309 assert log2TransferSize >= 0 && log2TransferSize < 4;
1310 assert rt.getRegisterCategory().equals(CPU) && rs.getRegisterCategory().equals(CPU) && !rs.equals(rt);
1311 int transferSizeEncoding = log2TransferSize << LoadStoreTransferSizeOffset;
1312 emitInt(transferSizeEncoding | instr.encoding | rs2(rs) | rn(rn) | rt(rt));
1313 }
1314
1315 /* PC-relative Address Calculation (5.4.4) */
1316
1317 /**
1318 * Address of page: sign extends 21-bit offset, shifts if left by 12 and adds it to the value of
1319 * the PC with its bottom 12-bits cleared, writing the result to dst.
1320 * No offset is emiited; the instruction will be patched later.
1321 *
1322 * @param dst general purpose register. May not be null, zero-register or stackpointer.
1323 */
1324 public void adrp(Register dst) {
1325 emitInt(ADRP.encoding | PcRelImmOp | rd(dst) );
1326 }
1327
1328 /**
1329 * Adds a 21-bit signed offset to the program counter and writes the result to dst.
1330 *
1331 * @param dst general purpose register. May not be null, zero-register or stackpointer.
1332 * @param imm21 Signed 21-bit offset.
1333 */
1334 public void adr(Register dst, int imm21) {
1335 emitInt(ADR.encoding | PcRelImmOp | rd(dst) | getPcRelativeImmEncoding(imm21));
1336 }
1337
1338 public void adr(Register dst, int imm21, int pos) {
1339 emitInt(ADR.encoding | PcRelImmOp | rd(dst) | getPcRelativeImmEncoding(imm21), pos);
1340 }
1341
1342 public void adrp(Register dst, int pageOffset) {
1343 emitInt(ADRP.encoding | PcRelImmOp | rd(dst) | getPcRelativeImmEncoding(pageOffset));
1344 }
1345
1346 private static int getPcRelativeImmEncoding(int imm21) {
1347 assert NumUtil.isSignedNbit(21, imm21);
1348 int imm = imm21 & NumUtil.getNbitNumberInt(21);
1349 // higher 19 bit
1350 int immHi = (imm >> 2) << PcRelImmHiOffset;
1351 // lower 2 bit
1352 int immLo = (imm & 0x3) << PcRelImmLoOffset;
1353 return immHi | immLo;
1354 }
1355
1356 /* Arithmetic (Immediate) (5.4.1) */
1357
1358 /**
1359 * dst = src + aimm.
1360 *
1361 * @param size register size. Has to be 32 or 64.
1362 * @param dst general purpose register. May not be null or zero-register.
1363 * @param src general purpose register. May not be null or zero-register.
|