1 /* |
1 /* |
2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
48 import jdk.vm.ci.meta.AllocatableValue; |
48 import jdk.vm.ci.meta.AllocatableValue; |
49 import jdk.vm.ci.meta.Value; |
49 import jdk.vm.ci.meta.Value; |
50 |
50 |
51 public class AMD64VectorUnary { |
51 public class AMD64VectorUnary { |
52 |
52 |
53 public static final class AVXUnaryOp extends AMD64LIRInstruction { |
53 public static final class AVXUnaryOp extends AMD64VectorInstruction { |
54 public static final LIRInstructionClass<AVXUnaryOp> TYPE = LIRInstructionClass.create(AVXUnaryOp.class); |
54 public static final LIRInstructionClass<AVXUnaryOp> TYPE = LIRInstructionClass.create(AVXUnaryOp.class); |
55 |
55 |
56 @Opcode private final VexRMOp opcode; |
56 @Opcode private final VexRMOp opcode; |
57 private final AVXKind.AVXSize size; |
|
58 |
57 |
59 @Def({REG}) protected AllocatableValue result; |
58 @Def({REG}) protected AllocatableValue result; |
60 @Use({REG, STACK}) protected AllocatableValue input; |
59 @Use({REG, STACK}) protected AllocatableValue input; |
61 |
60 |
62 public AVXUnaryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue input) { |
61 public AVXUnaryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue input) { |
63 super(TYPE); |
62 super(TYPE, size); |
64 this.opcode = opcode; |
63 this.opcode = opcode; |
65 this.size = size; |
|
66 this.result = result; |
64 this.result = result; |
67 this.input = input; |
65 this.input = input; |
68 } |
66 } |
69 |
67 |
70 @Override |
68 @Override |
75 opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); |
73 opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); |
76 } |
74 } |
77 } |
75 } |
78 } |
76 } |
79 |
77 |
80 public static final class AVXUnaryMemoryOp extends AMD64LIRInstruction { |
78 public static final class AVXUnaryMemoryOp extends AMD64VectorInstruction { |
81 public static final LIRInstructionClass<AVXUnaryMemoryOp> TYPE = LIRInstructionClass.create(AVXUnaryMemoryOp.class); |
79 public static final LIRInstructionClass<AVXUnaryMemoryOp> TYPE = LIRInstructionClass.create(AVXUnaryMemoryOp.class); |
82 |
80 |
83 @Opcode private final VexRMOp opcode; |
81 @Opcode private final VexRMOp opcode; |
84 private final AVXKind.AVXSize size; |
|
85 |
82 |
86 @Def({REG}) protected AllocatableValue result; |
83 @Def({REG}) protected AllocatableValue result; |
87 @Use({COMPOSITE}) protected AMD64AddressValue input; |
84 @Use({COMPOSITE}) protected AMD64AddressValue input; |
88 @State protected LIRFrameState state; |
85 @State protected LIRFrameState state; |
89 |
86 |
90 public AVXUnaryMemoryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) { |
87 public AVXUnaryMemoryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) { |
91 super(TYPE); |
88 super(TYPE, size); |
92 this.opcode = opcode; |
89 this.opcode = opcode; |
93 this.size = size; |
|
94 this.result = result; |
90 this.result = result; |
95 this.input = input; |
91 this.input = input; |
96 this.state = state; |
92 this.state = state; |
97 } |
93 } |
98 |
94 |
103 } |
99 } |
104 opcode.emit(masm, size, asRegister(result), input.toAddress()); |
100 opcode.emit(masm, size, asRegister(result), input.toAddress()); |
105 } |
101 } |
106 } |
102 } |
107 |
103 |
108 public static final class AVXBroadcastOp extends AMD64LIRInstruction { |
104 public static final class AVXBroadcastOp extends AMD64VectorInstruction { |
109 public static final LIRInstructionClass<AVXBroadcastOp> TYPE = LIRInstructionClass.create(AVXBroadcastOp.class); |
105 public static final LIRInstructionClass<AVXBroadcastOp> TYPE = LIRInstructionClass.create(AVXBroadcastOp.class); |
110 |
106 |
111 @Opcode private final VexRMOp opcode; |
107 @Opcode private final VexRMOp opcode; |
112 private final AVXKind.AVXSize size; |
|
113 |
108 |
114 @Def({REG}) protected AllocatableValue result; |
109 @Def({REG}) protected AllocatableValue result; |
115 @Use({REG, STACK, CONST}) protected Value input; |
110 @Use({REG, STACK, CONST}) protected Value input; |
116 |
111 |
117 public AVXBroadcastOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, Value input) { |
112 public AVXBroadcastOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, Value input) { |
118 super(TYPE); |
113 super(TYPE, size); |
119 this.opcode = opcode; |
114 this.opcode = opcode; |
120 this.size = size; |
|
121 this.result = result; |
115 this.result = result; |
122 this.input = input; |
116 this.input = input; |
123 } |
117 } |
124 |
118 |
125 @Override |
119 @Override |
134 opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); |
128 opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); |
135 } |
129 } |
136 } |
130 } |
137 } |
131 } |
138 |
132 |
139 public static final class AVXConvertMemoryOp extends AMD64LIRInstruction { |
133 public static final class AVXConvertMemoryOp extends AMD64VectorInstruction { |
140 public static final LIRInstructionClass<AVXConvertMemoryOp> TYPE = LIRInstructionClass.create(AVXConvertMemoryOp.class); |
134 public static final LIRInstructionClass<AVXConvertMemoryOp> TYPE = LIRInstructionClass.create(AVXConvertMemoryOp.class); |
141 |
135 |
142 @Opcode private final VexRVMOp opcode; |
136 @Opcode private final VexRVMOp opcode; |
143 private final AVXKind.AVXSize size; |
|
144 |
137 |
145 @Def({REG}) protected AllocatableValue result; |
138 @Def({REG}) protected AllocatableValue result; |
146 @Use({COMPOSITE}) protected AMD64AddressValue input; |
139 @Use({COMPOSITE}) protected AMD64AddressValue input; |
147 @State protected LIRFrameState state; |
140 @State protected LIRFrameState state; |
148 |
141 |
149 public AVXConvertMemoryOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) { |
142 public AVXConvertMemoryOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) { |
150 super(TYPE); |
143 super(TYPE, size); |
151 this.opcode = opcode; |
144 this.opcode = opcode; |
152 this.size = size; |
|
153 this.result = result; |
145 this.result = result; |
154 this.input = input; |
146 this.input = input; |
155 this.state = state; |
147 this.state = state; |
156 } |
148 } |
157 |
149 |
178 this.input = input; |
170 this.input = input; |
179 } |
171 } |
180 |
172 |
181 @Override |
173 @Override |
182 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { |
174 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { |
|
175 // Note that we assume only XMM-size instructions are emitted here. Loosening this |
|
176 // restriction would require informing AMD64HotSpotReturnOp when emitting vzeroupper. |
183 if (isRegister(input)) { |
177 if (isRegister(input)) { |
184 if (!asRegister(input).equals(asRegister(result))) { |
178 if (!asRegister(input).equals(asRegister(result))) { |
185 // clear result register to avoid unnecessary dependency |
179 // clear result register to avoid unnecessary dependency |
186 VexRVMOp.VXORPD.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result)); |
180 VexRVMOp.VXORPD.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result)); |
187 } |
181 } |