OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <list> | 5 #include <list> |
6 | 6 |
7 #include "src/compiler/instruction-selector-unittest.h" | 7 #include "src/compiler/instruction-selector-unittest.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 return NULL; | 51 return NULL; |
52 } | 52 } |
53 | 53 |
54 | 54 |
55 // ARM64 logical instructions. | 55 // ARM64 logical instructions. |
56 static const MachInst2 kLogicalInstructions[] = { | 56 static const MachInst2 kLogicalInstructions[] = { |
57 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32}, | 57 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32}, |
58 {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64}, | 58 {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64}, |
59 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32}, | 59 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32}, |
60 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64}, | 60 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64}, |
61 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32, kMachInt32}, | 61 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eor32, kMachInt32}, |
62 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor, kMachInt64}}; | 62 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eor, kMachInt64}}; |
63 | 63 |
64 | 64 |
65 // ARM64 logical immediates: contiguous set bits, rotated about a power of two | 65 // ARM64 logical immediates: contiguous set bits, rotated about a power of two |
66 // sized block. The block is then duplicated across the word. Below is a random | 66 // sized block. The block is then duplicated across the word. Below is a random |
67 // subset of the 32-bit immediates. | 67 // subset of the 32-bit immediates. |
68 static const uint32_t kLogicalImmediates[] = { | 68 static const uint32_t kLogicalImmediates[] = { |
69 0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0, | 69 0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0, |
70 0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000, | 70 0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000, |
71 0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000, | 71 0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000, |
72 0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000, | 72 0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000, |
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1036 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
1037 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); | 1037 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
1038 EXPECT_EQ(1U, s[0]->OutputCount()); | 1038 EXPECT_EQ(1U, s[0]->OutputCount()); |
1039 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1039 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1040 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1040 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
1041 } | 1041 } |
1042 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 1042 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
1043 // Compare with 0 are turned into tst instruction. | 1043 // Compare with 0 are turned into tst instruction. |
1044 if (imm == 0) continue; | 1044 if (imm == 0) continue; |
1045 StreamBuilder m(this, type, type); | 1045 StreamBuilder m(this, type, type); |
1046 m.Return((m.*cmp.constructor)(m.Parameter(0), BuildConstant(m, type, imm))); | 1046 m.Return((m.*cmp.constructor)(BuildConstant(m, type, imm), m.Parameter(0))); |
1047 Stream s = m.Build(); | 1047 Stream s = m.Build(); |
1048 ASSERT_EQ(1U, s.size()); | 1048 ASSERT_EQ(1U, s.size()); |
1049 EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode()); | 1049 EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode()); |
1050 ASSERT_EQ(2U, s[0]->InputCount()); | 1050 ASSERT_EQ(2U, s[0]->InputCount()); |
1051 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1051 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
1052 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); | 1052 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
1053 EXPECT_EQ(1U, s[0]->OutputCount()); | 1053 EXPECT_EQ(1U, s[0]->OutputCount()); |
1054 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1054 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1055 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1055 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
1056 } | 1056 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 ASSERT_EQ(1U, s.size()); | 1109 ASSERT_EQ(1U, s.size()); |
1110 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); | 1110 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); |
1111 ASSERT_EQ(2U, s[0]->InputCount()); | 1111 ASSERT_EQ(2U, s[0]->InputCount()); |
1112 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1112 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
1113 EXPECT_EQ(1U, s[0]->OutputCount()); | 1113 EXPECT_EQ(1U, s[0]->OutputCount()); |
1114 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1114 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1115 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1115 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
1116 } | 1116 } |
1117 } | 1117 } |
1118 | 1118 |
| 1119 |
| 1120 // ----------------------------------------------------------------------------- |
| 1121 // Miscellaneous |
| 1122 |
| 1123 |
| 1124 static const MachInst2 kLogicalWithNotRHSs[] = { |
| 1125 {&RawMachineAssembler::Word32And, "Word32And", kArm64Bic32, kMachInt32}, |
| 1126 {&RawMachineAssembler::Word64And, "Word64And", kArm64Bic, kMachInt64}, |
| 1127 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Orn32, kMachInt32}, |
| 1128 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Orn, kMachInt64}, |
| 1129 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eon32, kMachInt32}, |
| 1130 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eon, kMachInt64}}; |
| 1131 |
| 1132 |
| 1133 typedef InstructionSelectorTestWithParam<MachInst2> |
| 1134 InstructionSelectorLogicalWithNotRHSTest; |
| 1135 |
| 1136 |
| 1137 TEST_P(InstructionSelectorLogicalWithNotRHSTest, Parameter) { |
| 1138 const MachInst2 inst = GetParam(); |
| 1139 const MachineType type = inst.machine_type; |
| 1140 // Test cases where RHS is Xor(x, -1). |
| 1141 { |
| 1142 StreamBuilder m(this, type, type, type); |
| 1143 if (type == kMachInt32) { |
| 1144 m.Return((m.*inst.constructor)( |
| 1145 m.Parameter(0), m.Word32Xor(m.Parameter(1), m.Int32Constant(-1)))); |
| 1146 } else { |
| 1147 ASSERT_EQ(kMachInt64, type); |
| 1148 m.Return((m.*inst.constructor)( |
| 1149 m.Parameter(0), m.Word64Xor(m.Parameter(1), m.Int64Constant(-1)))); |
| 1150 } |
| 1151 Stream s = m.Build(); |
| 1152 ASSERT_EQ(1U, s.size()); |
| 1153 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 1154 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1155 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1156 } |
| 1157 { |
| 1158 StreamBuilder m(this, type, type, type); |
| 1159 if (type == kMachInt32) { |
| 1160 m.Return((m.*inst.constructor)( |
| 1161 m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)), m.Parameter(1))); |
| 1162 } else { |
| 1163 ASSERT_EQ(kMachInt64, type); |
| 1164 m.Return((m.*inst.constructor)( |
| 1165 m.Word64Xor(m.Parameter(0), m.Int64Constant(-1)), m.Parameter(1))); |
| 1166 } |
| 1167 Stream s = m.Build(); |
| 1168 ASSERT_EQ(1U, s.size()); |
| 1169 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 1170 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1171 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1172 } |
| 1173 // Test cases where RHS is Not(x). |
| 1174 { |
| 1175 StreamBuilder m(this, type, type, type); |
| 1176 if (type == kMachInt32) { |
| 1177 m.Return( |
| 1178 (m.*inst.constructor)(m.Parameter(0), m.Word32Not(m.Parameter(1)))); |
| 1179 } else { |
| 1180 ASSERT_EQ(kMachInt64, type); |
| 1181 m.Return( |
| 1182 (m.*inst.constructor)(m.Parameter(0), m.Word64Not(m.Parameter(1)))); |
| 1183 } |
| 1184 Stream s = m.Build(); |
| 1185 ASSERT_EQ(1U, s.size()); |
| 1186 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 1187 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1188 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1189 } |
| 1190 { |
| 1191 StreamBuilder m(this, type, type, type); |
| 1192 if (type == kMachInt32) { |
| 1193 m.Return( |
| 1194 (m.*inst.constructor)(m.Word32Not(m.Parameter(0)), m.Parameter(1))); |
| 1195 } else { |
| 1196 ASSERT_EQ(kMachInt64, type); |
| 1197 m.Return( |
| 1198 (m.*inst.constructor)(m.Word64Not(m.Parameter(0)), m.Parameter(1))); |
| 1199 } |
| 1200 Stream s = m.Build(); |
| 1201 ASSERT_EQ(1U, s.size()); |
| 1202 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 1203 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1204 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1205 } |
| 1206 } |
| 1207 |
| 1208 |
| 1209 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 1210 InstructionSelectorLogicalWithNotRHSTest, |
| 1211 ::testing::ValuesIn(kLogicalWithNotRHSs)); |
| 1212 |
| 1213 |
| 1214 TEST_F(InstructionSelectorTest, Word32NotWithParameter) { |
| 1215 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 1216 m.Return(m.Word32Not(m.Parameter(0))); |
| 1217 Stream s = m.Build(); |
| 1218 ASSERT_EQ(1U, s.size()); |
| 1219 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); |
| 1220 EXPECT_EQ(1U, s[0]->InputCount()); |
| 1221 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1222 } |
| 1223 |
| 1224 |
| 1225 TEST_F(InstructionSelectorTest, Word64NotWithParameter) { |
| 1226 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 1227 m.Return(m.Word64Not(m.Parameter(0))); |
| 1228 Stream s = m.Build(); |
| 1229 ASSERT_EQ(1U, s.size()); |
| 1230 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); |
| 1231 EXPECT_EQ(1U, s[0]->InputCount()); |
| 1232 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1233 } |
| 1234 |
| 1235 |
| 1236 TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) { |
| 1237 { |
| 1238 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 1239 m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1))); |
| 1240 Stream s = m.Build(); |
| 1241 ASSERT_EQ(1U, s.size()); |
| 1242 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); |
| 1243 EXPECT_EQ(1U, s[0]->InputCount()); |
| 1244 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1245 } |
| 1246 { |
| 1247 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 1248 m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0))); |
| 1249 Stream s = m.Build(); |
| 1250 ASSERT_EQ(1U, s.size()); |
| 1251 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); |
| 1252 EXPECT_EQ(1U, s[0]->InputCount()); |
| 1253 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1254 } |
| 1255 } |
| 1256 |
| 1257 |
| 1258 TEST_F(InstructionSelectorTest, Word64XorMinusOneWithParameter) { |
| 1259 { |
| 1260 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 1261 m.Return(m.Word64Xor(m.Parameter(0), m.Int64Constant(-1))); |
| 1262 Stream s = m.Build(); |
| 1263 ASSERT_EQ(1U, s.size()); |
| 1264 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); |
| 1265 EXPECT_EQ(1U, s[0]->InputCount()); |
| 1266 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1267 } |
| 1268 { |
| 1269 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 1270 m.Return(m.Word64Xor(m.Int64Constant(-1), m.Parameter(0))); |
| 1271 Stream s = m.Build(); |
| 1272 ASSERT_EQ(1U, s.size()); |
| 1273 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); |
| 1274 EXPECT_EQ(1U, s[0]->InputCount()); |
| 1275 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1276 } |
| 1277 } |
| 1278 |
1119 } // namespace compiler | 1279 } // namespace compiler |
1120 } // namespace internal | 1280 } // namespace internal |
1121 } // namespace v8 | 1281 } // namespace v8 |
OLD | NEW |