1 /*
2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
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.
|
1 /*
2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2018, Red Hat Inc. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24 package org.graalvm.compiler.asm.aarch64;
25
26 import static jdk.vm.ci.aarch64.AArch64.cpuRegisters;
27 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADD;
28 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADDS;
29 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADR;
30 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ADRP;
31 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.AND;
32 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ANDS;
33 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ASRV;
34 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BFM;
35 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BIC;
36 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BICS;
37 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BLR;
38 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BR;
39 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BRK;
40 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLREX;
41 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLS;
42 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLZ;
43 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSEL;
44 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSINC;
45 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSNEG;
46 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.DMB;
47 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EON;
48 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EOR;
49 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EXTR;
50 import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.FABS;
1301 *
1302 * @param rs general purpose register into which the exclusive access status is written. May not
1303 * be null.
1304 * @param rt general purpose register containing data to be written to memory at address. May
1305 * not be null
1306 * @param rn general purpose register containing the address specifying where rt is written to.
1307 * @param log2TransferSize log2Ceil of memory transfer size.
1308 */
1309 private void exclusiveStoreInstruction(Instruction instr, Register rs, Register rt, Register rn, int log2TransferSize) {
1310 assert log2TransferSize >= 0 && log2TransferSize < 4;
1311 assert rt.getRegisterCategory().equals(CPU) && rs.getRegisterCategory().equals(CPU) && !rs.equals(rt);
1312 int transferSizeEncoding = log2TransferSize << LoadStoreTransferSizeOffset;
1313 emitInt(transferSizeEncoding | instr.encoding | rs2(rs) | rn(rn) | rt(rt));
1314 }
1315
1316 /* PC-relative Address Calculation (5.4.4) */
1317
1318 /**
1319 * Address of page: sign extends 21-bit offset, shifts if left by 12 and adds it to the value of
1320 * the PC with its bottom 12-bits cleared, writing the result to dst.
1321 * No offset is emiited; the instruction will be patched later.
1322 *
1323 * @param dst general purpose register. May not be null, zero-register or stackpointer.
1324 */
1325 public void adrp(Register dst) {
1326 emitInt(ADRP.encoding | PcRelImmOp | rd(dst) );
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 public void adrp(Register dst, int pageOffset) {
1344 emitInt(ADRP.encoding | PcRelImmOp | rd(dst) | getPcRelativeImmEncoding(pageOffset));
1345 }
1346
1347 private static int getPcRelativeImmEncoding(int imm21) {
1348 assert NumUtil.isSignedNbit(21, imm21);
1349 int imm = imm21 & NumUtil.getNbitNumberInt(21);
1350 // higher 19 bit
1351 int immHi = (imm >> 2) << PcRelImmHiOffset;
1352 // lower 2 bit
1353 int immLo = (imm & 0x3) << PcRelImmLoOffset;
1354 return immHi | immLo;
1355 }
1356
1357 /* Arithmetic (Immediate) (5.4.1) */
1358
1359 /**
1360 * dst = src + aimm.
1361 *
1362 * @param size register size. Has to be 32 or 64.
1363 * @param dst general purpose register. May not be null or zero-register.
1364 * @param src general purpose register. May not be null or zero-register.
|