129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); |
129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); |
130 |
130 |
131 |
131 |
132 // Floating Point Registers |
132 // Floating Point Registers |
133 |
133 |
134 // XMM registers. 128-bit registers or 4 words each, labeled (a)-d. |
|
135 // Word a in each register holds a Float, words ab hold a Double. We |
|
136 // currently do not use the SIMD capabilities, so registers cd are |
|
137 // unused at the moment. |
|
138 // XMM8-XMM15 must be encoded with REX. |
|
139 // Linux ABI: No register preserved across function calls |
|
140 // XMM0-XMM7 might hold parameters |
|
141 // Windows ABI: XMM6-XMM15 preserved across function calls |
|
142 // XMM0-XMM3 might hold parameters |
|
143 |
|
144 reg_def XMM0 (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()); |
|
145 reg_def XMM0_H (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()); |
|
146 |
|
147 reg_def XMM1 (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()); |
|
148 reg_def XMM1_H (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()); |
|
149 |
|
150 reg_def XMM2 (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()); |
|
151 reg_def XMM2_H (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()); |
|
152 |
|
153 reg_def XMM3 (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()); |
|
154 reg_def XMM3_H (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()); |
|
155 |
|
156 reg_def XMM4 (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()); |
|
157 reg_def XMM4_H (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()); |
|
158 |
|
159 reg_def XMM5 (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()); |
|
160 reg_def XMM5_H (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()); |
|
161 |
|
162 #ifdef _WIN64 |
|
163 |
|
164 reg_def XMM6 (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()); |
|
165 reg_def XMM6_H (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next()); |
|
166 |
|
167 reg_def XMM7 (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()); |
|
168 reg_def XMM7_H (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next()); |
|
169 |
|
170 reg_def XMM8 (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()); |
|
171 reg_def XMM8_H (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next()); |
|
172 |
|
173 reg_def XMM9 (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()); |
|
174 reg_def XMM9_H (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next()); |
|
175 |
|
176 reg_def XMM10 (SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()); |
|
177 reg_def XMM10_H(SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next()); |
|
178 |
|
179 reg_def XMM11 (SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()); |
|
180 reg_def XMM11_H(SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next()); |
|
181 |
|
182 reg_def XMM12 (SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()); |
|
183 reg_def XMM12_H(SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next()); |
|
184 |
|
185 reg_def XMM13 (SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()); |
|
186 reg_def XMM13_H(SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next()); |
|
187 |
|
188 reg_def XMM14 (SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()); |
|
189 reg_def XMM14_H(SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next()); |
|
190 |
|
191 reg_def XMM15 (SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()); |
|
192 reg_def XMM15_H(SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next()); |
|
193 |
|
194 #else |
|
195 |
|
196 reg_def XMM6 (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()); |
|
197 reg_def XMM6_H (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()); |
|
198 |
|
199 reg_def XMM7 (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()); |
|
200 reg_def XMM7_H (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next()); |
|
201 |
|
202 reg_def XMM8 (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()); |
|
203 reg_def XMM8_H (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next()); |
|
204 |
|
205 reg_def XMM9 (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()); |
|
206 reg_def XMM9_H (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next()); |
|
207 |
|
208 reg_def XMM10 (SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()); |
|
209 reg_def XMM10_H(SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next()); |
|
210 |
|
211 reg_def XMM11 (SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()); |
|
212 reg_def XMM11_H(SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next()); |
|
213 |
|
214 reg_def XMM12 (SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()); |
|
215 reg_def XMM12_H(SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next()); |
|
216 |
|
217 reg_def XMM13 (SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()); |
|
218 reg_def XMM13_H(SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next()); |
|
219 |
|
220 reg_def XMM14 (SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()); |
|
221 reg_def XMM14_H(SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next()); |
|
222 |
|
223 reg_def XMM15 (SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()); |
|
224 reg_def XMM15_H(SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next()); |
|
225 |
|
226 #endif // _WIN64 |
|
227 |
|
228 reg_def RFLAGS(SOC, SOC, 0, 16, VMRegImpl::Bad()); |
|
229 |
|
230 // Specify priority of register selection within phases of register |
134 // Specify priority of register selection within phases of register |
231 // allocation. Highest priority is first. A useful heuristic is to |
135 // allocation. Highest priority is first. A useful heuristic is to |
232 // give registers a low priority when they are required by machine |
136 // give registers a low priority when they are required by machine |
233 // instructions, like EAX and EDX on I486, and choose no-save registers |
137 // instructions, like EAX and EDX on I486, and choose no-save registers |
234 // before save-on-call, & save-on-call before save-on-entry. Registers |
138 // before save-on-call, & save-on-call before save-on-entry. Registers |
1025 |
870 |
1026 assert(r->is_XMMRegister(), "must be"); |
871 assert(r->is_XMMRegister(), "must be"); |
1027 return rc_float; |
872 return rc_float; |
1028 } |
873 } |
1029 |
874 |
|
875 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. |
|
876 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, |
|
877 int src_hi, int dst_hi, uint ireg, outputStream* st); |
|
878 |
|
879 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, |
|
880 int stack_offset, int reg, uint ireg, outputStream* st); |
|
881 |
|
882 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, |
|
883 int dst_offset, uint ireg, outputStream* st) { |
|
884 if (cbuf) { |
|
885 MacroAssembler _masm(cbuf); |
|
886 switch (ireg) { |
|
887 case Op_VecS: |
|
888 __ movq(Address(rsp, -8), rax); |
|
889 __ movl(rax, Address(rsp, src_offset)); |
|
890 __ movl(Address(rsp, dst_offset), rax); |
|
891 __ movq(rax, Address(rsp, -8)); |
|
892 break; |
|
893 case Op_VecD: |
|
894 __ pushq(Address(rsp, src_offset)); |
|
895 __ popq (Address(rsp, dst_offset)); |
|
896 break; |
|
897 case Op_VecX: |
|
898 __ pushq(Address(rsp, src_offset)); |
|
899 __ popq (Address(rsp, dst_offset)); |
|
900 __ pushq(Address(rsp, src_offset+8)); |
|
901 __ popq (Address(rsp, dst_offset+8)); |
|
902 break; |
|
903 case Op_VecY: |
|
904 __ vmovdqu(Address(rsp, -32), xmm0); |
|
905 __ vmovdqu(xmm0, Address(rsp, src_offset)); |
|
906 __ vmovdqu(Address(rsp, dst_offset), xmm0); |
|
907 __ vmovdqu(xmm0, Address(rsp, -32)); |
|
908 break; |
|
909 default: |
|
910 ShouldNotReachHere(); |
|
911 } |
|
912 #ifndef PRODUCT |
|
913 } else { |
|
914 switch (ireg) { |
|
915 case Op_VecS: |
|
916 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" |
|
917 "movl rax, [rsp + #%d]\n\t" |
|
918 "movl [rsp + #%d], rax\n\t" |
|
919 "movq rax, [rsp - #8]", |
|
920 src_offset, dst_offset); |
|
921 break; |
|
922 case Op_VecD: |
|
923 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" |
|
924 "popq [rsp + #%d]", |
|
925 src_offset, dst_offset); |
|
926 break; |
|
927 case Op_VecX: |
|
928 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" |
|
929 "popq [rsp + #%d]\n\t" |
|
930 "pushq [rsp + #%d]\n\t" |
|
931 "popq [rsp + #%d]", |
|
932 src_offset, dst_offset, src_offset+8, dst_offset+8); |
|
933 break; |
|
934 case Op_VecY: |
|
935 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" |
|
936 "vmovdqu xmm0, [rsp + #%d]\n\t" |
|
937 "vmovdqu [rsp + #%d], xmm0\n\t" |
|
938 "vmovdqu xmm0, [rsp - #32]", |
|
939 src_offset, dst_offset); |
|
940 break; |
|
941 default: |
|
942 ShouldNotReachHere(); |
|
943 } |
|
944 #endif |
|
945 } |
|
946 } |
|
947 |
1030 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, |
948 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, |
1031 PhaseRegAlloc* ra_, |
949 PhaseRegAlloc* ra_, |
1032 bool do_size, |
950 bool do_size, |
1033 outputStream* st) const |
951 outputStream* st) const { |
1034 { |
952 assert(cbuf != NULL || st != NULL, "sanity"); |
1035 |
|
1036 // Get registers to move |
953 // Get registers to move |
1037 OptoReg::Name src_second = ra_->get_reg_second(in(1)); |
954 OptoReg::Name src_second = ra_->get_reg_second(in(1)); |
1038 OptoReg::Name src_first = ra_->get_reg_first(in(1)); |
955 OptoReg::Name src_first = ra_->get_reg_first(in(1)); |
1039 OptoReg::Name dst_second = ra_->get_reg_second(this); |
956 OptoReg::Name dst_second = ra_->get_reg_second(this); |
1040 OptoReg::Name dst_first = ra_->get_reg_first(this); |
957 OptoReg::Name dst_first = ra_->get_reg_first(this); |
1048 "must move at least 1 register" ); |
965 "must move at least 1 register" ); |
1049 |
966 |
1050 if (src_first == dst_first && src_second == dst_second) { |
967 if (src_first == dst_first && src_second == dst_second) { |
1051 // Self copy, no move |
968 // Self copy, no move |
1052 return 0; |
969 return 0; |
1053 } else if (src_first_rc == rc_stack) { |
970 } |
|
971 if (bottom_type()->isa_vect() != NULL) { |
|
972 uint ireg = ideal_reg(); |
|
973 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); |
|
974 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity"); |
|
975 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { |
|
976 // mem -> mem |
|
977 int src_offset = ra_->reg2offset(src_first); |
|
978 int dst_offset = ra_->reg2offset(dst_first); |
|
979 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); |
|
980 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { |
|
981 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); |
|
982 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { |
|
983 int stack_offset = ra_->reg2offset(dst_first); |
|
984 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); |
|
985 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { |
|
986 int stack_offset = ra_->reg2offset(src_first); |
|
987 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); |
|
988 } else { |
|
989 ShouldNotReachHere(); |
|
990 } |
|
991 return 0; |
|
992 } |
|
993 if (src_first_rc == rc_stack) { |
1054 // mem -> |
994 // mem -> |
1055 if (dst_first_rc == rc_stack) { |
995 if (dst_first_rc == rc_stack) { |
1056 // mem -> mem |
996 // mem -> mem |
1057 assert(src_second != dst_first, "overlap"); |
997 assert(src_second != dst_first, "overlap"); |
1058 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
998 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1059 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
999 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1060 // 64-bit |
1000 // 64-bit |
1061 int src_offset = ra_->reg2offset(src_first); |
1001 int src_offset = ra_->reg2offset(src_first); |
1062 int dst_offset = ra_->reg2offset(dst_first); |
1002 int dst_offset = ra_->reg2offset(dst_first); |
1063 if (cbuf) { |
1003 if (cbuf) { |
1064 emit_opcode(*cbuf, 0xFF); |
1004 MacroAssembler _masm(cbuf); |
1065 encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false); |
1005 __ pushq(Address(rsp, src_offset)); |
1066 |
1006 __ popq (Address(rsp, dst_offset)); |
1067 emit_opcode(*cbuf, 0x8F); |
|
1068 encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false); |
|
1069 |
|
1070 #ifndef PRODUCT |
1007 #ifndef PRODUCT |
1071 } else if (!do_size) { |
1008 } else { |
1072 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" |
1009 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" |
1073 "popq [rsp + #%d]", |
1010 "popq [rsp + #%d]", |
1074 src_offset, |
1011 src_offset, dst_offset); |
1075 dst_offset); |
|
1076 #endif |
1012 #endif |
1077 } |
1013 } |
1078 return |
|
1079 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + |
|
1080 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)); |
|
1081 } else { |
1014 } else { |
1082 // 32-bit |
1015 // 32-bit |
1083 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1016 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1084 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1017 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1085 // No pushl/popl, so: |
1018 // No pushl/popl, so: |
1086 int src_offset = ra_->reg2offset(src_first); |
1019 int src_offset = ra_->reg2offset(src_first); |
1087 int dst_offset = ra_->reg2offset(dst_first); |
1020 int dst_offset = ra_->reg2offset(dst_first); |
1088 if (cbuf) { |
1021 if (cbuf) { |
1089 emit_opcode(*cbuf, Assembler::REX_W); |
1022 MacroAssembler _masm(cbuf); |
1090 emit_opcode(*cbuf, 0x89); |
1023 __ movq(Address(rsp, -8), rax); |
1091 emit_opcode(*cbuf, 0x44); |
1024 __ movl(rax, Address(rsp, src_offset)); |
1092 emit_opcode(*cbuf, 0x24); |
1025 __ movl(Address(rsp, dst_offset), rax); |
1093 emit_opcode(*cbuf, 0xF8); |
1026 __ movq(rax, Address(rsp, -8)); |
1094 |
|
1095 emit_opcode(*cbuf, 0x8B); |
|
1096 encode_RegMem(*cbuf, |
|
1097 RAX_enc, |
|
1098 RSP_enc, 0x4, 0, src_offset, |
|
1099 false); |
|
1100 |
|
1101 emit_opcode(*cbuf, 0x89); |
|
1102 encode_RegMem(*cbuf, |
|
1103 RAX_enc, |
|
1104 RSP_enc, 0x4, 0, dst_offset, |
|
1105 false); |
|
1106 |
|
1107 emit_opcode(*cbuf, Assembler::REX_W); |
|
1108 emit_opcode(*cbuf, 0x8B); |
|
1109 emit_opcode(*cbuf, 0x44); |
|
1110 emit_opcode(*cbuf, 0x24); |
|
1111 emit_opcode(*cbuf, 0xF8); |
|
1112 |
|
1113 #ifndef PRODUCT |
1027 #ifndef PRODUCT |
1114 } else if (!do_size) { |
1028 } else { |
1115 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" |
1029 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" |
1116 "movl rax, [rsp + #%d]\n\t" |
1030 "movl rax, [rsp + #%d]\n\t" |
1117 "movl [rsp + #%d], rax\n\t" |
1031 "movl [rsp + #%d], rax\n\t" |
1118 "movq rax, [rsp - #8]", |
1032 "movq rax, [rsp - #8]", |
1119 src_offset, |
1033 src_offset, dst_offset); |
1120 dst_offset); |
|
1121 #endif |
1034 #endif |
1122 } |
1035 } |
1123 return |
|
1124 5 + // movq |
|
1125 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl |
|
1126 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl |
|
1127 5; // movq |
|
1128 } |
1036 } |
|
1037 return 0; |
1129 } else if (dst_first_rc == rc_int) { |
1038 } else if (dst_first_rc == rc_int) { |
1130 // mem -> gpr |
1039 // mem -> gpr |
1131 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1040 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1132 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1041 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1133 // 64-bit |
1042 // 64-bit |
1134 int offset = ra_->reg2offset(src_first); |
1043 int offset = ra_->reg2offset(src_first); |
1135 if (cbuf) { |
1044 if (cbuf) { |
1136 if (Matcher::_regEncode[dst_first] < 8) { |
1045 MacroAssembler _masm(cbuf); |
1137 emit_opcode(*cbuf, Assembler::REX_W); |
1046 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); |
1138 } else { |
|
1139 emit_opcode(*cbuf, Assembler::REX_WR); |
|
1140 } |
|
1141 emit_opcode(*cbuf, 0x8B); |
|
1142 encode_RegMem(*cbuf, |
|
1143 Matcher::_regEncode[dst_first], |
|
1144 RSP_enc, 0x4, 0, offset, |
|
1145 false); |
|
1146 #ifndef PRODUCT |
1047 #ifndef PRODUCT |
1147 } else if (!do_size) { |
1048 } else { |
1148 st->print("movq %s, [rsp + #%d]\t# spill", |
1049 st->print("movq %s, [rsp + #%d]\t# spill", |
1149 Matcher::regName[dst_first], |
1050 Matcher::regName[dst_first], |
1150 offset); |
1051 offset); |
1151 #endif |
1052 #endif |
1152 } |
1053 } |
1153 return |
|
1154 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX |
|
1155 } else { |
1054 } else { |
1156 // 32-bit |
1055 // 32-bit |
1157 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1056 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1158 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1057 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1159 int offset = ra_->reg2offset(src_first); |
1058 int offset = ra_->reg2offset(src_first); |
1160 if (cbuf) { |
1059 if (cbuf) { |
1161 if (Matcher::_regEncode[dst_first] >= 8) { |
1060 MacroAssembler _masm(cbuf); |
1162 emit_opcode(*cbuf, Assembler::REX_R); |
1061 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); |
1163 } |
|
1164 emit_opcode(*cbuf, 0x8B); |
|
1165 encode_RegMem(*cbuf, |
|
1166 Matcher::_regEncode[dst_first], |
|
1167 RSP_enc, 0x4, 0, offset, |
|
1168 false); |
|
1169 #ifndef PRODUCT |
1062 #ifndef PRODUCT |
1170 } else if (!do_size) { |
1063 } else { |
1171 st->print("movl %s, [rsp + #%d]\t# spill", |
1064 st->print("movl %s, [rsp + #%d]\t# spill", |
1172 Matcher::regName[dst_first], |
1065 Matcher::regName[dst_first], |
1173 offset); |
1066 offset); |
1174 #endif |
1067 #endif |
1175 } |
1068 } |
1176 return |
|
1177 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + |
|
1178 ((Matcher::_regEncode[dst_first] < 8) |
|
1179 ? 3 |
|
1180 : 4); // REX |
|
1181 } |
1069 } |
|
1070 return 0; |
1182 } else if (dst_first_rc == rc_float) { |
1071 } else if (dst_first_rc == rc_float) { |
1183 // mem-> xmm |
1072 // mem-> xmm |
1184 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1073 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1185 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1074 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1186 // 64-bit |
1075 // 64-bit |
1187 int offset = ra_->reg2offset(src_first); |
1076 int offset = ra_->reg2offset(src_first); |
1188 if (cbuf) { |
1077 if (cbuf) { |
1189 MacroAssembler _masm(cbuf); |
1078 MacroAssembler _masm(cbuf); |
1190 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); |
1079 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); |
1191 #ifndef PRODUCT |
1080 #ifndef PRODUCT |
1192 } else if (!do_size) { |
1081 } else { |
1193 st->print("%s %s, [rsp + #%d]\t# spill", |
1082 st->print("%s %s, [rsp + #%d]\t# spill", |
1194 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", |
1083 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", |
1195 Matcher::regName[dst_first], |
1084 Matcher::regName[dst_first], |
1196 offset); |
1085 offset); |
1197 #endif |
1086 #endif |
1198 } |
1087 } |
1199 return |
|
1200 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + |
|
1201 ((Matcher::_regEncode[dst_first] >= 8) |
|
1202 ? 6 |
|
1203 : (5 + ((UseAVX>0)?1:0))); // REX |
|
1204 } else { |
1088 } else { |
1205 // 32-bit |
1089 // 32-bit |
1206 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1090 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1207 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1091 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1208 int offset = ra_->reg2offset(src_first); |
1092 int offset = ra_->reg2offset(src_first); |
1209 if (cbuf) { |
1093 if (cbuf) { |
1210 MacroAssembler _masm(cbuf); |
1094 MacroAssembler _masm(cbuf); |
1211 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); |
1095 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); |
1212 #ifndef PRODUCT |
1096 #ifndef PRODUCT |
1213 } else if (!do_size) { |
1097 } else { |
1214 st->print("movss %s, [rsp + #%d]\t# spill", |
1098 st->print("movss %s, [rsp + #%d]\t# spill", |
1215 Matcher::regName[dst_first], |
1099 Matcher::regName[dst_first], |
1216 offset); |
1100 offset); |
1217 #endif |
1101 #endif |
1218 } |
1102 } |
1219 return |
|
1220 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + |
|
1221 ((Matcher::_regEncode[dst_first] >= 8) |
|
1222 ? 6 |
|
1223 : (5 + ((UseAVX>0)?1:0))); // REX |
|
1224 } |
1103 } |
|
1104 return 0; |
1225 } |
1105 } |
1226 } else if (src_first_rc == rc_int) { |
1106 } else if (src_first_rc == rc_int) { |
1227 // gpr -> |
1107 // gpr -> |
1228 if (dst_first_rc == rc_stack) { |
1108 if (dst_first_rc == rc_stack) { |
1229 // gpr -> mem |
1109 // gpr -> mem |
1230 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1110 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1231 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1111 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1232 // 64-bit |
1112 // 64-bit |
1233 int offset = ra_->reg2offset(dst_first); |
1113 int offset = ra_->reg2offset(dst_first); |
1234 if (cbuf) { |
1114 if (cbuf) { |
1235 if (Matcher::_regEncode[src_first] < 8) { |
1115 MacroAssembler _masm(cbuf); |
1236 emit_opcode(*cbuf, Assembler::REX_W); |
1116 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); |
1237 } else { |
|
1238 emit_opcode(*cbuf, Assembler::REX_WR); |
|
1239 } |
|
1240 emit_opcode(*cbuf, 0x89); |
|
1241 encode_RegMem(*cbuf, |
|
1242 Matcher::_regEncode[src_first], |
|
1243 RSP_enc, 0x4, 0, offset, |
|
1244 false); |
|
1245 #ifndef PRODUCT |
1117 #ifndef PRODUCT |
1246 } else if (!do_size) { |
1118 } else { |
1247 st->print("movq [rsp + #%d], %s\t# spill", |
1119 st->print("movq [rsp + #%d], %s\t# spill", |
1248 offset, |
1120 offset, |
1249 Matcher::regName[src_first]); |
1121 Matcher::regName[src_first]); |
1250 #endif |
1122 #endif |
1251 } |
1123 } |
1252 return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX |
|
1253 } else { |
1124 } else { |
1254 // 32-bit |
1125 // 32-bit |
1255 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1126 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1256 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1127 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1257 int offset = ra_->reg2offset(dst_first); |
1128 int offset = ra_->reg2offset(dst_first); |
1258 if (cbuf) { |
1129 if (cbuf) { |
1259 if (Matcher::_regEncode[src_first] >= 8) { |
1130 MacroAssembler _masm(cbuf); |
1260 emit_opcode(*cbuf, Assembler::REX_R); |
1131 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); |
1261 } |
|
1262 emit_opcode(*cbuf, 0x89); |
|
1263 encode_RegMem(*cbuf, |
|
1264 Matcher::_regEncode[src_first], |
|
1265 RSP_enc, 0x4, 0, offset, |
|
1266 false); |
|
1267 #ifndef PRODUCT |
1132 #ifndef PRODUCT |
1268 } else if (!do_size) { |
1133 } else { |
1269 st->print("movl [rsp + #%d], %s\t# spill", |
1134 st->print("movl [rsp + #%d], %s\t# spill", |
1270 offset, |
1135 offset, |
1271 Matcher::regName[src_first]); |
1136 Matcher::regName[src_first]); |
1272 #endif |
1137 #endif |
1273 } |
1138 } |
1274 return |
|
1275 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + |
|
1276 ((Matcher::_regEncode[src_first] < 8) |
|
1277 ? 3 |
|
1278 : 4); // REX |
|
1279 } |
1139 } |
|
1140 return 0; |
1280 } else if (dst_first_rc == rc_int) { |
1141 } else if (dst_first_rc == rc_int) { |
1281 // gpr -> gpr |
1142 // gpr -> gpr |
1282 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1143 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1283 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1144 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1284 // 64-bit |
1145 // 64-bit |
1285 if (cbuf) { |
1146 if (cbuf) { |
1286 if (Matcher::_regEncode[dst_first] < 8) { |
1147 MacroAssembler _masm(cbuf); |
1287 if (Matcher::_regEncode[src_first] < 8) { |
1148 __ movq(as_Register(Matcher::_regEncode[dst_first]), |
1288 emit_opcode(*cbuf, Assembler::REX_W); |
1149 as_Register(Matcher::_regEncode[src_first])); |
1289 } else { |
|
1290 emit_opcode(*cbuf, Assembler::REX_WB); |
|
1291 } |
|
1292 } else { |
|
1293 if (Matcher::_regEncode[src_first] < 8) { |
|
1294 emit_opcode(*cbuf, Assembler::REX_WR); |
|
1295 } else { |
|
1296 emit_opcode(*cbuf, Assembler::REX_WRB); |
|
1297 } |
|
1298 } |
|
1299 emit_opcode(*cbuf, 0x8B); |
|
1300 emit_rm(*cbuf, 0x3, |
|
1301 Matcher::_regEncode[dst_first] & 7, |
|
1302 Matcher::_regEncode[src_first] & 7); |
|
1303 #ifndef PRODUCT |
1150 #ifndef PRODUCT |
1304 } else if (!do_size) { |
1151 } else { |
1305 st->print("movq %s, %s\t# spill", |
1152 st->print("movq %s, %s\t# spill", |
1306 Matcher::regName[dst_first], |
1153 Matcher::regName[dst_first], |
1307 Matcher::regName[src_first]); |
1154 Matcher::regName[src_first]); |
1308 #endif |
1155 #endif |
1309 } |
1156 } |
1310 return 3; // REX |
1157 return 0; |
1311 } else { |
1158 } else { |
1312 // 32-bit |
1159 // 32-bit |
1313 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1160 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1314 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1161 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1315 if (cbuf) { |
1162 if (cbuf) { |
1316 if (Matcher::_regEncode[dst_first] < 8) { |
1163 MacroAssembler _masm(cbuf); |
1317 if (Matcher::_regEncode[src_first] >= 8) { |
1164 __ movl(as_Register(Matcher::_regEncode[dst_first]), |
1318 emit_opcode(*cbuf, Assembler::REX_B); |
1165 as_Register(Matcher::_regEncode[src_first])); |
1319 } |
|
1320 } else { |
|
1321 if (Matcher::_regEncode[src_first] < 8) { |
|
1322 emit_opcode(*cbuf, Assembler::REX_R); |
|
1323 } else { |
|
1324 emit_opcode(*cbuf, Assembler::REX_RB); |
|
1325 } |
|
1326 } |
|
1327 emit_opcode(*cbuf, 0x8B); |
|
1328 emit_rm(*cbuf, 0x3, |
|
1329 Matcher::_regEncode[dst_first] & 7, |
|
1330 Matcher::_regEncode[src_first] & 7); |
|
1331 #ifndef PRODUCT |
1166 #ifndef PRODUCT |
1332 } else if (!do_size) { |
1167 } else { |
1333 st->print("movl %s, %s\t# spill", |
1168 st->print("movl %s, %s\t# spill", |
1334 Matcher::regName[dst_first], |
1169 Matcher::regName[dst_first], |
1335 Matcher::regName[src_first]); |
1170 Matcher::regName[src_first]); |
1336 #endif |
1171 #endif |
1337 } |
1172 } |
1338 return |
1173 return 0; |
1339 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) |
|
1340 ? 2 |
|
1341 : 3; // REX |
|
1342 } |
1174 } |
1343 } else if (dst_first_rc == rc_float) { |
1175 } else if (dst_first_rc == rc_float) { |
1344 // gpr -> xmm |
1176 // gpr -> xmm |
1345 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1177 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1346 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1178 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1347 // 64-bit |
1179 // 64-bit |
1348 if (cbuf) { |
1180 if (cbuf) { |
1349 MacroAssembler _masm(cbuf); |
1181 MacroAssembler _masm(cbuf); |
1350 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); |
1182 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); |
1351 #ifndef PRODUCT |
1183 #ifndef PRODUCT |
1352 } else if (!do_size) { |
1184 } else { |
1353 st->print("movdq %s, %s\t# spill", |
1185 st->print("movdq %s, %s\t# spill", |
1354 Matcher::regName[dst_first], |
1186 Matcher::regName[dst_first], |
1355 Matcher::regName[src_first]); |
1187 Matcher::regName[src_first]); |
1356 #endif |
1188 #endif |
1357 } |
1189 } |
1358 return 5; // REX |
|
1359 } else { |
1190 } else { |
1360 // 32-bit |
1191 // 32-bit |
1361 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1192 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1362 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1193 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1363 if (cbuf) { |
1194 if (cbuf) { |
1364 MacroAssembler _masm(cbuf); |
1195 MacroAssembler _masm(cbuf); |
1365 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); |
1196 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); |
1366 #ifndef PRODUCT |
1197 #ifndef PRODUCT |
1367 } else if (!do_size) { |
1198 } else { |
1368 st->print("movdl %s, %s\t# spill", |
1199 st->print("movdl %s, %s\t# spill", |
1369 Matcher::regName[dst_first], |
1200 Matcher::regName[dst_first], |
1370 Matcher::regName[src_first]); |
1201 Matcher::regName[src_first]); |
1371 #endif |
1202 #endif |
1372 } |
1203 } |
1373 return |
|
1374 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) |
|
1375 ? 5 |
|
1376 : (4 + ((UseAVX>0)?1:0)); // REX |
|
1377 } |
1204 } |
|
1205 return 0; |
1378 } |
1206 } |
1379 } else if (src_first_rc == rc_float) { |
1207 } else if (src_first_rc == rc_float) { |
1380 // xmm -> |
1208 // xmm -> |
1381 if (dst_first_rc == rc_stack) { |
1209 if (dst_first_rc == rc_stack) { |
1382 // xmm -> mem |
1210 // xmm -> mem |
1386 int offset = ra_->reg2offset(dst_first); |
1214 int offset = ra_->reg2offset(dst_first); |
1387 if (cbuf) { |
1215 if (cbuf) { |
1388 MacroAssembler _masm(cbuf); |
1216 MacroAssembler _masm(cbuf); |
1389 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); |
1217 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); |
1390 #ifndef PRODUCT |
1218 #ifndef PRODUCT |
1391 } else if (!do_size) { |
1219 } else { |
1392 st->print("movsd [rsp + #%d], %s\t# spill", |
1220 st->print("movsd [rsp + #%d], %s\t# spill", |
1393 offset, |
1221 offset, |
1394 Matcher::regName[src_first]); |
1222 Matcher::regName[src_first]); |
1395 #endif |
1223 #endif |
1396 } |
1224 } |
1397 return |
|
1398 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + |
|
1399 ((Matcher::_regEncode[src_first] >= 8) |
|
1400 ? 6 |
|
1401 : (5 + ((UseAVX>0)?1:0))); // REX |
|
1402 } else { |
1225 } else { |
1403 // 32-bit |
1226 // 32-bit |
1404 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1227 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1405 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1228 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1406 int offset = ra_->reg2offset(dst_first); |
1229 int offset = ra_->reg2offset(dst_first); |
1407 if (cbuf) { |
1230 if (cbuf) { |
1408 MacroAssembler _masm(cbuf); |
1231 MacroAssembler _masm(cbuf); |
1409 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); |
1232 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); |
1410 #ifndef PRODUCT |
1233 #ifndef PRODUCT |
1411 } else if (!do_size) { |
1234 } else { |
1412 st->print("movss [rsp + #%d], %s\t# spill", |
1235 st->print("movss [rsp + #%d], %s\t# spill", |
1413 offset, |
1236 offset, |
1414 Matcher::regName[src_first]); |
1237 Matcher::regName[src_first]); |
1415 #endif |
1238 #endif |
1416 } |
1239 } |
1417 return |
|
1418 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + |
|
1419 ((Matcher::_regEncode[src_first] >=8) |
|
1420 ? 6 |
|
1421 : (5 + ((UseAVX>0)?1:0))); // REX |
|
1422 } |
1240 } |
|
1241 return 0; |
1423 } else if (dst_first_rc == rc_int) { |
1242 } else if (dst_first_rc == rc_int) { |
1424 // xmm -> gpr |
1243 // xmm -> gpr |
1425 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1244 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1426 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1245 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1427 // 64-bit |
1246 // 64-bit |
1428 if (cbuf) { |
1247 if (cbuf) { |
1429 MacroAssembler _masm(cbuf); |
1248 MacroAssembler _masm(cbuf); |
1430 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); |
1249 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); |
1431 #ifndef PRODUCT |
1250 #ifndef PRODUCT |
1432 } else if (!do_size) { |
1251 } else { |
1433 st->print("movdq %s, %s\t# spill", |
1252 st->print("movdq %s, %s\t# spill", |
1434 Matcher::regName[dst_first], |
1253 Matcher::regName[dst_first], |
1435 Matcher::regName[src_first]); |
1254 Matcher::regName[src_first]); |
1436 #endif |
1255 #endif |
1437 } |
1256 } |
1438 return 5; // REX |
|
1439 } else { |
1257 } else { |
1440 // 32-bit |
1258 // 32-bit |
1441 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1259 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1442 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1260 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1443 if (cbuf) { |
1261 if (cbuf) { |
1444 MacroAssembler _masm(cbuf); |
1262 MacroAssembler _masm(cbuf); |
1445 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); |
1263 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); |
1446 #ifndef PRODUCT |
1264 #ifndef PRODUCT |
1447 } else if (!do_size) { |
1265 } else { |
1448 st->print("movdl %s, %s\t# spill", |
1266 st->print("movdl %s, %s\t# spill", |
1449 Matcher::regName[dst_first], |
1267 Matcher::regName[dst_first], |
1450 Matcher::regName[src_first]); |
1268 Matcher::regName[src_first]); |
1451 #endif |
1269 #endif |
1452 } |
1270 } |
1453 return |
|
1454 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) |
|
1455 ? 5 |
|
1456 : (4 + ((UseAVX>0)?1:0)); // REX |
|
1457 } |
1271 } |
|
1272 return 0; |
1458 } else if (dst_first_rc == rc_float) { |
1273 } else if (dst_first_rc == rc_float) { |
1459 // xmm -> xmm |
1274 // xmm -> xmm |
1460 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1275 if ((src_first & 1) == 0 && src_first + 1 == src_second && |
1461 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1276 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { |
1462 // 64-bit |
1277 // 64-bit |
1463 if (cbuf) { |
1278 if (cbuf) { |
1464 MacroAssembler _masm(cbuf); |
1279 MacroAssembler _masm(cbuf); |
1465 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); |
1280 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); |
1466 #ifndef PRODUCT |
1281 #ifndef PRODUCT |
1467 } else if (!do_size) { |
1282 } else { |
1468 st->print("%s %s, %s\t# spill", |
1283 st->print("%s %s, %s\t# spill", |
1469 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", |
1284 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", |
1470 Matcher::regName[dst_first], |
1285 Matcher::regName[dst_first], |
1471 Matcher::regName[src_first]); |
1286 Matcher::regName[src_first]); |
1472 #endif |
1287 #endif |
1473 } |
1288 } |
1474 return |
|
1475 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) |
|
1476 ? 5 |
|
1477 : (4 + ((UseAVX>0)?1:0)); // REX |
|
1478 } else { |
1289 } else { |
1479 // 32-bit |
1290 // 32-bit |
1480 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1291 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); |
1481 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1292 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); |
1482 if (cbuf) { |
1293 if (cbuf) { |
1483 MacroAssembler _masm(cbuf); |
1294 MacroAssembler _masm(cbuf); |
1484 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); |
1295 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); |
1485 #ifndef PRODUCT |
1296 #ifndef PRODUCT |
1486 } else if (!do_size) { |
1297 } else { |
1487 st->print("%s %s, %s\t# spill", |
1298 st->print("%s %s, %s\t# spill", |
1488 UseXmmRegToRegMoveAll ? "movaps" : "movss ", |
1299 UseXmmRegToRegMoveAll ? "movaps" : "movss ", |
1489 Matcher::regName[dst_first], |
1300 Matcher::regName[dst_first], |
1490 Matcher::regName[src_first]); |
1301 Matcher::regName[src_first]); |
1491 #endif |
1302 #endif |
1492 } |
1303 } |
1493 return ((UseAVX>0) ? 5: |
|
1494 ((Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) |
|
1495 ? (UseXmmRegToRegMoveAll ? 4 : 5) |
|
1496 : (UseXmmRegToRegMoveAll ? 3 : 4))); // REX |
|
1497 } |
1304 } |
|
1305 return 0; |
1498 } |
1306 } |
1499 } |
1307 } |
1500 |
1308 |
1501 assert(0," foo "); |
1309 assert(0," foo "); |
1502 Unimplemented(); |
1310 Unimplemented(); |
1503 |
|
1504 return 0; |
1311 return 0; |
1505 } |
1312 } |
1506 |
1313 |
1507 #ifndef PRODUCT |
1314 #ifndef PRODUCT |
1508 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const |
1315 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { |
1509 { |
|
1510 implementation(NULL, ra_, false, st); |
1316 implementation(NULL, ra_, false, st); |
1511 } |
1317 } |
1512 #endif |
1318 #endif |
1513 |
1319 |
1514 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const |
1320 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { |
1515 { |
|
1516 implementation(&cbuf, ra_, false, NULL); |
1321 implementation(&cbuf, ra_, false, NULL); |
1517 } |
1322 } |
1518 |
1323 |
1519 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const |
1324 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { |
1520 { |
1325 return MachNode::size(ra_); |
1521 return implementation(NULL, ra_, true, NULL); |
|
1522 } |
1326 } |
1523 |
1327 |
1524 //============================================================================= |
1328 //============================================================================= |
1525 #ifndef PRODUCT |
1329 #ifndef PRODUCT |
1526 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const |
1330 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const |
10373 format %{ "movd $dst,$src\t# MoveL2D" %} |
10068 format %{ "movd $dst,$src\t# MoveL2D" %} |
10374 ins_encode %{ |
10069 ins_encode %{ |
10375 __ movdq($dst$$XMMRegister, $src$$Register); |
10070 __ movdq($dst$$XMMRegister, $src$$Register); |
10376 %} |
10071 %} |
10377 ins_pipe( pipe_slow ); |
10072 ins_pipe( pipe_slow ); |
10378 %} |
|
10379 |
|
10380 // Replicate scalar to packed byte (1 byte) values in xmm |
|
10381 instruct Repl8B_reg(regD dst, regD src) %{ |
|
10382 match(Set dst (Replicate8B src)); |
|
10383 format %{ "MOVDQA $dst,$src\n\t" |
|
10384 "PUNPCKLBW $dst,$dst\n\t" |
|
10385 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} |
|
10386 ins_encode %{ |
|
10387 if ($dst$$reg != $src$$reg) { |
|
10388 __ movdqa($dst$$XMMRegister, $src$$XMMRegister); |
|
10389 } |
|
10390 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister); |
|
10391 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); |
|
10392 %} |
|
10393 ins_pipe( pipe_slow ); |
|
10394 %} |
|
10395 |
|
10396 // Replicate scalar to packed byte (1 byte) values in xmm |
|
10397 instruct Repl8B_rRegI(regD dst, rRegI src) %{ |
|
10398 match(Set dst (Replicate8B src)); |
|
10399 format %{ "MOVD $dst,$src\n\t" |
|
10400 "PUNPCKLBW $dst,$dst\n\t" |
|
10401 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} |
|
10402 ins_encode %{ |
|
10403 __ movdl($dst$$XMMRegister, $src$$Register); |
|
10404 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister); |
|
10405 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); |
|
10406 %} |
|
10407 ins_pipe( pipe_slow ); |
|
10408 %} |
|
10409 |
|
10410 // Replicate scalar zero to packed byte (1 byte) values in xmm |
|
10411 instruct Repl8B_immI0(regD dst, immI0 zero) %{ |
|
10412 match(Set dst (Replicate8B zero)); |
|
10413 format %{ "PXOR $dst,$dst\t! replicate8B" %} |
|
10414 ins_encode %{ |
|
10415 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); |
|
10416 %} |
|
10417 ins_pipe( fpu_reg_reg ); |
|
10418 %} |
|
10419 |
|
10420 // Replicate scalar to packed shore (2 byte) values in xmm |
|
10421 instruct Repl4S_reg(regD dst, regD src) %{ |
|
10422 match(Set dst (Replicate4S src)); |
|
10423 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %} |
|
10424 ins_encode %{ |
|
10425 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00); |
|
10426 %} |
|
10427 ins_pipe( fpu_reg_reg ); |
|
10428 %} |
|
10429 |
|
10430 // Replicate scalar to packed shore (2 byte) values in xmm |
|
10431 instruct Repl4S_rRegI(regD dst, rRegI src) %{ |
|
10432 match(Set dst (Replicate4S src)); |
|
10433 format %{ "MOVD $dst,$src\n\t" |
|
10434 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %} |
|
10435 ins_encode %{ |
|
10436 __ movdl($dst$$XMMRegister, $src$$Register); |
|
10437 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); |
|
10438 %} |
|
10439 ins_pipe( fpu_reg_reg ); |
|
10440 %} |
|
10441 |
|
10442 // Replicate scalar zero to packed short (2 byte) values in xmm |
|
10443 instruct Repl4S_immI0(regD dst, immI0 zero) %{ |
|
10444 match(Set dst (Replicate4S zero)); |
|
10445 format %{ "PXOR $dst,$dst\t! replicate4S" %} |
|
10446 ins_encode %{ |
|
10447 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); |
|
10448 %} |
|
10449 ins_pipe( fpu_reg_reg ); |
|
10450 %} |
|
10451 |
|
10452 // Replicate scalar to packed char (2 byte) values in xmm |
|
10453 instruct Repl4C_reg(regD dst, regD src) %{ |
|
10454 match(Set dst (Replicate4C src)); |
|
10455 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %} |
|
10456 ins_encode %{ |
|
10457 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00); |
|
10458 %} |
|
10459 ins_pipe( fpu_reg_reg ); |
|
10460 %} |
|
10461 |
|
10462 // Replicate scalar to packed char (2 byte) values in xmm |
|
10463 instruct Repl4C_rRegI(regD dst, rRegI src) %{ |
|
10464 match(Set dst (Replicate4C src)); |
|
10465 format %{ "MOVD $dst,$src\n\t" |
|
10466 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %} |
|
10467 ins_encode %{ |
|
10468 __ movdl($dst$$XMMRegister, $src$$Register); |
|
10469 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); |
|
10470 %} |
|
10471 ins_pipe( fpu_reg_reg ); |
|
10472 %} |
|
10473 |
|
10474 // Replicate scalar zero to packed char (2 byte) values in xmm |
|
10475 instruct Repl4C_immI0(regD dst, immI0 zero) %{ |
|
10476 match(Set dst (Replicate4C zero)); |
|
10477 format %{ "PXOR $dst,$dst\t! replicate4C" %} |
|
10478 ins_encode %{ |
|
10479 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); |
|
10480 %} |
|
10481 ins_pipe( fpu_reg_reg ); |
|
10482 %} |
|
10483 |
|
10484 // Replicate scalar to packed integer (4 byte) values in xmm |
|
10485 instruct Repl2I_reg(regD dst, regD src) %{ |
|
10486 match(Set dst (Replicate2I src)); |
|
10487 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %} |
|
10488 ins_encode %{ |
|
10489 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00); |
|
10490 %} |
|
10491 ins_pipe( fpu_reg_reg ); |
|
10492 %} |
|
10493 |
|
10494 // Replicate scalar to packed integer (4 byte) values in xmm |
|
10495 instruct Repl2I_rRegI(regD dst, rRegI src) %{ |
|
10496 match(Set dst (Replicate2I src)); |
|
10497 format %{ "MOVD $dst,$src\n\t" |
|
10498 "PSHUFD $dst,$dst,0x00\t! replicate2I" %} |
|
10499 ins_encode %{ |
|
10500 __ movdl($dst$$XMMRegister, $src$$Register); |
|
10501 __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00); |
|
10502 %} |
|
10503 ins_pipe( fpu_reg_reg ); |
|
10504 %} |
|
10505 |
|
10506 // Replicate scalar zero to packed integer (2 byte) values in xmm |
|
10507 instruct Repl2I_immI0(regD dst, immI0 zero) %{ |
|
10508 match(Set dst (Replicate2I zero)); |
|
10509 format %{ "PXOR $dst,$dst\t! replicate2I" %} |
|
10510 ins_encode %{ |
|
10511 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); |
|
10512 %} |
|
10513 ins_pipe( fpu_reg_reg ); |
|
10514 %} |
|
10515 |
|
10516 // Replicate scalar to packed single precision floating point values in xmm |
|
10517 instruct Repl2F_reg(regD dst, regD src) %{ |
|
10518 match(Set dst (Replicate2F src)); |
|
10519 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} |
|
10520 ins_encode %{ |
|
10521 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0); |
|
10522 %} |
|
10523 ins_pipe( fpu_reg_reg ); |
|
10524 %} |
|
10525 |
|
10526 // Replicate scalar to packed single precision floating point values in xmm |
|
10527 instruct Repl2F_regF(regD dst, regF src) %{ |
|
10528 match(Set dst (Replicate2F src)); |
|
10529 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} |
|
10530 ins_encode %{ |
|
10531 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0); |
|
10532 %} |
|
10533 ins_pipe( fpu_reg_reg ); |
|
10534 %} |
|
10535 |
|
10536 // Replicate scalar to packed single precision floating point values in xmm |
|
10537 instruct Repl2F_immF0(regD dst, immF0 zero) %{ |
|
10538 match(Set dst (Replicate2F zero)); |
|
10539 format %{ "PXOR $dst,$dst\t! replicate2F" %} |
|
10540 ins_encode %{ |
|
10541 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); |
|
10542 %} |
|
10543 ins_pipe( fpu_reg_reg ); |
|
10544 %} |
10073 %} |
10545 |
10074 |
10546 |
10075 |
10547 // ======================================================================= |
10076 // ======================================================================= |
10548 // fast clearing of an array |
10077 // fast clearing of an array |