| 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 23 matching lines...) Expand all Loading... |
| 34 uint32_t expected_size; | 34 uint32_t expected_size; |
| 35 }; | 35 }; |
| 36 | 36 |
| 37 struct FPCmp { | 37 struct FPCmp { |
| 38 MachInst2 mi; | 38 MachInst2 mi; |
| 39 FlagsCondition cond; | 39 FlagsCondition cond; |
| 40 }; | 40 }; |
| 41 | 41 |
| 42 const FPCmp kFPCmpInstructions[] = { | 42 const FPCmp kFPCmpInstructions[] = { |
| 43 {{&RawMachineAssembler::Float64Equal, "Float64Equal", kMipsCmpD, | 43 {{&RawMachineAssembler::Float64Equal, "Float64Equal", kMipsCmpD, |
| 44 kMachFloat64}, | 44 MachineType::Float64()}, |
| 45 kEqual}, | 45 kEqual}, |
| 46 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", kMipsCmpD, | 46 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", kMipsCmpD, |
| 47 kMachFloat64}, | 47 MachineType::Float64()}, |
| 48 kUnsignedLessThan}, | 48 kUnsignedLessThan}, |
| 49 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", | 49 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", |
| 50 kMipsCmpD, kMachFloat64}, | 50 kMipsCmpD, MachineType::Float64()}, |
| 51 kUnsignedLessThanOrEqual}, | 51 kUnsignedLessThanOrEqual}, |
| 52 {{&RawMachineAssembler::Float64GreaterThan, "Float64GreaterThan", kMipsCmpD, | 52 {{&RawMachineAssembler::Float64GreaterThan, "Float64GreaterThan", kMipsCmpD, |
| 53 kMachFloat64}, | 53 MachineType::Float64()}, |
| 54 kUnsignedLessThan}, | 54 kUnsignedLessThan}, |
| 55 {{&RawMachineAssembler::Float64GreaterThanOrEqual, | 55 {{&RawMachineAssembler::Float64GreaterThanOrEqual, |
| 56 "Float64GreaterThanOrEqual", kMipsCmpD, kMachFloat64}, | 56 "Float64GreaterThanOrEqual", kMipsCmpD, MachineType::Float64()}, |
| 57 kUnsignedLessThanOrEqual}}; | 57 kUnsignedLessThanOrEqual}}; |
| 58 | 58 |
| 59 struct Conversion { | 59 struct Conversion { |
| 60 // The machine_type field in MachInst1 represents the destination type. | 60 // The machine_type field in MachInst1 represents the destination type. |
| 61 MachInst1 mi; | 61 MachInst1 mi; |
| 62 MachineType src_machine_type; | 62 MachineType src_machine_type; |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 | 65 |
| 66 // ---------------------------------------------------------------------------- | 66 // ---------------------------------------------------------------------------- |
| 67 // Logical instructions. | 67 // Logical instructions. |
| 68 // ---------------------------------------------------------------------------- | 68 // ---------------------------------------------------------------------------- |
| 69 | 69 |
| 70 | 70 |
| 71 const MachInst2 kLogicalInstructions[] = { | 71 const MachInst2 kLogicalInstructions[] = { |
| 72 {&RawMachineAssembler::WordAnd, "WordAnd", kMipsAnd, kMachInt16}, | 72 {&RawMachineAssembler::WordAnd, "WordAnd", kMipsAnd, MachineType::Int16()}, |
| 73 {&RawMachineAssembler::WordOr, "WordOr", kMipsOr, kMachInt16}, | 73 {&RawMachineAssembler::WordOr, "WordOr", kMipsOr, MachineType::Int16()}, |
| 74 {&RawMachineAssembler::WordXor, "WordXor", kMipsXor, kMachInt16}, | 74 {&RawMachineAssembler::WordXor, "WordXor", kMipsXor, MachineType::Int16()}, |
| 75 {&RawMachineAssembler::Word32And, "Word32And", kMipsAnd, kMachInt32}, | 75 {&RawMachineAssembler::Word32And, "Word32And", kMipsAnd, |
| 76 {&RawMachineAssembler::Word32Or, "Word32Or", kMipsOr, kMachInt32}, | 76 MachineType::Int32()}, |
| 77 {&RawMachineAssembler::Word32Xor, "Word32Xor", kMipsXor, kMachInt32}}; | 77 {&RawMachineAssembler::Word32Or, "Word32Or", kMipsOr, MachineType::Int32()}, |
| 78 {&RawMachineAssembler::Word32Xor, "Word32Xor", kMipsXor, |
| 79 MachineType::Int32()}}; |
| 78 | 80 |
| 79 | 81 |
| 80 // ---------------------------------------------------------------------------- | 82 // ---------------------------------------------------------------------------- |
| 81 // Shift instructions. | 83 // Shift instructions. |
| 82 // ---------------------------------------------------------------------------- | 84 // ---------------------------------------------------------------------------- |
| 83 | 85 |
| 84 | 86 |
| 85 const MachInst2 kShiftInstructions[] = { | 87 const MachInst2 kShiftInstructions[] = { |
| 86 {&RawMachineAssembler::WordShl, "WordShl", kMipsShl, kMachInt16}, | 88 {&RawMachineAssembler::WordShl, "WordShl", kMipsShl, MachineType::Int16()}, |
| 87 {&RawMachineAssembler::WordShr, "WordShr", kMipsShr, kMachInt16}, | 89 {&RawMachineAssembler::WordShr, "WordShr", kMipsShr, MachineType::Int16()}, |
| 88 {&RawMachineAssembler::WordSar, "WordSar", kMipsSar, kMachInt16}, | 90 {&RawMachineAssembler::WordSar, "WordSar", kMipsSar, MachineType::Int16()}, |
| 89 {&RawMachineAssembler::WordRor, "WordRor", kMipsRor, kMachInt16}, | 91 {&RawMachineAssembler::WordRor, "WordRor", kMipsRor, MachineType::Int16()}, |
| 90 {&RawMachineAssembler::Word32Shl, "Word32Shl", kMipsShl, kMachInt32}, | 92 {&RawMachineAssembler::Word32Shl, "Word32Shl", kMipsShl, |
| 91 {&RawMachineAssembler::Word32Shr, "Word32Shr", kMipsShr, kMachInt32}, | 93 MachineType::Int32()}, |
| 92 {&RawMachineAssembler::Word32Sar, "Word32Sar", kMipsSar, kMachInt32}, | 94 {&RawMachineAssembler::Word32Shr, "Word32Shr", kMipsShr, |
| 93 {&RawMachineAssembler::Word32Ror, "Word32Ror", kMipsRor, kMachInt32}}; | 95 MachineType::Int32()}, |
| 96 {&RawMachineAssembler::Word32Sar, "Word32Sar", kMipsSar, |
| 97 MachineType::Int32()}, |
| 98 {&RawMachineAssembler::Word32Ror, "Word32Ror", kMipsRor, |
| 99 MachineType::Int32()}}; |
| 94 | 100 |
| 95 | 101 |
| 96 // ---------------------------------------------------------------------------- | 102 // ---------------------------------------------------------------------------- |
| 97 // MUL/DIV instructions. | 103 // MUL/DIV instructions. |
| 98 // ---------------------------------------------------------------------------- | 104 // ---------------------------------------------------------------------------- |
| 99 | 105 |
| 100 | 106 |
| 101 const MachInst2 kMulDivInstructions[] = { | 107 const MachInst2 kMulDivInstructions[] = { |
| 102 {&RawMachineAssembler::Int32Mul, "Int32Mul", kMipsMul, kMachInt32}, | 108 {&RawMachineAssembler::Int32Mul, "Int32Mul", kMipsMul, |
| 103 {&RawMachineAssembler::Int32Div, "Int32Div", kMipsDiv, kMachInt32}, | 109 MachineType::Int32()}, |
| 104 {&RawMachineAssembler::Uint32Div, "Uint32Div", kMipsDivU, kMachUint32}, | 110 {&RawMachineAssembler::Int32Div, "Int32Div", kMipsDiv, |
| 105 {&RawMachineAssembler::Float64Mul, "Float64Mul", kMipsMulD, kMachFloat64}, | 111 MachineType::Int32()}, |
| 106 {&RawMachineAssembler::Float64Div, "Float64Div", kMipsDivD, kMachFloat64}}; | 112 {&RawMachineAssembler::Uint32Div, "Uint32Div", kMipsDivU, |
| 113 MachineType::Uint32()}, |
| 114 {&RawMachineAssembler::Float64Mul, "Float64Mul", kMipsMulD, |
| 115 MachineType::Float64()}, |
| 116 {&RawMachineAssembler::Float64Div, "Float64Div", kMipsDivD, |
| 117 MachineType::Float64()}}; |
| 107 | 118 |
| 108 | 119 |
| 109 // ---------------------------------------------------------------------------- | 120 // ---------------------------------------------------------------------------- |
| 110 // MOD instructions. | 121 // MOD instructions. |
| 111 // ---------------------------------------------------------------------------- | 122 // ---------------------------------------------------------------------------- |
| 112 | 123 |
| 113 | 124 |
| 114 const MachInst2 kModInstructions[] = { | 125 const MachInst2 kModInstructions[] = { |
| 115 {&RawMachineAssembler::Int32Mod, "Int32Mod", kMipsMod, kMachInt32}, | 126 {&RawMachineAssembler::Int32Mod, "Int32Mod", kMipsMod, |
| 116 {&RawMachineAssembler::Uint32Mod, "Int32UMod", kMipsModU, kMachInt32}, | 127 MachineType::Int32()}, |
| 117 {&RawMachineAssembler::Float64Mod, "Float64Mod", kMipsModD, kMachFloat64}}; | 128 {&RawMachineAssembler::Uint32Mod, "Int32UMod", kMipsModU, |
| 129 MachineType::Int32()}, |
| 130 {&RawMachineAssembler::Float64Mod, "Float64Mod", kMipsModD, |
| 131 MachineType::Float64()}}; |
| 118 | 132 |
| 119 | 133 |
| 120 // ---------------------------------------------------------------------------- | 134 // ---------------------------------------------------------------------------- |
| 121 // Arithmetic FPU instructions. | 135 // Arithmetic FPU instructions. |
| 122 // ---------------------------------------------------------------------------- | 136 // ---------------------------------------------------------------------------- |
| 123 | 137 |
| 124 | 138 |
| 125 const MachInst2 kFPArithInstructions[] = { | 139 const MachInst2 kFPArithInstructions[] = { |
| 126 {&RawMachineAssembler::Float64Add, "Float64Add", kMipsAddD, kMachFloat64}, | 140 {&RawMachineAssembler::Float64Add, "Float64Add", kMipsAddD, |
| 127 {&RawMachineAssembler::Float64Sub, "Float64Sub", kMipsSubD, kMachFloat64}}; | 141 MachineType::Float64()}, |
| 142 {&RawMachineAssembler::Float64Sub, "Float64Sub", kMipsSubD, |
| 143 MachineType::Float64()}}; |
| 128 | 144 |
| 129 | 145 |
| 130 // ---------------------------------------------------------------------------- | 146 // ---------------------------------------------------------------------------- |
| 131 // IntArithTest instructions, two nodes. | 147 // IntArithTest instructions, two nodes. |
| 132 // ---------------------------------------------------------------------------- | 148 // ---------------------------------------------------------------------------- |
| 133 | 149 |
| 134 | 150 |
| 135 const MachInst2 kAddSubInstructions[] = { | 151 const MachInst2 kAddSubInstructions[] = { |
| 136 {&RawMachineAssembler::Int32Add, "Int32Add", kMipsAdd, kMachInt32}, | 152 {&RawMachineAssembler::Int32Add, "Int32Add", kMipsAdd, |
| 137 {&RawMachineAssembler::Int32Sub, "Int32Sub", kMipsSub, kMachInt32}, | 153 MachineType::Int32()}, |
| 154 {&RawMachineAssembler::Int32Sub, "Int32Sub", kMipsSub, |
| 155 MachineType::Int32()}, |
| 138 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", | 156 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", |
| 139 kMipsAddOvf, kMachInt32}, | 157 kMipsAddOvf, MachineType::Int32()}, |
| 140 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", | 158 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", |
| 141 kMipsSubOvf, kMachInt32}}; | 159 kMipsSubOvf, MachineType::Int32()}}; |
| 142 | 160 |
| 143 | 161 |
| 144 // ---------------------------------------------------------------------------- | 162 // ---------------------------------------------------------------------------- |
| 145 // IntArithTest instructions, one node. | 163 // IntArithTest instructions, one node. |
| 146 // ---------------------------------------------------------------------------- | 164 // ---------------------------------------------------------------------------- |
| 147 | 165 |
| 148 | 166 |
| 149 const MachInst1 kAddSubOneInstructions[] = { | 167 const MachInst1 kAddSubOneInstructions[] = { |
| 150 {&RawMachineAssembler::Int32Neg, "Int32Neg", kMipsSub, kMachInt32}, | 168 {&RawMachineAssembler::Int32Neg, "Int32Neg", kMipsSub, |
| 169 MachineType::Int32()}, |
| 151 // TODO(dusmil): check this ... | 170 // TODO(dusmil): check this ... |
| 152 // {&RawMachineAssembler::WordEqual , "WordEqual" , kMipsTst, kMachInt32} | 171 // {&RawMachineAssembler::WordEqual , "WordEqual" , kMipsTst, |
| 172 // MachineType::Int32()} |
| 153 }; | 173 }; |
| 154 | 174 |
| 155 | 175 |
| 156 // ---------------------------------------------------------------------------- | 176 // ---------------------------------------------------------------------------- |
| 157 // Arithmetic compare instructions. | 177 // Arithmetic compare instructions. |
| 158 // ---------------------------------------------------------------------------- | 178 // ---------------------------------------------------------------------------- |
| 159 | 179 |
| 160 | 180 |
| 161 const IntCmp kCmpInstructions[] = { | 181 const IntCmp kCmpInstructions[] = { |
| 162 {{&RawMachineAssembler::WordEqual, "WordEqual", kMipsCmp, kMachInt16}, 1U}, | 182 {{&RawMachineAssembler::WordEqual, "WordEqual", kMipsCmp, |
| 163 {{&RawMachineAssembler::WordNotEqual, "WordNotEqual", kMipsCmp, kMachInt16}, | 183 MachineType::Int16()}, |
| 164 1U}, | 184 1U}, |
| 165 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kMipsCmp, kMachInt32}, | 185 {{&RawMachineAssembler::WordNotEqual, "WordNotEqual", kMipsCmp, |
| 186 MachineType::Int16()}, |
| 187 1U}, |
| 188 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kMipsCmp, |
| 189 MachineType::Int32()}, |
| 166 1U}, | 190 1U}, |
| 167 {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kMipsCmp, | 191 {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kMipsCmp, |
| 168 kMachInt32}, | 192 MachineType::Int32()}, |
| 169 1U}, | 193 1U}, |
| 170 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kMipsCmp, | 194 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kMipsCmp, |
| 171 kMachInt32}, | 195 MachineType::Int32()}, |
| 172 1U}, | 196 1U}, |
| 173 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", | 197 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", |
| 174 kMipsCmp, kMachInt32}, | 198 kMipsCmp, MachineType::Int32()}, |
| 175 1U}, | 199 1U}, |
| 176 {{&RawMachineAssembler::Int32GreaterThan, "Int32GreaterThan", kMipsCmp, | 200 {{&RawMachineAssembler::Int32GreaterThan, "Int32GreaterThan", kMipsCmp, |
| 177 kMachInt32}, | 201 MachineType::Int32()}, |
| 178 1U}, | 202 1U}, |
| 179 {{&RawMachineAssembler::Int32GreaterThanOrEqual, "Int32GreaterThanOrEqual", | 203 {{&RawMachineAssembler::Int32GreaterThanOrEqual, "Int32GreaterThanOrEqual", |
| 180 kMipsCmp, kMachInt32}, | 204 kMipsCmp, MachineType::Int32()}, |
| 181 1U}, | 205 1U}, |
| 182 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kMipsCmp, | 206 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kMipsCmp, |
| 183 kMachUint32}, | 207 MachineType::Uint32()}, |
| 184 1U}, | 208 1U}, |
| 185 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", | 209 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", |
| 186 kMipsCmp, kMachUint32}, | 210 kMipsCmp, MachineType::Uint32()}, |
| 187 1U}}; | 211 1U}}; |
| 188 | 212 |
| 189 | 213 |
| 190 // ---------------------------------------------------------------------------- | 214 // ---------------------------------------------------------------------------- |
| 191 // Conversion instructions. | 215 // Conversion instructions. |
| 192 // ---------------------------------------------------------------------------- | 216 // ---------------------------------------------------------------------------- |
| 193 | 217 |
| 194 const Conversion kConversionInstructions[] = { | 218 const Conversion kConversionInstructions[] = { |
| 195 // Conversion instructions are related to machine_operator.h: | 219 // Conversion instructions are related to machine_operator.h: |
| 196 // FPU conversions: | 220 // FPU conversions: |
| 197 // Convert representation of integers between float64 and int32/uint32. | 221 // Convert representation of integers between float64 and int32/uint32. |
| 198 // The precise rounding mode and handling of out of range inputs are *not* | 222 // The precise rounding mode and handling of out of range inputs are *not* |
| 199 // defined for these operators, since they are intended only for use with | 223 // defined for these operators, since they are intended only for use with |
| 200 // integers. | 224 // integers. |
| 201 // mips instruction: cvt_d_w | 225 // mips instruction: cvt_d_w |
| 202 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64", | 226 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64", |
| 203 kMipsCvtDW, kMachFloat64}, | 227 kMipsCvtDW, MachineType::Float64()}, |
| 204 kMachInt32}, | 228 MachineType::Int32()}, |
| 205 | 229 |
| 206 // mips instruction: cvt_d_uw | 230 // mips instruction: cvt_d_uw |
| 207 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64", | 231 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64", |
| 208 kMipsCvtDUw, kMachFloat64}, | 232 kMipsCvtDUw, MachineType::Float64()}, |
| 209 kMachInt32}, | 233 MachineType::Int32()}, |
| 210 | 234 |
| 211 // mips instruction: trunc_w_d | 235 // mips instruction: trunc_w_d |
| 212 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32", | 236 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32", |
| 213 kMipsTruncWD, kMachFloat64}, | 237 kMipsTruncWD, MachineType::Float64()}, |
| 214 kMachInt32}, | 238 MachineType::Int32()}, |
| 215 | 239 |
| 216 // mips instruction: trunc_uw_d | 240 // mips instruction: trunc_uw_d |
| 217 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32", | 241 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32", |
| 218 kMipsTruncUwD, kMachFloat64}, | 242 kMipsTruncUwD, MachineType::Float64()}, |
| 219 kMachInt32}}; | 243 MachineType::Int32()}}; |
| 220 | 244 |
| 221 const Conversion kFloat64RoundInstructions[] = { | 245 const Conversion kFloat64RoundInstructions[] = { |
| 222 {{&RawMachineAssembler::Float64RoundUp, "Float64RoundUp", kMipsCeilWD, | 246 {{&RawMachineAssembler::Float64RoundUp, "Float64RoundUp", kMipsCeilWD, |
| 223 kMachFloat64}, | 247 MachineType::Float64()}, |
| 224 kMachInt32}, | 248 MachineType::Int32()}, |
| 225 {{&RawMachineAssembler::Float64RoundDown, "Float64RoundDown", kMipsFloorWD, | 249 {{&RawMachineAssembler::Float64RoundDown, "Float64RoundDown", kMipsFloorWD, |
| 226 kMachFloat64}, | 250 MachineType::Float64()}, |
| 227 kMachInt32}, | 251 MachineType::Int32()}, |
| 228 {{&RawMachineAssembler::Float64RoundTiesEven, "Float64RoundTiesEven", | 252 {{&RawMachineAssembler::Float64RoundTiesEven, "Float64RoundTiesEven", |
| 229 kMipsRoundWD, kMachFloat64}, | 253 kMipsRoundWD, MachineType::Float64()}, |
| 230 kMachInt32}, | 254 MachineType::Int32()}, |
| 231 {{&RawMachineAssembler::Float64RoundTruncate, "Float64RoundTruncate", | 255 {{&RawMachineAssembler::Float64RoundTruncate, "Float64RoundTruncate", |
| 232 kMipsTruncWD, kMachFloat64}, | 256 kMipsTruncWD, MachineType::Float64()}, |
| 233 kMachInt32}}; | 257 MachineType::Int32()}}; |
| 234 | 258 |
| 235 } // namespace | 259 } // namespace |
| 236 | 260 |
| 237 | 261 |
| 238 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest; | 262 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest; |
| 239 | 263 |
| 240 | 264 |
| 241 TEST_P(InstructionSelectorFPCmpTest, Parameter) { | 265 TEST_P(InstructionSelectorFPCmpTest, Parameter) { |
| 242 const FPCmp cmp = GetParam(); | 266 const FPCmp cmp = GetParam(); |
| 243 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type); | 267 StreamBuilder m(this, MachineType::Int32(), cmp.mi.machine_type, |
| 268 cmp.mi.machine_type); |
| 244 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); | 269 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 245 Stream s = m.Build(); | 270 Stream s = m.Build(); |
| 246 ASSERT_EQ(1U, s.size()); | 271 ASSERT_EQ(1U, s.size()); |
| 247 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); | 272 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); |
| 248 EXPECT_EQ(2U, s[0]->InputCount()); | 273 EXPECT_EQ(2U, s[0]->InputCount()); |
| 249 EXPECT_EQ(1U, s[0]->OutputCount()); | 274 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 250 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 275 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 251 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); | 276 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 252 } | 277 } |
| 253 | 278 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 // ---------------------------------------------------------------------------- | 310 // ---------------------------------------------------------------------------- |
| 286 | 311 |
| 287 | 312 |
| 288 typedef InstructionSelectorTestWithParam<MachInst2> | 313 typedef InstructionSelectorTestWithParam<MachInst2> |
| 289 InstructionSelectorShiftTest; | 314 InstructionSelectorShiftTest; |
| 290 | 315 |
| 291 | 316 |
| 292 TEST_P(InstructionSelectorShiftTest, Immediate) { | 317 TEST_P(InstructionSelectorShiftTest, Immediate) { |
| 293 const MachInst2 dpi = GetParam(); | 318 const MachInst2 dpi = GetParam(); |
| 294 const MachineType type = dpi.machine_type; | 319 const MachineType type = dpi.machine_type; |
| 295 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) { | 320 TRACED_FORRANGE(int32_t, imm, 0, |
| 321 ((1 << ElementSizeLog2Of(type.representation())) * 8) - 1) { |
| 296 StreamBuilder m(this, type, type); | 322 StreamBuilder m(this, type, type); |
| 297 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); | 323 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); |
| 298 Stream s = m.Build(); | 324 Stream s = m.Build(); |
| 299 ASSERT_EQ(1U, s.size()); | 325 ASSERT_EQ(1U, s.size()); |
| 300 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 326 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 301 EXPECT_EQ(2U, s[0]->InputCount()); | 327 EXPECT_EQ(2U, s[0]->InputCount()); |
| 302 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 328 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 303 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 329 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 304 EXPECT_EQ(1U, s[0]->OutputCount()); | 330 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 305 } | 331 } |
| 306 } | 332 } |
| 307 | 333 |
| 308 | 334 |
| 309 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, | 335 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, |
| 310 ::testing::ValuesIn(kShiftInstructions)); | 336 ::testing::ValuesIn(kShiftInstructions)); |
| 311 | 337 |
| 312 | 338 |
| 313 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) { | 339 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) { |
| 314 // The available shift operand range is `0 <= imm < 32`, but we also test | 340 // The available shift operand range is `0 <= imm < 32`, but we also test |
| 315 // that immediates outside this range are handled properly (modulo-32). | 341 // that immediates outside this range are handled properly (modulo-32). |
| 316 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 342 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 317 int32_t lsb = shift & 0x1f; | 343 int32_t lsb = shift & 0x1f; |
| 318 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { | 344 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
| 319 uint32_t jnk = rng()->NextInt(); | 345 uint32_t jnk = rng()->NextInt(); |
| 320 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; | 346 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; |
| 321 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; | 347 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; |
| 322 StreamBuilder m(this, kMachInt32, kMachInt32); | 348 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 323 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)), | 349 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)), |
| 324 m.Int32Constant(shift))); | 350 m.Int32Constant(shift))); |
| 325 Stream s = m.Build(); | 351 Stream s = m.Build(); |
| 326 ASSERT_EQ(1U, s.size()); | 352 ASSERT_EQ(1U, s.size()); |
| 327 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); | 353 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); |
| 328 ASSERT_EQ(3U, s[0]->InputCount()); | 354 ASSERT_EQ(3U, s[0]->InputCount()); |
| 329 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 355 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 330 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); | 356 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 331 } | 357 } |
| 332 } | 358 } |
| 333 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 359 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 334 int32_t lsb = shift & 0x1f; | 360 int32_t lsb = shift & 0x1f; |
| 335 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { | 361 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
| 336 uint32_t jnk = rng()->NextInt(); | 362 uint32_t jnk = rng()->NextInt(); |
| 337 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; | 363 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; |
| 338 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; | 364 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; |
| 339 StreamBuilder m(this, kMachInt32, kMachInt32); | 365 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 340 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)), | 366 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)), |
| 341 m.Int32Constant(shift))); | 367 m.Int32Constant(shift))); |
| 342 Stream s = m.Build(); | 368 Stream s = m.Build(); |
| 343 ASSERT_EQ(1U, s.size()); | 369 ASSERT_EQ(1U, s.size()); |
| 344 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); | 370 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); |
| 345 ASSERT_EQ(3U, s[0]->InputCount()); | 371 ASSERT_EQ(3U, s[0]->InputCount()); |
| 346 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 372 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 347 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); | 373 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 348 } | 374 } |
| 349 } | 375 } |
| 350 } | 376 } |
| 351 | 377 |
| 352 | 378 |
| 353 TEST_F(InstructionSelectorTest, Word32ShlWithWord32And) { | 379 TEST_F(InstructionSelectorTest, Word32ShlWithWord32And) { |
| 354 TRACED_FORRANGE(int32_t, shift, 0, 30) { | 380 TRACED_FORRANGE(int32_t, shift, 0, 30) { |
| 355 StreamBuilder m(this, kMachInt32, kMachInt32); | 381 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 356 Node* const p0 = m.Parameter(0); | 382 Node* const p0 = m.Parameter(0); |
| 357 Node* const r = | 383 Node* const r = |
| 358 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)), | 384 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)), |
| 359 m.Int32Constant(shift + 1)); | 385 m.Int32Constant(shift + 1)); |
| 360 m.Return(r); | 386 m.Return(r); |
| 361 Stream s = m.Build(); | 387 Stream s = m.Build(); |
| 362 ASSERT_EQ(1U, s.size()); | 388 ASSERT_EQ(1U, s.size()); |
| 363 EXPECT_EQ(kMipsShl, s[0]->arch_opcode()); | 389 EXPECT_EQ(kMipsShl, s[0]->arch_opcode()); |
| 364 ASSERT_EQ(2U, s[0]->InputCount()); | 390 ASSERT_EQ(2U, s[0]->InputCount()); |
| 365 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 391 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 390 EXPECT_EQ(1U, s[0]->OutputCount()); | 416 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 391 } | 417 } |
| 392 | 418 |
| 393 | 419 |
| 394 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, | 420 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, |
| 395 ::testing::ValuesIn(kLogicalInstructions)); | 421 ::testing::ValuesIn(kLogicalInstructions)); |
| 396 | 422 |
| 397 | 423 |
| 398 TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) { | 424 TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) { |
| 399 { | 425 { |
| 400 StreamBuilder m(this, kMachInt32, kMachInt32); | 426 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 401 m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1))); | 427 m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1))); |
| 402 Stream s = m.Build(); | 428 Stream s = m.Build(); |
| 403 ASSERT_EQ(1U, s.size()); | 429 ASSERT_EQ(1U, s.size()); |
| 404 EXPECT_EQ(kMipsNor, s[0]->arch_opcode()); | 430 EXPECT_EQ(kMipsNor, s[0]->arch_opcode()); |
| 405 EXPECT_EQ(2U, s[0]->InputCount()); | 431 EXPECT_EQ(2U, s[0]->InputCount()); |
| 406 EXPECT_EQ(1U, s[0]->OutputCount()); | 432 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 407 } | 433 } |
| 408 { | 434 { |
| 409 StreamBuilder m(this, kMachInt32, kMachInt32); | 435 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 410 m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0))); | 436 m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0))); |
| 411 Stream s = m.Build(); | 437 Stream s = m.Build(); |
| 412 ASSERT_EQ(1U, s.size()); | 438 ASSERT_EQ(1U, s.size()); |
| 413 EXPECT_EQ(kMipsNor, s[0]->arch_opcode()); | 439 EXPECT_EQ(kMipsNor, s[0]->arch_opcode()); |
| 414 EXPECT_EQ(2U, s[0]->InputCount()); | 440 EXPECT_EQ(2U, s[0]->InputCount()); |
| 415 EXPECT_EQ(1U, s[0]->OutputCount()); | 441 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 416 } | 442 } |
| 417 } | 443 } |
| 418 | 444 |
| 419 | 445 |
| 420 TEST_F(InstructionSelectorTest, Word32XorMinusOneWithWord32Or) { | 446 TEST_F(InstructionSelectorTest, Word32XorMinusOneWithWord32Or) { |
| 421 { | 447 { |
| 422 StreamBuilder m(this, kMachInt32, kMachInt32); | 448 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 423 m.Return(m.Word32Xor(m.Word32Or(m.Parameter(0), m.Parameter(0)), | 449 m.Return(m.Word32Xor(m.Word32Or(m.Parameter(0), m.Parameter(0)), |
| 424 m.Int32Constant(-1))); | 450 m.Int32Constant(-1))); |
| 425 Stream s = m.Build(); | 451 Stream s = m.Build(); |
| 426 ASSERT_EQ(1U, s.size()); | 452 ASSERT_EQ(1U, s.size()); |
| 427 EXPECT_EQ(kMipsNor, s[0]->arch_opcode()); | 453 EXPECT_EQ(kMipsNor, s[0]->arch_opcode()); |
| 428 EXPECT_EQ(2U, s[0]->InputCount()); | 454 EXPECT_EQ(2U, s[0]->InputCount()); |
| 429 EXPECT_EQ(1U, s[0]->OutputCount()); | 455 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 430 } | 456 } |
| 431 { | 457 { |
| 432 StreamBuilder m(this, kMachInt32, kMachInt32); | 458 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 433 m.Return(m.Word32Xor(m.Int32Constant(-1), | 459 m.Return(m.Word32Xor(m.Int32Constant(-1), |
| 434 m.Word32Or(m.Parameter(0), m.Parameter(0)))); | 460 m.Word32Or(m.Parameter(0), m.Parameter(0)))); |
| 435 Stream s = m.Build(); | 461 Stream s = m.Build(); |
| 436 ASSERT_EQ(1U, s.size()); | 462 ASSERT_EQ(1U, s.size()); |
| 437 EXPECT_EQ(kMipsNor, s[0]->arch_opcode()); | 463 EXPECT_EQ(kMipsNor, s[0]->arch_opcode()); |
| 438 EXPECT_EQ(2U, s[0]->InputCount()); | 464 EXPECT_EQ(2U, s[0]->InputCount()); |
| 439 EXPECT_EQ(1U, s[0]->OutputCount()); | 465 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 440 } | 466 } |
| 441 } | 467 } |
| 442 | 468 |
| 443 | 469 |
| 444 TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) { | 470 TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) { |
| 445 // The available shift operand range is `0 <= imm < 32`, but we also test | 471 // The available shift operand range is `0 <= imm < 32`, but we also test |
| 446 // that immediates outside this range are handled properly (modulo-32). | 472 // that immediates outside this range are handled properly (modulo-32). |
| 447 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 473 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 448 int32_t lsb = shift & 0x1f; | 474 int32_t lsb = shift & 0x1f; |
| 449 TRACED_FORRANGE(int32_t, width, 1, 31) { | 475 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 450 uint32_t msk = (1 << width) - 1; | 476 uint32_t msk = (1 << width) - 1; |
| 451 StreamBuilder m(this, kMachInt32, kMachInt32); | 477 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 452 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), | 478 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), |
| 453 m.Int32Constant(msk))); | 479 m.Int32Constant(msk))); |
| 454 Stream s = m.Build(); | 480 Stream s = m.Build(); |
| 455 ASSERT_EQ(1U, s.size()); | 481 ASSERT_EQ(1U, s.size()); |
| 456 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); | 482 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); |
| 457 ASSERT_EQ(3U, s[0]->InputCount()); | 483 ASSERT_EQ(3U, s[0]->InputCount()); |
| 458 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 484 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 459 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; | 485 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; |
| 460 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); | 486 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); |
| 461 } | 487 } |
| 462 } | 488 } |
| 463 TRACED_FORRANGE(int32_t, shift, -32, 63) { | 489 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 464 int32_t lsb = shift & 0x1f; | 490 int32_t lsb = shift & 0x1f; |
| 465 TRACED_FORRANGE(int32_t, width, 1, 31) { | 491 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 466 uint32_t msk = (1 << width) - 1; | 492 uint32_t msk = (1 << width) - 1; |
| 467 StreamBuilder m(this, kMachInt32, kMachInt32); | 493 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 468 m.Return( | 494 m.Return( |
| 469 m.Word32And(m.Int32Constant(msk), | 495 m.Word32And(m.Int32Constant(msk), |
| 470 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)))); | 496 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)))); |
| 471 Stream s = m.Build(); | 497 Stream s = m.Build(); |
| 472 ASSERT_EQ(1U, s.size()); | 498 ASSERT_EQ(1U, s.size()); |
| 473 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); | 499 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); |
| 474 ASSERT_EQ(3U, s[0]->InputCount()); | 500 ASSERT_EQ(3U, s[0]->InputCount()); |
| 475 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 501 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 476 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; | 502 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; |
| 477 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); | 503 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); |
| 478 } | 504 } |
| 479 } | 505 } |
| 480 } | 506 } |
| 481 | 507 |
| 482 | 508 |
| 483 TEST_F(InstructionSelectorTest, Word32AndToClearBits) { | 509 TEST_F(InstructionSelectorTest, Word32AndToClearBits) { |
| 484 TRACED_FORRANGE(int32_t, shift, 1, 31) { | 510 TRACED_FORRANGE(int32_t, shift, 1, 31) { |
| 485 int32_t mask = ~((1 << shift) - 1); | 511 int32_t mask = ~((1 << shift) - 1); |
| 486 StreamBuilder m(this, kMachInt32, kMachInt32); | 512 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 487 m.Return(m.Word32And(m.Parameter(0), m.Int32Constant(mask))); | 513 m.Return(m.Word32And(m.Parameter(0), m.Int32Constant(mask))); |
| 488 Stream s = m.Build(); | 514 Stream s = m.Build(); |
| 489 ASSERT_EQ(1U, s.size()); | 515 ASSERT_EQ(1U, s.size()); |
| 490 EXPECT_EQ(kMipsIns, s[0]->arch_opcode()); | 516 EXPECT_EQ(kMipsIns, s[0]->arch_opcode()); |
| 491 ASSERT_EQ(3U, s[0]->InputCount()); | 517 ASSERT_EQ(3U, s[0]->InputCount()); |
| 492 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); | 518 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); |
| 493 EXPECT_EQ(shift, s.ToInt32(s[0]->InputAt(2))); | 519 EXPECT_EQ(shift, s.ToInt32(s[0]->InputAt(2))); |
| 494 } | 520 } |
| 495 TRACED_FORRANGE(int32_t, shift, 1, 31) { | 521 TRACED_FORRANGE(int32_t, shift, 1, 31) { |
| 496 int32_t mask = ~((1 << shift) - 1); | 522 int32_t mask = ~((1 << shift) - 1); |
| 497 StreamBuilder m(this, kMachInt32, kMachInt32); | 523 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 498 m.Return(m.Word32And(m.Int32Constant(mask), m.Parameter(0))); | 524 m.Return(m.Word32And(m.Int32Constant(mask), m.Parameter(0))); |
| 499 Stream s = m.Build(); | 525 Stream s = m.Build(); |
| 500 ASSERT_EQ(1U, s.size()); | 526 ASSERT_EQ(1U, s.size()); |
| 501 EXPECT_EQ(kMipsIns, s[0]->arch_opcode()); | 527 EXPECT_EQ(kMipsIns, s[0]->arch_opcode()); |
| 502 ASSERT_EQ(3U, s[0]->InputCount()); | 528 ASSERT_EQ(3U, s[0]->InputCount()); |
| 503 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); | 529 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); |
| 504 EXPECT_EQ(shift, s.ToInt32(s[0]->InputAt(2))); | 530 EXPECT_EQ(shift, s.ToInt32(s[0]->InputAt(2))); |
| 505 } | 531 } |
| 506 } | 532 } |
| 507 | 533 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 namespace { | 717 namespace { |
| 692 | 718 |
| 693 struct MemoryAccess { | 719 struct MemoryAccess { |
| 694 MachineType type; | 720 MachineType type; |
| 695 ArchOpcode load_opcode; | 721 ArchOpcode load_opcode; |
| 696 ArchOpcode store_opcode; | 722 ArchOpcode store_opcode; |
| 697 }; | 723 }; |
| 698 | 724 |
| 699 | 725 |
| 700 static const MemoryAccess kMemoryAccesses[] = { | 726 static const MemoryAccess kMemoryAccesses[] = { |
| 701 {kMachInt8, kMipsLb, kMipsSb}, | 727 {MachineType::Int8(), kMipsLb, kMipsSb}, |
| 702 {kMachUint8, kMipsLbu, kMipsSb}, | 728 {MachineType::Uint8(), kMipsLbu, kMipsSb}, |
| 703 {kMachInt16, kMipsLh, kMipsSh}, | 729 {MachineType::Int16(), kMipsLh, kMipsSh}, |
| 704 {kMachUint16, kMipsLhu, kMipsSh}, | 730 {MachineType::Uint16(), kMipsLhu, kMipsSh}, |
| 705 {kMachInt32, kMipsLw, kMipsSw}, | 731 {MachineType::Int32(), kMipsLw, kMipsSw}, |
| 706 {kMachFloat32, kMipsLwc1, kMipsSwc1}, | 732 {MachineType::Float32(), kMipsLwc1, kMipsSwc1}, |
| 707 {kMachFloat64, kMipsLdc1, kMipsSdc1}}; | 733 {MachineType::Float64(), kMipsLdc1, kMipsSdc1}}; |
| 708 | 734 |
| 709 | 735 |
| 710 struct MemoryAccessImm { | 736 struct MemoryAccessImm { |
| 711 MachineType type; | 737 MachineType type; |
| 712 ArchOpcode load_opcode; | 738 ArchOpcode load_opcode; |
| 713 ArchOpcode store_opcode; | 739 ArchOpcode store_opcode; |
| 714 bool (InstructionSelectorTest::Stream::*val_predicate)( | 740 bool (InstructionSelectorTest::Stream::*val_predicate)( |
| 715 const InstructionOperand*) const; | 741 const InstructionOperand*) const; |
| 716 const int32_t immediates[40]; | 742 const int32_t immediates[40]; |
| 717 }; | 743 }; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 736 return os << acc.type; | 762 return os << acc.type; |
| 737 } | 763 } |
| 738 | 764 |
| 739 | 765 |
| 740 // ---------------------------------------------------------------------------- | 766 // ---------------------------------------------------------------------------- |
| 741 // Loads and stores immediate values. | 767 // Loads and stores immediate values. |
| 742 // ---------------------------------------------------------------------------- | 768 // ---------------------------------------------------------------------------- |
| 743 | 769 |
| 744 | 770 |
| 745 const MemoryAccessImm kMemoryAccessesImm[] = { | 771 const MemoryAccessImm kMemoryAccessesImm[] = { |
| 746 {kMachInt8, | 772 {MachineType::Int8(), |
| 747 kMipsLb, | 773 kMipsLb, |
| 748 kMipsSb, | 774 kMipsSb, |
| 749 &InstructionSelectorTest::Stream::IsInteger, | 775 &InstructionSelectorTest::Stream::IsInteger, |
| 750 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 776 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 751 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 777 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 752 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 778 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 753 {kMachUint8, | 779 {MachineType::Uint8(), |
| 754 kMipsLbu, | 780 kMipsLbu, |
| 755 kMipsSb, | 781 kMipsSb, |
| 756 &InstructionSelectorTest::Stream::IsInteger, | 782 &InstructionSelectorTest::Stream::IsInteger, |
| 757 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 783 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 758 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 784 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 759 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 785 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 760 {kMachInt16, | 786 {MachineType::Int16(), |
| 761 kMipsLh, | 787 kMipsLh, |
| 762 kMipsSh, | 788 kMipsSh, |
| 763 &InstructionSelectorTest::Stream::IsInteger, | 789 &InstructionSelectorTest::Stream::IsInteger, |
| 764 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 790 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 765 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 791 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 766 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 792 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 767 {kMachUint16, | 793 {MachineType::Uint16(), |
| 768 kMipsLhu, | 794 kMipsLhu, |
| 769 kMipsSh, | 795 kMipsSh, |
| 770 &InstructionSelectorTest::Stream::IsInteger, | 796 &InstructionSelectorTest::Stream::IsInteger, |
| 771 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 797 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 772 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 798 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 773 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 799 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 774 {kMachInt32, | 800 {MachineType::Int32(), |
| 775 kMipsLw, | 801 kMipsLw, |
| 776 kMipsSw, | 802 kMipsSw, |
| 777 &InstructionSelectorTest::Stream::IsInteger, | 803 &InstructionSelectorTest::Stream::IsInteger, |
| 778 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 804 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 779 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 805 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 780 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 806 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 781 {kMachFloat32, | 807 {MachineType::Float32(), |
| 782 kMipsLwc1, | 808 kMipsLwc1, |
| 783 kMipsSwc1, | 809 kMipsSwc1, |
| 784 &InstructionSelectorTest::Stream::IsDouble, | 810 &InstructionSelectorTest::Stream::IsDouble, |
| 785 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 811 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 786 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 812 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 787 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 813 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 788 {kMachFloat64, | 814 {MachineType::Float64(), |
| 789 kMipsLdc1, | 815 kMipsLdc1, |
| 790 kMipsSdc1, | 816 kMipsSdc1, |
| 791 &InstructionSelectorTest::Stream::IsDouble, | 817 &InstructionSelectorTest::Stream::IsDouble, |
| 792 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 818 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 793 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 819 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 794 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}}; | 820 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}}; |
| 795 | 821 |
| 796 | 822 |
| 797 const MemoryAccessImm1 kMemoryAccessImmMoreThan16bit[] = { | 823 const MemoryAccessImm1 kMemoryAccessImmMoreThan16bit[] = { |
| 798 {kMachInt8, | 824 {MachineType::Int8(), |
| 799 kMipsLb, | 825 kMipsLb, |
| 800 kMipsSb, | 826 kMipsSb, |
| 801 &InstructionSelectorTest::Stream::IsInteger, | 827 &InstructionSelectorTest::Stream::IsInteger, |
| 802 {-65000, -55000, 32777, 55000, 65000}}, | 828 {-65000, -55000, 32777, 55000, 65000}}, |
| 803 {kMachInt8, | 829 {MachineType::Int8(), |
| 804 kMipsLbu, | 830 kMipsLbu, |
| 805 kMipsSb, | 831 kMipsSb, |
| 806 &InstructionSelectorTest::Stream::IsInteger, | 832 &InstructionSelectorTest::Stream::IsInteger, |
| 807 {-65000, -55000, 32777, 55000, 65000}}, | 833 {-65000, -55000, 32777, 55000, 65000}}, |
| 808 {kMachInt16, | 834 {MachineType::Int16(), |
| 809 kMipsLh, | 835 kMipsLh, |
| 810 kMipsSh, | 836 kMipsSh, |
| 811 &InstructionSelectorTest::Stream::IsInteger, | 837 &InstructionSelectorTest::Stream::IsInteger, |
| 812 {-65000, -55000, 32777, 55000, 65000}}, | 838 {-65000, -55000, 32777, 55000, 65000}}, |
| 813 {kMachInt16, | 839 {MachineType::Int16(), |
| 814 kMipsLhu, | 840 kMipsLhu, |
| 815 kMipsSh, | 841 kMipsSh, |
| 816 &InstructionSelectorTest::Stream::IsInteger, | 842 &InstructionSelectorTest::Stream::IsInteger, |
| 817 {-65000, -55000, 32777, 55000, 65000}}, | 843 {-65000, -55000, 32777, 55000, 65000}}, |
| 818 {kMachInt32, | 844 {MachineType::Int32(), |
| 819 kMipsLw, | 845 kMipsLw, |
| 820 kMipsSw, | 846 kMipsSw, |
| 821 &InstructionSelectorTest::Stream::IsInteger, | 847 &InstructionSelectorTest::Stream::IsInteger, |
| 822 {-65000, -55000, 32777, 55000, 65000}}, | 848 {-65000, -55000, 32777, 55000, 65000}}, |
| 823 {kMachFloat32, | 849 {MachineType::Float32(), |
| 824 kMipsLwc1, | 850 kMipsLwc1, |
| 825 kMipsSwc1, | 851 kMipsSwc1, |
| 826 &InstructionSelectorTest::Stream::IsDouble, | 852 &InstructionSelectorTest::Stream::IsDouble, |
| 827 {-65000, -55000, 32777, 55000, 65000}}, | 853 {-65000, -55000, 32777, 55000, 65000}}, |
| 828 {kMachFloat64, | 854 {MachineType::Float64(), |
| 829 kMipsLdc1, | 855 kMipsLdc1, |
| 830 kMipsSdc1, | 856 kMipsSdc1, |
| 831 &InstructionSelectorTest::Stream::IsDouble, | 857 &InstructionSelectorTest::Stream::IsDouble, |
| 832 {-65000, -55000, 32777, 55000, 65000}}}; | 858 {-65000, -55000, 32777, 55000, 65000}}}; |
| 833 | 859 |
| 834 } // namespace | 860 } // namespace |
| 835 | 861 |
| 836 | 862 |
| 837 typedef InstructionSelectorTestWithParam<MemoryAccess> | 863 typedef InstructionSelectorTestWithParam<MemoryAccess> |
| 838 InstructionSelectorMemoryAccessTest; | 864 InstructionSelectorMemoryAccessTest; |
| 839 | 865 |
| 840 | 866 |
| 841 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { | 867 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { |
| 842 const MemoryAccess memacc = GetParam(); | 868 const MemoryAccess memacc = GetParam(); |
| 843 StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32); | 869 StreamBuilder m(this, memacc.type, MachineType::Pointer(), |
| 870 MachineType::Int32()); |
| 844 m.Return(m.Load(memacc.type, m.Parameter(0))); | 871 m.Return(m.Load(memacc.type, m.Parameter(0))); |
| 845 Stream s = m.Build(); | 872 Stream s = m.Build(); |
| 846 ASSERT_EQ(1U, s.size()); | 873 ASSERT_EQ(1U, s.size()); |
| 847 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); | 874 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); |
| 848 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 875 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 849 } | 876 } |
| 850 | 877 |
| 851 | 878 |
| 852 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { | 879 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { |
| 853 const MemoryAccess memacc = GetParam(); | 880 const MemoryAccess memacc = GetParam(); |
| 854 StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); | 881 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 882 MachineType::Int32(), memacc.type); |
| 855 m.Store(memacc.type, m.Parameter(0), m.Parameter(1), kNoWriteBarrier); | 883 m.Store(memacc.type, m.Parameter(0), m.Parameter(1), kNoWriteBarrier); |
| 856 m.Return(m.Int32Constant(0)); | 884 m.Return(m.Int32Constant(0)); |
| 857 Stream s = m.Build(); | 885 Stream s = m.Build(); |
| 858 ASSERT_EQ(1U, s.size()); | 886 ASSERT_EQ(1U, s.size()); |
| 859 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); | 887 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); |
| 860 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 888 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 861 } | 889 } |
| 862 | 890 |
| 863 | 891 |
| 864 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 892 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 865 InstructionSelectorMemoryAccessTest, | 893 InstructionSelectorMemoryAccessTest, |
| 866 ::testing::ValuesIn(kMemoryAccesses)); | 894 ::testing::ValuesIn(kMemoryAccesses)); |
| 867 | 895 |
| 868 | 896 |
| 869 // ---------------------------------------------------------------------------- | 897 // ---------------------------------------------------------------------------- |
| 870 // Load immediate. | 898 // Load immediate. |
| 871 // ---------------------------------------------------------------------------- | 899 // ---------------------------------------------------------------------------- |
| 872 | 900 |
| 873 | 901 |
| 874 typedef InstructionSelectorTestWithParam<MemoryAccessImm> | 902 typedef InstructionSelectorTestWithParam<MemoryAccessImm> |
| 875 InstructionSelectorMemoryAccessImmTest; | 903 InstructionSelectorMemoryAccessImmTest; |
| 876 | 904 |
| 877 | 905 |
| 878 TEST_P(InstructionSelectorMemoryAccessImmTest, LoadWithImmediateIndex) { | 906 TEST_P(InstructionSelectorMemoryAccessImmTest, LoadWithImmediateIndex) { |
| 879 const MemoryAccessImm memacc = GetParam(); | 907 const MemoryAccessImm memacc = GetParam(); |
| 880 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 908 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
| 881 StreamBuilder m(this, memacc.type, kMachPtr); | 909 StreamBuilder m(this, memacc.type, MachineType::Pointer()); |
| 882 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); | 910 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); |
| 883 Stream s = m.Build(); | 911 Stream s = m.Build(); |
| 884 ASSERT_EQ(1U, s.size()); | 912 ASSERT_EQ(1U, s.size()); |
| 885 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); | 913 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); |
| 886 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 914 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 887 ASSERT_EQ(2U, s[0]->InputCount()); | 915 ASSERT_EQ(2U, s[0]->InputCount()); |
| 888 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 916 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 889 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); | 917 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); |
| 890 ASSERT_EQ(1U, s[0]->OutputCount()); | 918 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 891 EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output())); | 919 EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output())); |
| 892 } | 920 } |
| 893 } | 921 } |
| 894 | 922 |
| 895 | 923 |
| 896 // ---------------------------------------------------------------------------- | 924 // ---------------------------------------------------------------------------- |
| 897 // Store immediate. | 925 // Store immediate. |
| 898 // ---------------------------------------------------------------------------- | 926 // ---------------------------------------------------------------------------- |
| 899 | 927 |
| 900 | 928 |
| 901 TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) { | 929 TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) { |
| 902 const MemoryAccessImm memacc = GetParam(); | 930 const MemoryAccessImm memacc = GetParam(); |
| 903 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 931 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
| 904 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); | 932 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 933 memacc.type); |
| 905 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), | 934 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), |
| 906 kNoWriteBarrier); | 935 kNoWriteBarrier); |
| 907 m.Return(m.Int32Constant(0)); | 936 m.Return(m.Int32Constant(0)); |
| 908 Stream s = m.Build(); | 937 Stream s = m.Build(); |
| 909 ASSERT_EQ(1U, s.size()); | 938 ASSERT_EQ(1U, s.size()); |
| 910 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); | 939 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); |
| 911 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 940 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 912 ASSERT_EQ(3U, s[0]->InputCount()); | 941 ASSERT_EQ(3U, s[0]->InputCount()); |
| 913 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 942 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 914 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); | 943 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 928 | 957 |
| 929 | 958 |
| 930 typedef InstructionSelectorTestWithParam<MemoryAccessImm1> | 959 typedef InstructionSelectorTestWithParam<MemoryAccessImm1> |
| 931 InstructionSelectorMemoryAccessImmMoreThan16bitTest; | 960 InstructionSelectorMemoryAccessImmMoreThan16bitTest; |
| 932 | 961 |
| 933 | 962 |
| 934 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, | 963 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, |
| 935 LoadWithImmediateIndex) { | 964 LoadWithImmediateIndex) { |
| 936 const MemoryAccessImm1 memacc = GetParam(); | 965 const MemoryAccessImm1 memacc = GetParam(); |
| 937 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 966 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
| 938 StreamBuilder m(this, memacc.type, kMachPtr); | 967 StreamBuilder m(this, memacc.type, MachineType::Pointer()); |
| 939 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); | 968 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); |
| 940 Stream s = m.Build(); | 969 Stream s = m.Build(); |
| 941 ASSERT_EQ(2U, s.size()); | 970 ASSERT_EQ(2U, s.size()); |
| 942 // kMipsAdd is expected opcode. | 971 // kMipsAdd is expected opcode. |
| 943 // size more than 16 bits wide. | 972 // size more than 16 bits wide. |
| 944 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode()); | 973 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode()); |
| 945 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); | 974 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 946 EXPECT_EQ(2U, s[0]->InputCount()); | 975 EXPECT_EQ(2U, s[0]->InputCount()); |
| 947 EXPECT_EQ(1U, s[0]->OutputCount()); | 976 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 948 } | 977 } |
| 949 } | 978 } |
| 950 | 979 |
| 951 | 980 |
| 952 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, | 981 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, |
| 953 StoreWithImmediateIndex) { | 982 StoreWithImmediateIndex) { |
| 954 const MemoryAccessImm1 memacc = GetParam(); | 983 const MemoryAccessImm1 memacc = GetParam(); |
| 955 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 984 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
| 956 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); | 985 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 986 memacc.type); |
| 957 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), | 987 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), |
| 958 kNoWriteBarrier); | 988 kNoWriteBarrier); |
| 959 m.Return(m.Int32Constant(0)); | 989 m.Return(m.Int32Constant(0)); |
| 960 Stream s = m.Build(); | 990 Stream s = m.Build(); |
| 961 ASSERT_EQ(2U, s.size()); | 991 ASSERT_EQ(2U, s.size()); |
| 962 // kMipsAdd is expected opcode | 992 // kMipsAdd is expected opcode |
| 963 // size more than 16 bits wide | 993 // size more than 16 bits wide |
| 964 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode()); | 994 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode()); |
| 965 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); | 995 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 966 EXPECT_EQ(2U, s[0]->InputCount()); | 996 EXPECT_EQ(2U, s[0]->InputCount()); |
| 967 EXPECT_EQ(1U, s[0]->OutputCount()); | 997 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 968 } | 998 } |
| 969 } | 999 } |
| 970 | 1000 |
| 971 | 1001 |
| 972 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 1002 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 973 InstructionSelectorMemoryAccessImmMoreThan16bitTest, | 1003 InstructionSelectorMemoryAccessImmMoreThan16bitTest, |
| 974 ::testing::ValuesIn(kMemoryAccessImmMoreThan16bit)); | 1004 ::testing::ValuesIn(kMemoryAccessImmMoreThan16bit)); |
| 975 | 1005 |
| 976 | 1006 |
| 977 // ---------------------------------------------------------------------------- | 1007 // ---------------------------------------------------------------------------- |
| 978 // kMipsTst testing. | 1008 // kMipsTst testing. |
| 979 // ---------------------------------------------------------------------------- | 1009 // ---------------------------------------------------------------------------- |
| 980 | 1010 |
| 981 | 1011 |
| 982 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { | 1012 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { |
| 983 { | 1013 { |
| 984 StreamBuilder m(this, kMachInt32, kMachInt32); | 1014 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 985 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); | 1015 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); |
| 986 Stream s = m.Build(); | 1016 Stream s = m.Build(); |
| 987 ASSERT_EQ(1U, s.size()); | 1017 ASSERT_EQ(1U, s.size()); |
| 988 EXPECT_EQ(kMipsCmp, s[0]->arch_opcode()); | 1018 EXPECT_EQ(kMipsCmp, s[0]->arch_opcode()); |
| 989 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); | 1019 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 990 ASSERT_EQ(2U, s[0]->InputCount()); | 1020 ASSERT_EQ(2U, s[0]->InputCount()); |
| 991 EXPECT_EQ(1U, s[0]->OutputCount()); | 1021 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 992 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1022 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 993 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1023 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 994 } | 1024 } |
| 995 { | 1025 { |
| 996 StreamBuilder m(this, kMachInt32, kMachInt32); | 1026 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 997 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); | 1027 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); |
| 998 Stream s = m.Build(); | 1028 Stream s = m.Build(); |
| 999 ASSERT_EQ(1U, s.size()); | 1029 ASSERT_EQ(1U, s.size()); |
| 1000 EXPECT_EQ(kMipsCmp, s[0]->arch_opcode()); | 1030 EXPECT_EQ(kMipsCmp, s[0]->arch_opcode()); |
| 1001 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); | 1031 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 1002 ASSERT_EQ(2U, s[0]->InputCount()); | 1032 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1003 EXPECT_EQ(1U, s[0]->OutputCount()); | 1033 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1004 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1034 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 1005 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1035 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 1006 } | 1036 } |
| 1007 } | 1037 } |
| 1008 | 1038 |
| 1009 | 1039 |
| 1010 TEST_F(InstructionSelectorTest, Word32Clz) { | 1040 TEST_F(InstructionSelectorTest, Word32Clz) { |
| 1011 StreamBuilder m(this, kMachUint32, kMachUint32); | 1041 StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32()); |
| 1012 Node* const p0 = m.Parameter(0); | 1042 Node* const p0 = m.Parameter(0); |
| 1013 Node* const n = m.Word32Clz(p0); | 1043 Node* const n = m.Word32Clz(p0); |
| 1014 m.Return(n); | 1044 m.Return(n); |
| 1015 Stream s = m.Build(); | 1045 Stream s = m.Build(); |
| 1016 ASSERT_EQ(1U, s.size()); | 1046 ASSERT_EQ(1U, s.size()); |
| 1017 EXPECT_EQ(kMipsClz, s[0]->arch_opcode()); | 1047 EXPECT_EQ(kMipsClz, s[0]->arch_opcode()); |
| 1018 ASSERT_EQ(1U, s[0]->InputCount()); | 1048 ASSERT_EQ(1U, s[0]->InputCount()); |
| 1019 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 1049 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1020 ASSERT_EQ(1U, s[0]->OutputCount()); | 1050 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1021 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1051 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1022 } | 1052 } |
| 1023 | 1053 |
| 1024 | 1054 |
| 1025 TEST_F(InstructionSelectorTest, Float32Abs) { | 1055 TEST_F(InstructionSelectorTest, Float32Abs) { |
| 1026 StreamBuilder m(this, kMachFloat32, kMachFloat32); | 1056 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32()); |
| 1027 Node* const p0 = m.Parameter(0); | 1057 Node* const p0 = m.Parameter(0); |
| 1028 Node* const n = m.Float32Abs(p0); | 1058 Node* const n = m.Float32Abs(p0); |
| 1029 m.Return(n); | 1059 m.Return(n); |
| 1030 Stream s = m.Build(); | 1060 Stream s = m.Build(); |
| 1031 ASSERT_EQ(1U, s.size()); | 1061 ASSERT_EQ(1U, s.size()); |
| 1032 EXPECT_EQ(kMipsAbsS, s[0]->arch_opcode()); | 1062 EXPECT_EQ(kMipsAbsS, s[0]->arch_opcode()); |
| 1033 ASSERT_EQ(1U, s[0]->InputCount()); | 1063 ASSERT_EQ(1U, s[0]->InputCount()); |
| 1034 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 1064 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1035 ASSERT_EQ(1U, s[0]->OutputCount()); | 1065 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1036 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1066 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1037 } | 1067 } |
| 1038 | 1068 |
| 1039 | 1069 |
| 1040 TEST_F(InstructionSelectorTest, Float64Abs) { | 1070 TEST_F(InstructionSelectorTest, Float64Abs) { |
| 1041 StreamBuilder m(this, kMachFloat64, kMachFloat64); | 1071 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64()); |
| 1042 Node* const p0 = m.Parameter(0); | 1072 Node* const p0 = m.Parameter(0); |
| 1043 Node* const n = m.Float64Abs(p0); | 1073 Node* const n = m.Float64Abs(p0); |
| 1044 m.Return(n); | 1074 m.Return(n); |
| 1045 Stream s = m.Build(); | 1075 Stream s = m.Build(); |
| 1046 ASSERT_EQ(1U, s.size()); | 1076 ASSERT_EQ(1U, s.size()); |
| 1047 EXPECT_EQ(kMipsAbsD, s[0]->arch_opcode()); | 1077 EXPECT_EQ(kMipsAbsD, s[0]->arch_opcode()); |
| 1048 ASSERT_EQ(1U, s[0]->InputCount()); | 1078 ASSERT_EQ(1U, s[0]->InputCount()); |
| 1049 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 1079 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 1050 ASSERT_EQ(1U, s[0]->OutputCount()); | 1080 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1051 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1081 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1052 } | 1082 } |
| 1053 | 1083 |
| 1054 | 1084 |
| 1055 TEST_F(InstructionSelectorTest, Float32Max) { | 1085 TEST_F(InstructionSelectorTest, Float32Max) { |
| 1056 StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); | 1086 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(), |
| 1087 MachineType::Float32()); |
| 1057 Node* const p0 = m.Parameter(0); | 1088 Node* const p0 = m.Parameter(0); |
| 1058 Node* const p1 = m.Parameter(1); | 1089 Node* const p1 = m.Parameter(1); |
| 1059 Node* const n = m.Float32Max(p0, p1); | 1090 Node* const n = m.Float32Max(p0, p1); |
| 1060 m.Return(n); | 1091 m.Return(n); |
| 1061 Stream s = m.Build(); | 1092 Stream s = m.Build(); |
| 1062 // Float32Max is `(b < a) ? a : b`. | 1093 // Float32Max is `(b < a) ? a : b`. |
| 1063 ASSERT_EQ(1U, s.size()); | 1094 ASSERT_EQ(1U, s.size()); |
| 1064 EXPECT_EQ(kMipsFloat32Max, s[0]->arch_opcode()); | 1095 EXPECT_EQ(kMipsFloat32Max, s[0]->arch_opcode()); |
| 1065 ASSERT_EQ(2U, s[0]->InputCount()); | 1096 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1066 ASSERT_EQ(1U, s[0]->OutputCount()); | 1097 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1067 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1098 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1068 } | 1099 } |
| 1069 | 1100 |
| 1070 | 1101 |
| 1071 TEST_F(InstructionSelectorTest, Float32Min) { | 1102 TEST_F(InstructionSelectorTest, Float32Min) { |
| 1072 StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); | 1103 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(), |
| 1104 MachineType::Float32()); |
| 1073 Node* const p0 = m.Parameter(0); | 1105 Node* const p0 = m.Parameter(0); |
| 1074 Node* const p1 = m.Parameter(1); | 1106 Node* const p1 = m.Parameter(1); |
| 1075 Node* const n = m.Float32Min(p0, p1); | 1107 Node* const n = m.Float32Min(p0, p1); |
| 1076 m.Return(n); | 1108 m.Return(n); |
| 1077 Stream s = m.Build(); | 1109 Stream s = m.Build(); |
| 1078 // Float32Min is `(a < b) ? a : b`. | 1110 // Float32Min is `(a < b) ? a : b`. |
| 1079 ASSERT_EQ(1U, s.size()); | 1111 ASSERT_EQ(1U, s.size()); |
| 1080 EXPECT_EQ(kMipsFloat32Min, s[0]->arch_opcode()); | 1112 EXPECT_EQ(kMipsFloat32Min, s[0]->arch_opcode()); |
| 1081 ASSERT_EQ(2U, s[0]->InputCount()); | 1113 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1082 ASSERT_EQ(1U, s[0]->OutputCount()); | 1114 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1083 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1115 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1084 } | 1116 } |
| 1085 | 1117 |
| 1086 | 1118 |
| 1087 TEST_F(InstructionSelectorTest, Float64Max) { | 1119 TEST_F(InstructionSelectorTest, Float64Max) { |
| 1088 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); | 1120 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(), |
| 1121 MachineType::Float64()); |
| 1089 Node* const p0 = m.Parameter(0); | 1122 Node* const p0 = m.Parameter(0); |
| 1090 Node* const p1 = m.Parameter(1); | 1123 Node* const p1 = m.Parameter(1); |
| 1091 Node* const n = m.Float64Max(p0, p1); | 1124 Node* const n = m.Float64Max(p0, p1); |
| 1092 m.Return(n); | 1125 m.Return(n); |
| 1093 Stream s = m.Build(); | 1126 Stream s = m.Build(); |
| 1094 // Float64Max is `(b < a) ? a : b`. | 1127 // Float64Max is `(b < a) ? a : b`. |
| 1095 ASSERT_EQ(1U, s.size()); | 1128 ASSERT_EQ(1U, s.size()); |
| 1096 EXPECT_EQ(kMipsFloat64Max, s[0]->arch_opcode()); | 1129 EXPECT_EQ(kMipsFloat64Max, s[0]->arch_opcode()); |
| 1097 ASSERT_EQ(2U, s[0]->InputCount()); | 1130 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1098 ASSERT_EQ(1U, s[0]->OutputCount()); | 1131 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1099 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1132 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1100 } | 1133 } |
| 1101 | 1134 |
| 1102 | 1135 |
| 1103 TEST_F(InstructionSelectorTest, Float64Min) { | 1136 TEST_F(InstructionSelectorTest, Float64Min) { |
| 1104 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); | 1137 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(), |
| 1138 MachineType::Float64()); |
| 1105 Node* const p0 = m.Parameter(0); | 1139 Node* const p0 = m.Parameter(0); |
| 1106 Node* const p1 = m.Parameter(1); | 1140 Node* const p1 = m.Parameter(1); |
| 1107 Node* const n = m.Float64Min(p0, p1); | 1141 Node* const n = m.Float64Min(p0, p1); |
| 1108 m.Return(n); | 1142 m.Return(n); |
| 1109 Stream s = m.Build(); | 1143 Stream s = m.Build(); |
| 1110 // Float64Min is `(a < b) ? a : b`. | 1144 // Float64Min is `(a < b) ? a : b`. |
| 1111 ASSERT_EQ(1U, s.size()); | 1145 ASSERT_EQ(1U, s.size()); |
| 1112 EXPECT_EQ(kMipsFloat64Min, s[0]->arch_opcode()); | 1146 EXPECT_EQ(kMipsFloat64Min, s[0]->arch_opcode()); |
| 1113 ASSERT_EQ(2U, s[0]->InputCount()); | 1147 ASSERT_EQ(2U, s[0]->InputCount()); |
| 1114 ASSERT_EQ(1U, s[0]->OutputCount()); | 1148 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 1115 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 1149 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 1116 } | 1150 } |
| 1117 | 1151 |
| 1118 | 1152 |
| 1119 } // namespace compiler | 1153 } // namespace compiler |
| 1120 } // namespace internal | 1154 } // namespace internal |
| 1121 } // namespace v8 | 1155 } // namespace v8 |
| OLD | NEW |