| 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 "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
| 6 | 6 |
| 7 namespace v8 { | 7 namespace v8 { |
| 8 namespace internal { | 8 namespace internal { |
| 9 namespace compiler { | 9 namespace compiler { |
| 10 | 10 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 | 36 |
| 37 std::ostream& operator<<(std::ostream& os, const Shift& shift) { | 37 std::ostream& operator<<(std::ostream& os, const Shift& shift) { |
| 38 return os << shift.mi; | 38 return os << shift.mi; |
| 39 } | 39 } |
| 40 | 40 |
| 41 | 41 |
| 42 // Helper to build Int32Constant or Int64Constant depending on the given | 42 // Helper to build Int32Constant or Int64Constant depending on the given |
| 43 // machine type. | 43 // machine type. |
| 44 Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type, | 44 Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type, |
| 45 int64_t value) { | 45 int64_t value) { |
| 46 switch (type) { | 46 switch (type.representation()) { |
| 47 case kMachInt32: | 47 case MachineRepresentation::kWord32: |
| 48 return m.Int32Constant(static_cast<int32_t>(value)); | 48 return m.Int32Constant(static_cast<int32_t>(value)); |
| 49 break; | 49 break; |
| 50 | 50 |
| 51 case kMachInt64: | 51 case MachineRepresentation::kWord64: |
| 52 return m.Int64Constant(value); | 52 return m.Int64Constant(value); |
| 53 break; | 53 break; |
| 54 | 54 |
| 55 default: | 55 default: |
| 56 UNIMPLEMENTED(); | 56 UNIMPLEMENTED(); |
| 57 } | 57 } |
| 58 return NULL; | 58 return NULL; |
| 59 } | 59 } |
| 60 | 60 |
| 61 | 61 |
| 62 // ARM64 logical instructions. | 62 // ARM64 logical instructions. |
| 63 const MachInst2 kLogicalInstructions[] = { | 63 const MachInst2 kLogicalInstructions[] = { |
| 64 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32}, | 64 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, |
| 65 {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64}, | 65 MachineType::Int32()}, |
| 66 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32}, | 66 {&RawMachineAssembler::Word64And, "Word64And", kArm64And, |
| 67 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64}, | 67 MachineType::Int64()}, |
| 68 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eor32, kMachInt32}, | 68 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, |
| 69 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eor, kMachInt64}}; | 69 MachineType::Int32()}, |
| 70 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, |
| 71 MachineType::Int64()}, |
| 72 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eor32, |
| 73 MachineType::Int32()}, |
| 74 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eor, |
| 75 MachineType::Int64()}}; |
| 70 | 76 |
| 71 | 77 |
| 72 // ARM64 logical immediates: contiguous set bits, rotated about a power of two | 78 // ARM64 logical immediates: contiguous set bits, rotated about a power of two |
| 73 // sized block. The block is then duplicated across the word. Below is a random | 79 // sized block. The block is then duplicated across the word. Below is a random |
| 74 // subset of the 32-bit immediates. | 80 // subset of the 32-bit immediates. |
| 75 const uint32_t kLogical32Immediates[] = { | 81 const uint32_t kLogical32Immediates[] = { |
| 76 0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0, | 82 0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0, |
| 77 0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000, | 83 0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000, |
| 78 0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000, | 84 0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000, |
| 79 0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000, | 85 0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 ArchOpcode negate_arch_opcode; | 129 ArchOpcode negate_arch_opcode; |
| 124 }; | 130 }; |
| 125 | 131 |
| 126 | 132 |
| 127 std::ostream& operator<<(std::ostream& os, const AddSub& op) { | 133 std::ostream& operator<<(std::ostream& os, const AddSub& op) { |
| 128 return os << op.mi; | 134 return os << op.mi; |
| 129 } | 135 } |
| 130 | 136 |
| 131 | 137 |
| 132 const AddSub kAddSubInstructions[] = { | 138 const AddSub kAddSubInstructions[] = { |
| 133 {{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32}, | 139 {{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, |
| 140 MachineType::Int32()}, |
| 134 kArm64Sub32}, | 141 kArm64Sub32}, |
| 135 {{&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64}, | 142 {{&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, |
| 143 MachineType::Int64()}, |
| 136 kArm64Sub}, | 144 kArm64Sub}, |
| 137 {{&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32}, | 145 {{&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, |
| 146 MachineType::Int32()}, |
| 138 kArm64Add32}, | 147 kArm64Add32}, |
| 139 {{&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}, | 148 {{&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, |
| 149 MachineType::Int64()}, |
| 140 kArm64Add}}; | 150 kArm64Add}}; |
| 141 | 151 |
| 142 | 152 |
| 143 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12. | 153 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12. |
| 144 // Below is a combination of a random subset and some edge values. | 154 // Below is a combination of a random subset and some edge values. |
| 145 const int32_t kAddSubImmediates[] = { | 155 const int32_t kAddSubImmediates[] = { |
| 146 0, 1, 69, 493, 599, 701, 719, | 156 0, 1, 69, 493, 599, 701, 719, |
| 147 768, 818, 842, 945, 1246, 1286, 1429, | 157 768, 818, 842, 945, 1246, 1286, 1429, |
| 148 1669, 2171, 2179, 2182, 2254, 2334, 2338, | 158 1669, 2171, 2179, 2182, 2254, 2334, 2338, |
| 149 2343, 2396, 2449, 2610, 2732, 2855, 2876, | 159 2343, 2396, 2449, 2610, 2732, 2855, 2876, |
| 150 2944, 3377, 3458, 3475, 3476, 3540, 3574, | 160 2944, 3377, 3458, 3475, 3476, 3540, 3574, |
| 151 3601, 3813, 3871, 3917, 4095, 4096, 16384, | 161 3601, 3813, 3871, 3917, 4095, 4096, 16384, |
| 152 364544, 462848, 970752, 1523712, 1863680, 2363392, 3219456, | 162 364544, 462848, 970752, 1523712, 1863680, 2363392, 3219456, |
| 153 3280896, 4247552, 4526080, 4575232, 4960256, 5505024, 5894144, | 163 3280896, 4247552, 4526080, 4575232, 4960256, 5505024, 5894144, |
| 154 6004736, 6193152, 6385664, 6795264, 7114752, 7233536, 7348224, | 164 6004736, 6193152, 6385664, 6795264, 7114752, 7233536, 7348224, |
| 155 7499776, 7573504, 7729152, 8634368, 8937472, 9465856, 10354688, | 165 7499776, 7573504, 7729152, 8634368, 8937472, 9465856, 10354688, |
| 156 10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224, | 166 10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224, |
| 157 15597568, 15892480, 16773120}; | 167 15597568, 15892480, 16773120}; |
| 158 | 168 |
| 159 | 169 |
| 160 // ARM64 flag setting data processing instructions. | 170 // ARM64 flag setting data processing instructions. |
| 161 const MachInst2 kDPFlagSetInstructions[] = { | 171 const MachInst2 kDPFlagSetInstructions[] = { |
| 162 {&RawMachineAssembler::Word32And, "Word32And", kArm64Tst32, kMachInt32}, | 172 {&RawMachineAssembler::Word32And, "Word32And", kArm64Tst32, |
| 163 {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Cmn32, kMachInt32}, | 173 MachineType::Int32()}, |
| 164 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32, kMachInt32}, | 174 {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Cmn32, |
| 165 {&RawMachineAssembler::Word64And, "Word64And", kArm64Tst, kMachInt64}}; | 175 MachineType::Int32()}, |
| 176 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32, |
| 177 MachineType::Int32()}, |
| 178 {&RawMachineAssembler::Word64And, "Word64And", kArm64Tst, |
| 179 MachineType::Int64()}}; |
| 166 | 180 |
| 167 | 181 |
| 168 // ARM64 arithmetic with overflow instructions. | 182 // ARM64 arithmetic with overflow instructions. |
| 169 const MachInst2 kOvfAddSubInstructions[] = { | 183 const MachInst2 kOvfAddSubInstructions[] = { |
| 170 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", | 184 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", |
| 171 kArm64Add32, kMachInt32}, | 185 kArm64Add32, MachineType::Int32()}, |
| 172 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", | 186 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", |
| 173 kArm64Sub32, kMachInt32}}; | 187 kArm64Sub32, MachineType::Int32()}}; |
| 174 | 188 |
| 175 | 189 |
| 176 // ARM64 shift instructions. | 190 // ARM64 shift instructions. |
| 177 const Shift kShiftInstructions[] = { | 191 const Shift kShiftInstructions[] = { |
| 178 {{&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Lsl32, kMachInt32}, | 192 {{&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Lsl32, |
| 193 MachineType::Int32()}, |
| 179 kMode_Operand2_R_LSL_I}, | 194 kMode_Operand2_R_LSL_I}, |
| 180 {{&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Lsl, kMachInt64}, | 195 {{&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Lsl, |
| 196 MachineType::Int64()}, |
| 181 kMode_Operand2_R_LSL_I}, | 197 kMode_Operand2_R_LSL_I}, |
| 182 {{&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Lsr32, kMachInt32}, | 198 {{&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Lsr32, |
| 199 MachineType::Int32()}, |
| 183 kMode_Operand2_R_LSR_I}, | 200 kMode_Operand2_R_LSR_I}, |
| 184 {{&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Lsr, kMachInt64}, | 201 {{&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Lsr, |
| 202 MachineType::Int64()}, |
| 185 kMode_Operand2_R_LSR_I}, | 203 kMode_Operand2_R_LSR_I}, |
| 186 {{&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Asr32, kMachInt32}, | 204 {{&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Asr32, |
| 205 MachineType::Int32()}, |
| 187 kMode_Operand2_R_ASR_I}, | 206 kMode_Operand2_R_ASR_I}, |
| 188 {{&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Asr, kMachInt64}, | 207 {{&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Asr, |
| 208 MachineType::Int64()}, |
| 189 kMode_Operand2_R_ASR_I}, | 209 kMode_Operand2_R_ASR_I}, |
| 190 {{&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, | 210 {{&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, |
| 211 MachineType::Int32()}, |
| 191 kMode_Operand2_R_ROR_I}, | 212 kMode_Operand2_R_ROR_I}, |
| 192 {{&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}, | 213 {{&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, |
| 214 MachineType::Int64()}, |
| 193 kMode_Operand2_R_ROR_I}}; | 215 kMode_Operand2_R_ROR_I}}; |
| 194 | 216 |
| 195 | 217 |
| 196 // ARM64 Mul/Div instructions. | 218 // ARM64 Mul/Div instructions. |
| 197 const MachInst2 kMulDivInstructions[] = { | 219 const MachInst2 kMulDivInstructions[] = { |
| 198 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32}, | 220 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, |
| 199 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64}, | 221 MachineType::Int32()}, |
| 200 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32}, | 222 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, |
| 201 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64}, | 223 MachineType::Int64()}, |
| 202 {&RawMachineAssembler::Uint32Div, "Uint32Div", kArm64Udiv32, kMachInt32}, | 224 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, |
| 203 {&RawMachineAssembler::Uint64Div, "Uint64Div", kArm64Udiv, kMachInt64}}; | 225 MachineType::Int32()}, |
| 226 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, |
| 227 MachineType::Int64()}, |
| 228 {&RawMachineAssembler::Uint32Div, "Uint32Div", kArm64Udiv32, |
| 229 MachineType::Int32()}, |
| 230 {&RawMachineAssembler::Uint64Div, "Uint64Div", kArm64Udiv, |
| 231 MachineType::Int64()}}; |
| 204 | 232 |
| 205 | 233 |
| 206 // ARM64 FP arithmetic instructions. | 234 // ARM64 FP arithmetic instructions. |
| 207 const MachInst2 kFPArithInstructions[] = { | 235 const MachInst2 kFPArithInstructions[] = { |
| 208 {&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add, | 236 {&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add, |
| 209 kMachFloat64}, | 237 MachineType::Float64()}, |
| 210 {&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub, | 238 {&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub, |
| 211 kMachFloat64}, | 239 MachineType::Float64()}, |
| 212 {&RawMachineAssembler::Float64Mul, "Float64Mul", kArm64Float64Mul, | 240 {&RawMachineAssembler::Float64Mul, "Float64Mul", kArm64Float64Mul, |
| 213 kMachFloat64}, | 241 MachineType::Float64()}, |
| 214 {&RawMachineAssembler::Float64Div, "Float64Div", kArm64Float64Div, | 242 {&RawMachineAssembler::Float64Div, "Float64Div", kArm64Float64Div, |
| 215 kMachFloat64}}; | 243 MachineType::Float64()}}; |
| 216 | 244 |
| 217 | 245 |
| 218 struct FPCmp { | 246 struct FPCmp { |
| 219 MachInst2 mi; | 247 MachInst2 mi; |
| 220 FlagsCondition cond; | 248 FlagsCondition cond; |
| 221 FlagsCondition commuted_cond; | 249 FlagsCondition commuted_cond; |
| 222 }; | 250 }; |
| 223 | 251 |
| 224 | 252 |
| 225 std::ostream& operator<<(std::ostream& os, const FPCmp& cmp) { | 253 std::ostream& operator<<(std::ostream& os, const FPCmp& cmp) { |
| 226 return os << cmp.mi; | 254 return os << cmp.mi; |
| 227 } | 255 } |
| 228 | 256 |
| 229 | 257 |
| 230 // ARM64 FP comparison instructions. | 258 // ARM64 FP comparison instructions. |
| 231 const FPCmp kFPCmpInstructions[] = { | 259 const FPCmp kFPCmpInstructions[] = { |
| 232 {{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp, | 260 {{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp, |
| 233 kMachFloat64}, | 261 MachineType::Float64()}, |
| 234 kEqual, kEqual}, | 262 kEqual, |
| 263 kEqual}, |
| 235 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", | 264 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", |
| 236 kArm64Float64Cmp, kMachFloat64}, | 265 kArm64Float64Cmp, MachineType::Float64()}, |
| 237 kFloatLessThan, kFloatGreaterThan}, | 266 kFloatLessThan, |
| 267 kFloatGreaterThan}, |
| 238 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", | 268 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", |
| 239 kArm64Float64Cmp, kMachFloat64}, | 269 kArm64Float64Cmp, MachineType::Float64()}, |
| 240 kFloatLessThanOrEqual, kFloatGreaterThanOrEqual}, | 270 kFloatLessThanOrEqual, |
| 271 kFloatGreaterThanOrEqual}, |
| 241 {{&RawMachineAssembler::Float32Equal, "Float32Equal", kArm64Float32Cmp, | 272 {{&RawMachineAssembler::Float32Equal, "Float32Equal", kArm64Float32Cmp, |
| 242 kMachFloat32}, | 273 MachineType::Float32()}, |
| 243 kEqual, kEqual}, | 274 kEqual, |
| 275 kEqual}, |
| 244 {{&RawMachineAssembler::Float32LessThan, "Float32LessThan", | 276 {{&RawMachineAssembler::Float32LessThan, "Float32LessThan", |
| 245 kArm64Float32Cmp, kMachFloat32}, | 277 kArm64Float32Cmp, MachineType::Float32()}, |
| 246 kFloatLessThan, kFloatGreaterThan}, | 278 kFloatLessThan, |
| 279 kFloatGreaterThan}, |
| 247 {{&RawMachineAssembler::Float32LessThanOrEqual, "Float32LessThanOrEqual", | 280 {{&RawMachineAssembler::Float32LessThanOrEqual, "Float32LessThanOrEqual", |
| 248 kArm64Float32Cmp, kMachFloat32}, | 281 kArm64Float32Cmp, MachineType::Float32()}, |
| 249 kFloatLessThanOrEqual, kFloatGreaterThanOrEqual}}; | 282 kFloatLessThanOrEqual, |
| 283 kFloatGreaterThanOrEqual}}; |
| 250 | 284 |
| 251 | 285 |
| 252 struct Conversion { | 286 struct Conversion { |
| 253 // The machine_type field in MachInst1 represents the destination type. | 287 // The machine_type field in MachInst1 represents the destination type. |
| 254 MachInst1 mi; | 288 MachInst1 mi; |
| 255 MachineType src_machine_type; | 289 MachineType src_machine_type; |
| 256 }; | 290 }; |
| 257 | 291 |
| 258 | 292 |
| 259 std::ostream& operator<<(std::ostream& os, const Conversion& conv) { | 293 std::ostream& operator<<(std::ostream& os, const Conversion& conv) { |
| 260 return os << conv.mi; | 294 return os << conv.mi; |
| 261 } | 295 } |
| 262 | 296 |
| 263 | 297 |
| 264 // ARM64 type conversion instructions. | 298 // ARM64 type conversion instructions. |
| 265 const Conversion kConversionInstructions[] = { | 299 const Conversion kConversionInstructions[] = { |
| 266 {{&RawMachineAssembler::ChangeFloat32ToFloat64, "ChangeFloat32ToFloat64", | 300 {{&RawMachineAssembler::ChangeFloat32ToFloat64, "ChangeFloat32ToFloat64", |
| 267 kArm64Float32ToFloat64, kMachFloat64}, | 301 kArm64Float32ToFloat64, MachineType::Float64()}, |
| 268 kMachFloat32}, | 302 MachineType::Float32()}, |
| 269 {{&RawMachineAssembler::TruncateFloat64ToFloat32, | 303 {{&RawMachineAssembler::TruncateFloat64ToFloat32, |
| 270 "TruncateFloat64ToFloat32", kArm64Float64ToFloat32, kMachFloat32}, | 304 "TruncateFloat64ToFloat32", kArm64Float64ToFloat32, |
| 271 kMachFloat64}, | 305 MachineType::Float32()}, |
| 306 MachineType::Float64()}, |
| 272 {{&RawMachineAssembler::ChangeInt32ToInt64, "ChangeInt32ToInt64", | 307 {{&RawMachineAssembler::ChangeInt32ToInt64, "ChangeInt32ToInt64", |
| 273 kArm64Sxtw, kMachInt64}, | 308 kArm64Sxtw, MachineType::Int64()}, |
| 274 kMachInt32}, | 309 MachineType::Int32()}, |
| 275 {{&RawMachineAssembler::ChangeUint32ToUint64, "ChangeUint32ToUint64", | 310 {{&RawMachineAssembler::ChangeUint32ToUint64, "ChangeUint32ToUint64", |
| 276 kArm64Mov32, kMachUint64}, | 311 kArm64Mov32, MachineType::Uint64()}, |
| 277 kMachUint32}, | 312 MachineType::Uint32()}, |
| 278 {{&RawMachineAssembler::TruncateInt64ToInt32, "TruncateInt64ToInt32", | 313 {{&RawMachineAssembler::TruncateInt64ToInt32, "TruncateInt64ToInt32", |
| 279 kArm64Mov32, kMachInt32}, | 314 kArm64Mov32, MachineType::Int32()}, |
| 280 kMachInt64}, | 315 MachineType::Int64()}, |
| 281 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64", | 316 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64", |
| 282 kArm64Int32ToFloat64, kMachFloat64}, | 317 kArm64Int32ToFloat64, MachineType::Float64()}, |
| 283 kMachInt32}, | 318 MachineType::Int32()}, |
| 284 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64", | 319 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64", |
| 285 kArm64Uint32ToFloat64, kMachFloat64}, | 320 kArm64Uint32ToFloat64, MachineType::Float64()}, |
| 286 kMachUint32}, | 321 MachineType::Uint32()}, |
| 287 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32", | 322 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32", |
| 288 kArm64Float64ToInt32, kMachInt32}, | 323 kArm64Float64ToInt32, MachineType::Int32()}, |
| 289 kMachFloat64}, | 324 MachineType::Float64()}, |
| 290 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32", | 325 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32", |
| 291 kArm64Float64ToUint32, kMachUint32}, | 326 kArm64Float64ToUint32, MachineType::Uint32()}, |
| 292 kMachFloat64}}; | 327 MachineType::Float64()}}; |
| 293 | 328 |
| 294 } // namespace | 329 } // namespace |
| 295 | 330 |
| 296 | 331 |
| 297 // ----------------------------------------------------------------------------- | 332 // ----------------------------------------------------------------------------- |
| 298 // Logical instructions. | 333 // Logical instructions. |
| 299 | 334 |
| 300 | 335 |
| 301 typedef InstructionSelectorTestWithParam<MachInst2> | 336 typedef InstructionSelectorTestWithParam<MachInst2> |
| 302 InstructionSelectorLogicalTest; | 337 InstructionSelectorLogicalTest; |
| 303 | 338 |
| 304 | 339 |
| 305 TEST_P(InstructionSelectorLogicalTest, Parameter) { | 340 TEST_P(InstructionSelectorLogicalTest, Parameter) { |
| 306 const MachInst2 dpi = GetParam(); | 341 const MachInst2 dpi = GetParam(); |
| 307 const MachineType type = dpi.machine_type; | 342 const MachineType type = dpi.machine_type; |
| 308 StreamBuilder m(this, type, type, type); | 343 StreamBuilder m(this, type, type, type); |
| 309 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 344 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 310 Stream s = m.Build(); | 345 Stream s = m.Build(); |
| 311 ASSERT_EQ(1U, s.size()); | 346 ASSERT_EQ(1U, s.size()); |
| 312 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 347 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 313 EXPECT_EQ(2U, s[0]->InputCount()); | 348 EXPECT_EQ(2U, s[0]->InputCount()); |
| 314 EXPECT_EQ(1U, s[0]->OutputCount()); | 349 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 315 } | 350 } |
| 316 | 351 |
| 317 | 352 |
| 318 TEST_P(InstructionSelectorLogicalTest, Immediate) { | 353 TEST_P(InstructionSelectorLogicalTest, Immediate) { |
| 319 const MachInst2 dpi = GetParam(); | 354 const MachInst2 dpi = GetParam(); |
| 320 const MachineType type = dpi.machine_type; | 355 const MachineType type = dpi.machine_type; |
| 321 // TODO(all): Add support for testing 64-bit immediates. | 356 // TODO(all): Add support for testing 64-bit immediates. |
| 322 if (type == kMachInt32) { | 357 if (type == MachineType::Int32()) { |
| 323 // Immediate on the right. | 358 // Immediate on the right. |
| 324 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { | 359 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { |
| 325 StreamBuilder m(this, type, type); | 360 StreamBuilder m(this, type, type); |
| 326 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); | 361 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); |
| 327 Stream s = m.Build(); | 362 Stream s = m.Build(); |
| 328 ASSERT_EQ(1U, s.size()); | 363 ASSERT_EQ(1U, s.size()); |
| 329 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 364 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 330 ASSERT_EQ(2U, s[0]->InputCount()); | 365 ASSERT_EQ(2U, s[0]->InputCount()); |
| 331 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 366 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 332 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 367 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 349 } | 384 } |
| 350 | 385 |
| 351 | 386 |
| 352 TEST_P(InstructionSelectorLogicalTest, ShiftByImmediate) { | 387 TEST_P(InstructionSelectorLogicalTest, ShiftByImmediate) { |
| 353 const MachInst2 dpi = GetParam(); | 388 const MachInst2 dpi = GetParam(); |
| 354 const MachineType type = dpi.machine_type; | 389 const MachineType type = dpi.machine_type; |
| 355 TRACED_FOREACH(Shift, shift, kShiftInstructions) { | 390 TRACED_FOREACH(Shift, shift, kShiftInstructions) { |
| 356 // Only test 64-bit shifted operands with 64-bit instructions. | 391 // Only test 64-bit shifted operands with 64-bit instructions. |
| 357 if (shift.mi.machine_type != type) continue; | 392 if (shift.mi.machine_type != type) continue; |
| 358 | 393 |
| 359 TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) { | 394 TRACED_FORRANGE(int, imm, 0, ((type == MachineType::Int32()) ? 31 : 63)) { |
| 360 StreamBuilder m(this, type, type, type); | 395 StreamBuilder m(this, type, type, type); |
| 361 m.Return((m.*dpi.constructor)( | 396 m.Return((m.*dpi.constructor)( |
| 362 m.Parameter(0), | 397 m.Parameter(0), |
| 363 (m.*shift.mi.constructor)(m.Parameter(1), | 398 (m.*shift.mi.constructor)(m.Parameter(1), |
| 364 BuildConstant(m, type, imm)))); | 399 BuildConstant(m, type, imm)))); |
| 365 Stream s = m.Build(); | 400 Stream s = m.Build(); |
| 366 ASSERT_EQ(1U, s.size()); | 401 ASSERT_EQ(1U, s.size()); |
| 367 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 402 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 368 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 403 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 369 EXPECT_EQ(3U, s[0]->InputCount()); | 404 EXPECT_EQ(3U, s[0]->InputCount()); |
| 370 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); | 405 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); |
| 371 EXPECT_EQ(1U, s[0]->OutputCount()); | 406 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 372 } | 407 } |
| 373 | 408 |
| 374 TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) { | 409 TRACED_FORRANGE(int, imm, 0, ((type == MachineType::Int32()) ? 31 : 63)) { |
| 375 StreamBuilder m(this, type, type, type); | 410 StreamBuilder m(this, type, type, type); |
| 376 m.Return((m.*dpi.constructor)( | 411 m.Return((m.*dpi.constructor)( |
| 377 (m.*shift.mi.constructor)(m.Parameter(1), | 412 (m.*shift.mi.constructor)(m.Parameter(1), |
| 378 BuildConstant(m, type, imm)), | 413 BuildConstant(m, type, imm)), |
| 379 m.Parameter(0))); | 414 m.Parameter(0))); |
| 380 Stream s = m.Build(); | 415 Stream s = m.Build(); |
| 381 ASSERT_EQ(1U, s.size()); | 416 ASSERT_EQ(1U, s.size()); |
| 382 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 417 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 383 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 418 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 384 EXPECT_EQ(3U, s[0]->InputCount()); | 419 EXPECT_EQ(3U, s[0]->InputCount()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 TRACED_FOREACH(Shift, shift, kShiftInstructions) { | 490 TRACED_FOREACH(Shift, shift, kShiftInstructions) { |
| 456 // Only test 64-bit shifted operands with 64-bit instructions. | 491 // Only test 64-bit shifted operands with 64-bit instructions. |
| 457 if (shift.mi.machine_type != type) continue; | 492 if (shift.mi.machine_type != type) continue; |
| 458 | 493 |
| 459 if ((shift.mi.arch_opcode == kArm64Ror32) || | 494 if ((shift.mi.arch_opcode == kArm64Ror32) || |
| 460 (shift.mi.arch_opcode == kArm64Ror)) { | 495 (shift.mi.arch_opcode == kArm64Ror)) { |
| 461 // Not supported by add/sub instructions. | 496 // Not supported by add/sub instructions. |
| 462 continue; | 497 continue; |
| 463 } | 498 } |
| 464 | 499 |
| 465 TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) { | 500 TRACED_FORRANGE(int, imm, 0, ((type == MachineType::Int32()) ? 31 : 63)) { |
| 466 StreamBuilder m(this, type, type, type); | 501 StreamBuilder m(this, type, type, type); |
| 467 m.Return((m.*dpi.mi.constructor)( | 502 m.Return((m.*dpi.mi.constructor)( |
| 468 m.Parameter(0), | 503 m.Parameter(0), |
| 469 (m.*shift.mi.constructor)(m.Parameter(1), | 504 (m.*shift.mi.constructor)(m.Parameter(1), |
| 470 BuildConstant(m, type, imm)))); | 505 BuildConstant(m, type, imm)))); |
| 471 Stream s = m.Build(); | 506 Stream s = m.Build(); |
| 472 ASSERT_EQ(1U, s.size()); | 507 ASSERT_EQ(1U, s.size()); |
| 473 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode()); | 508 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode()); |
| 474 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 509 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 475 EXPECT_EQ(3U, s[0]->InputCount()); | 510 EXPECT_EQ(3U, s[0]->InputCount()); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 | 580 |
| 546 | 581 |
| 547 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, | 582 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, |
| 548 ::testing::ValuesIn(kAddSubInstructions)); | 583 ::testing::ValuesIn(kAddSubInstructions)); |
| 549 | 584 |
| 550 | 585 |
| 551 TEST_F(InstructionSelectorTest, AddImmediateOnLeft) { | 586 TEST_F(InstructionSelectorTest, AddImmediateOnLeft) { |
| 552 { | 587 { |
| 553 // 32-bit add. | 588 // 32-bit add. |
| 554 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 589 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 555 StreamBuilder m(this, kMachInt32, kMachInt32); | 590 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 556 m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0))); | 591 m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0))); |
| 557 Stream s = m.Build(); | 592 Stream s = m.Build(); |
| 558 ASSERT_EQ(1U, s.size()); | 593 ASSERT_EQ(1U, s.size()); |
| 559 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 594 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 560 ASSERT_EQ(2U, s[0]->InputCount()); | 595 ASSERT_EQ(2U, s[0]->InputCount()); |
| 561 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 596 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 562 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 597 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 563 EXPECT_EQ(1U, s[0]->OutputCount()); | 598 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 564 } | 599 } |
| 565 } | 600 } |
| 566 { | 601 { |
| 567 // 64-bit add. | 602 // 64-bit add. |
| 568 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 603 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 569 StreamBuilder m(this, kMachInt64, kMachInt64); | 604 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 570 m.Return(m.Int64Add(m.Int64Constant(imm), m.Parameter(0))); | 605 m.Return(m.Int64Add(m.Int64Constant(imm), m.Parameter(0))); |
| 571 Stream s = m.Build(); | 606 Stream s = m.Build(); |
| 572 ASSERT_EQ(1U, s.size()); | 607 ASSERT_EQ(1U, s.size()); |
| 573 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 608 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 574 ASSERT_EQ(2U, s[0]->InputCount()); | 609 ASSERT_EQ(2U, s[0]->InputCount()); |
| 575 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 610 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 576 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); | 611 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
| 577 EXPECT_EQ(1U, s[0]->OutputCount()); | 612 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 578 } | 613 } |
| 579 } | 614 } |
| 580 } | 615 } |
| 581 | 616 |
| 582 | 617 |
| 583 TEST_F(InstructionSelectorTest, SubZeroOnLeft) { | 618 TEST_F(InstructionSelectorTest, SubZeroOnLeft) { |
| 584 { | 619 { |
| 585 // 32-bit subtract. | 620 // 32-bit subtract. |
| 586 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 621 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 622 MachineType::Int32()); |
| 587 m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0))); | 623 m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0))); |
| 588 Stream s = m.Build(); | 624 Stream s = m.Build(); |
| 589 | 625 |
| 590 ASSERT_EQ(1U, s.size()); | 626 ASSERT_EQ(1U, s.size()); |
| 591 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); | 627 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); |
| 592 ASSERT_EQ(2U, s[0]->InputCount()); | 628 ASSERT_EQ(2U, s[0]->InputCount()); |
| 593 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); | 629 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); |
| 594 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); | 630 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); |
| 595 EXPECT_EQ(1U, s[0]->OutputCount()); | 631 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 596 } | 632 } |
| 597 { | 633 { |
| 598 // 64-bit subtract. | 634 // 64-bit subtract. |
| 599 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); | 635 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(), |
| 636 MachineType::Int64()); |
| 600 m.Return(m.Int64Sub(m.Int64Constant(0), m.Parameter(0))); | 637 m.Return(m.Int64Sub(m.Int64Constant(0), m.Parameter(0))); |
| 601 Stream s = m.Build(); | 638 Stream s = m.Build(); |
| 602 | 639 |
| 603 ASSERT_EQ(1U, s.size()); | 640 ASSERT_EQ(1U, s.size()); |
| 604 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); | 641 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); |
| 605 ASSERT_EQ(2U, s[0]->InputCount()); | 642 ASSERT_EQ(2U, s[0]->InputCount()); |
| 606 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); | 643 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); |
| 607 EXPECT_EQ(0, s.ToInt64(s[0]->InputAt(0))); | 644 EXPECT_EQ(0, s.ToInt64(s[0]->InputAt(0))); |
| 608 EXPECT_EQ(1U, s[0]->OutputCount()); | 645 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 609 } | 646 } |
| 610 } | 647 } |
| 611 | 648 |
| 612 | 649 |
| 613 TEST_F(InstructionSelectorTest, SubZeroOnLeftWithShift) { | 650 TEST_F(InstructionSelectorTest, SubZeroOnLeftWithShift) { |
| 614 TRACED_FOREACH(Shift, shift, kShiftInstructions) { | 651 TRACED_FOREACH(Shift, shift, kShiftInstructions) { |
| 615 { | 652 { |
| 616 // Test 32-bit operations. Ignore ROR shifts, as subtract does not | 653 // Test 32-bit operations. Ignore ROR shifts, as subtract does not |
| 617 // support them. | 654 // support them. |
| 618 if ((shift.mi.machine_type != kMachInt32) || | 655 if ((shift.mi.machine_type != MachineType::Int32()) || |
| 619 (shift.mi.arch_opcode == kArm64Ror32) || | 656 (shift.mi.arch_opcode == kArm64Ror32) || |
| 620 (shift.mi.arch_opcode == kArm64Ror)) | 657 (shift.mi.arch_opcode == kArm64Ror)) |
| 621 continue; | 658 continue; |
| 622 | 659 |
| 623 TRACED_FORRANGE(int, imm, -32, 63) { | 660 TRACED_FORRANGE(int, imm, -32, 63) { |
| 624 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 661 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 662 MachineType::Int32()); |
| 625 m.Return(m.Int32Sub( | 663 m.Return(m.Int32Sub( |
| 626 m.Int32Constant(0), | 664 m.Int32Constant(0), |
| 627 (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)))); | 665 (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)))); |
| 628 Stream s = m.Build(); | 666 Stream s = m.Build(); |
| 629 | 667 |
| 630 ASSERT_EQ(1U, s.size()); | 668 ASSERT_EQ(1U, s.size()); |
| 631 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); | 669 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); |
| 632 ASSERT_EQ(3U, s[0]->InputCount()); | 670 ASSERT_EQ(3U, s[0]->InputCount()); |
| 633 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); | 671 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); |
| 634 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); | 672 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); |
| 635 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 673 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 636 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); | 674 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); |
| 637 EXPECT_EQ(1U, s[0]->OutputCount()); | 675 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 638 } | 676 } |
| 639 } | 677 } |
| 640 { | 678 { |
| 641 // Test 64-bit operations. Ignore ROR shifts, as subtract does not | 679 // Test 64-bit operations. Ignore ROR shifts, as subtract does not |
| 642 // support them. | 680 // support them. |
| 643 if ((shift.mi.machine_type != kMachInt64) || | 681 if ((shift.mi.machine_type != MachineType::Int64()) || |
| 644 (shift.mi.arch_opcode == kArm64Ror32) || | 682 (shift.mi.arch_opcode == kArm64Ror32) || |
| 645 (shift.mi.arch_opcode == kArm64Ror)) | 683 (shift.mi.arch_opcode == kArm64Ror)) |
| 646 continue; | 684 continue; |
| 647 | 685 |
| 648 TRACED_FORRANGE(int, imm, -32, 127) { | 686 TRACED_FORRANGE(int, imm, -32, 127) { |
| 649 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); | 687 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(), |
| 688 MachineType::Int64()); |
| 650 m.Return(m.Int64Sub( | 689 m.Return(m.Int64Sub( |
| 651 m.Int64Constant(0), | 690 m.Int64Constant(0), |
| 652 (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)))); | 691 (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)))); |
| 653 Stream s = m.Build(); | 692 Stream s = m.Build(); |
| 654 | 693 |
| 655 ASSERT_EQ(1U, s.size()); | 694 ASSERT_EQ(1U, s.size()); |
| 656 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); | 695 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); |
| 657 ASSERT_EQ(3U, s[0]->InputCount()); | 696 ASSERT_EQ(3U, s[0]->InputCount()); |
| 658 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); | 697 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); |
| 659 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); | 698 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); |
| 660 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 699 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 661 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); | 700 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); |
| 662 EXPECT_EQ(1U, s[0]->OutputCount()); | 701 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 663 } | 702 } |
| 664 } | 703 } |
| 665 } | 704 } |
| 666 } | 705 } |
| 667 | 706 |
| 668 | 707 |
| 669 TEST_F(InstructionSelectorTest, AddNegImmediateOnLeft) { | 708 TEST_F(InstructionSelectorTest, AddNegImmediateOnLeft) { |
| 670 { | 709 { |
| 671 // 32-bit add. | 710 // 32-bit add. |
| 672 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 711 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 673 if (imm == 0) continue; | 712 if (imm == 0) continue; |
| 674 StreamBuilder m(this, kMachInt32, kMachInt32); | 713 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 675 m.Return(m.Int32Add(m.Int32Constant(-imm), m.Parameter(0))); | 714 m.Return(m.Int32Add(m.Int32Constant(-imm), m.Parameter(0))); |
| 676 Stream s = m.Build(); | 715 Stream s = m.Build(); |
| 677 | 716 |
| 678 ASSERT_EQ(1U, s.size()); | 717 ASSERT_EQ(1U, s.size()); |
| 679 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); | 718 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); |
| 680 ASSERT_EQ(2U, s[0]->InputCount()); | 719 ASSERT_EQ(2U, s[0]->InputCount()); |
| 681 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 720 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 682 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 721 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 683 EXPECT_EQ(1U, s[0]->OutputCount()); | 722 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 684 } | 723 } |
| 685 } | 724 } |
| 686 { | 725 { |
| 687 // 64-bit add. | 726 // 64-bit add. |
| 688 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 727 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 689 if (imm == 0) continue; | 728 if (imm == 0) continue; |
| 690 StreamBuilder m(this, kMachInt64, kMachInt64); | 729 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 691 m.Return(m.Int64Add(m.Int64Constant(-imm), m.Parameter(0))); | 730 m.Return(m.Int64Add(m.Int64Constant(-imm), m.Parameter(0))); |
| 692 Stream s = m.Build(); | 731 Stream s = m.Build(); |
| 693 | 732 |
| 694 ASSERT_EQ(1U, s.size()); | 733 ASSERT_EQ(1U, s.size()); |
| 695 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); | 734 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); |
| 696 ASSERT_EQ(2U, s[0]->InputCount()); | 735 ASSERT_EQ(2U, s[0]->InputCount()); |
| 697 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 736 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 698 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); | 737 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
| 699 EXPECT_EQ(1U, s[0]->OutputCount()); | 738 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 700 } | 739 } |
| 701 } | 740 } |
| 702 } | 741 } |
| 703 | 742 |
| 704 | 743 |
| 705 TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) { | 744 TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) { |
| 706 // 32-bit add. | 745 // 32-bit add. |
| 707 TRACED_FOREACH(Shift, shift, kShiftInstructions) { | 746 TRACED_FOREACH(Shift, shift, kShiftInstructions) { |
| 708 // Only test relevant shifted operands. | 747 // Only test relevant shifted operands. |
| 709 if (shift.mi.machine_type != kMachInt32) continue; | 748 if (shift.mi.machine_type != MachineType::Int32()) continue; |
| 710 if (shift.mi.arch_opcode == kArm64Ror32) continue; | 749 if (shift.mi.arch_opcode == kArm64Ror32) continue; |
| 711 | 750 |
| 712 // The available shift operand range is `0 <= imm < 32`, but we also test | 751 // The available shift operand range is `0 <= imm < 32`, but we also test |
| 713 // that immediates outside this range are handled properly (modulo-32). | 752 // that immediates outside this range are handled properly (modulo-32). |
| 714 TRACED_FORRANGE(int, imm, -32, 63) { | 753 TRACED_FORRANGE(int, imm, -32, 63) { |
| 715 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 754 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 755 MachineType::Int32()); |
| 716 m.Return((m.Int32Add)( | 756 m.Return((m.Int32Add)( |
| 717 (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)), | 757 (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)), |
| 718 m.Parameter(0))); | 758 m.Parameter(0))); |
| 719 Stream s = m.Build(); | 759 Stream s = m.Build(); |
| 720 ASSERT_EQ(1U, s.size()); | 760 ASSERT_EQ(1U, s.size()); |
| 721 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 761 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 722 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 762 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 723 EXPECT_EQ(3U, s[0]->InputCount()); | 763 EXPECT_EQ(3U, s[0]->InputCount()); |
| 724 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); | 764 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); |
| 725 EXPECT_EQ(1U, s[0]->OutputCount()); | 765 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 726 } | 766 } |
| 727 } | 767 } |
| 728 | 768 |
| 729 // 64-bit add. | 769 // 64-bit add. |
| 730 TRACED_FOREACH(Shift, shift, kShiftInstructions) { | 770 TRACED_FOREACH(Shift, shift, kShiftInstructions) { |
| 731 // Only test relevant shifted operands. | 771 // Only test relevant shifted operands. |
| 732 if (shift.mi.machine_type != kMachInt64) continue; | 772 if (shift.mi.machine_type != MachineType::Int64()) continue; |
| 733 if (shift.mi.arch_opcode == kArm64Ror) continue; | 773 if (shift.mi.arch_opcode == kArm64Ror) continue; |
| 734 | 774 |
| 735 // The available shift operand range is `0 <= imm < 64`, but we also test | 775 // The available shift operand range is `0 <= imm < 64`, but we also test |
| 736 // that immediates outside this range are handled properly (modulo-64). | 776 // that immediates outside this range are handled properly (modulo-64). |
| 737 TRACED_FORRANGE(int, imm, -64, 127) { | 777 TRACED_FORRANGE(int, imm, -64, 127) { |
| 738 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); | 778 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(), |
| 779 MachineType::Int64()); |
| 739 m.Return((m.Int64Add)( | 780 m.Return((m.Int64Add)( |
| 740 (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)), | 781 (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)), |
| 741 m.Parameter(0))); | 782 m.Parameter(0))); |
| 742 Stream s = m.Build(); | 783 Stream s = m.Build(); |
| 743 ASSERT_EQ(1U, s.size()); | 784 ASSERT_EQ(1U, s.size()); |
| 744 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 785 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 745 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 786 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 746 EXPECT_EQ(3U, s[0]->InputCount()); | 787 EXPECT_EQ(3U, s[0]->InputCount()); |
| 747 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); | 788 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); |
| 748 EXPECT_EQ(1U, s[0]->OutputCount()); | 789 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 749 } | 790 } |
| 750 } | 791 } |
| 751 } | 792 } |
| 752 | 793 |
| 753 | 794 |
| 754 TEST_F(InstructionSelectorTest, AddUnsignedExtendByteOnLeft) { | 795 TEST_F(InstructionSelectorTest, AddUnsignedExtendByteOnLeft) { |
| 755 { | 796 { |
| 756 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 797 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 798 MachineType::Int32()); |
| 757 m.Return(m.Int32Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xff)), | 799 m.Return(m.Int32Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xff)), |
| 758 m.Parameter(1))); | 800 m.Parameter(1))); |
| 759 Stream s = m.Build(); | 801 Stream s = m.Build(); |
| 760 ASSERT_EQ(1U, s.size()); | 802 ASSERT_EQ(1U, s.size()); |
| 761 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 803 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 762 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); | 804 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); |
| 763 ASSERT_EQ(2U, s[0]->InputCount()); | 805 ASSERT_EQ(2U, s[0]->InputCount()); |
| 764 ASSERT_EQ(1U, s[0]->OutputCount()); | 806 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 765 } | 807 } |
| 766 { | 808 { |
| 767 StreamBuilder m(this, kMachInt64, kMachInt32, kMachInt64); | 809 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32(), |
| 810 MachineType::Int64()); |
| 768 m.Return(m.Int64Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xff)), | 811 m.Return(m.Int64Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xff)), |
| 769 m.Parameter(1))); | 812 m.Parameter(1))); |
| 770 Stream s = m.Build(); | 813 Stream s = m.Build(); |
| 771 ASSERT_EQ(1U, s.size()); | 814 ASSERT_EQ(1U, s.size()); |
| 772 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 815 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 773 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); | 816 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); |
| 774 ASSERT_EQ(2U, s[0]->InputCount()); | 817 ASSERT_EQ(2U, s[0]->InputCount()); |
| 775 ASSERT_EQ(1U, s[0]->OutputCount()); | 818 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 776 } | 819 } |
| 777 } | 820 } |
| 778 | 821 |
| 779 | 822 |
| 780 TEST_F(InstructionSelectorTest, AddUnsignedExtendHalfwordOnLeft) { | 823 TEST_F(InstructionSelectorTest, AddUnsignedExtendHalfwordOnLeft) { |
| 781 { | 824 { |
| 782 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 825 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 826 MachineType::Int32()); |
| 783 m.Return(m.Int32Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xffff)), | 827 m.Return(m.Int32Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xffff)), |
| 784 m.Parameter(1))); | 828 m.Parameter(1))); |
| 785 Stream s = m.Build(); | 829 Stream s = m.Build(); |
| 786 ASSERT_EQ(1U, s.size()); | 830 ASSERT_EQ(1U, s.size()); |
| 787 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 831 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 788 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); | 832 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); |
| 789 ASSERT_EQ(2U, s[0]->InputCount()); | 833 ASSERT_EQ(2U, s[0]->InputCount()); |
| 790 ASSERT_EQ(1U, s[0]->OutputCount()); | 834 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 791 } | 835 } |
| 792 { | 836 { |
| 793 StreamBuilder m(this, kMachInt64, kMachInt32, kMachInt64); | 837 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32(), |
| 838 MachineType::Int64()); |
| 794 m.Return(m.Int64Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xffff)), | 839 m.Return(m.Int64Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xffff)), |
| 795 m.Parameter(1))); | 840 m.Parameter(1))); |
| 796 Stream s = m.Build(); | 841 Stream s = m.Build(); |
| 797 ASSERT_EQ(1U, s.size()); | 842 ASSERT_EQ(1U, s.size()); |
| 798 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 843 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 799 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); | 844 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); |
| 800 ASSERT_EQ(2U, s[0]->InputCount()); | 845 ASSERT_EQ(2U, s[0]->InputCount()); |
| 801 ASSERT_EQ(1U, s[0]->OutputCount()); | 846 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 802 } | 847 } |
| 803 } | 848 } |
| 804 | 849 |
| 805 | 850 |
| 806 TEST_F(InstructionSelectorTest, AddSignedExtendByteOnLeft) { | 851 TEST_F(InstructionSelectorTest, AddSignedExtendByteOnLeft) { |
| 807 { | 852 { |
| 808 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 853 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 854 MachineType::Int32()); |
| 809 m.Return( | 855 m.Return( |
| 810 m.Int32Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)), | 856 m.Int32Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)), |
| 811 m.Int32Constant(24)), | 857 m.Int32Constant(24)), |
| 812 m.Parameter(1))); | 858 m.Parameter(1))); |
| 813 Stream s = m.Build(); | 859 Stream s = m.Build(); |
| 814 ASSERT_EQ(1U, s.size()); | 860 ASSERT_EQ(1U, s.size()); |
| 815 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 861 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 816 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); | 862 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); |
| 817 ASSERT_EQ(2U, s[0]->InputCount()); | 863 ASSERT_EQ(2U, s[0]->InputCount()); |
| 818 ASSERT_EQ(1U, s[0]->OutputCount()); | 864 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 819 } | 865 } |
| 820 { | 866 { |
| 821 StreamBuilder m(this, kMachInt64, kMachInt32, kMachInt64); | 867 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32(), |
| 868 MachineType::Int64()); |
| 822 m.Return( | 869 m.Return( |
| 823 m.Int64Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)), | 870 m.Int64Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)), |
| 824 m.Int32Constant(24)), | 871 m.Int32Constant(24)), |
| 825 m.Parameter(1))); | 872 m.Parameter(1))); |
| 826 Stream s = m.Build(); | 873 Stream s = m.Build(); |
| 827 ASSERT_EQ(1U, s.size()); | 874 ASSERT_EQ(1U, s.size()); |
| 828 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 875 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 829 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); | 876 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); |
| 830 ASSERT_EQ(2U, s[0]->InputCount()); | 877 ASSERT_EQ(2U, s[0]->InputCount()); |
| 831 ASSERT_EQ(1U, s[0]->OutputCount()); | 878 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 832 } | 879 } |
| 833 } | 880 } |
| 834 | 881 |
| 835 | 882 |
| 836 TEST_F(InstructionSelectorTest, AddSignedExtendHalfwordOnLeft) { | 883 TEST_F(InstructionSelectorTest, AddSignedExtendHalfwordOnLeft) { |
| 837 { | 884 { |
| 838 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 885 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 886 MachineType::Int32()); |
| 839 m.Return( | 887 m.Return( |
| 840 m.Int32Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(16)), | 888 m.Int32Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(16)), |
| 841 m.Int32Constant(16)), | 889 m.Int32Constant(16)), |
| 842 m.Parameter(1))); | 890 m.Parameter(1))); |
| 843 Stream s = m.Build(); | 891 Stream s = m.Build(); |
| 844 ASSERT_EQ(1U, s.size()); | 892 ASSERT_EQ(1U, s.size()); |
| 845 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 893 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 846 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); | 894 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); |
| 847 ASSERT_EQ(2U, s[0]->InputCount()); | 895 ASSERT_EQ(2U, s[0]->InputCount()); |
| 848 ASSERT_EQ(1U, s[0]->OutputCount()); | 896 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 849 } | 897 } |
| 850 { | 898 { |
| 851 StreamBuilder m(this, kMachInt64, kMachInt32, kMachInt64); | 899 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32(), |
| 900 MachineType::Int64()); |
| 852 m.Return( | 901 m.Return( |
| 853 m.Int64Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(16)), | 902 m.Int64Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(16)), |
| 854 m.Int32Constant(16)), | 903 m.Int32Constant(16)), |
| 855 m.Parameter(1))); | 904 m.Parameter(1))); |
| 856 Stream s = m.Build(); | 905 Stream s = m.Build(); |
| 857 ASSERT_EQ(1U, s.size()); | 906 ASSERT_EQ(1U, s.size()); |
| 858 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 907 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 859 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); | 908 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); |
| 860 ASSERT_EQ(2U, s[0]->InputCount()); | 909 ASSERT_EQ(2U, s[0]->InputCount()); |
| 861 ASSERT_EQ(1U, s[0]->OutputCount()); | 910 ASSERT_EQ(1U, s[0]->OutputCount()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 892 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 941 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 893 InstructionSelectorDPFlagSetTest, | 942 InstructionSelectorDPFlagSetTest, |
| 894 ::testing::ValuesIn(kDPFlagSetInstructions)); | 943 ::testing::ValuesIn(kDPFlagSetInstructions)); |
| 895 | 944 |
| 896 | 945 |
| 897 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnRight) { | 946 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnRight) { |
| 898 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { | 947 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { |
| 899 // Skip the cases where the instruction selector would use tbz/tbnz. | 948 // Skip the cases where the instruction selector would use tbz/tbnz. |
| 900 if (base::bits::CountPopulation32(imm) == 1) continue; | 949 if (base::bits::CountPopulation32(imm) == 1) continue; |
| 901 | 950 |
| 902 StreamBuilder m(this, kMachInt32, kMachInt32); | 951 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 903 RawMachineLabel a, b; | 952 RawMachineLabel a, b; |
| 904 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b); | 953 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b); |
| 905 m.Bind(&a); | 954 m.Bind(&a); |
| 906 m.Return(m.Int32Constant(1)); | 955 m.Return(m.Int32Constant(1)); |
| 907 m.Bind(&b); | 956 m.Bind(&b); |
| 908 m.Return(m.Int32Constant(0)); | 957 m.Return(m.Int32Constant(0)); |
| 909 Stream s = m.Build(); | 958 Stream s = m.Build(); |
| 910 ASSERT_EQ(1U, s.size()); | 959 ASSERT_EQ(1U, s.size()); |
| 911 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); | 960 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); |
| 912 EXPECT_EQ(4U, s[0]->InputCount()); | 961 EXPECT_EQ(4U, s[0]->InputCount()); |
| 913 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 962 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 914 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 963 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 915 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 964 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 916 } | 965 } |
| 917 } | 966 } |
| 918 | 967 |
| 919 | 968 |
| 920 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnRight) { | 969 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnRight) { |
| 921 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { | 970 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { |
| 922 // Skip the cases where the instruction selector would use tbz/tbnz. | 971 // Skip the cases where the instruction selector would use tbz/tbnz. |
| 923 if (base::bits::CountPopulation64(imm) == 1) continue; | 972 if (base::bits::CountPopulation64(imm) == 1) continue; |
| 924 | 973 |
| 925 StreamBuilder m(this, kMachInt64, kMachInt64); | 974 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 926 RawMachineLabel a, b; | 975 RawMachineLabel a, b; |
| 927 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(imm)), &a, &b); | 976 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(imm)), &a, &b); |
| 928 m.Bind(&a); | 977 m.Bind(&a); |
| 929 m.Return(m.Int32Constant(1)); | 978 m.Return(m.Int32Constant(1)); |
| 930 m.Bind(&b); | 979 m.Bind(&b); |
| 931 m.Return(m.Int32Constant(0)); | 980 m.Return(m.Int32Constant(0)); |
| 932 Stream s = m.Build(); | 981 Stream s = m.Build(); |
| 933 ASSERT_EQ(1U, s.size()); | 982 ASSERT_EQ(1U, s.size()); |
| 934 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); | 983 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); |
| 935 EXPECT_EQ(4U, s[0]->InputCount()); | 984 EXPECT_EQ(4U, s[0]->InputCount()); |
| 936 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 985 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 937 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 986 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 938 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 987 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 939 } | 988 } |
| 940 } | 989 } |
| 941 | 990 |
| 942 | 991 |
| 943 TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnRight) { | 992 TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnRight) { |
| 944 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 993 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 945 StreamBuilder m(this, kMachInt32, kMachInt32); | 994 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 946 RawMachineLabel a, b; | 995 RawMachineLabel a, b; |
| 947 m.Branch(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)), &a, &b); | 996 m.Branch(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)), &a, &b); |
| 948 m.Bind(&a); | 997 m.Bind(&a); |
| 949 m.Return(m.Int32Constant(1)); | 998 m.Return(m.Int32Constant(1)); |
| 950 m.Bind(&b); | 999 m.Bind(&b); |
| 951 m.Return(m.Int32Constant(0)); | 1000 m.Return(m.Int32Constant(0)); |
| 952 Stream s = m.Build(); | 1001 Stream s = m.Build(); |
| 953 ASSERT_EQ(1U, s.size()); | 1002 ASSERT_EQ(1U, s.size()); |
| 954 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); | 1003 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); |
| 955 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 1004 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 956 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1005 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 957 } | 1006 } |
| 958 } | 1007 } |
| 959 | 1008 |
| 960 | 1009 |
| 961 TEST_F(InstructionSelectorTest, SubBranchWithImmediateOnRight) { | 1010 TEST_F(InstructionSelectorTest, SubBranchWithImmediateOnRight) { |
| 962 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 1011 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 963 StreamBuilder m(this, kMachInt32, kMachInt32); | 1012 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 964 RawMachineLabel a, b; | 1013 RawMachineLabel a, b; |
| 965 m.Branch(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)), &a, &b); | 1014 m.Branch(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)), &a, &b); |
| 966 m.Bind(&a); | 1015 m.Bind(&a); |
| 967 m.Return(m.Int32Constant(1)); | 1016 m.Return(m.Int32Constant(1)); |
| 968 m.Bind(&b); | 1017 m.Bind(&b); |
| 969 m.Return(m.Int32Constant(0)); | 1018 m.Return(m.Int32Constant(0)); |
| 970 Stream s = m.Build(); | 1019 Stream s = m.Build(); |
| 971 ASSERT_EQ(1U, s.size()); | 1020 ASSERT_EQ(1U, s.size()); |
| 972 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 1021 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 973 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 1022 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 974 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1023 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 975 } | 1024 } |
| 976 } | 1025 } |
| 977 | 1026 |
| 978 | 1027 |
| 979 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnLeft) { | 1028 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnLeft) { |
| 980 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { | 1029 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { |
| 981 // Skip the cases where the instruction selector would use tbz/tbnz. | 1030 // Skip the cases where the instruction selector would use tbz/tbnz. |
| 982 if (base::bits::CountPopulation32(imm) == 1) continue; | 1031 if (base::bits::CountPopulation32(imm) == 1) continue; |
| 983 | 1032 |
| 984 StreamBuilder m(this, kMachInt32, kMachInt32); | 1033 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 985 RawMachineLabel a, b; | 1034 RawMachineLabel a, b; |
| 986 m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b); | 1035 m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b); |
| 987 m.Bind(&a); | 1036 m.Bind(&a); |
| 988 m.Return(m.Int32Constant(1)); | 1037 m.Return(m.Int32Constant(1)); |
| 989 m.Bind(&b); | 1038 m.Bind(&b); |
| 990 m.Return(m.Int32Constant(0)); | 1039 m.Return(m.Int32Constant(0)); |
| 991 Stream s = m.Build(); | 1040 Stream s = m.Build(); |
| 992 ASSERT_EQ(1U, s.size()); | 1041 ASSERT_EQ(1U, s.size()); |
| 993 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); | 1042 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); |
| 994 EXPECT_EQ(4U, s[0]->InputCount()); | 1043 EXPECT_EQ(4U, s[0]->InputCount()); |
| 995 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1044 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 996 ASSERT_LE(1U, s[0]->InputCount()); | 1045 ASSERT_LE(1U, s[0]->InputCount()); |
| 997 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 1046 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 998 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1047 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 999 } | 1048 } |
| 1000 } | 1049 } |
| 1001 | 1050 |
| 1002 | 1051 |
| 1003 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) { | 1052 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) { |
| 1004 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { | 1053 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { |
| 1005 // Skip the cases where the instruction selector would use tbz/tbnz. | 1054 // Skip the cases where the instruction selector would use tbz/tbnz. |
| 1006 if (base::bits::CountPopulation64(imm) == 1) continue; | 1055 if (base::bits::CountPopulation64(imm) == 1) continue; |
| 1007 | 1056 |
| 1008 StreamBuilder m(this, kMachInt64, kMachInt64); | 1057 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 1009 RawMachineLabel a, b; | 1058 RawMachineLabel a, b; |
| 1010 m.Branch(m.Word64And(m.Int64Constant(imm), m.Parameter(0)), &a, &b); | 1059 m.Branch(m.Word64And(m.Int64Constant(imm), m.Parameter(0)), &a, &b); |
| 1011 m.Bind(&a); | 1060 m.Bind(&a); |
| 1012 m.Return(m.Int32Constant(1)); | 1061 m.Return(m.Int32Constant(1)); |
| 1013 m.Bind(&b); | 1062 m.Bind(&b); |
| 1014 m.Return(m.Int32Constant(0)); | 1063 m.Return(m.Int32Constant(0)); |
| 1015 Stream s = m.Build(); | 1064 Stream s = m.Build(); |
| 1016 ASSERT_EQ(1U, s.size()); | 1065 ASSERT_EQ(1U, s.size()); |
| 1017 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); | 1066 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); |
| 1018 EXPECT_EQ(4U, s[0]->InputCount()); | 1067 EXPECT_EQ(4U, s[0]->InputCount()); |
| 1019 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1068 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 1020 ASSERT_LE(1U, s[0]->InputCount()); | 1069 ASSERT_LE(1U, s[0]->InputCount()); |
| 1021 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 1070 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 1022 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1071 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 1023 } | 1072 } |
| 1024 } | 1073 } |
| 1025 | 1074 |
| 1026 | 1075 |
| 1027 TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnLeft) { | 1076 TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnLeft) { |
| 1028 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 1077 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 1029 StreamBuilder m(this, kMachInt32, kMachInt32); | 1078 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1030 RawMachineLabel a, b; | 1079 RawMachineLabel a, b; |
| 1031 m.Branch(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)), &a, &b); | 1080 m.Branch(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)), &a, &b); |
| 1032 m.Bind(&a); | 1081 m.Bind(&a); |
| 1033 m.Return(m.Int32Constant(1)); | 1082 m.Return(m.Int32Constant(1)); |
| 1034 m.Bind(&b); | 1083 m.Bind(&b); |
| 1035 m.Return(m.Int32Constant(0)); | 1084 m.Return(m.Int32Constant(0)); |
| 1036 Stream s = m.Build(); | 1085 Stream s = m.Build(); |
| 1037 ASSERT_EQ(1U, s.size()); | 1086 ASSERT_EQ(1U, s.size()); |
| 1038 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); | 1087 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); |
| 1039 ASSERT_LE(1U, s[0]->InputCount()); | 1088 ASSERT_LE(1U, s[0]->InputCount()); |
| 1040 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 1089 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 1041 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1090 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 1042 } | 1091 } |
| 1043 } | 1092 } |
| 1044 | 1093 |
| 1045 | 1094 |
| 1046 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnRight) { | 1095 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnRight) { |
| 1047 TRACED_FORRANGE(int, bit, 0, 31) { | 1096 TRACED_FORRANGE(int, bit, 0, 31) { |
| 1048 uint32_t mask = 1 << bit; | 1097 uint32_t mask = 1 << bit; |
| 1049 StreamBuilder m(this, kMachInt32, kMachInt32); | 1098 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1050 RawMachineLabel a, b; | 1099 RawMachineLabel a, b; |
| 1051 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(mask)), &a, &b); | 1100 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(mask)), &a, &b); |
| 1052 m.Bind(&a); | 1101 m.Bind(&a); |
| 1053 m.Return(m.Int32Constant(1)); | 1102 m.Return(m.Int32Constant(1)); |
| 1054 m.Bind(&b); | 1103 m.Bind(&b); |
| 1055 m.Return(m.Int32Constant(0)); | 1104 m.Return(m.Int32Constant(0)); |
| 1056 Stream s = m.Build(); | 1105 Stream s = m.Build(); |
| 1057 ASSERT_EQ(1U, s.size()); | 1106 ASSERT_EQ(1U, s.size()); |
| 1058 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); | 1107 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
| 1059 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1108 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 1060 EXPECT_EQ(4U, s[0]->InputCount()); | 1109 EXPECT_EQ(4U, s[0]->InputCount()); |
| 1061 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1110 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 1062 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); | 1111 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 1063 } | 1112 } |
| 1064 | 1113 |
| 1065 TRACED_FORRANGE(int, bit, 0, 31) { | 1114 TRACED_FORRANGE(int, bit, 0, 31) { |
| 1066 uint32_t mask = 1 << bit; | 1115 uint32_t mask = 1 << bit; |
| 1067 StreamBuilder m(this, kMachInt32, kMachInt32); | 1116 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1068 RawMachineLabel a, b; | 1117 RawMachineLabel a, b; |
| 1069 m.Branch( | 1118 m.Branch( |
| 1070 m.Word32BinaryNot(m.Word32And(m.Parameter(0), m.Int32Constant(mask))), | 1119 m.Word32BinaryNot(m.Word32And(m.Parameter(0), m.Int32Constant(mask))), |
| 1071 &a, &b); | 1120 &a, &b); |
| 1072 m.Bind(&a); | 1121 m.Bind(&a); |
| 1073 m.Return(m.Int32Constant(1)); | 1122 m.Return(m.Int32Constant(1)); |
| 1074 m.Bind(&b); | 1123 m.Bind(&b); |
| 1075 m.Return(m.Int32Constant(0)); | 1124 m.Return(m.Int32Constant(0)); |
| 1076 Stream s = m.Build(); | 1125 Stream s = m.Build(); |
| 1077 ASSERT_EQ(1U, s.size()); | 1126 ASSERT_EQ(1U, s.size()); |
| 1078 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); | 1127 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
| 1079 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1128 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 1080 EXPECT_EQ(4U, s[0]->InputCount()); | 1129 EXPECT_EQ(4U, s[0]->InputCount()); |
| 1081 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1130 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 1082 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); | 1131 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 1083 } | 1132 } |
| 1084 } | 1133 } |
| 1085 | 1134 |
| 1086 | 1135 |
| 1087 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) { | 1136 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) { |
| 1088 TRACED_FORRANGE(int, bit, 0, 31) { | 1137 TRACED_FORRANGE(int, bit, 0, 31) { |
| 1089 uint32_t mask = 1 << bit; | 1138 uint32_t mask = 1 << bit; |
| 1090 StreamBuilder m(this, kMachInt32, kMachInt32); | 1139 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1091 RawMachineLabel a, b; | 1140 RawMachineLabel a, b; |
| 1092 m.Branch(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), &a, &b); | 1141 m.Branch(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), &a, &b); |
| 1093 m.Bind(&a); | 1142 m.Bind(&a); |
| 1094 m.Return(m.Int32Constant(1)); | 1143 m.Return(m.Int32Constant(1)); |
| 1095 m.Bind(&b); | 1144 m.Bind(&b); |
| 1096 m.Return(m.Int32Constant(0)); | 1145 m.Return(m.Int32Constant(0)); |
| 1097 Stream s = m.Build(); | 1146 Stream s = m.Build(); |
| 1098 ASSERT_EQ(1U, s.size()); | 1147 ASSERT_EQ(1U, s.size()); |
| 1099 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); | 1148 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
| 1100 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1149 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 1101 EXPECT_EQ(4U, s[0]->InputCount()); | 1150 EXPECT_EQ(4U, s[0]->InputCount()); |
| 1102 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1151 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 1103 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); | 1152 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 1104 } | 1153 } |
| 1105 | 1154 |
| 1106 TRACED_FORRANGE(int, bit, 0, 31) { | 1155 TRACED_FORRANGE(int, bit, 0, 31) { |
| 1107 uint32_t mask = 1 << bit; | 1156 uint32_t mask = 1 << bit; |
| 1108 StreamBuilder m(this, kMachInt32, kMachInt32); | 1157 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1109 RawMachineLabel a, b; | 1158 RawMachineLabel a, b; |
| 1110 m.Branch( | 1159 m.Branch( |
| 1111 m.Word32BinaryNot(m.Word32And(m.Int32Constant(mask), m.Parameter(0))), | 1160 m.Word32BinaryNot(m.Word32And(m.Int32Constant(mask), m.Parameter(0))), |
| 1112 &a, &b); | 1161 &a, &b); |
| 1113 m.Bind(&a); | 1162 m.Bind(&a); |
| 1114 m.Return(m.Int32Constant(1)); | 1163 m.Return(m.Int32Constant(1)); |
| 1115 m.Bind(&b); | 1164 m.Bind(&b); |
| 1116 m.Return(m.Int32Constant(0)); | 1165 m.Return(m.Int32Constant(0)); |
| 1117 Stream s = m.Build(); | 1166 Stream s = m.Build(); |
| 1118 ASSERT_EQ(1U, s.size()); | 1167 ASSERT_EQ(1U, s.size()); |
| 1119 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); | 1168 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
| 1120 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1169 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 1121 EXPECT_EQ(4U, s[0]->InputCount()); | 1170 EXPECT_EQ(4U, s[0]->InputCount()); |
| 1122 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1171 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 1123 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); | 1172 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 1124 } | 1173 } |
| 1125 } | 1174 } |
| 1126 | 1175 |
| 1127 | 1176 |
| 1128 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnRight) { | 1177 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnRight) { |
| 1129 TRACED_FORRANGE(int, bit, 0, 63) { | 1178 TRACED_FORRANGE(int, bit, 0, 63) { |
| 1130 uint64_t mask = 1L << bit; | 1179 uint64_t mask = 1L << bit; |
| 1131 StreamBuilder m(this, kMachInt64, kMachInt64); | 1180 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 1132 RawMachineLabel a, b; | 1181 RawMachineLabel a, b; |
| 1133 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(mask)), &a, &b); | 1182 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(mask)), &a, &b); |
| 1134 m.Bind(&a); | 1183 m.Bind(&a); |
| 1135 m.Return(m.Int32Constant(1)); | 1184 m.Return(m.Int32Constant(1)); |
| 1136 m.Bind(&b); | 1185 m.Bind(&b); |
| 1137 m.Return(m.Int32Constant(0)); | 1186 m.Return(m.Int32Constant(0)); |
| 1138 Stream s = m.Build(); | 1187 Stream s = m.Build(); |
| 1139 ASSERT_EQ(1U, s.size()); | 1188 ASSERT_EQ(1U, s.size()); |
| 1140 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); | 1189 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); |
| 1141 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1190 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 1142 EXPECT_EQ(4U, s[0]->InputCount()); | 1191 EXPECT_EQ(4U, s[0]->InputCount()); |
| 1143 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1192 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 1144 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); | 1193 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 1145 } | 1194 } |
| 1146 } | 1195 } |
| 1147 | 1196 |
| 1148 | 1197 |
| 1149 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) { | 1198 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) { |
| 1150 TRACED_FORRANGE(int, bit, 0, 63) { | 1199 TRACED_FORRANGE(int, bit, 0, 63) { |
| 1151 uint64_t mask = 1L << bit; | 1200 uint64_t mask = 1L << bit; |
| 1152 StreamBuilder m(this, kMachInt64, kMachInt64); | 1201 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 1153 RawMachineLabel a, b; | 1202 RawMachineLabel a, b; |
| 1154 m.Branch(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), &a, &b); | 1203 m.Branch(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), &a, &b); |
| 1155 m.Bind(&a); | 1204 m.Bind(&a); |
| 1156 m.Return(m.Int32Constant(1)); | 1205 m.Return(m.Int32Constant(1)); |
| 1157 m.Bind(&b); | 1206 m.Bind(&b); |
| 1158 m.Return(m.Int32Constant(0)); | 1207 m.Return(m.Int32Constant(0)); |
| 1159 Stream s = m.Build(); | 1208 Stream s = m.Build(); |
| 1160 ASSERT_EQ(1U, s.size()); | 1209 ASSERT_EQ(1U, s.size()); |
| 1161 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); | 1210 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); |
| 1162 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1211 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 1163 EXPECT_EQ(4U, s[0]->InputCount()); | 1212 EXPECT_EQ(4U, s[0]->InputCount()); |
| 1164 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1213 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 1165 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); | 1214 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 1166 } | 1215 } |
| 1167 } | 1216 } |
| 1168 | 1217 |
| 1169 | 1218 |
| 1170 TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) { | 1219 TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) { |
| 1171 { | 1220 { |
| 1172 StreamBuilder m(this, kMachInt32, kMachInt32); | 1221 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1173 RawMachineLabel a, b; | 1222 RawMachineLabel a, b; |
| 1174 Node* p0 = m.Parameter(0); | 1223 Node* p0 = m.Parameter(0); |
| 1175 m.Branch(p0, &a, &b); | 1224 m.Branch(p0, &a, &b); |
| 1176 m.Bind(&a); | 1225 m.Bind(&a); |
| 1177 m.Return(m.Int32Constant(1)); | 1226 m.Return(m.Int32Constant(1)); |
| 1178 m.Bind(&b); | 1227 m.Bind(&b); |
| 1179 m.Return(m.Int32Constant(0)); | 1228 m.Return(m.Int32Constant(0)); |
| 1180 Stream s = m.Build(); | 1229 Stream s = m.Build(); |
| 1181 ASSERT_EQ(1U, s.size()); | 1230 ASSERT_EQ(1U, s.size()); |
| 1182 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); | 1231 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); |
| 1183 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 1232 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 1184 EXPECT_EQ(3U, s[0]->InputCount()); | 1233 EXPECT_EQ(3U, s[0]->InputCount()); |
| 1185 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 1234 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1186 } | 1235 } |
| 1187 | 1236 |
| 1188 { | 1237 { |
| 1189 StreamBuilder m(this, kMachInt32, kMachInt32); | 1238 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1190 RawMachineLabel a, b; | 1239 RawMachineLabel a, b; |
| 1191 Node* p0 = m.Parameter(0); | 1240 Node* p0 = m.Parameter(0); |
| 1192 m.Branch(m.Word32BinaryNot(p0), &a, &b); | 1241 m.Branch(m.Word32BinaryNot(p0), &a, &b); |
| 1193 m.Bind(&a); | 1242 m.Bind(&a); |
| 1194 m.Return(m.Int32Constant(1)); | 1243 m.Return(m.Int32Constant(1)); |
| 1195 m.Bind(&b); | 1244 m.Bind(&b); |
| 1196 m.Return(m.Int32Constant(0)); | 1245 m.Return(m.Int32Constant(0)); |
| 1197 Stream s = m.Build(); | 1246 Stream s = m.Build(); |
| 1198 ASSERT_EQ(1U, s.size()); | 1247 ASSERT_EQ(1U, s.size()); |
| 1199 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); | 1248 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1359 } | 1408 } |
| 1360 | 1409 |
| 1361 | 1410 |
| 1362 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 1411 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 1363 InstructionSelectorOvfAddSubTest, | 1412 InstructionSelectorOvfAddSubTest, |
| 1364 ::testing::ValuesIn(kOvfAddSubInstructions)); | 1413 ::testing::ValuesIn(kOvfAddSubInstructions)); |
| 1365 | 1414 |
| 1366 | 1415 |
| 1367 TEST_F(InstructionSelectorTest, OvfFlagAddImmediateOnLeft) { | 1416 TEST_F(InstructionSelectorTest, OvfFlagAddImmediateOnLeft) { |
| 1368 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 1417 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 1369 StreamBuilder m(this, kMachInt32, kMachInt32); | 1418 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1370 m.Return(m.Projection( | 1419 m.Return(m.Projection( |
| 1371 1, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)))); | 1420 1, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)))); |
| 1372 Stream s = m.Build(); | 1421 Stream s = m.Build(); |
| 1373 | 1422 |
| 1374 ASSERT_EQ(1U, s.size()); | 1423 ASSERT_EQ(1U, s.size()); |
| 1375 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1424 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1376 EXPECT_EQ(2U, s[0]->InputCount()); | 1425 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1377 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 1426 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 1378 EXPECT_LE(1U, s[0]->OutputCount()); | 1427 EXPECT_LE(1U, s[0]->OutputCount()); |
| 1379 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1428 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 1380 EXPECT_EQ(kOverflow, s[0]->flags_condition()); | 1429 EXPECT_EQ(kOverflow, s[0]->flags_condition()); |
| 1381 } | 1430 } |
| 1382 } | 1431 } |
| 1383 | 1432 |
| 1384 | 1433 |
| 1385 TEST_F(InstructionSelectorTest, OvfValAddImmediateOnLeft) { | 1434 TEST_F(InstructionSelectorTest, OvfValAddImmediateOnLeft) { |
| 1386 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 1435 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 1387 StreamBuilder m(this, kMachInt32, kMachInt32); | 1436 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1388 m.Return(m.Projection( | 1437 m.Return(m.Projection( |
| 1389 0, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)))); | 1438 0, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)))); |
| 1390 Stream s = m.Build(); | 1439 Stream s = m.Build(); |
| 1391 | 1440 |
| 1392 ASSERT_EQ(1U, s.size()); | 1441 ASSERT_EQ(1U, s.size()); |
| 1393 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1442 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1394 ASSERT_EQ(2U, s[0]->InputCount()); | 1443 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1395 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 1444 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 1396 EXPECT_LE(1U, s[0]->OutputCount()); | 1445 EXPECT_LE(1U, s[0]->OutputCount()); |
| 1397 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | 1446 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 1398 } | 1447 } |
| 1399 } | 1448 } |
| 1400 | 1449 |
| 1401 | 1450 |
| 1402 TEST_F(InstructionSelectorTest, OvfBothAddImmediateOnLeft) { | 1451 TEST_F(InstructionSelectorTest, OvfBothAddImmediateOnLeft) { |
| 1403 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 1452 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 1404 StreamBuilder m(this, kMachInt32, kMachInt32); | 1453 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1405 Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)); | 1454 Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)); |
| 1406 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n))); | 1455 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n))); |
| 1407 Stream s = m.Build(); | 1456 Stream s = m.Build(); |
| 1408 | 1457 |
| 1409 ASSERT_LE(1U, s.size()); | 1458 ASSERT_LE(1U, s.size()); |
| 1410 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1459 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1411 ASSERT_EQ(2U, s[0]->InputCount()); | 1460 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1412 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 1461 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 1413 EXPECT_EQ(2U, s[0]->OutputCount()); | 1462 EXPECT_EQ(2U, s[0]->OutputCount()); |
| 1414 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1463 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 1415 EXPECT_EQ(kOverflow, s[0]->flags_condition()); | 1464 EXPECT_EQ(kOverflow, s[0]->flags_condition()); |
| 1416 } | 1465 } |
| 1417 } | 1466 } |
| 1418 | 1467 |
| 1419 | 1468 |
| 1420 TEST_F(InstructionSelectorTest, OvfBranchWithImmediateOnLeft) { | 1469 TEST_F(InstructionSelectorTest, OvfBranchWithImmediateOnLeft) { |
| 1421 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 1470 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 1422 StreamBuilder m(this, kMachInt32, kMachInt32); | 1471 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1423 RawMachineLabel a, b; | 1472 RawMachineLabel a, b; |
| 1424 Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)); | 1473 Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)); |
| 1425 m.Branch(m.Projection(1, n), &a, &b); | 1474 m.Branch(m.Projection(1, n), &a, &b); |
| 1426 m.Bind(&a); | 1475 m.Bind(&a); |
| 1427 m.Return(m.Int32Constant(0)); | 1476 m.Return(m.Int32Constant(0)); |
| 1428 m.Bind(&b); | 1477 m.Bind(&b); |
| 1429 m.Return(m.Projection(0, n)); | 1478 m.Return(m.Projection(0, n)); |
| 1430 Stream s = m.Build(); | 1479 Stream s = m.Build(); |
| 1431 | 1480 |
| 1432 ASSERT_EQ(1U, s.size()); | 1481 ASSERT_EQ(1U, s.size()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1456 ASSERT_EQ(1U, s.size()); | 1505 ASSERT_EQ(1U, s.size()); |
| 1457 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode()); | 1506 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode()); |
| 1458 EXPECT_EQ(2U, s[0]->InputCount()); | 1507 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1459 EXPECT_EQ(1U, s[0]->OutputCount()); | 1508 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1460 } | 1509 } |
| 1461 | 1510 |
| 1462 | 1511 |
| 1463 TEST_P(InstructionSelectorShiftTest, Immediate) { | 1512 TEST_P(InstructionSelectorShiftTest, Immediate) { |
| 1464 const Shift shift = GetParam(); | 1513 const Shift shift = GetParam(); |
| 1465 const MachineType type = shift.mi.machine_type; | 1514 const MachineType type = shift.mi.machine_type; |
| 1466 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) { | 1515 TRACED_FORRANGE(int32_t, imm, 0, |
| 1516 ((1 << ElementSizeLog2Of(type.representation())) * 8) - 1) { |
| 1467 StreamBuilder m(this, type, type); | 1517 StreamBuilder m(this, type, type); |
| 1468 m.Return((m.*shift.mi.constructor)(m.Parameter(0), m.Int32Constant(imm))); | 1518 m.Return((m.*shift.mi.constructor)(m.Parameter(0), m.Int32Constant(imm))); |
| 1469 Stream s = m.Build(); | 1519 Stream s = m.Build(); |
| 1470 ASSERT_EQ(1U, s.size()); | 1520 ASSERT_EQ(1U, s.size()); |
| 1471 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode()); | 1521 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode()); |
| 1472 EXPECT_EQ(2U, s[0]->InputCount()); | 1522 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1473 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 1523 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 1474 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 1524 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 1475 EXPECT_EQ(1U, s[0]->OutputCount()); | 1525 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1476 } | 1526 } |
| 1477 } | 1527 } |
| 1478 | 1528 |
| 1479 | 1529 |
| 1480 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, | 1530 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, |
| 1481 ::testing::ValuesIn(kShiftInstructions)); | 1531 ::testing::ValuesIn(kShiftInstructions)); |
| 1482 | 1532 |
| 1483 | 1533 |
| 1484 TEST_F(InstructionSelectorTest, Word64ShlWithChangeInt32ToInt64) { | 1534 TEST_F(InstructionSelectorTest, Word64ShlWithChangeInt32ToInt64) { |
| 1485 TRACED_FORRANGE(int64_t, x, 32, 63) { | 1535 TRACED_FORRANGE(int64_t, x, 32, 63) { |
| 1486 StreamBuilder m(this, kMachInt64, kMachInt32); | 1536 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32()); |
| 1487 Node* const p0 = m.Parameter(0); | 1537 Node* const p0 = m.Parameter(0); |
| 1488 Node* const n = m.Word64Shl(m.ChangeInt32ToInt64(p0), m.Int64Constant(x)); | 1538 Node* const n = m.Word64Shl(m.ChangeInt32ToInt64(p0), m.Int64Constant(x)); |
| 1489 m.Return(n); | 1539 m.Return(n); |
| 1490 Stream s = m.Build(); | 1540 Stream s = m.Build(); |
| 1491 ASSERT_EQ(1U, s.size()); | 1541 ASSERT_EQ(1U, s.size()); |
| 1492 EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode()); | 1542 EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode()); |
| 1493 ASSERT_EQ(2U, s[0]->InputCount()); | 1543 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1494 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 1544 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1495 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1))); | 1545 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1))); |
| 1496 ASSERT_EQ(1U, s[0]->OutputCount()); | 1546 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1497 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1547 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1498 } | 1548 } |
| 1499 } | 1549 } |
| 1500 | 1550 |
| 1501 | 1551 |
| 1502 TEST_F(InstructionSelectorTest, Word64ShlWithChangeUint32ToUint64) { | 1552 TEST_F(InstructionSelectorTest, Word64ShlWithChangeUint32ToUint64) { |
| 1503 TRACED_FORRANGE(int64_t, x, 32, 63) { | 1553 TRACED_FORRANGE(int64_t, x, 32, 63) { |
| 1504 StreamBuilder m(this, kMachInt64, kMachUint32); | 1554 StreamBuilder m(this, MachineType::Int64(), MachineType::Uint32()); |
| 1505 Node* const p0 = m.Parameter(0); | 1555 Node* const p0 = m.Parameter(0); |
| 1506 Node* const n = m.Word64Shl(m.ChangeUint32ToUint64(p0), m.Int64Constant(x)); | 1556 Node* const n = m.Word64Shl(m.ChangeUint32ToUint64(p0), m.Int64Constant(x)); |
| 1507 m.Return(n); | 1557 m.Return(n); |
| 1508 Stream s = m.Build(); | 1558 Stream s = m.Build(); |
| 1509 ASSERT_EQ(1U, s.size()); | 1559 ASSERT_EQ(1U, s.size()); |
| 1510 EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode()); | 1560 EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode()); |
| 1511 ASSERT_EQ(2U, s[0]->InputCount()); | 1561 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1512 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 1562 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1513 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1))); | 1563 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1))); |
| 1514 ASSERT_EQ(1U, s[0]->OutputCount()); | 1564 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1515 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1565 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1516 } | 1566 } |
| 1517 } | 1567 } |
| 1518 | 1568 |
| 1519 | 1569 |
| 1520 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) { | 1570 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) { |
| 1521 StreamBuilder m(this, kMachInt32, kMachInt64); | 1571 StreamBuilder m(this, MachineType::Int32(), MachineType::Int64()); |
| 1522 Node* const p = m.Parameter(0); | 1572 Node* const p = m.Parameter(0); |
| 1523 Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32))); | 1573 Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32))); |
| 1524 m.Return(t); | 1574 m.Return(t); |
| 1525 Stream s = m.Build(); | 1575 Stream s = m.Build(); |
| 1526 ASSERT_EQ(1U, s.size()); | 1576 ASSERT_EQ(1U, s.size()); |
| 1527 EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode()); | 1577 EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode()); |
| 1528 ASSERT_EQ(2U, s[0]->InputCount()); | 1578 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1529 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0))); | 1579 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0))); |
| 1530 EXPECT_EQ(32, s.ToInt64(s[0]->InputAt(1))); | 1580 EXPECT_EQ(32, s.ToInt64(s[0]->InputAt(1))); |
| 1531 ASSERT_EQ(1U, s[0]->OutputCount()); | 1581 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1532 EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0))); | 1582 EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0))); |
| 1533 } | 1583 } |
| 1534 | 1584 |
| 1535 | 1585 |
| 1536 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Shr) { | 1586 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Shr) { |
| 1537 TRACED_FORRANGE(int64_t, x, 32, 63) { | 1587 TRACED_FORRANGE(int64_t, x, 32, 63) { |
| 1538 StreamBuilder m(this, kMachInt32, kMachInt64); | 1588 StreamBuilder m(this, MachineType::Int32(), MachineType::Int64()); |
| 1539 Node* const p = m.Parameter(0); | 1589 Node* const p = m.Parameter(0); |
| 1540 Node* const t = m.TruncateInt64ToInt32(m.Word64Shr(p, m.Int64Constant(x))); | 1590 Node* const t = m.TruncateInt64ToInt32(m.Word64Shr(p, m.Int64Constant(x))); |
| 1541 m.Return(t); | 1591 m.Return(t); |
| 1542 Stream s = m.Build(); | 1592 Stream s = m.Build(); |
| 1543 ASSERT_EQ(1U, s.size()); | 1593 ASSERT_EQ(1U, s.size()); |
| 1544 EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode()); | 1594 EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode()); |
| 1545 ASSERT_EQ(2U, s[0]->InputCount()); | 1595 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1546 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0))); | 1596 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0))); |
| 1547 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1))); | 1597 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1))); |
| 1548 ASSERT_EQ(1U, s[0]->OutputCount()); | 1598 ASSERT_EQ(1U, s[0]->OutputCount()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1593 std::ostream& operator<<(std::ostream& os, const MulDPInst& inst) { | 1643 std::ostream& operator<<(std::ostream& os, const MulDPInst& inst) { |
| 1594 return os << inst.mul_constructor_name; | 1644 return os << inst.mul_constructor_name; |
| 1595 } | 1645 } |
| 1596 | 1646 |
| 1597 } // namespace | 1647 } // namespace |
| 1598 | 1648 |
| 1599 | 1649 |
| 1600 static const MulDPInst kMulDPInstructions[] = { | 1650 static const MulDPInst kMulDPInstructions[] = { |
| 1601 {"Int32Mul", &RawMachineAssembler::Int32Mul, &RawMachineAssembler::Int32Add, | 1651 {"Int32Mul", &RawMachineAssembler::Int32Mul, &RawMachineAssembler::Int32Add, |
| 1602 &RawMachineAssembler::Int32Sub, kArm64Madd32, kArm64Msub32, kArm64Mneg32, | 1652 &RawMachineAssembler::Int32Sub, kArm64Madd32, kArm64Msub32, kArm64Mneg32, |
| 1603 kMachInt32}, | 1653 MachineType::Int32()}, |
| 1604 {"Int64Mul", &RawMachineAssembler::Int64Mul, &RawMachineAssembler::Int64Add, | 1654 {"Int64Mul", &RawMachineAssembler::Int64Mul, &RawMachineAssembler::Int64Add, |
| 1605 &RawMachineAssembler::Int64Sub, kArm64Madd, kArm64Msub, kArm64Mneg, | 1655 &RawMachineAssembler::Int64Sub, kArm64Madd, kArm64Msub, kArm64Mneg, |
| 1606 kMachInt64}}; | 1656 MachineType::Int64()}}; |
| 1607 | 1657 |
| 1608 | 1658 |
| 1609 typedef InstructionSelectorTestWithParam<MulDPInst> | 1659 typedef InstructionSelectorTestWithParam<MulDPInst> |
| 1610 InstructionSelectorIntDPWithIntMulTest; | 1660 InstructionSelectorIntDPWithIntMulTest; |
| 1611 | 1661 |
| 1612 | 1662 |
| 1613 TEST_P(InstructionSelectorIntDPWithIntMulTest, AddWithMul) { | 1663 TEST_P(InstructionSelectorIntDPWithIntMulTest, AddWithMul) { |
| 1614 const MulDPInst mdpi = GetParam(); | 1664 const MulDPInst mdpi = GetParam(); |
| 1615 const MachineType type = mdpi.machine_type; | 1665 const MachineType type = mdpi.machine_type; |
| 1616 { | 1666 { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1681 | 1731 |
| 1682 | 1732 |
| 1683 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 1733 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 1684 InstructionSelectorIntDPWithIntMulTest, | 1734 InstructionSelectorIntDPWithIntMulTest, |
| 1685 ::testing::ValuesIn(kMulDPInstructions)); | 1735 ::testing::ValuesIn(kMulDPInstructions)); |
| 1686 | 1736 |
| 1687 | 1737 |
| 1688 TEST_F(InstructionSelectorTest, Int32MulWithImmediate) { | 1738 TEST_F(InstructionSelectorTest, Int32MulWithImmediate) { |
| 1689 // x * (2^k + 1) -> x + (x << k) | 1739 // x * (2^k + 1) -> x + (x << k) |
| 1690 TRACED_FORRANGE(int32_t, k, 1, 30) { | 1740 TRACED_FORRANGE(int32_t, k, 1, 30) { |
| 1691 StreamBuilder m(this, kMachInt32, kMachInt32); | 1741 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1692 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1))); | 1742 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1))); |
| 1693 Stream s = m.Build(); | 1743 Stream s = m.Build(); |
| 1694 ASSERT_EQ(1U, s.size()); | 1744 ASSERT_EQ(1U, s.size()); |
| 1695 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1745 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1696 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1746 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1697 ASSERT_EQ(3U, s[0]->InputCount()); | 1747 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1698 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1748 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1699 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); | 1749 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); |
| 1700 EXPECT_EQ(1U, s[0]->OutputCount()); | 1750 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1701 } | 1751 } |
| 1702 // (2^k + 1) * x -> x + (x << k) | 1752 // (2^k + 1) * x -> x + (x << k) |
| 1703 TRACED_FORRANGE(int32_t, k, 1, 30) { | 1753 TRACED_FORRANGE(int32_t, k, 1, 30) { |
| 1704 StreamBuilder m(this, kMachInt32, kMachInt32); | 1754 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 1705 m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0))); | 1755 m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0))); |
| 1706 Stream s = m.Build(); | 1756 Stream s = m.Build(); |
| 1707 ASSERT_EQ(1U, s.size()); | 1757 ASSERT_EQ(1U, s.size()); |
| 1708 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1758 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1709 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1759 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1710 ASSERT_EQ(3U, s[0]->InputCount()); | 1760 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1711 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1761 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1712 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); | 1762 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); |
| 1713 EXPECT_EQ(1U, s[0]->OutputCount()); | 1763 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1714 } | 1764 } |
| 1715 // x * (2^k + 1) + c -> x + (x << k) + c | 1765 // x * (2^k + 1) + c -> x + (x << k) + c |
| 1716 TRACED_FORRANGE(int32_t, k, 1, 30) { | 1766 TRACED_FORRANGE(int32_t, k, 1, 30) { |
| 1717 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 1767 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 1768 MachineType::Int32()); |
| 1718 m.Return( | 1769 m.Return( |
| 1719 m.Int32Add(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)), | 1770 m.Int32Add(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)), |
| 1720 m.Parameter(1))); | 1771 m.Parameter(1))); |
| 1721 Stream s = m.Build(); | 1772 Stream s = m.Build(); |
| 1722 ASSERT_EQ(2U, s.size()); | 1773 ASSERT_EQ(2U, s.size()); |
| 1723 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1774 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1724 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); | 1775 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); |
| 1725 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1776 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1726 ASSERT_EQ(3U, s[0]->InputCount()); | 1777 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1727 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1778 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1728 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); | 1779 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); |
| 1729 EXPECT_EQ(1U, s[0]->OutputCount()); | 1780 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1730 } | 1781 } |
| 1731 // (2^k + 1) * x + c -> x + (x << k) + c | 1782 // (2^k + 1) * x + c -> x + (x << k) + c |
| 1732 TRACED_FORRANGE(int32_t, k, 1, 30) { | 1783 TRACED_FORRANGE(int32_t, k, 1, 30) { |
| 1733 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 1784 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 1785 MachineType::Int32()); |
| 1734 m.Return( | 1786 m.Return( |
| 1735 m.Int32Add(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)), | 1787 m.Int32Add(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)), |
| 1736 m.Parameter(1))); | 1788 m.Parameter(1))); |
| 1737 Stream s = m.Build(); | 1789 Stream s = m.Build(); |
| 1738 ASSERT_EQ(2U, s.size()); | 1790 ASSERT_EQ(2U, s.size()); |
| 1739 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1791 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1740 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); | 1792 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); |
| 1741 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1793 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1742 ASSERT_EQ(3U, s[0]->InputCount()); | 1794 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1743 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1795 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1744 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); | 1796 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); |
| 1745 EXPECT_EQ(1U, s[0]->OutputCount()); | 1797 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1746 } | 1798 } |
| 1747 // c + x * (2^k + 1) -> c + x + (x << k) | 1799 // c + x * (2^k + 1) -> c + x + (x << k) |
| 1748 TRACED_FORRANGE(int32_t, k, 1, 30) { | 1800 TRACED_FORRANGE(int32_t, k, 1, 30) { |
| 1749 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 1801 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 1802 MachineType::Int32()); |
| 1750 m.Return( | 1803 m.Return( |
| 1751 m.Int32Add(m.Parameter(0), | 1804 m.Int32Add(m.Parameter(0), |
| 1752 m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1)))); | 1805 m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1)))); |
| 1753 Stream s = m.Build(); | 1806 Stream s = m.Build(); |
| 1754 ASSERT_EQ(2U, s.size()); | 1807 ASSERT_EQ(2U, s.size()); |
| 1755 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1808 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1756 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); | 1809 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); |
| 1757 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1810 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1758 ASSERT_EQ(3U, s[0]->InputCount()); | 1811 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1759 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); | 1812 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); |
| 1760 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); | 1813 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); |
| 1761 EXPECT_EQ(1U, s[0]->OutputCount()); | 1814 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1762 } | 1815 } |
| 1763 // c + (2^k + 1) * x -> c + x + (x << k) | 1816 // c + (2^k + 1) * x -> c + x + (x << k) |
| 1764 TRACED_FORRANGE(int32_t, k, 1, 30) { | 1817 TRACED_FORRANGE(int32_t, k, 1, 30) { |
| 1765 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 1818 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 1819 MachineType::Int32()); |
| 1766 m.Return( | 1820 m.Return( |
| 1767 m.Int32Add(m.Parameter(0), | 1821 m.Int32Add(m.Parameter(0), |
| 1768 m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1)))); | 1822 m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1)))); |
| 1769 Stream s = m.Build(); | 1823 Stream s = m.Build(); |
| 1770 ASSERT_EQ(2U, s.size()); | 1824 ASSERT_EQ(2U, s.size()); |
| 1771 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1825 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1772 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); | 1826 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); |
| 1773 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1827 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1774 ASSERT_EQ(3U, s[0]->InputCount()); | 1828 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1775 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); | 1829 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); |
| 1776 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); | 1830 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); |
| 1777 EXPECT_EQ(1U, s[0]->OutputCount()); | 1831 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1778 } | 1832 } |
| 1779 // c - x * (2^k + 1) -> c - x + (x << k) | 1833 // c - x * (2^k + 1) -> c - x + (x << k) |
| 1780 TRACED_FORRANGE(int32_t, k, 1, 30) { | 1834 TRACED_FORRANGE(int32_t, k, 1, 30) { |
| 1781 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 1835 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 1836 MachineType::Int32()); |
| 1782 m.Return( | 1837 m.Return( |
| 1783 m.Int32Sub(m.Parameter(0), | 1838 m.Int32Sub(m.Parameter(0), |
| 1784 m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1)))); | 1839 m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1)))); |
| 1785 Stream s = m.Build(); | 1840 Stream s = m.Build(); |
| 1786 ASSERT_EQ(2U, s.size()); | 1841 ASSERT_EQ(2U, s.size()); |
| 1787 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1842 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1788 EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode()); | 1843 EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode()); |
| 1789 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1844 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1790 ASSERT_EQ(3U, s[0]->InputCount()); | 1845 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1791 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); | 1846 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); |
| 1792 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); | 1847 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); |
| 1793 EXPECT_EQ(1U, s[0]->OutputCount()); | 1848 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1794 } | 1849 } |
| 1795 // c - (2^k + 1) * x -> c - x + (x << k) | 1850 // c - (2^k + 1) * x -> c - x + (x << k) |
| 1796 TRACED_FORRANGE(int32_t, k, 1, 30) { | 1851 TRACED_FORRANGE(int32_t, k, 1, 30) { |
| 1797 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 1852 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 1853 MachineType::Int32()); |
| 1798 m.Return( | 1854 m.Return( |
| 1799 m.Int32Sub(m.Parameter(0), | 1855 m.Int32Sub(m.Parameter(0), |
| 1800 m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1)))); | 1856 m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1)))); |
| 1801 Stream s = m.Build(); | 1857 Stream s = m.Build(); |
| 1802 ASSERT_EQ(2U, s.size()); | 1858 ASSERT_EQ(2U, s.size()); |
| 1803 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); | 1859 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 1804 EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode()); | 1860 EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode()); |
| 1805 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1861 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1806 ASSERT_EQ(3U, s[0]->InputCount()); | 1862 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1807 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); | 1863 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); |
| 1808 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); | 1864 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); |
| 1809 EXPECT_EQ(1U, s[0]->OutputCount()); | 1865 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1810 } | 1866 } |
| 1811 } | 1867 } |
| 1812 | 1868 |
| 1813 | 1869 |
| 1814 TEST_F(InstructionSelectorTest, Int64MulWithImmediate) { | 1870 TEST_F(InstructionSelectorTest, Int64MulWithImmediate) { |
| 1815 // x * (2^k + 1) -> x + (x << k) | 1871 // x * (2^k + 1) -> x + (x << k) |
| 1816 TRACED_FORRANGE(int64_t, k, 1, 62) { | 1872 TRACED_FORRANGE(int64_t, k, 1, 62) { |
| 1817 StreamBuilder m(this, kMachInt64, kMachInt64); | 1873 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 1818 m.Return(m.Int64Mul(m.Parameter(0), m.Int64Constant((1L << k) + 1))); | 1874 m.Return(m.Int64Mul(m.Parameter(0), m.Int64Constant((1L << k) + 1))); |
| 1819 Stream s = m.Build(); | 1875 Stream s = m.Build(); |
| 1820 ASSERT_EQ(1U, s.size()); | 1876 ASSERT_EQ(1U, s.size()); |
| 1821 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 1877 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 1822 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1878 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1823 ASSERT_EQ(3U, s[0]->InputCount()); | 1879 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1824 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1880 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1825 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); | 1881 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); |
| 1826 EXPECT_EQ(1U, s[0]->OutputCount()); | 1882 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1827 } | 1883 } |
| 1828 // (2^k + 1) * x -> x + (x << k) | 1884 // (2^k + 1) * x -> x + (x << k) |
| 1829 TRACED_FORRANGE(int64_t, k, 1, 62) { | 1885 TRACED_FORRANGE(int64_t, k, 1, 62) { |
| 1830 StreamBuilder m(this, kMachInt64, kMachInt64); | 1886 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 1831 m.Return(m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(0))); | 1887 m.Return(m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(0))); |
| 1832 Stream s = m.Build(); | 1888 Stream s = m.Build(); |
| 1833 ASSERT_EQ(1U, s.size()); | 1889 ASSERT_EQ(1U, s.size()); |
| 1834 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 1890 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 1835 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1891 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1836 ASSERT_EQ(3U, s[0]->InputCount()); | 1892 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1837 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1893 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1838 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); | 1894 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); |
| 1839 EXPECT_EQ(1U, s[0]->OutputCount()); | 1895 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1840 } | 1896 } |
| 1841 // x * (2^k + 1) + c -> x + (x << k) + c | 1897 // x * (2^k + 1) + c -> x + (x << k) + c |
| 1842 TRACED_FORRANGE(int64_t, k, 1, 62) { | 1898 TRACED_FORRANGE(int64_t, k, 1, 62) { |
| 1843 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); | 1899 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(), |
| 1900 MachineType::Int64()); |
| 1844 m.Return( | 1901 m.Return( |
| 1845 m.Int64Add(m.Int64Mul(m.Parameter(0), m.Int64Constant((1L << k) + 1)), | 1902 m.Int64Add(m.Int64Mul(m.Parameter(0), m.Int64Constant((1L << k) + 1)), |
| 1846 m.Parameter(1))); | 1903 m.Parameter(1))); |
| 1847 Stream s = m.Build(); | 1904 Stream s = m.Build(); |
| 1848 ASSERT_EQ(2U, s.size()); | 1905 ASSERT_EQ(2U, s.size()); |
| 1849 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 1906 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 1850 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); | 1907 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); |
| 1851 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1908 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1852 ASSERT_EQ(3U, s[0]->InputCount()); | 1909 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1853 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1910 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1854 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); | 1911 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); |
| 1855 EXPECT_EQ(1U, s[0]->OutputCount()); | 1912 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1856 } | 1913 } |
| 1857 // (2^k + 1) * x + c -> x + (x << k) + c | 1914 // (2^k + 1) * x + c -> x + (x << k) + c |
| 1858 TRACED_FORRANGE(int64_t, k, 1, 62) { | 1915 TRACED_FORRANGE(int64_t, k, 1, 62) { |
| 1859 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); | 1916 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(), |
| 1917 MachineType::Int64()); |
| 1860 m.Return( | 1918 m.Return( |
| 1861 m.Int64Add(m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(0)), | 1919 m.Int64Add(m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(0)), |
| 1862 m.Parameter(1))); | 1920 m.Parameter(1))); |
| 1863 Stream s = m.Build(); | 1921 Stream s = m.Build(); |
| 1864 ASSERT_EQ(2U, s.size()); | 1922 ASSERT_EQ(2U, s.size()); |
| 1865 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 1923 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 1866 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); | 1924 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); |
| 1867 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1925 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1868 ASSERT_EQ(3U, s[0]->InputCount()); | 1926 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1869 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1927 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1870 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); | 1928 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); |
| 1871 EXPECT_EQ(1U, s[0]->OutputCount()); | 1929 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1872 } | 1930 } |
| 1873 // c + x * (2^k + 1) -> c + x + (x << k) | 1931 // c + x * (2^k + 1) -> c + x + (x << k) |
| 1874 TRACED_FORRANGE(int64_t, k, 1, 62) { | 1932 TRACED_FORRANGE(int64_t, k, 1, 62) { |
| 1875 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); | 1933 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(), |
| 1934 MachineType::Int64()); |
| 1876 m.Return( | 1935 m.Return( |
| 1877 m.Int64Add(m.Parameter(0), | 1936 m.Int64Add(m.Parameter(0), |
| 1878 m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1)))); | 1937 m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1)))); |
| 1879 Stream s = m.Build(); | 1938 Stream s = m.Build(); |
| 1880 ASSERT_EQ(2U, s.size()); | 1939 ASSERT_EQ(2U, s.size()); |
| 1881 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 1940 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 1882 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); | 1941 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); |
| 1883 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1942 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1884 ASSERT_EQ(3U, s[0]->InputCount()); | 1943 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1885 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1944 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1886 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); | 1945 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); |
| 1887 EXPECT_EQ(1U, s[0]->OutputCount()); | 1946 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1888 } | 1947 } |
| 1889 // c + (2^k + 1) * x -> c + x + (x << k) | 1948 // c + (2^k + 1) * x -> c + x + (x << k) |
| 1890 TRACED_FORRANGE(int64_t, k, 1, 62) { | 1949 TRACED_FORRANGE(int64_t, k, 1, 62) { |
| 1891 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); | 1950 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(), |
| 1951 MachineType::Int64()); |
| 1892 m.Return( | 1952 m.Return( |
| 1893 m.Int64Add(m.Parameter(0), | 1953 m.Int64Add(m.Parameter(0), |
| 1894 m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1)))); | 1954 m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1)))); |
| 1895 Stream s = m.Build(); | 1955 Stream s = m.Build(); |
| 1896 ASSERT_EQ(2U, s.size()); | 1956 ASSERT_EQ(2U, s.size()); |
| 1897 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 1957 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 1898 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); | 1958 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); |
| 1899 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1959 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1900 ASSERT_EQ(3U, s[0]->InputCount()); | 1960 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1901 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1961 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1902 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); | 1962 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); |
| 1903 EXPECT_EQ(1U, s[0]->OutputCount()); | 1963 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1904 } | 1964 } |
| 1905 // c - x * (2^k + 1) -> c - x + (x << k) | 1965 // c - x * (2^k + 1) -> c - x + (x << k) |
| 1906 TRACED_FORRANGE(int64_t, k, 1, 62) { | 1966 TRACED_FORRANGE(int64_t, k, 1, 62) { |
| 1907 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); | 1967 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(), |
| 1968 MachineType::Int64()); |
| 1908 m.Return( | 1969 m.Return( |
| 1909 m.Int64Sub(m.Parameter(0), | 1970 m.Int64Sub(m.Parameter(0), |
| 1910 m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1)))); | 1971 m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1)))); |
| 1911 Stream s = m.Build(); | 1972 Stream s = m.Build(); |
| 1912 ASSERT_EQ(2U, s.size()); | 1973 ASSERT_EQ(2U, s.size()); |
| 1913 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 1974 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 1914 EXPECT_EQ(kArm64Sub, s[1]->arch_opcode()); | 1975 EXPECT_EQ(kArm64Sub, s[1]->arch_opcode()); |
| 1915 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1976 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1916 ASSERT_EQ(3U, s[0]->InputCount()); | 1977 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1917 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1978 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 1918 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); | 1979 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); |
| 1919 EXPECT_EQ(1U, s[0]->OutputCount()); | 1980 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1920 } | 1981 } |
| 1921 // c - (2^k + 1) * x -> c - x + (x << k) | 1982 // c - (2^k + 1) * x -> c - x + (x << k) |
| 1922 TRACED_FORRANGE(int64_t, k, 1, 62) { | 1983 TRACED_FORRANGE(int64_t, k, 1, 62) { |
| 1923 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); | 1984 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(), |
| 1985 MachineType::Int64()); |
| 1924 m.Return( | 1986 m.Return( |
| 1925 m.Int64Sub(m.Parameter(0), | 1987 m.Int64Sub(m.Parameter(0), |
| 1926 m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1)))); | 1988 m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1)))); |
| 1927 Stream s = m.Build(); | 1989 Stream s = m.Build(); |
| 1928 ASSERT_EQ(2U, s.size()); | 1990 ASSERT_EQ(2U, s.size()); |
| 1929 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); | 1991 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); |
| 1930 EXPECT_EQ(kArm64Sub, s[1]->arch_opcode()); | 1992 EXPECT_EQ(kArm64Sub, s[1]->arch_opcode()); |
| 1931 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); | 1993 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 1932 ASSERT_EQ(3U, s[0]->InputCount()); | 1994 ASSERT_EQ(3U, s[0]->InputCount()); |
| 1933 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1995 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1958 | 2020 |
| 1959 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest, | 2021 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest, |
| 1960 ::testing::ValuesIn(kFPArithInstructions)); | 2022 ::testing::ValuesIn(kFPArithInstructions)); |
| 1961 | 2023 |
| 1962 | 2024 |
| 1963 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest; | 2025 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest; |
| 1964 | 2026 |
| 1965 | 2027 |
| 1966 TEST_P(InstructionSelectorFPCmpTest, Parameter) { | 2028 TEST_P(InstructionSelectorFPCmpTest, Parameter) { |
| 1967 const FPCmp cmp = GetParam(); | 2029 const FPCmp cmp = GetParam(); |
| 1968 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type); | 2030 StreamBuilder m(this, MachineType::Int32(), cmp.mi.machine_type, |
| 2031 cmp.mi.machine_type); |
| 1969 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); | 2032 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 1970 Stream s = m.Build(); | 2033 Stream s = m.Build(); |
| 1971 ASSERT_EQ(1U, s.size()); | 2034 ASSERT_EQ(1U, s.size()); |
| 1972 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); | 2035 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); |
| 1973 EXPECT_EQ(2U, s[0]->InputCount()); | 2036 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1974 EXPECT_EQ(1U, s[0]->OutputCount()); | 2037 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1975 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 2038 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 1976 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); | 2039 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 1977 } | 2040 } |
| 1978 | 2041 |
| 1979 | 2042 |
| 1980 TEST_P(InstructionSelectorFPCmpTest, WithImmediateZeroOnRight) { | 2043 TEST_P(InstructionSelectorFPCmpTest, WithImmediateZeroOnRight) { |
| 1981 const FPCmp cmp = GetParam(); | 2044 const FPCmp cmp = GetParam(); |
| 1982 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type); | 2045 StreamBuilder m(this, MachineType::Int32(), cmp.mi.machine_type); |
| 1983 if (cmp.mi.machine_type == kMachFloat64) { | 2046 if (cmp.mi.machine_type == MachineType::Float64()) { |
| 1984 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Float64Constant(0.0))); | 2047 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Float64Constant(0.0))); |
| 1985 } else { | 2048 } else { |
| 1986 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Float32Constant(0.0f))); | 2049 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Float32Constant(0.0f))); |
| 1987 } | 2050 } |
| 1988 Stream s = m.Build(); | 2051 Stream s = m.Build(); |
| 1989 ASSERT_EQ(1U, s.size()); | 2052 ASSERT_EQ(1U, s.size()); |
| 1990 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); | 2053 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); |
| 1991 EXPECT_EQ(2U, s[0]->InputCount()); | 2054 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1992 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 2055 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 1993 EXPECT_EQ(1U, s[0]->OutputCount()); | 2056 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1994 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 2057 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 1995 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); | 2058 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 1996 } | 2059 } |
| 1997 | 2060 |
| 1998 | 2061 |
| 1999 TEST_P(InstructionSelectorFPCmpTest, WithImmediateZeroOnLeft) { | 2062 TEST_P(InstructionSelectorFPCmpTest, WithImmediateZeroOnLeft) { |
| 2000 const FPCmp cmp = GetParam(); | 2063 const FPCmp cmp = GetParam(); |
| 2001 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type); | 2064 StreamBuilder m(this, MachineType::Int32(), cmp.mi.machine_type); |
| 2002 if (cmp.mi.machine_type == kMachFloat64) { | 2065 if (cmp.mi.machine_type == MachineType::Float64()) { |
| 2003 m.Return((m.*cmp.mi.constructor)(m.Float64Constant(0.0), m.Parameter(0))); | 2066 m.Return((m.*cmp.mi.constructor)(m.Float64Constant(0.0), m.Parameter(0))); |
| 2004 } else { | 2067 } else { |
| 2005 m.Return((m.*cmp.mi.constructor)(m.Float32Constant(0.0f), m.Parameter(0))); | 2068 m.Return((m.*cmp.mi.constructor)(m.Float32Constant(0.0f), m.Parameter(0))); |
| 2006 } | 2069 } |
| 2007 Stream s = m.Build(); | 2070 Stream s = m.Build(); |
| 2008 ASSERT_EQ(1U, s.size()); | 2071 ASSERT_EQ(1U, s.size()); |
| 2009 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); | 2072 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); |
| 2010 EXPECT_EQ(2U, s[0]->InputCount()); | 2073 EXPECT_EQ(2U, s[0]->InputCount()); |
| 2011 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 2074 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 2012 EXPECT_EQ(1U, s[0]->OutputCount()); | 2075 EXPECT_EQ(1U, s[0]->OutputCount()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2058 | 2121 |
| 2059 | 2122 |
| 2060 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) { | 2123 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) { |
| 2061 return os << memacc.type; | 2124 return os << memacc.type; |
| 2062 } | 2125 } |
| 2063 | 2126 |
| 2064 } // namespace | 2127 } // namespace |
| 2065 | 2128 |
| 2066 | 2129 |
| 2067 static const MemoryAccess kMemoryAccesses[] = { | 2130 static const MemoryAccess kMemoryAccesses[] = { |
| 2068 {kMachInt8, | 2131 {MachineType::Int8(), |
| 2069 kArm64Ldrsb, | 2132 kArm64Ldrsb, |
| 2070 kArm64Strb, | 2133 kArm64Strb, |
| 2071 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121, | 2134 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121, |
| 2072 2442, 4093, 4094, 4095}}, | 2135 2442, 4093, 4094, 4095}}, |
| 2073 {kMachUint8, | 2136 {MachineType::Uint8(), |
| 2074 kArm64Ldrb, | 2137 kArm64Ldrb, |
| 2075 kArm64Strb, | 2138 kArm64Strb, |
| 2076 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121, | 2139 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121, |
| 2077 2442, 4093, 4094, 4095}}, | 2140 2442, 4093, 4094, 4095}}, |
| 2078 {kMachInt16, | 2141 {MachineType::Int16(), |
| 2079 kArm64Ldrsh, | 2142 kArm64Ldrsh, |
| 2080 kArm64Strh, | 2143 kArm64Strh, |
| 2081 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100, | 2144 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100, |
| 2082 4242, 6786, 8188, 8190}}, | 2145 4242, 6786, 8188, 8190}}, |
| 2083 {kMachUint16, | 2146 {MachineType::Uint16(), |
| 2084 kArm64Ldrh, | 2147 kArm64Ldrh, |
| 2085 kArm64Strh, | 2148 kArm64Strh, |
| 2086 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100, | 2149 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100, |
| 2087 4242, 6786, 8188, 8190}}, | 2150 4242, 6786, 8188, 8190}}, |
| 2088 {kMachInt32, | 2151 {MachineType::Int32(), |
| 2089 kArm64LdrW, | 2152 kArm64LdrW, |
| 2090 kArm64StrW, | 2153 kArm64StrW, |
| 2091 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196, | 2154 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196, |
| 2092 3276, 3280, 16376, 16380}}, | 2155 3276, 3280, 16376, 16380}}, |
| 2093 {kMachUint32, | 2156 {MachineType::Uint32(), |
| 2094 kArm64LdrW, | 2157 kArm64LdrW, |
| 2095 kArm64StrW, | 2158 kArm64StrW, |
| 2096 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196, | 2159 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196, |
| 2097 3276, 3280, 16376, 16380}}, | 2160 3276, 3280, 16376, 16380}}, |
| 2098 {kMachInt64, | 2161 {MachineType::Int64(), |
| 2099 kArm64Ldr, | 2162 kArm64Ldr, |
| 2100 kArm64Str, | 2163 kArm64Str, |
| 2101 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200, | 2164 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200, |
| 2102 16384, 16392, 32752, 32760}}, | 2165 16384, 16392, 32752, 32760}}, |
| 2103 {kMachUint64, | 2166 {MachineType::Uint64(), |
| 2104 kArm64Ldr, | 2167 kArm64Ldr, |
| 2105 kArm64Str, | 2168 kArm64Str, |
| 2106 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200, | 2169 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200, |
| 2107 16384, 16392, 32752, 32760}}, | 2170 16384, 16392, 32752, 32760}}, |
| 2108 {kMachFloat32, | 2171 {MachineType::Float32(), |
| 2109 kArm64LdrS, | 2172 kArm64LdrS, |
| 2110 kArm64StrS, | 2173 kArm64StrS, |
| 2111 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196, | 2174 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196, |
| 2112 3276, 3280, 16376, 16380}}, | 2175 3276, 3280, 16376, 16380}}, |
| 2113 {kMachFloat64, | 2176 {MachineType::Float64(), |
| 2114 kArm64LdrD, | 2177 kArm64LdrD, |
| 2115 kArm64StrD, | 2178 kArm64StrD, |
| 2116 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200, | 2179 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200, |
| 2117 16384, 16392, 32752, 32760}}}; | 2180 16384, 16392, 32752, 32760}}}; |
| 2118 | 2181 |
| 2119 | 2182 |
| 2120 typedef InstructionSelectorTestWithParam<MemoryAccess> | 2183 typedef InstructionSelectorTestWithParam<MemoryAccess> |
| 2121 InstructionSelectorMemoryAccessTest; | 2184 InstructionSelectorMemoryAccessTest; |
| 2122 | 2185 |
| 2123 | 2186 |
| 2124 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { | 2187 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { |
| 2125 const MemoryAccess memacc = GetParam(); | 2188 const MemoryAccess memacc = GetParam(); |
| 2126 StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32); | 2189 StreamBuilder m(this, memacc.type, MachineType::Pointer(), |
| 2190 MachineType::Int32()); |
| 2127 m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1))); | 2191 m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1))); |
| 2128 Stream s = m.Build(); | 2192 Stream s = m.Build(); |
| 2129 ASSERT_EQ(1U, s.size()); | 2193 ASSERT_EQ(1U, s.size()); |
| 2130 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode()); | 2194 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode()); |
| 2131 EXPECT_EQ(kMode_MRR, s[0]->addressing_mode()); | 2195 EXPECT_EQ(kMode_MRR, s[0]->addressing_mode()); |
| 2132 EXPECT_EQ(2U, s[0]->InputCount()); | 2196 EXPECT_EQ(2U, s[0]->InputCount()); |
| 2133 EXPECT_EQ(1U, s[0]->OutputCount()); | 2197 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2134 } | 2198 } |
| 2135 | 2199 |
| 2136 | 2200 |
| 2137 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { | 2201 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { |
| 2138 const MemoryAccess memacc = GetParam(); | 2202 const MemoryAccess memacc = GetParam(); |
| 2139 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 2203 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
| 2140 StreamBuilder m(this, memacc.type, kMachPtr); | 2204 StreamBuilder m(this, memacc.type, MachineType::Pointer()); |
| 2141 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); | 2205 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); |
| 2142 Stream s = m.Build(); | 2206 Stream s = m.Build(); |
| 2143 ASSERT_EQ(1U, s.size()); | 2207 ASSERT_EQ(1U, s.size()); |
| 2144 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode()); | 2208 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode()); |
| 2145 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 2209 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 2146 EXPECT_EQ(2U, s[0]->InputCount()); | 2210 EXPECT_EQ(2U, s[0]->InputCount()); |
| 2147 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 2211 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 2148 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); | 2212 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); |
| 2149 ASSERT_EQ(1U, s[0]->OutputCount()); | 2213 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2150 } | 2214 } |
| 2151 } | 2215 } |
| 2152 | 2216 |
| 2153 | 2217 |
| 2154 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { | 2218 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { |
| 2155 const MemoryAccess memacc = GetParam(); | 2219 const MemoryAccess memacc = GetParam(); |
| 2156 StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); | 2220 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 2221 MachineType::Int32(), memacc.type); |
| 2157 m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2), | 2222 m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2), |
| 2158 kNoWriteBarrier); | 2223 kNoWriteBarrier); |
| 2159 m.Return(m.Int32Constant(0)); | 2224 m.Return(m.Int32Constant(0)); |
| 2160 Stream s = m.Build(); | 2225 Stream s = m.Build(); |
| 2161 ASSERT_EQ(1U, s.size()); | 2226 ASSERT_EQ(1U, s.size()); |
| 2162 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); | 2227 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); |
| 2163 EXPECT_EQ(kMode_MRR, s[0]->addressing_mode()); | 2228 EXPECT_EQ(kMode_MRR, s[0]->addressing_mode()); |
| 2164 EXPECT_EQ(3U, s[0]->InputCount()); | 2229 EXPECT_EQ(3U, s[0]->InputCount()); |
| 2165 EXPECT_EQ(0U, s[0]->OutputCount()); | 2230 EXPECT_EQ(0U, s[0]->OutputCount()); |
| 2166 } | 2231 } |
| 2167 | 2232 |
| 2168 | 2233 |
| 2169 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { | 2234 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { |
| 2170 const MemoryAccess memacc = GetParam(); | 2235 const MemoryAccess memacc = GetParam(); |
| 2171 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 2236 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
| 2172 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); | 2237 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 2238 memacc.type); |
| 2173 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), | 2239 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), |
| 2174 kNoWriteBarrier); | 2240 kNoWriteBarrier); |
| 2175 m.Return(m.Int32Constant(0)); | 2241 m.Return(m.Int32Constant(0)); |
| 2176 Stream s = m.Build(); | 2242 Stream s = m.Build(); |
| 2177 ASSERT_EQ(1U, s.size()); | 2243 ASSERT_EQ(1U, s.size()); |
| 2178 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); | 2244 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); |
| 2179 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 2245 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 2180 ASSERT_EQ(3U, s[0]->InputCount()); | 2246 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2181 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 2247 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 2182 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); | 2248 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); |
| 2183 EXPECT_EQ(0U, s[0]->OutputCount()); | 2249 EXPECT_EQ(0U, s[0]->OutputCount()); |
| 2184 } | 2250 } |
| 2185 } | 2251 } |
| 2186 | 2252 |
| 2187 | 2253 |
| 2188 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 2254 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 2189 InstructionSelectorMemoryAccessTest, | 2255 InstructionSelectorMemoryAccessTest, |
| 2190 ::testing::ValuesIn(kMemoryAccesses)); | 2256 ::testing::ValuesIn(kMemoryAccesses)); |
| 2191 | 2257 |
| 2192 | 2258 |
| 2193 // ----------------------------------------------------------------------------- | 2259 // ----------------------------------------------------------------------------- |
| 2194 // Comparison instructions. | 2260 // Comparison instructions. |
| 2195 | 2261 |
| 2196 static const MachInst2 kComparisonInstructions[] = { | 2262 static const MachInst2 kComparisonInstructions[] = { |
| 2197 {&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, kMachInt32}, | 2263 {&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, |
| 2198 {&RawMachineAssembler::Word64Equal, "Word64Equal", kArm64Cmp, kMachInt64}, | 2264 MachineType::Int32()}, |
| 2265 {&RawMachineAssembler::Word64Equal, "Word64Equal", kArm64Cmp, |
| 2266 MachineType::Int64()}, |
| 2199 }; | 2267 }; |
| 2200 | 2268 |
| 2201 | 2269 |
| 2202 typedef InstructionSelectorTestWithParam<MachInst2> | 2270 typedef InstructionSelectorTestWithParam<MachInst2> |
| 2203 InstructionSelectorComparisonTest; | 2271 InstructionSelectorComparisonTest; |
| 2204 | 2272 |
| 2205 | 2273 |
| 2206 TEST_P(InstructionSelectorComparisonTest, WithParameters) { | 2274 TEST_P(InstructionSelectorComparisonTest, WithParameters) { |
| 2207 const MachInst2 cmp = GetParam(); | 2275 const MachInst2 cmp = GetParam(); |
| 2208 const MachineType type = cmp.machine_type; | 2276 const MachineType type = cmp.machine_type; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2253 } | 2321 } |
| 2254 } | 2322 } |
| 2255 | 2323 |
| 2256 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 2324 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 2257 InstructionSelectorComparisonTest, | 2325 InstructionSelectorComparisonTest, |
| 2258 ::testing::ValuesIn(kComparisonInstructions)); | 2326 ::testing::ValuesIn(kComparisonInstructions)); |
| 2259 | 2327 |
| 2260 | 2328 |
| 2261 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { | 2329 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { |
| 2262 { | 2330 { |
| 2263 StreamBuilder m(this, kMachInt32, kMachInt32); | 2331 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 2264 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); | 2332 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); |
| 2265 Stream s = m.Build(); | 2333 Stream s = m.Build(); |
| 2266 ASSERT_EQ(1U, s.size()); | 2334 ASSERT_EQ(1U, s.size()); |
| 2267 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); | 2335 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); |
| 2268 ASSERT_EQ(2U, s[0]->InputCount()); | 2336 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2269 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 2337 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 2270 EXPECT_EQ(1U, s[0]->OutputCount()); | 2338 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2271 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 2339 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 2272 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 2340 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 2273 } | 2341 } |
| 2274 { | 2342 { |
| 2275 StreamBuilder m(this, kMachInt32, kMachInt32); | 2343 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 2276 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); | 2344 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); |
| 2277 Stream s = m.Build(); | 2345 Stream s = m.Build(); |
| 2278 ASSERT_EQ(1U, s.size()); | 2346 ASSERT_EQ(1U, s.size()); |
| 2279 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); | 2347 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); |
| 2280 ASSERT_EQ(2U, s[0]->InputCount()); | 2348 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2281 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 2349 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 2282 EXPECT_EQ(1U, s[0]->OutputCount()); | 2350 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2283 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 2351 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 2284 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 2352 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 2285 } | 2353 } |
| 2286 } | 2354 } |
| 2287 | 2355 |
| 2288 | 2356 |
| 2289 TEST_F(InstructionSelectorTest, Word64EqualWithZero) { | 2357 TEST_F(InstructionSelectorTest, Word64EqualWithZero) { |
| 2290 { | 2358 { |
| 2291 StreamBuilder m(this, kMachInt64, kMachInt64); | 2359 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 2292 m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0))); | 2360 m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0))); |
| 2293 Stream s = m.Build(); | 2361 Stream s = m.Build(); |
| 2294 ASSERT_EQ(1U, s.size()); | 2362 ASSERT_EQ(1U, s.size()); |
| 2295 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); | 2363 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); |
| 2296 ASSERT_EQ(2U, s[0]->InputCount()); | 2364 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2297 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 2365 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 2298 EXPECT_EQ(1U, s[0]->OutputCount()); | 2366 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2299 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 2367 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 2300 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 2368 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 2301 } | 2369 } |
| 2302 { | 2370 { |
| 2303 StreamBuilder m(this, kMachInt64, kMachInt64); | 2371 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 2304 m.Return(m.Word64Equal(m.Int64Constant(0), m.Parameter(0))); | 2372 m.Return(m.Word64Equal(m.Int64Constant(0), m.Parameter(0))); |
| 2305 Stream s = m.Build(); | 2373 Stream s = m.Build(); |
| 2306 ASSERT_EQ(1U, s.size()); | 2374 ASSERT_EQ(1U, s.size()); |
| 2307 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); | 2375 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); |
| 2308 ASSERT_EQ(2U, s[0]->InputCount()); | 2376 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2309 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 2377 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
| 2310 EXPECT_EQ(1U, s[0]->OutputCount()); | 2378 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2311 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 2379 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 2312 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 2380 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 2313 } | 2381 } |
| 2314 } | 2382 } |
| 2315 | 2383 |
| 2316 | 2384 |
| 2317 TEST_F(InstructionSelectorTest, Word32EqualWithWord32Shift) { | 2385 TEST_F(InstructionSelectorTest, Word32EqualWithWord32Shift) { |
| 2318 TRACED_FOREACH(Shift, shift, kShiftInstructions) { | 2386 TRACED_FOREACH(Shift, shift, kShiftInstructions) { |
| 2319 // Skip non 32-bit shifts or ror operations. | 2387 // Skip non 32-bit shifts or ror operations. |
| 2320 if (shift.mi.machine_type != kMachInt32 || | 2388 if (shift.mi.machine_type != MachineType::Int32() || |
| 2321 shift.mi.arch_opcode == kArm64Ror32) { | 2389 shift.mi.arch_opcode == kArm64Ror32) { |
| 2322 continue; | 2390 continue; |
| 2323 } | 2391 } |
| 2324 | 2392 |
| 2325 TRACED_FORRANGE(int32_t, imm, -32, 63) { | 2393 TRACED_FORRANGE(int32_t, imm, -32, 63) { |
| 2326 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2394 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2395 MachineType::Int32()); |
| 2327 Node* const p0 = m.Parameter(0); | 2396 Node* const p0 = m.Parameter(0); |
| 2328 Node* const p1 = m.Parameter(1); | 2397 Node* const p1 = m.Parameter(1); |
| 2329 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); | 2398 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); |
| 2330 m.Return(m.Word32Equal(p0, r)); | 2399 m.Return(m.Word32Equal(p0, r)); |
| 2331 Stream s = m.Build(); | 2400 Stream s = m.Build(); |
| 2332 ASSERT_EQ(1U, s.size()); | 2401 ASSERT_EQ(1U, s.size()); |
| 2333 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2402 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2334 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 2403 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 2335 ASSERT_EQ(3U, s[0]->InputCount()); | 2404 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2336 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2405 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2337 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2406 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2338 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); | 2407 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); |
| 2339 ASSERT_EQ(1U, s[0]->OutputCount()); | 2408 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2340 } | 2409 } |
| 2341 TRACED_FORRANGE(int32_t, imm, -32, 63) { | 2410 TRACED_FORRANGE(int32_t, imm, -32, 63) { |
| 2342 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2411 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2412 MachineType::Int32()); |
| 2343 Node* const p0 = m.Parameter(0); | 2413 Node* const p0 = m.Parameter(0); |
| 2344 Node* const p1 = m.Parameter(1); | 2414 Node* const p1 = m.Parameter(1); |
| 2345 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); | 2415 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); |
| 2346 m.Return(m.Word32Equal(r, p0)); | 2416 m.Return(m.Word32Equal(r, p0)); |
| 2347 Stream s = m.Build(); | 2417 Stream s = m.Build(); |
| 2348 ASSERT_EQ(1U, s.size()); | 2418 ASSERT_EQ(1U, s.size()); |
| 2349 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2419 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2350 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 2420 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 2351 ASSERT_EQ(3U, s[0]->InputCount()); | 2421 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2352 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2422 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2353 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2423 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2354 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); | 2424 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); |
| 2355 ASSERT_EQ(1U, s[0]->OutputCount()); | 2425 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2356 } | 2426 } |
| 2357 } | 2427 } |
| 2358 } | 2428 } |
| 2359 | 2429 |
| 2360 | 2430 |
| 2361 TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendByte) { | 2431 TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendByte) { |
| 2362 { | 2432 { |
| 2363 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2433 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2434 MachineType::Int32()); |
| 2364 Node* const p0 = m.Parameter(0); | 2435 Node* const p0 = m.Parameter(0); |
| 2365 Node* const p1 = m.Parameter(1); | 2436 Node* const p1 = m.Parameter(1); |
| 2366 Node* r = m.Word32And(p1, m.Int32Constant(0xff)); | 2437 Node* r = m.Word32And(p1, m.Int32Constant(0xff)); |
| 2367 m.Return(m.Word32Equal(p0, r)); | 2438 m.Return(m.Word32Equal(p0, r)); |
| 2368 Stream s = m.Build(); | 2439 Stream s = m.Build(); |
| 2369 ASSERT_EQ(1U, s.size()); | 2440 ASSERT_EQ(1U, s.size()); |
| 2370 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2441 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2371 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); | 2442 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); |
| 2372 ASSERT_EQ(2U, s[0]->InputCount()); | 2443 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2373 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2444 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2374 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2445 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2375 ASSERT_EQ(1U, s[0]->OutputCount()); | 2446 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2376 } | 2447 } |
| 2377 { | 2448 { |
| 2378 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2449 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2450 MachineType::Int32()); |
| 2379 Node* const p0 = m.Parameter(0); | 2451 Node* const p0 = m.Parameter(0); |
| 2380 Node* const p1 = m.Parameter(1); | 2452 Node* const p1 = m.Parameter(1); |
| 2381 Node* r = m.Word32And(p1, m.Int32Constant(0xff)); | 2453 Node* r = m.Word32And(p1, m.Int32Constant(0xff)); |
| 2382 m.Return(m.Word32Equal(r, p0)); | 2454 m.Return(m.Word32Equal(r, p0)); |
| 2383 Stream s = m.Build(); | 2455 Stream s = m.Build(); |
| 2384 ASSERT_EQ(1U, s.size()); | 2456 ASSERT_EQ(1U, s.size()); |
| 2385 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2457 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2386 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); | 2458 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); |
| 2387 ASSERT_EQ(2U, s[0]->InputCount()); | 2459 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2388 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2460 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2389 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2461 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2390 ASSERT_EQ(1U, s[0]->OutputCount()); | 2462 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2391 } | 2463 } |
| 2392 } | 2464 } |
| 2393 | 2465 |
| 2394 | 2466 |
| 2395 TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendHalfword) { | 2467 TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendHalfword) { |
| 2396 { | 2468 { |
| 2397 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2469 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2470 MachineType::Int32()); |
| 2398 Node* const p0 = m.Parameter(0); | 2471 Node* const p0 = m.Parameter(0); |
| 2399 Node* const p1 = m.Parameter(1); | 2472 Node* const p1 = m.Parameter(1); |
| 2400 Node* r = m.Word32And(p1, m.Int32Constant(0xffff)); | 2473 Node* r = m.Word32And(p1, m.Int32Constant(0xffff)); |
| 2401 m.Return(m.Word32Equal(p0, r)); | 2474 m.Return(m.Word32Equal(p0, r)); |
| 2402 Stream s = m.Build(); | 2475 Stream s = m.Build(); |
| 2403 ASSERT_EQ(1U, s.size()); | 2476 ASSERT_EQ(1U, s.size()); |
| 2404 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2477 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2405 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); | 2478 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); |
| 2406 ASSERT_EQ(2U, s[0]->InputCount()); | 2479 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2407 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2480 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2408 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2481 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2409 ASSERT_EQ(1U, s[0]->OutputCount()); | 2482 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2410 } | 2483 } |
| 2411 { | 2484 { |
| 2412 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2485 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2486 MachineType::Int32()); |
| 2413 Node* const p0 = m.Parameter(0); | 2487 Node* const p0 = m.Parameter(0); |
| 2414 Node* const p1 = m.Parameter(1); | 2488 Node* const p1 = m.Parameter(1); |
| 2415 Node* r = m.Word32And(p1, m.Int32Constant(0xffff)); | 2489 Node* r = m.Word32And(p1, m.Int32Constant(0xffff)); |
| 2416 m.Return(m.Word32Equal(r, p0)); | 2490 m.Return(m.Word32Equal(r, p0)); |
| 2417 Stream s = m.Build(); | 2491 Stream s = m.Build(); |
| 2418 ASSERT_EQ(1U, s.size()); | 2492 ASSERT_EQ(1U, s.size()); |
| 2419 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2493 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2420 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); | 2494 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); |
| 2421 ASSERT_EQ(2U, s[0]->InputCount()); | 2495 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2422 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2496 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2423 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2497 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2424 ASSERT_EQ(1U, s[0]->OutputCount()); | 2498 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2425 } | 2499 } |
| 2426 } | 2500 } |
| 2427 | 2501 |
| 2428 | 2502 |
| 2429 TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendByte) { | 2503 TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendByte) { |
| 2430 { | 2504 { |
| 2431 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2505 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2506 MachineType::Int32()); |
| 2432 Node* const p0 = m.Parameter(0); | 2507 Node* const p0 = m.Parameter(0); |
| 2433 Node* const p1 = m.Parameter(1); | 2508 Node* const p1 = m.Parameter(1); |
| 2434 Node* r = | 2509 Node* r = |
| 2435 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24)); | 2510 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24)); |
| 2436 m.Return(m.Word32Equal(p0, r)); | 2511 m.Return(m.Word32Equal(p0, r)); |
| 2437 Stream s = m.Build(); | 2512 Stream s = m.Build(); |
| 2438 ASSERT_EQ(1U, s.size()); | 2513 ASSERT_EQ(1U, s.size()); |
| 2439 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2514 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2440 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); | 2515 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); |
| 2441 ASSERT_EQ(2U, s[0]->InputCount()); | 2516 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2442 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2517 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2443 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2518 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2444 ASSERT_EQ(1U, s[0]->OutputCount()); | 2519 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2445 } | 2520 } |
| 2446 { | 2521 { |
| 2447 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2522 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2523 MachineType::Int32()); |
| 2448 Node* const p0 = m.Parameter(0); | 2524 Node* const p0 = m.Parameter(0); |
| 2449 Node* const p1 = m.Parameter(1); | 2525 Node* const p1 = m.Parameter(1); |
| 2450 Node* r = | 2526 Node* r = |
| 2451 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24)); | 2527 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24)); |
| 2452 m.Return(m.Word32Equal(r, p0)); | 2528 m.Return(m.Word32Equal(r, p0)); |
| 2453 Stream s = m.Build(); | 2529 Stream s = m.Build(); |
| 2454 ASSERT_EQ(1U, s.size()); | 2530 ASSERT_EQ(1U, s.size()); |
| 2455 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2531 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2456 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); | 2532 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); |
| 2457 ASSERT_EQ(2U, s[0]->InputCount()); | 2533 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2458 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2534 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2459 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2535 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2460 ASSERT_EQ(1U, s[0]->OutputCount()); | 2536 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2461 } | 2537 } |
| 2462 } | 2538 } |
| 2463 | 2539 |
| 2464 | 2540 |
| 2465 TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendHalfword) { | 2541 TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendHalfword) { |
| 2466 { | 2542 { |
| 2467 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2543 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2544 MachineType::Int32()); |
| 2468 Node* const p0 = m.Parameter(0); | 2545 Node* const p0 = m.Parameter(0); |
| 2469 Node* const p1 = m.Parameter(1); | 2546 Node* const p1 = m.Parameter(1); |
| 2470 Node* r = | 2547 Node* r = |
| 2471 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16)); | 2548 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16)); |
| 2472 m.Return(m.Word32Equal(p0, r)); | 2549 m.Return(m.Word32Equal(p0, r)); |
| 2473 Stream s = m.Build(); | 2550 Stream s = m.Build(); |
| 2474 ASSERT_EQ(1U, s.size()); | 2551 ASSERT_EQ(1U, s.size()); |
| 2475 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2552 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2476 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); | 2553 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); |
| 2477 ASSERT_EQ(2U, s[0]->InputCount()); | 2554 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2478 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2555 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2479 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2556 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2480 ASSERT_EQ(1U, s[0]->OutputCount()); | 2557 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2481 } | 2558 } |
| 2482 { | 2559 { |
| 2483 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2560 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2561 MachineType::Int32()); |
| 2484 Node* const p0 = m.Parameter(0); | 2562 Node* const p0 = m.Parameter(0); |
| 2485 Node* const p1 = m.Parameter(1); | 2563 Node* const p1 = m.Parameter(1); |
| 2486 Node* r = | 2564 Node* r = |
| 2487 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16)); | 2565 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16)); |
| 2488 m.Return(m.Word32Equal(r, p0)); | 2566 m.Return(m.Word32Equal(r, p0)); |
| 2489 Stream s = m.Build(); | 2567 Stream s = m.Build(); |
| 2490 ASSERT_EQ(1U, s.size()); | 2568 ASSERT_EQ(1U, s.size()); |
| 2491 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2569 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2492 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); | 2570 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); |
| 2493 ASSERT_EQ(2U, s[0]->InputCount()); | 2571 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2494 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2572 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2495 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2573 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2496 ASSERT_EQ(1U, s[0]->OutputCount()); | 2574 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2497 } | 2575 } |
| 2498 } | 2576 } |
| 2499 | 2577 |
| 2500 | 2578 |
| 2501 TEST_F(InstructionSelectorTest, Word32EqualZeroWithWord32Equal) { | 2579 TEST_F(InstructionSelectorTest, Word32EqualZeroWithWord32Equal) { |
| 2502 { | 2580 { |
| 2503 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2581 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2582 MachineType::Int32()); |
| 2504 Node* const p0 = m.Parameter(0); | 2583 Node* const p0 = m.Parameter(0); |
| 2505 Node* const p1 = m.Parameter(1); | 2584 Node* const p1 = m.Parameter(1); |
| 2506 m.Return(m.Word32Equal(m.Word32Equal(p0, p1), m.Int32Constant(0))); | 2585 m.Return(m.Word32Equal(m.Word32Equal(p0, p1), m.Int32Constant(0))); |
| 2507 Stream s = m.Build(); | 2586 Stream s = m.Build(); |
| 2508 ASSERT_EQ(1U, s.size()); | 2587 ASSERT_EQ(1U, s.size()); |
| 2509 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2588 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2510 ASSERT_EQ(2U, s[0]->InputCount()); | 2589 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2511 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2590 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2512 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2591 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2513 EXPECT_EQ(1U, s[0]->OutputCount()); | 2592 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2514 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 2593 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 2515 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 2594 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 2516 } | 2595 } |
| 2517 { | 2596 { |
| 2518 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2597 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2598 MachineType::Int32()); |
| 2519 Node* const p0 = m.Parameter(0); | 2599 Node* const p0 = m.Parameter(0); |
| 2520 Node* const p1 = m.Parameter(1); | 2600 Node* const p1 = m.Parameter(1); |
| 2521 m.Return(m.Word32Equal(m.Int32Constant(0), m.Word32Equal(p0, p1))); | 2601 m.Return(m.Word32Equal(m.Int32Constant(0), m.Word32Equal(p0, p1))); |
| 2522 Stream s = m.Build(); | 2602 Stream s = m.Build(); |
| 2523 ASSERT_EQ(1U, s.size()); | 2603 ASSERT_EQ(1U, s.size()); |
| 2524 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 2604 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
| 2525 ASSERT_EQ(2U, s[0]->InputCount()); | 2605 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2526 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2606 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2527 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 2607 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2528 EXPECT_EQ(1U, s[0]->OutputCount()); | 2608 EXPECT_EQ(1U, s[0]->OutputCount()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2540 | 2620 |
| 2541 | 2621 |
| 2542 std::ostream& operator<<(std::ostream& os, const IntegerCmp& cmp) { | 2622 std::ostream& operator<<(std::ostream& os, const IntegerCmp& cmp) { |
| 2543 return os << cmp.mi; | 2623 return os << cmp.mi; |
| 2544 } | 2624 } |
| 2545 | 2625 |
| 2546 | 2626 |
| 2547 // ARM64 32-bit integer comparison instructions. | 2627 // ARM64 32-bit integer comparison instructions. |
| 2548 const IntegerCmp kIntegerCmpInstructions[] = { | 2628 const IntegerCmp kIntegerCmpInstructions[] = { |
| 2549 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, | 2629 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, |
| 2550 kMachInt32}, | 2630 MachineType::Int32()}, |
| 2551 kEqual}, | 2631 kEqual}, |
| 2552 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kArm64Cmp32, | 2632 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kArm64Cmp32, |
| 2553 kMachInt32}, | 2633 MachineType::Int32()}, |
| 2554 kSignedLessThan}, | 2634 kSignedLessThan}, |
| 2555 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", | 2635 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", |
| 2556 kArm64Cmp32, kMachInt32}, | 2636 kArm64Cmp32, MachineType::Int32()}, |
| 2557 kSignedLessThanOrEqual}, | 2637 kSignedLessThanOrEqual}, |
| 2558 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kArm64Cmp32, | 2638 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kArm64Cmp32, |
| 2559 kMachUint32}, | 2639 MachineType::Uint32()}, |
| 2560 kUnsignedLessThan}, | 2640 kUnsignedLessThan}, |
| 2561 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", | 2641 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", |
| 2562 kArm64Cmp32, kMachUint32}, | 2642 kArm64Cmp32, MachineType::Uint32()}, |
| 2563 kUnsignedLessThanOrEqual}}; | 2643 kUnsignedLessThanOrEqual}}; |
| 2564 | 2644 |
| 2565 } // namespace | 2645 } // namespace |
| 2566 | 2646 |
| 2567 | 2647 |
| 2568 TEST_F(InstructionSelectorTest, Word32CompareNegateWithWord32Shift) { | 2648 TEST_F(InstructionSelectorTest, Word32CompareNegateWithWord32Shift) { |
| 2569 TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) { | 2649 TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) { |
| 2570 TRACED_FOREACH(Shift, shift, kShiftInstructions) { | 2650 TRACED_FOREACH(Shift, shift, kShiftInstructions) { |
| 2571 // Test 32-bit operations. Ignore ROR shifts, as compare-negate does not | 2651 // Test 32-bit operations. Ignore ROR shifts, as compare-negate does not |
| 2572 // support them. | 2652 // support them. |
| 2573 if (shift.mi.machine_type != kMachInt32 || | 2653 if (shift.mi.machine_type != MachineType::Int32() || |
| 2574 shift.mi.arch_opcode == kArm64Ror32) { | 2654 shift.mi.arch_opcode == kArm64Ror32) { |
| 2575 continue; | 2655 continue; |
| 2576 } | 2656 } |
| 2577 | 2657 |
| 2578 TRACED_FORRANGE(int32_t, imm, -32, 63) { | 2658 TRACED_FORRANGE(int32_t, imm, -32, 63) { |
| 2579 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 2659 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2660 MachineType::Int32()); |
| 2580 Node* const p0 = m.Parameter(0); | 2661 Node* const p0 = m.Parameter(0); |
| 2581 Node* const p1 = m.Parameter(1); | 2662 Node* const p1 = m.Parameter(1); |
| 2582 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); | 2663 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); |
| 2583 m.Return( | 2664 m.Return( |
| 2584 (m.*cmp.mi.constructor)(p0, m.Int32Sub(m.Int32Constant(0), r))); | 2665 (m.*cmp.mi.constructor)(p0, m.Int32Sub(m.Int32Constant(0), r))); |
| 2585 Stream s = m.Build(); | 2666 Stream s = m.Build(); |
| 2586 ASSERT_EQ(1U, s.size()); | 2667 ASSERT_EQ(1U, s.size()); |
| 2587 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); | 2668 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); |
| 2588 EXPECT_EQ(3U, s[0]->InputCount()); | 2669 EXPECT_EQ(3U, s[0]->InputCount()); |
| 2589 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); | 2670 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 2590 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); | 2671 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); |
| 2591 EXPECT_EQ(1U, s[0]->OutputCount()); | 2672 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2592 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 2673 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 2593 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); | 2674 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 2594 } | 2675 } |
| 2595 } | 2676 } |
| 2596 } | 2677 } |
| 2597 } | 2678 } |
| 2598 | 2679 |
| 2599 | 2680 |
| 2600 // ----------------------------------------------------------------------------- | 2681 // ----------------------------------------------------------------------------- |
| 2601 // Miscellaneous | 2682 // Miscellaneous |
| 2602 | 2683 |
| 2603 | 2684 |
| 2604 static const MachInst2 kLogicalWithNotRHSs[] = { | 2685 static const MachInst2 kLogicalWithNotRHSs[] = { |
| 2605 {&RawMachineAssembler::Word32And, "Word32And", kArm64Bic32, kMachInt32}, | 2686 {&RawMachineAssembler::Word32And, "Word32And", kArm64Bic32, |
| 2606 {&RawMachineAssembler::Word64And, "Word64And", kArm64Bic, kMachInt64}, | 2687 MachineType::Int32()}, |
| 2607 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Orn32, kMachInt32}, | 2688 {&RawMachineAssembler::Word64And, "Word64And", kArm64Bic, |
| 2608 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Orn, kMachInt64}, | 2689 MachineType::Int64()}, |
| 2609 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eon32, kMachInt32}, | 2690 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Orn32, |
| 2610 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eon, kMachInt64}}; | 2691 MachineType::Int32()}, |
| 2692 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Orn, |
| 2693 MachineType::Int64()}, |
| 2694 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eon32, |
| 2695 MachineType::Int32()}, |
| 2696 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eon, |
| 2697 MachineType::Int64()}}; |
| 2611 | 2698 |
| 2612 | 2699 |
| 2613 typedef InstructionSelectorTestWithParam<MachInst2> | 2700 typedef InstructionSelectorTestWithParam<MachInst2> |
| 2614 InstructionSelectorLogicalWithNotRHSTest; | 2701 InstructionSelectorLogicalWithNotRHSTest; |
| 2615 | 2702 |
| 2616 | 2703 |
| 2617 TEST_P(InstructionSelectorLogicalWithNotRHSTest, Parameter) { | 2704 TEST_P(InstructionSelectorLogicalWithNotRHSTest, Parameter) { |
| 2618 const MachInst2 inst = GetParam(); | 2705 const MachInst2 inst = GetParam(); |
| 2619 const MachineType type = inst.machine_type; | 2706 const MachineType type = inst.machine_type; |
| 2620 // Test cases where RHS is Xor(x, -1). | 2707 // Test cases where RHS is Xor(x, -1). |
| 2621 { | 2708 { |
| 2622 StreamBuilder m(this, type, type, type); | 2709 StreamBuilder m(this, type, type, type); |
| 2623 if (type == kMachInt32) { | 2710 if (type == MachineType::Int32()) { |
| 2624 m.Return((m.*inst.constructor)( | 2711 m.Return((m.*inst.constructor)( |
| 2625 m.Parameter(0), m.Word32Xor(m.Parameter(1), m.Int32Constant(-1)))); | 2712 m.Parameter(0), m.Word32Xor(m.Parameter(1), m.Int32Constant(-1)))); |
| 2626 } else { | 2713 } else { |
| 2627 ASSERT_EQ(kMachInt64, type); | 2714 ASSERT_EQ(MachineType::Int64(), type); |
| 2628 m.Return((m.*inst.constructor)( | 2715 m.Return((m.*inst.constructor)( |
| 2629 m.Parameter(0), m.Word64Xor(m.Parameter(1), m.Int64Constant(-1)))); | 2716 m.Parameter(0), m.Word64Xor(m.Parameter(1), m.Int64Constant(-1)))); |
| 2630 } | 2717 } |
| 2631 Stream s = m.Build(); | 2718 Stream s = m.Build(); |
| 2632 ASSERT_EQ(1U, s.size()); | 2719 ASSERT_EQ(1U, s.size()); |
| 2633 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); | 2720 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 2634 EXPECT_EQ(2U, s[0]->InputCount()); | 2721 EXPECT_EQ(2U, s[0]->InputCount()); |
| 2635 EXPECT_EQ(1U, s[0]->OutputCount()); | 2722 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2636 } | 2723 } |
| 2637 { | 2724 { |
| 2638 StreamBuilder m(this, type, type, type); | 2725 StreamBuilder m(this, type, type, type); |
| 2639 if (type == kMachInt32) { | 2726 if (type == MachineType::Int32()) { |
| 2640 m.Return((m.*inst.constructor)( | 2727 m.Return((m.*inst.constructor)( |
| 2641 m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)), m.Parameter(1))); | 2728 m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)), m.Parameter(1))); |
| 2642 } else { | 2729 } else { |
| 2643 ASSERT_EQ(kMachInt64, type); | 2730 ASSERT_EQ(MachineType::Int64(), type); |
| 2644 m.Return((m.*inst.constructor)( | 2731 m.Return((m.*inst.constructor)( |
| 2645 m.Word64Xor(m.Parameter(0), m.Int64Constant(-1)), m.Parameter(1))); | 2732 m.Word64Xor(m.Parameter(0), m.Int64Constant(-1)), m.Parameter(1))); |
| 2646 } | 2733 } |
| 2647 Stream s = m.Build(); | 2734 Stream s = m.Build(); |
| 2648 ASSERT_EQ(1U, s.size()); | 2735 ASSERT_EQ(1U, s.size()); |
| 2649 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); | 2736 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 2650 EXPECT_EQ(2U, s[0]->InputCount()); | 2737 EXPECT_EQ(2U, s[0]->InputCount()); |
| 2651 EXPECT_EQ(1U, s[0]->OutputCount()); | 2738 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2652 } | 2739 } |
| 2653 // Test cases where RHS is Not(x). | 2740 // Test cases where RHS is Not(x). |
| 2654 { | 2741 { |
| 2655 StreamBuilder m(this, type, type, type); | 2742 StreamBuilder m(this, type, type, type); |
| 2656 if (type == kMachInt32) { | 2743 if (type == MachineType::Int32()) { |
| 2657 m.Return( | 2744 m.Return( |
| 2658 (m.*inst.constructor)(m.Parameter(0), m.Word32Not(m.Parameter(1)))); | 2745 (m.*inst.constructor)(m.Parameter(0), m.Word32Not(m.Parameter(1)))); |
| 2659 } else { | 2746 } else { |
| 2660 ASSERT_EQ(kMachInt64, type); | 2747 ASSERT_EQ(MachineType::Int64(), type); |
| 2661 m.Return( | 2748 m.Return( |
| 2662 (m.*inst.constructor)(m.Parameter(0), m.Word64Not(m.Parameter(1)))); | 2749 (m.*inst.constructor)(m.Parameter(0), m.Word64Not(m.Parameter(1)))); |
| 2663 } | 2750 } |
| 2664 Stream s = m.Build(); | 2751 Stream s = m.Build(); |
| 2665 ASSERT_EQ(1U, s.size()); | 2752 ASSERT_EQ(1U, s.size()); |
| 2666 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); | 2753 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 2667 EXPECT_EQ(2U, s[0]->InputCount()); | 2754 EXPECT_EQ(2U, s[0]->InputCount()); |
| 2668 EXPECT_EQ(1U, s[0]->OutputCount()); | 2755 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2669 } | 2756 } |
| 2670 { | 2757 { |
| 2671 StreamBuilder m(this, type, type, type); | 2758 StreamBuilder m(this, type, type, type); |
| 2672 if (type == kMachInt32) { | 2759 if (type == MachineType::Int32()) { |
| 2673 m.Return( | 2760 m.Return( |
| 2674 (m.*inst.constructor)(m.Word32Not(m.Parameter(0)), m.Parameter(1))); | 2761 (m.*inst.constructor)(m.Word32Not(m.Parameter(0)), m.Parameter(1))); |
| 2675 } else { | 2762 } else { |
| 2676 ASSERT_EQ(kMachInt64, type); | 2763 ASSERT_EQ(MachineType::Int64(), type); |
| 2677 m.Return( | 2764 m.Return( |
| 2678 (m.*inst.constructor)(m.Word64Not(m.Parameter(0)), m.Parameter(1))); | 2765 (m.*inst.constructor)(m.Word64Not(m.Parameter(0)), m.Parameter(1))); |
| 2679 } | 2766 } |
| 2680 Stream s = m.Build(); | 2767 Stream s = m.Build(); |
| 2681 ASSERT_EQ(1U, s.size()); | 2768 ASSERT_EQ(1U, s.size()); |
| 2682 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); | 2769 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 2683 EXPECT_EQ(2U, s[0]->InputCount()); | 2770 EXPECT_EQ(2U, s[0]->InputCount()); |
| 2684 EXPECT_EQ(1U, s[0]->OutputCount()); | 2771 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2685 } | 2772 } |
| 2686 } | 2773 } |
| 2687 | 2774 |
| 2688 | 2775 |
| 2689 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 2776 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 2690 InstructionSelectorLogicalWithNotRHSTest, | 2777 InstructionSelectorLogicalWithNotRHSTest, |
| 2691 ::testing::ValuesIn(kLogicalWithNotRHSs)); | 2778 ::testing::ValuesIn(kLogicalWithNotRHSs)); |
| 2692 | 2779 |
| 2693 | 2780 |
| 2694 TEST_F(InstructionSelectorTest, Word32NotWithParameter) { | 2781 TEST_F(InstructionSelectorTest, Word32NotWithParameter) { |
| 2695 StreamBuilder m(this, kMachInt32, kMachInt32); | 2782 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 2696 m.Return(m.Word32Not(m.Parameter(0))); | 2783 m.Return(m.Word32Not(m.Parameter(0))); |
| 2697 Stream s = m.Build(); | 2784 Stream s = m.Build(); |
| 2698 ASSERT_EQ(1U, s.size()); | 2785 ASSERT_EQ(1U, s.size()); |
| 2699 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); | 2786 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); |
| 2700 EXPECT_EQ(1U, s[0]->InputCount()); | 2787 EXPECT_EQ(1U, s[0]->InputCount()); |
| 2701 EXPECT_EQ(1U, s[0]->OutputCount()); | 2788 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2702 } | 2789 } |
| 2703 | 2790 |
| 2704 | 2791 |
| 2705 TEST_F(InstructionSelectorTest, Word64NotWithParameter) { | 2792 TEST_F(InstructionSelectorTest, Word64NotWithParameter) { |
| 2706 StreamBuilder m(this, kMachInt64, kMachInt64); | 2793 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 2707 m.Return(m.Word64Not(m.Parameter(0))); | 2794 m.Return(m.Word64Not(m.Parameter(0))); |
| 2708 Stream s = m.Build(); | 2795 Stream s = m.Build(); |
| 2709 ASSERT_EQ(1U, s.size()); | 2796 ASSERT_EQ(1U, s.size()); |
| 2710 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); | 2797 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); |
| 2711 EXPECT_EQ(1U, s[0]->InputCount()); | 2798 EXPECT_EQ(1U, s[0]->InputCount()); |
| 2712 EXPECT_EQ(1U, s[0]->OutputCount()); | 2799 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2713 } | 2800 } |
| 2714 | 2801 |
| 2715 | 2802 |
| 2716 TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) { | 2803 TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) { |
| 2717 { | 2804 { |
| 2718 StreamBuilder m(this, kMachInt32, kMachInt32); | 2805 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 2719 m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1))); | 2806 m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1))); |
| 2720 Stream s = m.Build(); | 2807 Stream s = m.Build(); |
| 2721 ASSERT_EQ(1U, s.size()); | 2808 ASSERT_EQ(1U, s.size()); |
| 2722 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); | 2809 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); |
| 2723 EXPECT_EQ(1U, s[0]->InputCount()); | 2810 EXPECT_EQ(1U, s[0]->InputCount()); |
| 2724 EXPECT_EQ(1U, s[0]->OutputCount()); | 2811 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2725 } | 2812 } |
| 2726 { | 2813 { |
| 2727 StreamBuilder m(this, kMachInt32, kMachInt32); | 2814 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 2728 m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0))); | 2815 m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0))); |
| 2729 Stream s = m.Build(); | 2816 Stream s = m.Build(); |
| 2730 ASSERT_EQ(1U, s.size()); | 2817 ASSERT_EQ(1U, s.size()); |
| 2731 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); | 2818 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); |
| 2732 EXPECT_EQ(1U, s[0]->InputCount()); | 2819 EXPECT_EQ(1U, s[0]->InputCount()); |
| 2733 EXPECT_EQ(1U, s[0]->OutputCount()); | 2820 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2734 } | 2821 } |
| 2735 } | 2822 } |
| 2736 | 2823 |
| 2737 | 2824 |
| 2738 TEST_F(InstructionSelectorTest, Word64XorMinusOneWithParameter) { | 2825 TEST_F(InstructionSelectorTest, Word64XorMinusOneWithParameter) { |
| 2739 { | 2826 { |
| 2740 StreamBuilder m(this, kMachInt64, kMachInt64); | 2827 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 2741 m.Return(m.Word64Xor(m.Parameter(0), m.Int64Constant(-1))); | 2828 m.Return(m.Word64Xor(m.Parameter(0), m.Int64Constant(-1))); |
| 2742 Stream s = m.Build(); | 2829 Stream s = m.Build(); |
| 2743 ASSERT_EQ(1U, s.size()); | 2830 ASSERT_EQ(1U, s.size()); |
| 2744 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); | 2831 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); |
| 2745 EXPECT_EQ(1U, s[0]->InputCount()); | 2832 EXPECT_EQ(1U, s[0]->InputCount()); |
| 2746 EXPECT_EQ(1U, s[0]->OutputCount()); | 2833 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2747 } | 2834 } |
| 2748 { | 2835 { |
| 2749 StreamBuilder m(this, kMachInt64, kMachInt64); | 2836 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 2750 m.Return(m.Word64Xor(m.Int64Constant(-1), m.Parameter(0))); | 2837 m.Return(m.Word64Xor(m.Int64Constant(-1), m.Parameter(0))); |
| 2751 Stream s = m.Build(); | 2838 Stream s = m.Build(); |
| 2752 ASSERT_EQ(1U, s.size()); | 2839 ASSERT_EQ(1U, s.size()); |
| 2753 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); | 2840 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); |
| 2754 EXPECT_EQ(1U, s[0]->InputCount()); | 2841 EXPECT_EQ(1U, s[0]->InputCount()); |
| 2755 EXPECT_EQ(1U, s[0]->OutputCount()); | 2842 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2756 } | 2843 } |
| 2757 } | 2844 } |
| 2758 | 2845 |
| 2759 | 2846 |
| 2760 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) { | 2847 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) { |
| 2761 // The available shift operand range is `0 <= imm < 32`, but we also test | 2848 // The available shift operand range is `0 <= imm < 32`, but we also test |
| 2762 // that immediates outside this range are handled properly (modulo-32). | 2849 // that immediates outside this range are handled properly (modulo-32). |
| 2763 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 2850 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 2764 int32_t lsb = shift & 0x1f; | 2851 int32_t lsb = shift & 0x1f; |
| 2765 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { | 2852 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
| 2766 uint32_t jnk = rng()->NextInt(); | 2853 uint32_t jnk = rng()->NextInt(); |
| 2767 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; | 2854 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; |
| 2768 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; | 2855 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; |
| 2769 StreamBuilder m(this, kMachInt32, kMachInt32); | 2856 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 2770 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)), | 2857 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)), |
| 2771 m.Int32Constant(shift))); | 2858 m.Int32Constant(shift))); |
| 2772 Stream s = m.Build(); | 2859 Stream s = m.Build(); |
| 2773 ASSERT_EQ(1U, s.size()); | 2860 ASSERT_EQ(1U, s.size()); |
| 2774 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); | 2861 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 2775 ASSERT_EQ(3U, s[0]->InputCount()); | 2862 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2776 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 2863 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 2777 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); | 2864 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 2778 } | 2865 } |
| 2779 } | 2866 } |
| 2780 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 2867 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 2781 int32_t lsb = shift & 0x1f; | 2868 int32_t lsb = shift & 0x1f; |
| 2782 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { | 2869 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
| 2783 uint32_t jnk = rng()->NextInt(); | 2870 uint32_t jnk = rng()->NextInt(); |
| 2784 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; | 2871 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; |
| 2785 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; | 2872 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; |
| 2786 StreamBuilder m(this, kMachInt32, kMachInt32); | 2873 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 2787 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)), | 2874 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)), |
| 2788 m.Int32Constant(shift))); | 2875 m.Int32Constant(shift))); |
| 2789 Stream s = m.Build(); | 2876 Stream s = m.Build(); |
| 2790 ASSERT_EQ(1U, s.size()); | 2877 ASSERT_EQ(1U, s.size()); |
| 2791 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); | 2878 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 2792 ASSERT_EQ(3U, s[0]->InputCount()); | 2879 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2793 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 2880 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 2794 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); | 2881 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 2795 } | 2882 } |
| 2796 } | 2883 } |
| 2797 } | 2884 } |
| 2798 | 2885 |
| 2799 | 2886 |
| 2800 TEST_F(InstructionSelectorTest, Word64ShrWithWord64AndWithImmediate) { | 2887 TEST_F(InstructionSelectorTest, Word64ShrWithWord64AndWithImmediate) { |
| 2801 // The available shift operand range is `0 <= imm < 64`, but we also test | 2888 // The available shift operand range is `0 <= imm < 64`, but we also test |
| 2802 // that immediates outside this range are handled properly (modulo-64). | 2889 // that immediates outside this range are handled properly (modulo-64). |
| 2803 TRACED_FORRANGE(int32_t, shift, -64, 127) { | 2890 TRACED_FORRANGE(int32_t, shift, -64, 127) { |
| 2804 int32_t lsb = shift & 0x3f; | 2891 int32_t lsb = shift & 0x3f; |
| 2805 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) { | 2892 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) { |
| 2806 uint64_t jnk = rng()->NextInt64(); | 2893 uint64_t jnk = rng()->NextInt64(); |
| 2807 jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0; | 2894 jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0; |
| 2808 uint64_t msk = | 2895 uint64_t msk = |
| 2809 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk; | 2896 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk; |
| 2810 StreamBuilder m(this, kMachInt64, kMachInt64); | 2897 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 2811 m.Return(m.Word64Shr(m.Word64And(m.Parameter(0), m.Int64Constant(msk)), | 2898 m.Return(m.Word64Shr(m.Word64And(m.Parameter(0), m.Int64Constant(msk)), |
| 2812 m.Int64Constant(shift))); | 2899 m.Int64Constant(shift))); |
| 2813 Stream s = m.Build(); | 2900 Stream s = m.Build(); |
| 2814 ASSERT_EQ(1U, s.size()); | 2901 ASSERT_EQ(1U, s.size()); |
| 2815 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); | 2902 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); |
| 2816 ASSERT_EQ(3U, s[0]->InputCount()); | 2903 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2817 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); | 2904 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); |
| 2818 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); | 2905 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); |
| 2819 } | 2906 } |
| 2820 } | 2907 } |
| 2821 TRACED_FORRANGE(int32_t, shift, -64, 127) { | 2908 TRACED_FORRANGE(int32_t, shift, -64, 127) { |
| 2822 int32_t lsb = shift & 0x3f; | 2909 int32_t lsb = shift & 0x3f; |
| 2823 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) { | 2910 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) { |
| 2824 uint64_t jnk = rng()->NextInt64(); | 2911 uint64_t jnk = rng()->NextInt64(); |
| 2825 jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0; | 2912 jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0; |
| 2826 uint64_t msk = | 2913 uint64_t msk = |
| 2827 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk; | 2914 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk; |
| 2828 StreamBuilder m(this, kMachInt64, kMachInt64); | 2915 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 2829 m.Return(m.Word64Shr(m.Word64And(m.Int64Constant(msk), m.Parameter(0)), | 2916 m.Return(m.Word64Shr(m.Word64And(m.Int64Constant(msk), m.Parameter(0)), |
| 2830 m.Int64Constant(shift))); | 2917 m.Int64Constant(shift))); |
| 2831 Stream s = m.Build(); | 2918 Stream s = m.Build(); |
| 2832 ASSERT_EQ(1U, s.size()); | 2919 ASSERT_EQ(1U, s.size()); |
| 2833 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); | 2920 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); |
| 2834 ASSERT_EQ(3U, s[0]->InputCount()); | 2921 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2835 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); | 2922 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); |
| 2836 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); | 2923 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); |
| 2837 } | 2924 } |
| 2838 } | 2925 } |
| 2839 } | 2926 } |
| 2840 | 2927 |
| 2841 | 2928 |
| 2842 TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) { | 2929 TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) { |
| 2843 // The available shift operand range is `0 <= imm < 32`, but we also test | 2930 // The available shift operand range is `0 <= imm < 32`, but we also test |
| 2844 // that immediates outside this range are handled properly (modulo-32). | 2931 // that immediates outside this range are handled properly (modulo-32). |
| 2845 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 2932 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 2846 int32_t lsb = shift & 0x1f; | 2933 int32_t lsb = shift & 0x1f; |
| 2847 TRACED_FORRANGE(int32_t, width, 1, 31) { | 2934 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 2848 uint32_t msk = (1 << width) - 1; | 2935 uint32_t msk = (1 << width) - 1; |
| 2849 StreamBuilder m(this, kMachInt32, kMachInt32); | 2936 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 2850 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), | 2937 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), |
| 2851 m.Int32Constant(msk))); | 2938 m.Int32Constant(msk))); |
| 2852 Stream s = m.Build(); | 2939 Stream s = m.Build(); |
| 2853 ASSERT_EQ(1U, s.size()); | 2940 ASSERT_EQ(1U, s.size()); |
| 2854 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); | 2941 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 2855 ASSERT_EQ(3U, s[0]->InputCount()); | 2942 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2856 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 2943 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 2857 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; | 2944 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; |
| 2858 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); | 2945 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); |
| 2859 } | 2946 } |
| 2860 } | 2947 } |
| 2861 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 2948 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 2862 int32_t lsb = shift & 0x1f; | 2949 int32_t lsb = shift & 0x1f; |
| 2863 TRACED_FORRANGE(int32_t, width, 1, 31) { | 2950 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 2864 uint32_t msk = (1 << width) - 1; | 2951 uint32_t msk = (1 << width) - 1; |
| 2865 StreamBuilder m(this, kMachInt32, kMachInt32); | 2952 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 2866 m.Return( | 2953 m.Return( |
| 2867 m.Word32And(m.Int32Constant(msk), | 2954 m.Word32And(m.Int32Constant(msk), |
| 2868 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)))); | 2955 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)))); |
| 2869 Stream s = m.Build(); | 2956 Stream s = m.Build(); |
| 2870 ASSERT_EQ(1U, s.size()); | 2957 ASSERT_EQ(1U, s.size()); |
| 2871 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); | 2958 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 2872 ASSERT_EQ(3U, s[0]->InputCount()); | 2959 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2873 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 2960 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 2874 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; | 2961 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; |
| 2875 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); | 2962 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); |
| 2876 } | 2963 } |
| 2877 } | 2964 } |
| 2878 } | 2965 } |
| 2879 | 2966 |
| 2880 | 2967 |
| 2881 TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) { | 2968 TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) { |
| 2882 // The available shift operand range is `0 <= imm < 64`, but we also test | 2969 // The available shift operand range is `0 <= imm < 64`, but we also test |
| 2883 // that immediates outside this range are handled properly (modulo-64). | 2970 // that immediates outside this range are handled properly (modulo-64). |
| 2884 TRACED_FORRANGE(int64_t, shift, -64, 127) { | 2971 TRACED_FORRANGE(int64_t, shift, -64, 127) { |
| 2885 int64_t lsb = shift & 0x3f; | 2972 int64_t lsb = shift & 0x3f; |
| 2886 TRACED_FORRANGE(int64_t, width, 1, 63) { | 2973 TRACED_FORRANGE(int64_t, width, 1, 63) { |
| 2887 uint64_t msk = (V8_UINT64_C(1) << width) - 1; | 2974 uint64_t msk = (V8_UINT64_C(1) << width) - 1; |
| 2888 StreamBuilder m(this, kMachInt64, kMachInt64); | 2975 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 2889 m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(shift)), | 2976 m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(shift)), |
| 2890 m.Int64Constant(msk))); | 2977 m.Int64Constant(msk))); |
| 2891 Stream s = m.Build(); | 2978 Stream s = m.Build(); |
| 2892 ASSERT_EQ(1U, s.size()); | 2979 ASSERT_EQ(1U, s.size()); |
| 2893 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); | 2980 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); |
| 2894 ASSERT_EQ(3U, s[0]->InputCount()); | 2981 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2895 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); | 2982 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); |
| 2896 int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width; | 2983 int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width; |
| 2897 EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2))); | 2984 EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2))); |
| 2898 } | 2985 } |
| 2899 } | 2986 } |
| 2900 TRACED_FORRANGE(int64_t, shift, -64, 127) { | 2987 TRACED_FORRANGE(int64_t, shift, -64, 127) { |
| 2901 int64_t lsb = shift & 0x3f; | 2988 int64_t lsb = shift & 0x3f; |
| 2902 TRACED_FORRANGE(int64_t, width, 1, 63) { | 2989 TRACED_FORRANGE(int64_t, width, 1, 63) { |
| 2903 uint64_t msk = (V8_UINT64_C(1) << width) - 1; | 2990 uint64_t msk = (V8_UINT64_C(1) << width) - 1; |
| 2904 StreamBuilder m(this, kMachInt64, kMachInt64); | 2991 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
| 2905 m.Return( | 2992 m.Return( |
| 2906 m.Word64And(m.Int64Constant(msk), | 2993 m.Word64And(m.Int64Constant(msk), |
| 2907 m.Word64Shr(m.Parameter(0), m.Int64Constant(shift)))); | 2994 m.Word64Shr(m.Parameter(0), m.Int64Constant(shift)))); |
| 2908 Stream s = m.Build(); | 2995 Stream s = m.Build(); |
| 2909 ASSERT_EQ(1U, s.size()); | 2996 ASSERT_EQ(1U, s.size()); |
| 2910 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); | 2997 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); |
| 2911 ASSERT_EQ(3U, s[0]->InputCount()); | 2998 ASSERT_EQ(3U, s[0]->InputCount()); |
| 2912 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); | 2999 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); |
| 2913 int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width; | 3000 int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width; |
| 2914 EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2))); | 3001 EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2))); |
| 2915 } | 3002 } |
| 2916 } | 3003 } |
| 2917 } | 3004 } |
| 2918 | 3005 |
| 2919 | 3006 |
| 2920 TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) { | 3007 TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) { |
| 2921 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 3008 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3009 MachineType::Int32()); |
| 2922 Node* const p0 = m.Parameter(0); | 3010 Node* const p0 = m.Parameter(0); |
| 2923 Node* const p1 = m.Parameter(1); | 3011 Node* const p1 = m.Parameter(1); |
| 2924 Node* const n = m.Int32MulHigh(p0, p1); | 3012 Node* const n = m.Int32MulHigh(p0, p1); |
| 2925 m.Return(n); | 3013 m.Return(n); |
| 2926 Stream s = m.Build(); | 3014 Stream s = m.Build(); |
| 2927 ASSERT_EQ(2U, s.size()); | 3015 ASSERT_EQ(2U, s.size()); |
| 2928 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode()); | 3016 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode()); |
| 2929 ASSERT_EQ(2U, s[0]->InputCount()); | 3017 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2930 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3018 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2931 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 3019 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2932 ASSERT_EQ(1U, s[0]->OutputCount()); | 3020 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2933 EXPECT_EQ(kArm64Asr, s[1]->arch_opcode()); | 3021 EXPECT_EQ(kArm64Asr, s[1]->arch_opcode()); |
| 2934 ASSERT_EQ(2U, s[1]->InputCount()); | 3022 ASSERT_EQ(2U, s[1]->InputCount()); |
| 2935 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); | 3023 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); |
| 2936 EXPECT_EQ(32, s.ToInt64(s[1]->InputAt(1))); | 3024 EXPECT_EQ(32, s.ToInt64(s[1]->InputAt(1))); |
| 2937 ASSERT_EQ(1U, s[1]->OutputCount()); | 3025 ASSERT_EQ(1U, s[1]->OutputCount()); |
| 2938 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); | 3026 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); |
| 2939 } | 3027 } |
| 2940 | 3028 |
| 2941 | 3029 |
| 2942 TEST_F(InstructionSelectorTest, Int32MulHighWithSar) { | 3030 TEST_F(InstructionSelectorTest, Int32MulHighWithSar) { |
| 2943 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 3031 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 2944 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 3032 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3033 MachineType::Int32()); |
| 2945 Node* const p0 = m.Parameter(0); | 3034 Node* const p0 = m.Parameter(0); |
| 2946 Node* const p1 = m.Parameter(1); | 3035 Node* const p1 = m.Parameter(1); |
| 2947 Node* const n = m.Word32Sar(m.Int32MulHigh(p0, p1), m.Int32Constant(shift)); | 3036 Node* const n = m.Word32Sar(m.Int32MulHigh(p0, p1), m.Int32Constant(shift)); |
| 2948 m.Return(n); | 3037 m.Return(n); |
| 2949 Stream s = m.Build(); | 3038 Stream s = m.Build(); |
| 2950 ASSERT_EQ(2U, s.size()); | 3039 ASSERT_EQ(2U, s.size()); |
| 2951 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode()); | 3040 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode()); |
| 2952 ASSERT_EQ(2U, s[0]->InputCount()); | 3041 ASSERT_EQ(2U, s[0]->InputCount()); |
| 2953 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3042 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2954 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 3043 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 2955 ASSERT_EQ(1U, s[0]->OutputCount()); | 3044 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2956 EXPECT_EQ(kArm64Asr, s[1]->arch_opcode()); | 3045 EXPECT_EQ(kArm64Asr, s[1]->arch_opcode()); |
| 2957 ASSERT_EQ(2U, s[1]->InputCount()); | 3046 ASSERT_EQ(2U, s[1]->InputCount()); |
| 2958 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); | 3047 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); |
| 2959 EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1))); | 3048 EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1))); |
| 2960 ASSERT_EQ(1U, s[1]->OutputCount()); | 3049 ASSERT_EQ(1U, s[1]->OutputCount()); |
| 2961 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); | 3050 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); |
| 2962 } | 3051 } |
| 2963 } | 3052 } |
| 2964 | 3053 |
| 2965 | 3054 |
| 2966 TEST_F(InstructionSelectorTest, Int32MulHighWithAdd) { | 3055 TEST_F(InstructionSelectorTest, Int32MulHighWithAdd) { |
| 2967 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 3056 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3057 MachineType::Int32()); |
| 2968 Node* const p0 = m.Parameter(0); | 3058 Node* const p0 = m.Parameter(0); |
| 2969 Node* const p1 = m.Parameter(1); | 3059 Node* const p1 = m.Parameter(1); |
| 2970 Node* const a = m.Int32Add(m.Int32MulHigh(p0, p1), p0); | 3060 Node* const a = m.Int32Add(m.Int32MulHigh(p0, p1), p0); |
| 2971 // Test only one shift constant here, as we're only interested in it being a | 3061 // Test only one shift constant here, as we're only interested in it being a |
| 2972 // 32-bit operation; the shift amount is irrelevant. | 3062 // 32-bit operation; the shift amount is irrelevant. |
| 2973 Node* const n = m.Word32Sar(a, m.Int32Constant(1)); | 3063 Node* const n = m.Word32Sar(a, m.Int32Constant(1)); |
| 2974 m.Return(n); | 3064 m.Return(n); |
| 2975 Stream s = m.Build(); | 3065 Stream s = m.Build(); |
| 2976 ASSERT_EQ(3U, s.size()); | 3066 ASSERT_EQ(3U, s.size()); |
| 2977 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode()); | 3067 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2990 ASSERT_EQ(2U, s[2]->InputCount()); | 3080 ASSERT_EQ(2U, s[2]->InputCount()); |
| 2991 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(0))); | 3081 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(0))); |
| 2992 EXPECT_EQ(1, s.ToInt64(s[2]->InputAt(1))); | 3082 EXPECT_EQ(1, s.ToInt64(s[2]->InputAt(1))); |
| 2993 ASSERT_EQ(1U, s[2]->OutputCount()); | 3083 ASSERT_EQ(1U, s[2]->OutputCount()); |
| 2994 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[2]->Output())); | 3084 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[2]->Output())); |
| 2995 } | 3085 } |
| 2996 | 3086 |
| 2997 | 3087 |
| 2998 TEST_F(InstructionSelectorTest, Uint32MulHighWithShr) { | 3088 TEST_F(InstructionSelectorTest, Uint32MulHighWithShr) { |
| 2999 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 3089 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 3000 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 3090 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3091 MachineType::Int32()); |
| 3001 Node* const p0 = m.Parameter(0); | 3092 Node* const p0 = m.Parameter(0); |
| 3002 Node* const p1 = m.Parameter(1); | 3093 Node* const p1 = m.Parameter(1); |
| 3003 Node* const n = | 3094 Node* const n = |
| 3004 m.Word32Shr(m.Uint32MulHigh(p0, p1), m.Int32Constant(shift)); | 3095 m.Word32Shr(m.Uint32MulHigh(p0, p1), m.Int32Constant(shift)); |
| 3005 m.Return(n); | 3096 m.Return(n); |
| 3006 Stream s = m.Build(); | 3097 Stream s = m.Build(); |
| 3007 ASSERT_EQ(2U, s.size()); | 3098 ASSERT_EQ(2U, s.size()); |
| 3008 EXPECT_EQ(kArm64Umull, s[0]->arch_opcode()); | 3099 EXPECT_EQ(kArm64Umull, s[0]->arch_opcode()); |
| 3009 ASSERT_EQ(2U, s[0]->InputCount()); | 3100 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3010 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3101 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3011 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 3102 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 3012 ASSERT_EQ(1U, s[0]->OutputCount()); | 3103 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3013 EXPECT_EQ(kArm64Lsr, s[1]->arch_opcode()); | 3104 EXPECT_EQ(kArm64Lsr, s[1]->arch_opcode()); |
| 3014 ASSERT_EQ(2U, s[1]->InputCount()); | 3105 ASSERT_EQ(2U, s[1]->InputCount()); |
| 3015 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); | 3106 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); |
| 3016 EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1))); | 3107 EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1))); |
| 3017 ASSERT_EQ(1U, s[1]->OutputCount()); | 3108 ASSERT_EQ(1U, s[1]->OutputCount()); |
| 3018 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); | 3109 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); |
| 3019 } | 3110 } |
| 3020 } | 3111 } |
| 3021 | 3112 |
| 3022 | 3113 |
| 3023 TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) { | 3114 TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) { |
| 3024 TRACED_FORRANGE(int32_t, shift, 1, 31) { | 3115 TRACED_FORRANGE(int32_t, shift, 1, 31) { |
| 3025 StreamBuilder m(this, kMachInt32, kMachInt32); | 3116 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3026 Node* const p0 = m.Parameter(0); | 3117 Node* const p0 = m.Parameter(0); |
| 3027 Node* const r = m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(shift)), | 3118 Node* const r = m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(shift)), |
| 3028 m.Int32Constant(shift)); | 3119 m.Int32Constant(shift)); |
| 3029 m.Return(r); | 3120 m.Return(r); |
| 3030 Stream s = m.Build(); | 3121 Stream s = m.Build(); |
| 3031 ASSERT_EQ(1U, s.size()); | 3122 ASSERT_EQ(1U, s.size()); |
| 3032 EXPECT_EQ(kArm64Sbfx32, s[0]->arch_opcode()); | 3123 EXPECT_EQ(kArm64Sbfx32, s[0]->arch_opcode()); |
| 3033 ASSERT_EQ(3U, s[0]->InputCount()); | 3124 ASSERT_EQ(3U, s[0]->InputCount()); |
| 3034 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3125 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3035 ASSERT_EQ(1U, s[0]->OutputCount()); | 3126 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3036 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); | 3127 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); |
| 3037 } | 3128 } |
| 3038 TRACED_FORRANGE(int32_t, shift, 1, 31) { | 3129 TRACED_FORRANGE(int32_t, shift, 1, 31) { |
| 3039 StreamBuilder m(this, kMachInt32, kMachInt32); | 3130 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3040 Node* const p0 = m.Parameter(0); | 3131 Node* const p0 = m.Parameter(0); |
| 3041 Node* const r = m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(shift + 32)), | 3132 Node* const r = m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(shift + 32)), |
| 3042 m.Int32Constant(shift + 64)); | 3133 m.Int32Constant(shift + 64)); |
| 3043 m.Return(r); | 3134 m.Return(r); |
| 3044 Stream s = m.Build(); | 3135 Stream s = m.Build(); |
| 3045 ASSERT_EQ(1U, s.size()); | 3136 ASSERT_EQ(1U, s.size()); |
| 3046 EXPECT_EQ(kArm64Sbfx32, s[0]->arch_opcode()); | 3137 EXPECT_EQ(kArm64Sbfx32, s[0]->arch_opcode()); |
| 3047 ASSERT_EQ(3U, s[0]->InputCount()); | 3138 ASSERT_EQ(3U, s[0]->InputCount()); |
| 3048 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3139 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3049 ASSERT_EQ(1U, s[0]->OutputCount()); | 3140 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3050 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); | 3141 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); |
| 3051 } | 3142 } |
| 3052 } | 3143 } |
| 3053 | 3144 |
| 3054 | 3145 |
| 3055 TEST_F(InstructionSelectorTest, Word32ShrWithWord32Shl) { | 3146 TEST_F(InstructionSelectorTest, Word32ShrWithWord32Shl) { |
| 3056 TRACED_FORRANGE(int32_t, shift, 1, 31) { | 3147 TRACED_FORRANGE(int32_t, shift, 1, 31) { |
| 3057 StreamBuilder m(this, kMachInt32, kMachInt32); | 3148 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3058 Node* const p0 = m.Parameter(0); | 3149 Node* const p0 = m.Parameter(0); |
| 3059 Node* const r = m.Word32Shr(m.Word32Shl(p0, m.Int32Constant(shift)), | 3150 Node* const r = m.Word32Shr(m.Word32Shl(p0, m.Int32Constant(shift)), |
| 3060 m.Int32Constant(shift)); | 3151 m.Int32Constant(shift)); |
| 3061 m.Return(r); | 3152 m.Return(r); |
| 3062 Stream s = m.Build(); | 3153 Stream s = m.Build(); |
| 3063 ASSERT_EQ(1U, s.size()); | 3154 ASSERT_EQ(1U, s.size()); |
| 3064 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); | 3155 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 3065 ASSERT_EQ(3U, s[0]->InputCount()); | 3156 ASSERT_EQ(3U, s[0]->InputCount()); |
| 3066 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3157 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3067 ASSERT_EQ(1U, s[0]->OutputCount()); | 3158 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3068 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); | 3159 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); |
| 3069 } | 3160 } |
| 3070 TRACED_FORRANGE(int32_t, shift, 1, 31) { | 3161 TRACED_FORRANGE(int32_t, shift, 1, 31) { |
| 3071 StreamBuilder m(this, kMachInt32, kMachInt32); | 3162 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3072 Node* const p0 = m.Parameter(0); | 3163 Node* const p0 = m.Parameter(0); |
| 3073 Node* const r = m.Word32Shr(m.Word32Shl(p0, m.Int32Constant(shift + 32)), | 3164 Node* const r = m.Word32Shr(m.Word32Shl(p0, m.Int32Constant(shift + 32)), |
| 3074 m.Int32Constant(shift + 64)); | 3165 m.Int32Constant(shift + 64)); |
| 3075 m.Return(r); | 3166 m.Return(r); |
| 3076 Stream s = m.Build(); | 3167 Stream s = m.Build(); |
| 3077 ASSERT_EQ(1U, s.size()); | 3168 ASSERT_EQ(1U, s.size()); |
| 3078 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); | 3169 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); |
| 3079 ASSERT_EQ(3U, s[0]->InputCount()); | 3170 ASSERT_EQ(3U, s[0]->InputCount()); |
| 3080 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3171 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3081 ASSERT_EQ(1U, s[0]->OutputCount()); | 3172 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3082 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); | 3173 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); |
| 3083 } | 3174 } |
| 3084 } | 3175 } |
| 3085 | 3176 |
| 3086 | 3177 |
| 3087 TEST_F(InstructionSelectorTest, Word32ShlWithWord32And) { | 3178 TEST_F(InstructionSelectorTest, Word32ShlWithWord32And) { |
| 3088 TRACED_FORRANGE(int32_t, shift, 1, 30) { | 3179 TRACED_FORRANGE(int32_t, shift, 1, 30) { |
| 3089 StreamBuilder m(this, kMachInt32, kMachInt32); | 3180 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3090 Node* const p0 = m.Parameter(0); | 3181 Node* const p0 = m.Parameter(0); |
| 3091 Node* const r = | 3182 Node* const r = |
| 3092 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)), | 3183 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)), |
| 3093 m.Int32Constant(shift)); | 3184 m.Int32Constant(shift)); |
| 3094 m.Return(r); | 3185 m.Return(r); |
| 3095 Stream s = m.Build(); | 3186 Stream s = m.Build(); |
| 3096 ASSERT_EQ(1U, s.size()); | 3187 ASSERT_EQ(1U, s.size()); |
| 3097 EXPECT_EQ(kArm64Ubfiz32, s[0]->arch_opcode()); | 3188 EXPECT_EQ(kArm64Ubfiz32, s[0]->arch_opcode()); |
| 3098 ASSERT_EQ(3U, s[0]->InputCount()); | 3189 ASSERT_EQ(3U, s[0]->InputCount()); |
| 3099 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3190 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3100 ASSERT_EQ(1U, s[0]->OutputCount()); | 3191 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3101 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); | 3192 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); |
| 3102 } | 3193 } |
| 3103 TRACED_FORRANGE(int32_t, shift, 0, 30) { | 3194 TRACED_FORRANGE(int32_t, shift, 0, 30) { |
| 3104 StreamBuilder m(this, kMachInt32, kMachInt32); | 3195 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3105 Node* const p0 = m.Parameter(0); | 3196 Node* const p0 = m.Parameter(0); |
| 3106 Node* const r = | 3197 Node* const r = |
| 3107 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)), | 3198 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)), |
| 3108 m.Int32Constant(shift + 1)); | 3199 m.Int32Constant(shift + 1)); |
| 3109 m.Return(r); | 3200 m.Return(r); |
| 3110 Stream s = m.Build(); | 3201 Stream s = m.Build(); |
| 3111 ASSERT_EQ(1U, s.size()); | 3202 ASSERT_EQ(1U, s.size()); |
| 3112 EXPECT_EQ(kArm64Lsl32, s[0]->arch_opcode()); | 3203 EXPECT_EQ(kArm64Lsl32, s[0]->arch_opcode()); |
| 3113 ASSERT_EQ(2U, s[0]->InputCount()); | 3204 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3114 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3205 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3115 ASSERT_EQ(1U, s[0]->OutputCount()); | 3206 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3116 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); | 3207 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); |
| 3117 } | 3208 } |
| 3118 } | 3209 } |
| 3119 | 3210 |
| 3120 | 3211 |
| 3121 TEST_F(InstructionSelectorTest, Word32Clz) { | 3212 TEST_F(InstructionSelectorTest, Word32Clz) { |
| 3122 StreamBuilder m(this, kMachUint32, kMachUint32); | 3213 StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32()); |
| 3123 Node* const p0 = m.Parameter(0); | 3214 Node* const p0 = m.Parameter(0); |
| 3124 Node* const n = m.Word32Clz(p0); | 3215 Node* const n = m.Word32Clz(p0); |
| 3125 m.Return(n); | 3216 m.Return(n); |
| 3126 Stream s = m.Build(); | 3217 Stream s = m.Build(); |
| 3127 ASSERT_EQ(1U, s.size()); | 3218 ASSERT_EQ(1U, s.size()); |
| 3128 EXPECT_EQ(kArm64Clz32, s[0]->arch_opcode()); | 3219 EXPECT_EQ(kArm64Clz32, s[0]->arch_opcode()); |
| 3129 ASSERT_EQ(1U, s[0]->InputCount()); | 3220 ASSERT_EQ(1U, s[0]->InputCount()); |
| 3130 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3221 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3131 ASSERT_EQ(1U, s[0]->OutputCount()); | 3222 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3132 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3223 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 3133 } | 3224 } |
| 3134 | 3225 |
| 3135 | 3226 |
| 3136 TEST_F(InstructionSelectorTest, Float32Abs) { | 3227 TEST_F(InstructionSelectorTest, Float32Abs) { |
| 3137 StreamBuilder m(this, kMachFloat32, kMachFloat32); | 3228 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32()); |
| 3138 Node* const p0 = m.Parameter(0); | 3229 Node* const p0 = m.Parameter(0); |
| 3139 Node* const n = m.Float32Abs(p0); | 3230 Node* const n = m.Float32Abs(p0); |
| 3140 m.Return(n); | 3231 m.Return(n); |
| 3141 Stream s = m.Build(); | 3232 Stream s = m.Build(); |
| 3142 ASSERT_EQ(1U, s.size()); | 3233 ASSERT_EQ(1U, s.size()); |
| 3143 EXPECT_EQ(kArm64Float32Abs, s[0]->arch_opcode()); | 3234 EXPECT_EQ(kArm64Float32Abs, s[0]->arch_opcode()); |
| 3144 ASSERT_EQ(1U, s[0]->InputCount()); | 3235 ASSERT_EQ(1U, s[0]->InputCount()); |
| 3145 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3236 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3146 ASSERT_EQ(1U, s[0]->OutputCount()); | 3237 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3147 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3238 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 3148 } | 3239 } |
| 3149 | 3240 |
| 3150 | 3241 |
| 3151 TEST_F(InstructionSelectorTest, Float64Abs) { | 3242 TEST_F(InstructionSelectorTest, Float64Abs) { |
| 3152 StreamBuilder m(this, kMachFloat64, kMachFloat64); | 3243 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64()); |
| 3153 Node* const p0 = m.Parameter(0); | 3244 Node* const p0 = m.Parameter(0); |
| 3154 Node* const n = m.Float64Abs(p0); | 3245 Node* const n = m.Float64Abs(p0); |
| 3155 m.Return(n); | 3246 m.Return(n); |
| 3156 Stream s = m.Build(); | 3247 Stream s = m.Build(); |
| 3157 ASSERT_EQ(1U, s.size()); | 3248 ASSERT_EQ(1U, s.size()); |
| 3158 EXPECT_EQ(kArm64Float64Abs, s[0]->arch_opcode()); | 3249 EXPECT_EQ(kArm64Float64Abs, s[0]->arch_opcode()); |
| 3159 ASSERT_EQ(1U, s[0]->InputCount()); | 3250 ASSERT_EQ(1U, s[0]->InputCount()); |
| 3160 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3251 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3161 ASSERT_EQ(1U, s[0]->OutputCount()); | 3252 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3162 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3253 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 3163 } | 3254 } |
| 3164 | 3255 |
| 3165 | 3256 |
| 3166 TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) { | 3257 TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) { |
| 3167 StreamBuilder m(this, kMachFloat64, kMachFloat64); | 3258 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64()); |
| 3168 Node* const p0 = m.Parameter(0); | 3259 Node* const p0 = m.Parameter(0); |
| 3169 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0); | 3260 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0); |
| 3170 m.Return(n); | 3261 m.Return(n); |
| 3171 Stream s = m.Build(); | 3262 Stream s = m.Build(); |
| 3172 ASSERT_EQ(1U, s.size()); | 3263 ASSERT_EQ(1U, s.size()); |
| 3173 EXPECT_EQ(kArm64Float64Neg, s[0]->arch_opcode()); | 3264 EXPECT_EQ(kArm64Float64Neg, s[0]->arch_opcode()); |
| 3174 ASSERT_EQ(1U, s[0]->InputCount()); | 3265 ASSERT_EQ(1U, s[0]->InputCount()); |
| 3175 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3266 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3176 ASSERT_EQ(1U, s[0]->OutputCount()); | 3267 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3177 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3268 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 3178 } | 3269 } |
| 3179 | 3270 |
| 3180 | 3271 |
| 3181 TEST_F(InstructionSelectorTest, Float32Max) { | 3272 TEST_F(InstructionSelectorTest, Float32Max) { |
| 3182 StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); | 3273 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(), |
| 3274 MachineType::Float32()); |
| 3183 Node* const p0 = m.Parameter(0); | 3275 Node* const p0 = m.Parameter(0); |
| 3184 Node* const p1 = m.Parameter(1); | 3276 Node* const p1 = m.Parameter(1); |
| 3185 Node* const n = m.Float32Max(p0, p1); | 3277 Node* const n = m.Float32Max(p0, p1); |
| 3186 m.Return(n); | 3278 m.Return(n); |
| 3187 Stream s = m.Build(); | 3279 Stream s = m.Build(); |
| 3188 // Float32Max is `(b < a) ? a : b`. | 3280 // Float32Max is `(b < a) ? a : b`. |
| 3189 ASSERT_EQ(1U, s.size()); | 3281 ASSERT_EQ(1U, s.size()); |
| 3190 EXPECT_EQ(kArm64Float32Max, s[0]->arch_opcode()); | 3282 EXPECT_EQ(kArm64Float32Max, s[0]->arch_opcode()); |
| 3191 ASSERT_EQ(2U, s[0]->InputCount()); | 3283 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3192 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3284 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3193 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 3285 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 3194 ASSERT_EQ(1U, s[0]->OutputCount()); | 3286 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3195 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3287 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 3196 } | 3288 } |
| 3197 | 3289 |
| 3198 | 3290 |
| 3199 TEST_F(InstructionSelectorTest, Float32Min) { | 3291 TEST_F(InstructionSelectorTest, Float32Min) { |
| 3200 StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); | 3292 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(), |
| 3293 MachineType::Float32()); |
| 3201 Node* const p0 = m.Parameter(0); | 3294 Node* const p0 = m.Parameter(0); |
| 3202 Node* const p1 = m.Parameter(1); | 3295 Node* const p1 = m.Parameter(1); |
| 3203 Node* const n = m.Float32Min(p0, p1); | 3296 Node* const n = m.Float32Min(p0, p1); |
| 3204 m.Return(n); | 3297 m.Return(n); |
| 3205 Stream s = m.Build(); | 3298 Stream s = m.Build(); |
| 3206 // Float32Min is `(a < b) ? a : b`. | 3299 // Float32Min is `(a < b) ? a : b`. |
| 3207 ASSERT_EQ(1U, s.size()); | 3300 ASSERT_EQ(1U, s.size()); |
| 3208 EXPECT_EQ(kArm64Float32Min, s[0]->arch_opcode()); | 3301 EXPECT_EQ(kArm64Float32Min, s[0]->arch_opcode()); |
| 3209 ASSERT_EQ(2U, s[0]->InputCount()); | 3302 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3210 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3303 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3211 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 3304 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 3212 ASSERT_EQ(1U, s[0]->OutputCount()); | 3305 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3213 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3306 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 3214 } | 3307 } |
| 3215 | 3308 |
| 3216 | 3309 |
| 3217 TEST_F(InstructionSelectorTest, Float64Max) { | 3310 TEST_F(InstructionSelectorTest, Float64Max) { |
| 3218 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); | 3311 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(), |
| 3312 MachineType::Float64()); |
| 3219 Node* const p0 = m.Parameter(0); | 3313 Node* const p0 = m.Parameter(0); |
| 3220 Node* const p1 = m.Parameter(1); | 3314 Node* const p1 = m.Parameter(1); |
| 3221 Node* const n = m.Float64Max(p0, p1); | 3315 Node* const n = m.Float64Max(p0, p1); |
| 3222 m.Return(n); | 3316 m.Return(n); |
| 3223 Stream s = m.Build(); | 3317 Stream s = m.Build(); |
| 3224 // Float64Max is `(b < a) ? a : b`. | 3318 // Float64Max is `(b < a) ? a : b`. |
| 3225 ASSERT_EQ(1U, s.size()); | 3319 ASSERT_EQ(1U, s.size()); |
| 3226 EXPECT_EQ(kArm64Float64Max, s[0]->arch_opcode()); | 3320 EXPECT_EQ(kArm64Float64Max, s[0]->arch_opcode()); |
| 3227 ASSERT_EQ(2U, s[0]->InputCount()); | 3321 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3228 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3322 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3229 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 3323 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 3230 ASSERT_EQ(1U, s[0]->OutputCount()); | 3324 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3231 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3325 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 3232 } | 3326 } |
| 3233 | 3327 |
| 3234 | 3328 |
| 3235 TEST_F(InstructionSelectorTest, Float64Min) { | 3329 TEST_F(InstructionSelectorTest, Float64Min) { |
| 3236 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); | 3330 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(), |
| 3331 MachineType::Float64()); |
| 3237 Node* const p0 = m.Parameter(0); | 3332 Node* const p0 = m.Parameter(0); |
| 3238 Node* const p1 = m.Parameter(1); | 3333 Node* const p1 = m.Parameter(1); |
| 3239 Node* const n = m.Float64Min(p0, p1); | 3334 Node* const n = m.Float64Min(p0, p1); |
| 3240 m.Return(n); | 3335 m.Return(n); |
| 3241 Stream s = m.Build(); | 3336 Stream s = m.Build(); |
| 3242 // Float64Min is `(a < b) ? a : b`. | 3337 // Float64Min is `(a < b) ? a : b`. |
| 3243 ASSERT_EQ(1U, s.size()); | 3338 ASSERT_EQ(1U, s.size()); |
| 3244 EXPECT_EQ(kArm64Float64Min, s[0]->arch_opcode()); | 3339 EXPECT_EQ(kArm64Float64Min, s[0]->arch_opcode()); |
| 3245 ASSERT_EQ(2U, s[0]->InputCount()); | 3340 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3246 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3341 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3247 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 3342 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
| 3248 ASSERT_EQ(1U, s[0]->OutputCount()); | 3343 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3249 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3344 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 3250 } | 3345 } |
| 3251 | 3346 |
| 3252 } // namespace compiler | 3347 } // namespace compiler |
| 3253 } // namespace internal | 3348 } // namespace internal |
| 3254 } // namespace v8 | 3349 } // namespace v8 |
| OLD | NEW |