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.lir.amd64; 24 25 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE; 26 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT; 27 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; 28 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; 29 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.UNINITIALIZED; 30 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant; 31 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant; 32 import static java.lang.Double.doubleToRawLongBits; 33 import static java.lang.Float.floatToRawIntBits; 34 import static jdk.vm.ci.code.ValueUtil.asRegister; 35 import static jdk.vm.ci.code.ValueUtil.isRegister; 36 import static jdk.vm.ci.code.ValueUtil.isStackSlot; 37 38 import org.graalvm.compiler.core.common.NumUtil; 39 import org.graalvm.compiler.asm.amd64.AMD64Address; 40 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; 41 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp; 42 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; 43 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; 44 import org.graalvm.compiler.core.common.type.DataPointerConstant; 45 import org.graalvm.compiler.debug.GraalError; 46 import org.graalvm.compiler.lir.LIRFrameState; 47 import org.graalvm.compiler.lir.LIRInstructionClass; 48 import org.graalvm.compiler.lir.Opcode; 49 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp; 50 import org.graalvm.compiler.lir.StandardOp.NullCheck; 51 import org.graalvm.compiler.lir.StandardOp.ValueMoveOp; 52 import org.graalvm.compiler.lir.VirtualStackSlot; 53 import org.graalvm.compiler.lir.asm.CompilationResultBuilder; 54 55 import jdk.vm.ci.amd64.AMD64; 56 import jdk.vm.ci.amd64.AMD64Kind; 57 import jdk.vm.ci.code.Register; 58 import jdk.vm.ci.code.StackSlot; 59 import jdk.vm.ci.meta.AllocatableValue; 60 import jdk.vm.ci.meta.Constant; 61 import jdk.vm.ci.meta.JavaConstant; 62 import jdk.vm.ci.meta.Value; 63 721 switch ((AMD64Kind) result.getPlatformKind()) { 722 case BYTE: 723 assert NumUtil.isByte(imm) : "Is not in byte range: " + imm; 724 AMD64MIOp.MOVB.emit(masm, OperandSize.BYTE, dest, (int) imm); 725 break; 726 case WORD: 727 assert NumUtil.isShort(imm) : "Is not in short range: " + imm; 728 AMD64MIOp.MOV.emit(masm, OperandSize.WORD, dest, (int) imm); 729 break; 730 case DWORD: 731 case SINGLE: 732 assert NumUtil.isInt(imm) : "Is not in int range: " + imm; 733 masm.movl(dest, (int) imm); 734 break; 735 case QWORD: 736 case DOUBLE: 737 masm.movlong(dest, imm); 738 break; 739 default: 740 throw GraalError.shouldNotReachHere("Unknown result Kind: " + result.getPlatformKind()); 741 } 742 } 743 } | 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.lir.amd64; 24 25 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag.Equal; 26 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; 27 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE; 28 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT; 29 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL; 30 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; 31 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; 32 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.UNINITIALIZED; 33 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant; 34 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant; 35 import static java.lang.Double.doubleToRawLongBits; 36 import static java.lang.Float.floatToRawIntBits; 37 import static jdk.vm.ci.code.ValueUtil.asRegister; 38 import static jdk.vm.ci.code.ValueUtil.isRegister; 39 import static jdk.vm.ci.code.ValueUtil.isStackSlot; 40 41 import org.graalvm.compiler.asm.Label; 42 import org.graalvm.compiler.core.common.CompressEncoding; 43 import org.graalvm.compiler.core.common.LIRKind; 44 import org.graalvm.compiler.core.common.NumUtil; 45 import org.graalvm.compiler.asm.amd64.AMD64Address; 46 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; 47 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp; 48 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; 49 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; 50 import org.graalvm.compiler.core.common.spi.LIRKindTool; 51 import org.graalvm.compiler.core.common.type.DataPointerConstant; 52 import org.graalvm.compiler.debug.GraalError; 53 import org.graalvm.compiler.lir.LIRFrameState; 54 import org.graalvm.compiler.lir.LIRInstructionClass; 55 import org.graalvm.compiler.lir.Opcode; 56 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp; 57 import org.graalvm.compiler.lir.StandardOp.NullCheck; 58 import org.graalvm.compiler.lir.StandardOp.ValueMoveOp; 59 import org.graalvm.compiler.lir.VirtualStackSlot; 60 import org.graalvm.compiler.lir.asm.CompilationResultBuilder; 61 62 import jdk.vm.ci.amd64.AMD64; 63 import jdk.vm.ci.amd64.AMD64Kind; 64 import jdk.vm.ci.code.Register; 65 import jdk.vm.ci.code.StackSlot; 66 import jdk.vm.ci.meta.AllocatableValue; 67 import jdk.vm.ci.meta.Constant; 68 import jdk.vm.ci.meta.JavaConstant; 69 import jdk.vm.ci.meta.Value; 70 728 switch ((AMD64Kind) result.getPlatformKind()) { 729 case BYTE: 730 assert NumUtil.isByte(imm) : "Is not in byte range: " + imm; 731 AMD64MIOp.MOVB.emit(masm, OperandSize.BYTE, dest, (int) imm); 732 break; 733 case WORD: 734 assert NumUtil.isShort(imm) : "Is not in short range: " + imm; 735 AMD64MIOp.MOV.emit(masm, OperandSize.WORD, dest, (int) imm); 736 break; 737 case DWORD: 738 case SINGLE: 739 assert NumUtil.isInt(imm) : "Is not in int range: " + imm; 740 masm.movl(dest, (int) imm); 741 break; 742 case QWORD: 743 case DOUBLE: 744 masm.movlong(dest, imm); 745 break; 746 default: 747 throw GraalError.shouldNotReachHere("Unknown result Kind: " + result.getPlatformKind()); 748 } 749 } 750 751 public abstract static class Pointer extends AMD64LIRInstruction { 752 protected final LIRKindTool lirKindTool; 753 protected final CompressEncoding encoding; 754 protected final boolean nonNull; 755 756 @Def({REG, HINT}) private AllocatableValue result; 757 @Use({REG}) private AllocatableValue input; 758 @Alive({REG, ILLEGAL}) private AllocatableValue baseRegister; 759 760 protected Pointer(LIRInstructionClass<? extends Pointer> type, AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, 761 LIRKindTool lirKindTool) { 762 super(type); 763 this.result = result; 764 this.input = input; 765 this.baseRegister = baseRegister; 766 this.encoding = encoding; 767 this.nonNull = nonNull; 768 this.lirKindTool = lirKindTool; 769 } 770 771 protected boolean hasBase(CompilationResultBuilder crb) { 772 return GeneratePIC.getValue(crb.getOptions()) || encoding.hasBase(); 773 } 774 775 protected final Register getResultRegister() { 776 return asRegister(result); 777 } 778 779 protected final Register getBaseRegister() { 780 return asRegister(baseRegister); 781 } 782 783 protected final int getShift() { 784 return encoding.getShift(); 785 } 786 787 protected final void move(LIRKind kind, CompilationResultBuilder crb, AMD64MacroAssembler masm) { 788 AMD64Move.move((AMD64Kind) kind.getPlatformKind(), crb, masm, result, input); 789 } 790 } 791 792 public static final class CompressPointer extends Pointer { 793 public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class); 794 795 public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) { 796 super(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool); 797 } 798 799 @Override 800 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { 801 move(lirKindTool.getObjectKind(), crb, masm); 802 803 Register resReg = getResultRegister(); 804 if (hasBase(crb)) { 805 Register baseReg = getBaseRegister(); 806 if (!nonNull) { 807 masm.testq(resReg, resReg); 808 masm.cmovq(Equal, resReg, baseReg); 809 } 810 masm.subq(resReg, baseReg); 811 } 812 813 int shift = getShift(); 814 if (shift != 0) { 815 masm.shrq(resReg, shift); 816 } 817 } 818 } 819 820 public static final class UncompressPointer extends Pointer { 821 public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class); 822 823 public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) { 824 super(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool); 825 } 826 827 @Override 828 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { 829 move(lirKindTool.getNarrowOopKind(), crb, masm); 830 831 Register resReg = getResultRegister(); 832 int shift = getShift(); 833 if (shift != 0) { 834 masm.shlq(resReg, shift); 835 } 836 837 if (hasBase(crb)) { 838 Register baseReg = getBaseRegister(); 839 if (nonNull) { 840 masm.addq(resReg, baseReg); 841 return; 842 } 843 844 if (shift == 0) { 845 // if encoding.shift != 0, the flags are already set by the shlq 846 masm.testq(resReg, resReg); 847 } 848 849 Label done = new Label(); 850 masm.jccb(Equal, done); 851 masm.addq(resReg, baseReg); 852 masm.bind(done); 853 } 854 } 855 } 856 } |