| 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 |
| 11 namespace { | 11 namespace { |
| 12 | |
| 13 template <typename T> | 12 template <typename T> |
| 14 struct MachInst { | 13 struct MachInst { |
| 15 T constructor; | 14 T constructor; |
| 16 const char* constructor_name; | 15 const char* constructor_name; |
| 17 ArchOpcode arch_opcode; | 16 ArchOpcode arch_opcode; |
| 18 MachineType machine_type; | 17 MachineType machine_type; |
| 19 }; | 18 }; |
| 20 | 19 |
| 21 template <typename T> | 20 template <typename T> |
| 22 std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) { | 21 std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) { |
| 23 return os << mi.constructor_name; | 22 return os << mi.constructor_name; |
| 24 } | 23 } |
| 25 | 24 |
| 26 typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1; | 25 typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1; |
| 27 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2; | 26 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2; |
| 28 | 27 |
| 28 |
| 29 // To avoid duplicated code IntCmp helper structure | 29 // To avoid duplicated code IntCmp helper structure |
| 30 // is created. It contains MachInst2 with two nodes and expected_size | 30 // is created. It contains MachInst2 with two nodes and expected_size |
| 31 // because different cmp instructions have different size. | 31 // because different cmp instructions have different size. |
| 32 struct IntCmp { | 32 struct IntCmp { |
| 33 MachInst2 mi; | 33 MachInst2 mi; |
| 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", kMips64CmpD, |
| 44 kMachFloat64}, | 44 kMachFloat64}, |
| 45 kUnorderedEqual}, | 45 kUnorderedEqual}, |
| 46 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", kMipsCmpD, | 46 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", kMips64CmpD, |
| 47 kMachFloat64}, | 47 kMachFloat64}, |
| 48 kUnorderedLessThan}, | 48 kUnorderedLessThan}, |
| 49 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", | 49 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", |
| 50 kMipsCmpD, kMachFloat64}, | 50 kMips64CmpD, kMachFloat64}, |
| 51 kUnorderedLessThanOrEqual}, | 51 kUnorderedLessThanOrEqual}, |
| 52 {{&RawMachineAssembler::Float64GreaterThan, "Float64GreaterThan", kMipsCmpD, | 52 {{&RawMachineAssembler::Float64GreaterThan, "Float64GreaterThan", |
| 53 kMachFloat64}, | 53 kMips64CmpD, kMachFloat64}, |
| 54 kUnorderedLessThan}, | 54 kUnorderedLessThan}, |
| 55 {{&RawMachineAssembler::Float64GreaterThanOrEqual, | 55 {{&RawMachineAssembler::Float64GreaterThanOrEqual, |
| 56 "Float64GreaterThanOrEqual", kMipsCmpD, kMachFloat64}, | 56 "Float64GreaterThanOrEqual", kMips64CmpD, kMachFloat64}, |
| 57 kUnorderedLessThanOrEqual}}; | 57 kUnorderedLessThanOrEqual}}; |
| 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::Word32And, "Word32And", kMips64And, kMachInt32}, |
| 73 {&RawMachineAssembler::WordOr, "WordOr", kMipsOr, kMachInt16}, | 73 {&RawMachineAssembler::Word64And, "Word64And", kMips64And, kMachInt64}, |
| 74 {&RawMachineAssembler::WordXor, "WordXor", kMipsXor, kMachInt16}, | 74 {&RawMachineAssembler::Word32Or, "Word32Or", kMips64Or, kMachInt32}, |
| 75 {&RawMachineAssembler::Word32And, "Word32And", kMipsAnd, kMachInt32}, | 75 {&RawMachineAssembler::Word64Or, "Word64Or", kMips64Or, kMachInt64}, |
| 76 {&RawMachineAssembler::Word32Or, "Word32Or", kMipsOr, kMachInt32}, | 76 {&RawMachineAssembler::Word32Xor, "Word32Xor", kMips64Xor, kMachInt32}, |
| 77 {&RawMachineAssembler::Word32Xor, "Word32Xor", kMipsXor, kMachInt32}}; | 77 {&RawMachineAssembler::Word64Xor, "Word64Xor", kMips64Xor, kMachInt64}}; |
| 78 | 78 |
| 79 | 79 |
| 80 // ---------------------------------------------------------------------------- | 80 // ---------------------------------------------------------------------------- |
| 81 // Shift instructions. | 81 // Shift instructions. |
| 82 // ---------------------------------------------------------------------------- | 82 // ---------------------------------------------------------------------------- |
| 83 | 83 |
| 84 | 84 |
| 85 const MachInst2 kShiftInstructions[] = { | 85 const MachInst2 kShiftInstructions[] = { |
| 86 {&RawMachineAssembler::WordShl, "WordShl", kMipsShl, kMachInt16}, | 86 {&RawMachineAssembler::Word32Shl, "Word32Shl", kMips64Shl, kMachInt32}, |
| 87 {&RawMachineAssembler::WordShr, "WordShr", kMipsShr, kMachInt16}, | 87 {&RawMachineAssembler::Word64Shl, "Word64Shl", kMips64Dshl, kMachInt64}, |
| 88 {&RawMachineAssembler::WordSar, "WordSar", kMipsSar, kMachInt16}, | 88 {&RawMachineAssembler::Word32Shr, "Word32Shr", kMips64Shr, kMachInt32}, |
| 89 {&RawMachineAssembler::WordRor, "WordRor", kMipsRor, kMachInt16}, | 89 {&RawMachineAssembler::Word64Shr, "Word64Shr", kMips64Dshr, kMachInt64}, |
| 90 {&RawMachineAssembler::Word32Shl, "Word32Shl", kMipsShl, kMachInt32}, | 90 {&RawMachineAssembler::Word32Sar, "Word32Sar", kMips64Sar, kMachInt32}, |
| 91 {&RawMachineAssembler::Word32Shr, "Word32Shr", kMipsShr, kMachInt32}, | 91 {&RawMachineAssembler::Word64Sar, "Word64Sar", kMips64Dsar, kMachInt64}, |
| 92 {&RawMachineAssembler::Word32Sar, "Word32Sar", kMipsSar, kMachInt32}, | 92 {&RawMachineAssembler::Word32Ror, "Word32Ror", kMips64Ror, kMachInt32}, |
| 93 {&RawMachineAssembler::Word32Ror, "Word32Ror", kMipsRor, kMachInt32}}; | 93 {&RawMachineAssembler::Word64Ror, "Word64Ror", kMips64Dror, kMachInt64}}; |
| 94 | 94 |
| 95 | 95 |
| 96 // ---------------------------------------------------------------------------- | 96 // ---------------------------------------------------------------------------- |
| 97 // MUL/DIV instructions. | 97 // MUL/DIV instructions. |
| 98 // ---------------------------------------------------------------------------- | 98 // ---------------------------------------------------------------------------- |
| 99 | 99 |
| 100 | 100 |
| 101 const MachInst2 kMulDivInstructions[] = { | 101 const MachInst2 kMulDivInstructions[] = { |
| 102 {&RawMachineAssembler::Int32Mul, "Int32Mul", kMipsMul, kMachInt32}, | 102 {&RawMachineAssembler::Int32Mul, "Int32Mul", kMips64Mul, kMachInt32}, |
| 103 {&RawMachineAssembler::Int32Div, "Int32Div", kMipsDiv, kMachInt32}, | 103 {&RawMachineAssembler::Int32Div, "Int32Div", kMips64Div, kMachInt32}, |
| 104 {&RawMachineAssembler::Uint32Div, "Uint32Div", kMipsDivU, kMachUint32}, | 104 {&RawMachineAssembler::Uint32Div, "Uint32Div", kMips64DivU, kMachUint32}, |
| 105 {&RawMachineAssembler::Float64Mul, "Float64Mul", kMipsMulD, kMachFloat64}, | 105 {&RawMachineAssembler::Int64Mul, "Int64Mul", kMips64Dmul, kMachInt64}, |
| 106 {&RawMachineAssembler::Float64Div, "Float64Div", kMipsDivD, kMachFloat64}}; | 106 {&RawMachineAssembler::Int64Div, "Int64Div", kMips64Ddiv, kMachInt64}, |
| 107 {&RawMachineAssembler::Uint64Div, "Uint64Div", kMips64DdivU, kMachUint64}, |
| 108 {&RawMachineAssembler::Float64Mul, "Float64Mul", kMips64MulD, kMachFloat64}, |
| 109 {&RawMachineAssembler::Float64Div, "Float64Div", kMips64DivD, |
| 110 kMachFloat64}}; |
| 107 | 111 |
| 108 | 112 |
| 109 // ---------------------------------------------------------------------------- | 113 // ---------------------------------------------------------------------------- |
| 110 // MOD instructions. | 114 // MOD instructions. |
| 111 // ---------------------------------------------------------------------------- | 115 // ---------------------------------------------------------------------------- |
| 112 | 116 |
| 113 | 117 |
| 114 const MachInst2 kModInstructions[] = { | 118 const MachInst2 kModInstructions[] = { |
| 115 {&RawMachineAssembler::Int32Mod, "Int32Mod", kMipsMod, kMachInt32}, | 119 {&RawMachineAssembler::Int32Mod, "Int32Mod", kMips64Mod, kMachInt32}, |
| 116 {&RawMachineAssembler::Uint32Mod, "Int32UMod", kMipsModU, kMachInt32}, | 120 {&RawMachineAssembler::Uint32Mod, "Uint32Mod", kMips64ModU, kMachInt32}, |
| 117 {&RawMachineAssembler::Float64Mod, "Float64Mod", kMipsModD, kMachFloat64}}; | 121 {&RawMachineAssembler::Float64Mod, "Float64Mod", kMips64ModD, |
| 122 kMachFloat64}}; |
| 118 | 123 |
| 119 | 124 |
| 120 // ---------------------------------------------------------------------------- | 125 // ---------------------------------------------------------------------------- |
| 121 // Arithmetic FPU instructions. | 126 // Arithmetic FPU instructions. |
| 122 // ---------------------------------------------------------------------------- | 127 // ---------------------------------------------------------------------------- |
| 123 | 128 |
| 124 | 129 |
| 125 const MachInst2 kFPArithInstructions[] = { | 130 const MachInst2 kFPArithInstructions[] = { |
| 126 {&RawMachineAssembler::Float64Add, "Float64Add", kMipsAddD, kMachFloat64}, | 131 {&RawMachineAssembler::Float64Add, "Float64Add", kMips64AddD, kMachFloat64}, |
| 127 {&RawMachineAssembler::Float64Sub, "Float64Sub", kMipsSubD, kMachFloat64}}; | 132 {&RawMachineAssembler::Float64Sub, "Float64Sub", kMips64SubD, |
| 133 kMachFloat64}}; |
| 128 | 134 |
| 129 | 135 |
| 130 // ---------------------------------------------------------------------------- | 136 // ---------------------------------------------------------------------------- |
| 131 // IntArithTest instructions, two nodes. | 137 // IntArithTest instructions, two nodes. |
| 132 // ---------------------------------------------------------------------------- | 138 // ---------------------------------------------------------------------------- |
| 133 | 139 |
| 134 | 140 |
| 135 const MachInst2 kAddSubInstructions[] = { | 141 const MachInst2 kAddSubInstructions[] = { |
| 136 {&RawMachineAssembler::Int32Add, "Int32Add", kMipsAdd, kMachInt32}, | 142 {&RawMachineAssembler::Int32Add, "Int32Add", kMips64Add, kMachInt32}, |
| 137 {&RawMachineAssembler::Int32Sub, "Int32Sub", kMipsSub, kMachInt32}, | 143 {&RawMachineAssembler::Int64Add, "Int64Add", kMips64Dadd, kMachInt64}, |
| 138 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", | 144 {&RawMachineAssembler::Int32Sub, "Int32Sub", kMips64Sub, kMachInt32}, |
| 139 kMipsAddOvf, kMachInt32}, | 145 {&RawMachineAssembler::Int64Sub, "Int64Sub", kMips64Dsub, kMachInt64}}; |
| 140 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", | |
| 141 kMipsSubOvf, kMachInt32}}; | |
| 142 | 146 |
| 143 | 147 |
| 144 // ---------------------------------------------------------------------------- | 148 // ---------------------------------------------------------------------------- |
| 145 // IntArithTest instructions, one node. | 149 // IntArithTest instructions, one node. |
| 146 // ---------------------------------------------------------------------------- | 150 // ---------------------------------------------------------------------------- |
| 147 | 151 |
| 148 | 152 |
| 149 const MachInst1 kAddSubOneInstructions[] = { | 153 const MachInst1 kAddSubOneInstructions[] = { |
| 150 {&RawMachineAssembler::Int32Neg, "Int32Neg", kMipsSub, kMachInt32}, | 154 {&RawMachineAssembler::Int32Neg, "Int32Neg", kMips64Sub, kMachInt32}, |
| 151 // TODO(dusmil): check this ... | 155 {&RawMachineAssembler::Int64Neg, "Int64Neg", kMips64Dsub, kMachInt64}}; |
| 152 // {&RawMachineAssembler::WordEqual , "WordEqual" , kMipsTst, kMachInt32} | |
| 153 }; | |
| 154 | 156 |
| 155 | 157 |
| 156 // ---------------------------------------------------------------------------- | 158 // ---------------------------------------------------------------------------- |
| 157 // Arithmetic compare instructions. | 159 // Arithmetic compare instructions. |
| 158 // ---------------------------------------------------------------------------- | 160 // ---------------------------------------------------------------------------- |
| 159 | 161 |
| 160 | 162 |
| 161 const IntCmp kCmpInstructions[] = { | 163 const IntCmp kCmpInstructions[] = { |
| 162 {{&RawMachineAssembler::WordEqual, "WordEqual", kMipsCmp, kMachInt16}, 1U}, | 164 {{&RawMachineAssembler::WordEqual, "WordEqual", kMips64Cmp, kMachInt64}, |
| 163 {{&RawMachineAssembler::WordNotEqual, "WordNotEqual", kMipsCmp, kMachInt16}, | |
| 164 1U}, | 165 1U}, |
| 165 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kMipsCmp, kMachInt32}, | 166 {{&RawMachineAssembler::WordNotEqual, "WordNotEqual", kMips64Cmp, |
| 167 kMachInt64}, |
| 166 1U}, | 168 1U}, |
| 167 {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kMipsCmp, | 169 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kMips64Cmp32, |
| 168 kMachInt32}, | 170 kMachInt32}, |
| 169 1U}, | 171 1U}, |
| 170 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kMipsCmp, | 172 {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kMips64Cmp32, |
| 173 kMachInt32}, |
| 174 1U}, |
| 175 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kMips64Cmp32, |
| 171 kMachInt32}, | 176 kMachInt32}, |
| 172 1U}, | 177 1U}, |
| 173 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", | 178 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", |
| 174 kMipsCmp, kMachInt32}, | 179 kMips64Cmp32, kMachInt32}, |
| 175 1U}, | 180 1U}, |
| 176 {{&RawMachineAssembler::Int32GreaterThan, "Int32GreaterThan", kMipsCmp, | 181 {{&RawMachineAssembler::Int32GreaterThan, "Int32GreaterThan", kMips64Cmp32, |
| 177 kMachInt32}, | 182 kMachInt32}, |
| 178 1U}, | 183 1U}, |
| 179 {{&RawMachineAssembler::Int32GreaterThanOrEqual, "Int32GreaterThanOrEqual", | 184 {{&RawMachineAssembler::Int32GreaterThanOrEqual, "Int32GreaterThanOrEqual", |
| 180 kMipsCmp, kMachInt32}, | 185 kMips64Cmp32, kMachInt32}, |
| 181 1U}, | 186 1U}, |
| 182 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kMipsCmp, | 187 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kMips64Cmp32, |
| 183 kMachUint32}, | 188 kMachUint32}, |
| 184 1U}, | 189 1U}, |
| 185 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", | 190 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", |
| 186 kMipsCmp, kMachUint32}, | 191 kMips64Cmp32, kMachUint32}, |
| 187 1U}}; | 192 1U}}; |
| 188 | 193 |
| 189 | 194 |
| 190 // ---------------------------------------------------------------------------- | 195 // ---------------------------------------------------------------------------- |
| 191 // Conversion instructions. | 196 // Conversion instructions. |
| 192 // ---------------------------------------------------------------------------- | 197 // ---------------------------------------------------------------------------- |
| 193 | 198 |
| 194 const Conversion kConversionInstructions[] = { | 199 const Conversion kConversionInstructions[] = { |
| 195 // Conversion instructions are related to machine_operator.h: | 200 // Conversion instructions are related to machine_operator.h: |
| 196 // FPU conversions: | 201 // FPU conversions: |
| 197 // Convert representation of integers between float64 and int32/uint32. | 202 // Convert representation of integers between float64 and int32/uint32. |
| 198 // The precise rounding mode and handling of out of range inputs are *not* | 203 // 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 | 204 // defined for these operators, since they are intended only for use with |
| 200 // integers. | 205 // integers. |
| 201 // mips instruction: cvt_d_w | 206 // mips instructions: |
| 207 // mtc1, cvt.d.w |
| 202 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64", | 208 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64", |
| 203 kMipsCvtDW, kMachFloat64}, | 209 kMips64CvtDW, kMachFloat64}, |
| 204 kMachInt32}, | 210 kMachInt32}, |
| 205 | 211 |
| 206 // mips instruction: cvt_d_uw | 212 // mips instructions: |
| 213 // cvt.d.uw |
| 207 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64", | 214 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64", |
| 208 kMipsCvtDUw, kMachFloat64}, | 215 kMips64CvtDUw, kMachFloat64}, |
| 209 kMachInt32}, | 216 kMachInt32}, |
| 210 | 217 |
| 211 // mips instruction: trunc_w_d | 218 // mips instructions: |
| 219 // mfc1, trunc double to word, for more details look at mips macro |
| 220 // asm and mips asm file |
| 212 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32", | 221 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32", |
| 213 kMipsTruncWD, kMachFloat64}, | 222 kMips64TruncWD, kMachFloat64}, |
| 214 kMachInt32}, | 223 kMachInt32}, |
| 215 | 224 |
| 216 // mips instruction: trunc_uw_d | 225 // mips instructions: |
| 226 // trunc double to unsigned word, for more details look at mips macro |
| 227 // asm and mips asm file |
| 217 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32", | 228 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32", |
| 218 kMipsTruncUwD, kMachFloat64}, | 229 kMips64TruncUwD, kMachFloat64}, |
| 219 kMachInt32}}; | 230 kMachInt32}}; |
| 220 | 231 |
| 221 } // namespace | 232 } // namespace |
| 222 | 233 |
| 223 | 234 |
| 224 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest; | 235 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest; |
| 225 | 236 |
| 226 | |
| 227 TEST_P(InstructionSelectorFPCmpTest, Parameter) { | 237 TEST_P(InstructionSelectorFPCmpTest, Parameter) { |
| 228 const FPCmp cmp = GetParam(); | 238 const FPCmp cmp = GetParam(); |
| 229 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type); | 239 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type); |
| 230 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); | 240 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 231 Stream s = m.Build(); | 241 Stream s = m.Build(); |
| 232 ASSERT_EQ(1U, s.size()); | 242 ASSERT_EQ(1U, s.size()); |
| 233 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); | 243 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); |
| 234 EXPECT_EQ(2U, s[0]->InputCount()); | 244 EXPECT_EQ(2U, s[0]->InputCount()); |
| 235 EXPECT_EQ(1U, s[0]->OutputCount()); | 245 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 236 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 246 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 237 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); | 247 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 238 } | 248 } |
| 239 | 249 |
| 240 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest, | 250 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest, |
| 241 ::testing::ValuesIn(kFPCmpInstructions)); | 251 ::testing::ValuesIn(kFPCmpInstructions)); |
| 242 | 252 |
| 243 | |
| 244 // ---------------------------------------------------------------------------- | 253 // ---------------------------------------------------------------------------- |
| 245 // Arithmetic compare instructions integers. | 254 // Arithmetic compare instructions integers |
| 246 // ---------------------------------------------------------------------------- | 255 // ---------------------------------------------------------------------------- |
| 247 | |
| 248 | |
| 249 typedef InstructionSelectorTestWithParam<IntCmp> InstructionSelectorCmpTest; | 256 typedef InstructionSelectorTestWithParam<IntCmp> InstructionSelectorCmpTest; |
| 250 | 257 |
| 251 | 258 |
| 252 TEST_P(InstructionSelectorCmpTest, Parameter) { | 259 TEST_P(InstructionSelectorCmpTest, Parameter) { |
| 253 const IntCmp cmp = GetParam(); | 260 const IntCmp cmp = GetParam(); |
| 254 const MachineType type = cmp.mi.machine_type; | 261 const MachineType type = cmp.mi.machine_type; |
| 255 StreamBuilder m(this, type, type, type); | 262 StreamBuilder m(this, type, type, type); |
| 256 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); | 263 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 257 Stream s = m.Build(); | 264 Stream s = m.Build(); |
| 258 ASSERT_EQ(cmp.expected_size, s.size()); | 265 ASSERT_EQ(cmp.expected_size, s.size()); |
| 259 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); | 266 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); |
| 260 EXPECT_EQ(2U, s[0]->InputCount()); | 267 EXPECT_EQ(2U, s[0]->InputCount()); |
| 261 EXPECT_EQ(1U, s[0]->OutputCount()); | 268 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 262 } | 269 } |
| 263 | 270 |
| 264 | |
| 265 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorCmpTest, | 271 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorCmpTest, |
| 266 ::testing::ValuesIn(kCmpInstructions)); | 272 ::testing::ValuesIn(kCmpInstructions)); |
| 267 | 273 |
| 268 | |
| 269 // ---------------------------------------------------------------------------- | 274 // ---------------------------------------------------------------------------- |
| 270 // Shift instructions. | 275 // Shift instructions. |
| 271 // ---------------------------------------------------------------------------- | 276 // ---------------------------------------------------------------------------- |
| 272 | |
| 273 | |
| 274 typedef InstructionSelectorTestWithParam<MachInst2> | 277 typedef InstructionSelectorTestWithParam<MachInst2> |
| 275 InstructionSelectorShiftTest; | 278 InstructionSelectorShiftTest; |
| 276 | 279 |
| 277 | |
| 278 TEST_P(InstructionSelectorShiftTest, Immediate) { | 280 TEST_P(InstructionSelectorShiftTest, Immediate) { |
| 279 const MachInst2 dpi = GetParam(); | 281 const MachInst2 dpi = GetParam(); |
| 280 const MachineType type = dpi.machine_type; | 282 const MachineType type = dpi.machine_type; |
| 281 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) { | 283 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) { |
| 282 StreamBuilder m(this, type, type); | 284 StreamBuilder m(this, type, type); |
| 283 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); | 285 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); |
| 284 Stream s = m.Build(); | 286 Stream s = m.Build(); |
| 285 ASSERT_EQ(1U, s.size()); | 287 ASSERT_EQ(1U, s.size()); |
| 286 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 288 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 287 EXPECT_EQ(2U, s[0]->InputCount()); | 289 EXPECT_EQ(2U, s[0]->InputCount()); |
| 288 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 290 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 289 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 291 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 290 EXPECT_EQ(1U, s[0]->OutputCount()); | 292 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 291 } | 293 } |
| 292 } | 294 } |
| 293 | 295 |
| 294 | |
| 295 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, | 296 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, |
| 296 ::testing::ValuesIn(kShiftInstructions)); | 297 ::testing::ValuesIn(kShiftInstructions)); |
| 297 | 298 |
| 298 | |
| 299 // ---------------------------------------------------------------------------- | 299 // ---------------------------------------------------------------------------- |
| 300 // Logical instructions. | 300 // Logical instructions. |
| 301 // ---------------------------------------------------------------------------- | 301 // ---------------------------------------------------------------------------- |
| 302 | |
| 303 | |
| 304 typedef InstructionSelectorTestWithParam<MachInst2> | 302 typedef InstructionSelectorTestWithParam<MachInst2> |
| 305 InstructionSelectorLogicalTest; | 303 InstructionSelectorLogicalTest; |
| 306 | 304 |
| 307 | 305 |
| 308 TEST_P(InstructionSelectorLogicalTest, Parameter) { | 306 TEST_P(InstructionSelectorLogicalTest, Parameter) { |
| 309 const MachInst2 dpi = GetParam(); | 307 const MachInst2 dpi = GetParam(); |
| 310 const MachineType type = dpi.machine_type; | 308 const MachineType type = dpi.machine_type; |
| 311 StreamBuilder m(this, type, type, type); | 309 StreamBuilder m(this, type, type, type); |
| 312 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 310 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 313 Stream s = m.Build(); | 311 Stream s = m.Build(); |
| 314 ASSERT_EQ(1U, s.size()); | 312 ASSERT_EQ(1U, s.size()); |
| 315 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 313 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 316 EXPECT_EQ(2U, s[0]->InputCount()); | 314 EXPECT_EQ(2U, s[0]->InputCount()); |
| 317 EXPECT_EQ(1U, s[0]->OutputCount()); | 315 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 318 } | 316 } |
| 319 | 317 |
| 320 | |
| 321 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, | 318 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, |
| 322 ::testing::ValuesIn(kLogicalInstructions)); | 319 ::testing::ValuesIn(kLogicalInstructions)); |
| 323 | 320 |
| 324 | |
| 325 // ---------------------------------------------------------------------------- | 321 // ---------------------------------------------------------------------------- |
| 326 // MUL/DIV instructions. | 322 // MUL/DIV instructions. |
| 327 // ---------------------------------------------------------------------------- | 323 // ---------------------------------------------------------------------------- |
| 328 | |
| 329 | |
| 330 typedef InstructionSelectorTestWithParam<MachInst2> | 324 typedef InstructionSelectorTestWithParam<MachInst2> |
| 331 InstructionSelectorMulDivTest; | 325 InstructionSelectorMulDivTest; |
| 332 | 326 |
| 333 | |
| 334 TEST_P(InstructionSelectorMulDivTest, Parameter) { | 327 TEST_P(InstructionSelectorMulDivTest, Parameter) { |
| 335 const MachInst2 dpi = GetParam(); | 328 const MachInst2 dpi = GetParam(); |
| 336 const MachineType type = dpi.machine_type; | 329 const MachineType type = dpi.machine_type; |
| 337 StreamBuilder m(this, type, type, type); | 330 StreamBuilder m(this, type, type, type); |
| 338 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 331 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 339 Stream s = m.Build(); | 332 Stream s = m.Build(); |
| 340 ASSERT_EQ(1U, s.size()); | 333 ASSERT_EQ(1U, s.size()); |
| 341 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 334 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 342 EXPECT_EQ(2U, s[0]->InputCount()); | 335 EXPECT_EQ(2U, s[0]->InputCount()); |
| 343 EXPECT_EQ(1U, s[0]->OutputCount()); | 336 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 344 } | 337 } |
| 345 | 338 |
| 346 | |
| 347 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest, | 339 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest, |
| 348 ::testing::ValuesIn(kMulDivInstructions)); | 340 ::testing::ValuesIn(kMulDivInstructions)); |
| 349 | 341 |
| 350 | |
| 351 // ---------------------------------------------------------------------------- | 342 // ---------------------------------------------------------------------------- |
| 352 // MOD instructions. | 343 // MOD instructions. |
| 353 // ---------------------------------------------------------------------------- | 344 // ---------------------------------------------------------------------------- |
| 354 | |
| 355 | |
| 356 typedef InstructionSelectorTestWithParam<MachInst2> InstructionSelectorModTest; | 345 typedef InstructionSelectorTestWithParam<MachInst2> InstructionSelectorModTest; |
| 357 | 346 |
| 358 | |
| 359 TEST_P(InstructionSelectorModTest, Parameter) { | 347 TEST_P(InstructionSelectorModTest, Parameter) { |
| 360 const MachInst2 dpi = GetParam(); | 348 const MachInst2 dpi = GetParam(); |
| 361 const MachineType type = dpi.machine_type; | 349 const MachineType type = dpi.machine_type; |
| 362 StreamBuilder m(this, type, type, type); | 350 StreamBuilder m(this, type, type, type); |
| 363 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 351 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 364 Stream s = m.Build(); | 352 Stream s = m.Build(); |
| 365 ASSERT_EQ(1U, s.size()); | 353 ASSERT_EQ(1U, s.size()); |
| 366 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 354 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 367 EXPECT_EQ(2U, s[0]->InputCount()); | 355 EXPECT_EQ(2U, s[0]->InputCount()); |
| 368 EXPECT_EQ(1U, s[0]->OutputCount()); | 356 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 369 } | 357 } |
| 370 | 358 |
| 371 | |
| 372 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorModTest, | 359 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorModTest, |
| 373 ::testing::ValuesIn(kModInstructions)); | 360 ::testing::ValuesIn(kModInstructions)); |
| 374 | 361 |
| 375 | |
| 376 // ---------------------------------------------------------------------------- | 362 // ---------------------------------------------------------------------------- |
| 377 // Floating point instructions. | 363 // Floating point instructions. |
| 378 // ---------------------------------------------------------------------------- | 364 // ---------------------------------------------------------------------------- |
| 379 | |
| 380 | |
| 381 typedef InstructionSelectorTestWithParam<MachInst2> | 365 typedef InstructionSelectorTestWithParam<MachInst2> |
| 382 InstructionSelectorFPArithTest; | 366 InstructionSelectorFPArithTest; |
| 383 | 367 |
| 384 | |
| 385 TEST_P(InstructionSelectorFPArithTest, Parameter) { | 368 TEST_P(InstructionSelectorFPArithTest, Parameter) { |
| 386 const MachInst2 fpa = GetParam(); | 369 const MachInst2 fpa = GetParam(); |
| 387 StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type); | 370 StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type); |
| 388 m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1))); | 371 m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1))); |
| 389 Stream s = m.Build(); | 372 Stream s = m.Build(); |
| 390 ASSERT_EQ(1U, s.size()); | 373 ASSERT_EQ(1U, s.size()); |
| 391 EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode()); | 374 EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode()); |
| 392 EXPECT_EQ(2U, s[0]->InputCount()); | 375 EXPECT_EQ(2U, s[0]->InputCount()); |
| 393 EXPECT_EQ(1U, s[0]->OutputCount()); | 376 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 394 } | 377 } |
| 395 | 378 |
| 396 | |
| 397 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest, | 379 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest, |
| 398 ::testing::ValuesIn(kFPArithInstructions)); | 380 ::testing::ValuesIn(kFPArithInstructions)); |
| 399 | |
| 400 | |
| 401 // ---------------------------------------------------------------------------- | 381 // ---------------------------------------------------------------------------- |
| 402 // Integer arithmetic. | 382 // Integer arithmetic |
| 403 // ---------------------------------------------------------------------------- | 383 // ---------------------------------------------------------------------------- |
| 404 | |
| 405 | |
| 406 typedef InstructionSelectorTestWithParam<MachInst2> | 384 typedef InstructionSelectorTestWithParam<MachInst2> |
| 407 InstructionSelectorIntArithTwoTest; | 385 InstructionSelectorIntArithTwoTest; |
| 408 | 386 |
| 409 | |
| 410 TEST_P(InstructionSelectorIntArithTwoTest, Parameter) { | 387 TEST_P(InstructionSelectorIntArithTwoTest, Parameter) { |
| 411 const MachInst2 intpa = GetParam(); | 388 const MachInst2 intpa = GetParam(); |
| 412 StreamBuilder m(this, intpa.machine_type, intpa.machine_type, | 389 StreamBuilder m(this, intpa.machine_type, intpa.machine_type, |
| 413 intpa.machine_type); | 390 intpa.machine_type); |
| 414 m.Return((m.*intpa.constructor)(m.Parameter(0), m.Parameter(1))); | 391 m.Return((m.*intpa.constructor)(m.Parameter(0), m.Parameter(1))); |
| 415 Stream s = m.Build(); | 392 Stream s = m.Build(); |
| 416 ASSERT_EQ(1U, s.size()); | 393 ASSERT_EQ(1U, s.size()); |
| 417 EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode()); | 394 EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode()); |
| 418 EXPECT_EQ(2U, s[0]->InputCount()); | 395 EXPECT_EQ(2U, s[0]->InputCount()); |
| 419 EXPECT_EQ(1U, s[0]->OutputCount()); | 396 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 420 } | 397 } |
| 421 | 398 |
| 422 | |
| 423 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 399 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 424 InstructionSelectorIntArithTwoTest, | 400 InstructionSelectorIntArithTwoTest, |
| 425 ::testing::ValuesIn(kAddSubInstructions)); | 401 ::testing::ValuesIn(kAddSubInstructions)); |
| 426 | 402 |
| 427 | 403 |
| 428 // ---------------------------------------------------------------------------- | 404 // ---------------------------------------------------------------------------- |
| 429 // One node. | 405 // One node. |
| 430 // ---------------------------------------------------------------------------- | 406 // ---------------------------------------------------------------------------- |
| 431 | 407 |
| 432 | 408 |
| 433 typedef InstructionSelectorTestWithParam<MachInst1> | 409 typedef InstructionSelectorTestWithParam<MachInst1> |
| 434 InstructionSelectorIntArithOneTest; | 410 InstructionSelectorIntArithOneTest; |
| 435 | 411 |
| 436 | |
| 437 TEST_P(InstructionSelectorIntArithOneTest, Parameter) { | 412 TEST_P(InstructionSelectorIntArithOneTest, Parameter) { |
| 438 const MachInst1 intpa = GetParam(); | 413 const MachInst1 intpa = GetParam(); |
| 439 StreamBuilder m(this, intpa.machine_type, intpa.machine_type, | 414 StreamBuilder m(this, intpa.machine_type, intpa.machine_type, |
| 440 intpa.machine_type); | 415 intpa.machine_type); |
| 441 m.Return((m.*intpa.constructor)(m.Parameter(0))); | 416 m.Return((m.*intpa.constructor)(m.Parameter(0))); |
| 442 Stream s = m.Build(); | 417 Stream s = m.Build(); |
| 443 ASSERT_EQ(1U, s.size()); | 418 ASSERT_EQ(1U, s.size()); |
| 444 EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode()); | 419 EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode()); |
| 445 EXPECT_EQ(2U, s[0]->InputCount()); | 420 EXPECT_EQ(2U, s[0]->InputCount()); |
| 446 EXPECT_EQ(1U, s[0]->OutputCount()); | 421 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 447 } | 422 } |
| 448 | 423 |
| 449 | |
| 450 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 424 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 451 InstructionSelectorIntArithOneTest, | 425 InstructionSelectorIntArithOneTest, |
| 452 ::testing::ValuesIn(kAddSubOneInstructions)); | 426 ::testing::ValuesIn(kAddSubOneInstructions)); |
| 453 | |
| 454 | |
| 455 // ---------------------------------------------------------------------------- | 427 // ---------------------------------------------------------------------------- |
| 456 // Conversions. | 428 // Conversions. |
| 457 // ---------------------------------------------------------------------------- | 429 // ---------------------------------------------------------------------------- |
| 458 | |
| 459 | |
| 460 typedef InstructionSelectorTestWithParam<Conversion> | 430 typedef InstructionSelectorTestWithParam<Conversion> |
| 461 InstructionSelectorConversionTest; | 431 InstructionSelectorConversionTest; |
| 462 | 432 |
| 463 | |
| 464 TEST_P(InstructionSelectorConversionTest, Parameter) { | 433 TEST_P(InstructionSelectorConversionTest, Parameter) { |
| 465 const Conversion conv = GetParam(); | 434 const Conversion conv = GetParam(); |
| 466 StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type); | 435 StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type); |
| 467 m.Return((m.*conv.mi.constructor)(m.Parameter(0))); | 436 m.Return((m.*conv.mi.constructor)(m.Parameter(0))); |
| 468 Stream s = m.Build(); | 437 Stream s = m.Build(); |
| 469 ASSERT_EQ(1U, s.size()); | 438 ASSERT_EQ(1U, s.size()); |
| 470 EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode()); | 439 EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode()); |
| 471 EXPECT_EQ(1U, s[0]->InputCount()); | 440 EXPECT_EQ(1U, s[0]->InputCount()); |
| 472 EXPECT_EQ(1U, s[0]->OutputCount()); | 441 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 473 } | 442 } |
| 474 | 443 |
| 475 | |
| 476 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 444 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 477 InstructionSelectorConversionTest, | 445 InstructionSelectorConversionTest, |
| 478 ::testing::ValuesIn(kConversionInstructions)); | 446 ::testing::ValuesIn(kConversionInstructions)); |
| 479 | 447 |
| 480 | 448 |
| 481 // ---------------------------------------------------------------------------- | 449 // ---------------------------------------------------------------------------- |
| 482 // Loads and stores. | 450 // Loads and stores. |
| 483 // ---------------------------------------------------------------------------- | 451 // ---------------------------------------------------------------------------- |
| 484 | 452 |
| 453 |
| 485 namespace { | 454 namespace { |
| 486 | 455 |
| 487 struct MemoryAccess { | 456 struct MemoryAccess { |
| 488 MachineType type; | 457 MachineType type; |
| 489 ArchOpcode load_opcode; | 458 ArchOpcode load_opcode; |
| 490 ArchOpcode store_opcode; | 459 ArchOpcode store_opcode; |
| 491 }; | 460 }; |
| 492 | 461 |
| 493 | |
| 494 static const MemoryAccess kMemoryAccesses[] = { | 462 static const MemoryAccess kMemoryAccesses[] = { |
| 495 {kMachInt8, kMipsLb, kMipsSb}, | 463 {kMachInt8, kMips64Lb, kMips64Sb}, |
| 496 {kMachUint8, kMipsLbu, kMipsSb}, | 464 {kMachUint8, kMips64Lbu, kMips64Sb}, |
| 497 {kMachInt16, kMipsLh, kMipsSh}, | 465 {kMachInt16, kMips64Lh, kMips64Sh}, |
| 498 {kMachUint16, kMipsLhu, kMipsSh}, | 466 {kMachUint16, kMips64Lhu, kMips64Sh}, |
| 499 {kMachInt32, kMipsLw, kMipsSw}, | 467 {kMachInt32, kMips64Lw, kMips64Sw}, |
| 500 {kRepFloat32, kMipsLwc1, kMipsSwc1}, | 468 {kRepFloat32, kMips64Lwc1, kMips64Swc1}, |
| 501 {kRepFloat64, kMipsLdc1, kMipsSdc1}}; | 469 {kRepFloat64, kMips64Ldc1, kMips64Sdc1}, |
| 470 {kMachInt64, kMips64Ld, kMips64Sd}}; |
| 502 | 471 |
| 503 | 472 |
| 504 struct MemoryAccessImm { | 473 struct MemoryAccessImm { |
| 505 MachineType type; | 474 MachineType type; |
| 506 ArchOpcode load_opcode; | 475 ArchOpcode load_opcode; |
| 507 ArchOpcode store_opcode; | 476 ArchOpcode store_opcode; |
| 508 bool (InstructionSelectorTest::Stream::*val_predicate)( | 477 bool (InstructionSelectorTest::Stream::*val_predicate)( |
| 509 const InstructionOperand*) const; | 478 const InstructionOperand*) const; |
| 510 const int32_t immediates[40]; | 479 const int32_t immediates[40]; |
| 511 }; | 480 }; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 525 const int32_t immediates[5]; | 494 const int32_t immediates[5]; |
| 526 }; | 495 }; |
| 527 | 496 |
| 528 | 497 |
| 529 std::ostream& operator<<(std::ostream& os, const MemoryAccessImm1& acc) { | 498 std::ostream& operator<<(std::ostream& os, const MemoryAccessImm1& acc) { |
| 530 return os << acc.type; | 499 return os << acc.type; |
| 531 } | 500 } |
| 532 | 501 |
| 533 | 502 |
| 534 // ---------------------------------------------------------------------------- | 503 // ---------------------------------------------------------------------------- |
| 535 // Loads and stores immediate values. | 504 // Loads and stores immediate values |
| 536 // ---------------------------------------------------------------------------- | 505 // ---------------------------------------------------------------------------- |
| 537 | 506 |
| 538 | 507 |
| 539 const MemoryAccessImm kMemoryAccessesImm[] = { | 508 const MemoryAccessImm kMemoryAccessesImm[] = { |
| 540 {kMachInt8, | 509 {kMachInt8, |
| 541 kMipsLb, | 510 kMips64Lb, |
| 542 kMipsSb, | 511 kMips64Sb, |
| 543 &InstructionSelectorTest::Stream::IsInteger, | 512 &InstructionSelectorTest::Stream::IsInteger, |
| 544 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 513 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 545 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 514 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 546 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 515 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 547 {kMachUint8, | 516 {kMachUint8, |
| 548 kMipsLbu, | 517 kMips64Lbu, |
| 549 kMipsSb, | 518 kMips64Sb, |
| 550 &InstructionSelectorTest::Stream::IsInteger, | 519 &InstructionSelectorTest::Stream::IsInteger, |
| 551 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 520 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 552 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 521 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 553 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 522 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 554 {kMachInt16, | 523 {kMachInt16, |
| 555 kMipsLh, | 524 kMips64Lh, |
| 556 kMipsSh, | 525 kMips64Sh, |
| 557 &InstructionSelectorTest::Stream::IsInteger, | 526 &InstructionSelectorTest::Stream::IsInteger, |
| 558 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 527 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 559 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 528 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 560 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 529 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 561 {kMachUint16, | 530 {kMachUint16, |
| 562 kMipsLhu, | 531 kMips64Lhu, |
| 563 kMipsSh, | 532 kMips64Sh, |
| 564 &InstructionSelectorTest::Stream::IsInteger, | 533 &InstructionSelectorTest::Stream::IsInteger, |
| 565 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 534 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 566 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 535 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 567 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 536 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 568 {kMachInt32, | 537 {kMachInt32, |
| 569 kMipsLw, | 538 kMips64Lw, |
| 570 kMipsSw, | 539 kMips64Sw, |
| 571 &InstructionSelectorTest::Stream::IsInteger, | 540 &InstructionSelectorTest::Stream::IsInteger, |
| 572 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 541 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 573 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 542 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 574 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 543 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 575 {kMachFloat32, | 544 {kMachFloat32, |
| 576 kMipsLwc1, | 545 kMips64Lwc1, |
| 577 kMipsSwc1, | 546 kMips64Swc1, |
| 578 &InstructionSelectorTest::Stream::IsDouble, | 547 &InstructionSelectorTest::Stream::IsDouble, |
| 579 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 548 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 580 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 549 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 581 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, | 550 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 582 {kMachFloat64, | 551 {kMachFloat64, |
| 583 kMipsLdc1, | 552 kMips64Ldc1, |
| 584 kMipsSdc1, | 553 kMips64Sdc1, |
| 585 &InstructionSelectorTest::Stream::IsDouble, | 554 &InstructionSelectorTest::Stream::IsDouble, |
| 586 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, | 555 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 587 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, | 556 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 557 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}, |
| 558 {kMachInt64, |
| 559 kMips64Ld, |
| 560 kMips64Sd, |
| 561 &InstructionSelectorTest::Stream::IsInteger, |
| 562 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89, |
| 563 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109, |
| 588 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}}; | 564 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}}; |
| 589 | 565 |
| 590 | 566 |
| 591 const MemoryAccessImm1 kMemoryAccessImmMoreThan16bit[] = { | 567 const MemoryAccessImm1 kMemoryAccessImmMoreThan16bit[] = { |
| 592 {kMachInt8, | 568 {kMachInt8, |
| 593 kMipsLb, | 569 kMips64Lb, |
| 594 kMipsSb, | 570 kMips64Sb, |
| 595 &InstructionSelectorTest::Stream::IsInteger, | 571 &InstructionSelectorTest::Stream::IsInteger, |
| 596 {-65000, -55000, 32777, 55000, 65000}}, | 572 {-65000, -55000, 32777, 55000, 65000}}, |
| 597 {kMachInt8, | 573 {kMachInt8, |
| 598 kMipsLbu, | 574 kMips64Lbu, |
| 599 kMipsSb, | 575 kMips64Sb, |
| 600 &InstructionSelectorTest::Stream::IsInteger, | 576 &InstructionSelectorTest::Stream::IsInteger, |
| 601 {-65000, -55000, 32777, 55000, 65000}}, | 577 {-65000, -55000, 32777, 55000, 65000}}, |
| 602 {kMachInt16, | 578 {kMachInt16, |
| 603 kMipsLh, | 579 kMips64Lh, |
| 604 kMipsSh, | 580 kMips64Sh, |
| 605 &InstructionSelectorTest::Stream::IsInteger, | 581 &InstructionSelectorTest::Stream::IsInteger, |
| 606 {-65000, -55000, 32777, 55000, 65000}}, | 582 {-65000, -55000, 32777, 55000, 65000}}, |
| 607 {kMachInt16, | 583 {kMachInt16, |
| 608 kMipsLhu, | 584 kMips64Lhu, |
| 609 kMipsSh, | 585 kMips64Sh, |
| 610 &InstructionSelectorTest::Stream::IsInteger, | 586 &InstructionSelectorTest::Stream::IsInteger, |
| 611 {-65000, -55000, 32777, 55000, 65000}}, | 587 {-65000, -55000, 32777, 55000, 65000}}, |
| 612 {kMachInt32, | 588 {kMachInt32, |
| 613 kMipsLw, | 589 kMips64Lw, |
| 614 kMipsSw, | 590 kMips64Sw, |
| 615 &InstructionSelectorTest::Stream::IsInteger, | 591 &InstructionSelectorTest::Stream::IsInteger, |
| 616 {-65000, -55000, 32777, 55000, 65000}}, | 592 {-65000, -55000, 32777, 55000, 65000}}, |
| 617 {kMachFloat32, | 593 {kMachFloat32, |
| 618 kMipsLwc1, | 594 kMips64Lwc1, |
| 619 kMipsSwc1, | 595 kMips64Swc1, |
| 620 &InstructionSelectorTest::Stream::IsDouble, | 596 &InstructionSelectorTest::Stream::IsDouble, |
| 621 {-65000, -55000, 32777, 55000, 65000}}, | 597 {-65000, -55000, 32777, 55000, 65000}}, |
| 622 {kMachFloat64, | 598 {kMachFloat64, |
| 623 kMipsLdc1, | 599 kMips64Ldc1, |
| 624 kMipsSdc1, | 600 kMips64Sdc1, |
| 625 &InstructionSelectorTest::Stream::IsDouble, | 601 &InstructionSelectorTest::Stream::IsDouble, |
| 602 {-65000, -55000, 32777, 55000, 65000}}, |
| 603 {kMachInt64, |
| 604 kMips64Ld, |
| 605 kMips64Sd, |
| 606 &InstructionSelectorTest::Stream::IsInteger, |
| 626 {-65000, -55000, 32777, 55000, 65000}}}; | 607 {-65000, -55000, 32777, 55000, 65000}}}; |
| 627 | 608 |
| 628 } // namespace | 609 } // namespace |
| 629 | 610 |
| 630 | 611 |
| 631 typedef InstructionSelectorTestWithParam<MemoryAccess> | 612 typedef InstructionSelectorTestWithParam<MemoryAccess> |
| 632 InstructionSelectorMemoryAccessTest; | 613 InstructionSelectorMemoryAccessTest; |
| 633 | 614 |
| 634 | |
| 635 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { | 615 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { |
| 636 const MemoryAccess memacc = GetParam(); | 616 const MemoryAccess memacc = GetParam(); |
| 637 StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32); | 617 StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32); |
| 638 m.Return(m.Load(memacc.type, m.Parameter(0))); | 618 m.Return(m.Load(memacc.type, m.Parameter(0))); |
| 639 Stream s = m.Build(); | 619 Stream s = m.Build(); |
| 640 ASSERT_EQ(1U, s.size()); | 620 ASSERT_EQ(1U, s.size()); |
| 641 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); | 621 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); |
| 642 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 622 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 643 } | 623 } |
| 644 | 624 |
| 645 | 625 |
| 646 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { | 626 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { |
| 647 const MemoryAccess memacc = GetParam(); | 627 const MemoryAccess memacc = GetParam(); |
| 648 StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); | 628 StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); |
| 649 m.Store(memacc.type, m.Parameter(0), m.Parameter(1)); | 629 m.Store(memacc.type, m.Parameter(0), m.Parameter(1)); |
| 650 m.Return(m.Int32Constant(0)); | 630 m.Return(m.Int32Constant(0)); |
| 651 Stream s = m.Build(); | 631 Stream s = m.Build(); |
| 652 ASSERT_EQ(1U, s.size()); | 632 ASSERT_EQ(1U, s.size()); |
| 653 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); | 633 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); |
| 654 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 634 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 655 } | 635 } |
| 656 | 636 |
| 657 | |
| 658 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 637 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 659 InstructionSelectorMemoryAccessTest, | 638 InstructionSelectorMemoryAccessTest, |
| 660 ::testing::ValuesIn(kMemoryAccesses)); | 639 ::testing::ValuesIn(kMemoryAccesses)); |
| 661 | 640 |
| 662 | 641 |
| 663 // ---------------------------------------------------------------------------- | 642 // ---------------------------------------------------------------------------- |
| 664 // Load immediate. | 643 // Load immediate. |
| 665 // ---------------------------------------------------------------------------- | 644 // ---------------------------------------------------------------------------- |
| 666 | 645 |
| 667 | 646 |
| 668 typedef InstructionSelectorTestWithParam<MemoryAccessImm> | 647 typedef InstructionSelectorTestWithParam<MemoryAccessImm> |
| 669 InstructionSelectorMemoryAccessImmTest; | 648 InstructionSelectorMemoryAccessImmTest; |
| 670 | 649 |
| 671 | |
| 672 TEST_P(InstructionSelectorMemoryAccessImmTest, LoadWithImmediateIndex) { | 650 TEST_P(InstructionSelectorMemoryAccessImmTest, LoadWithImmediateIndex) { |
| 673 const MemoryAccessImm memacc = GetParam(); | 651 const MemoryAccessImm memacc = GetParam(); |
| 674 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 652 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
| 675 StreamBuilder m(this, memacc.type, kMachPtr); | 653 StreamBuilder m(this, memacc.type, kMachPtr); |
| 676 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); | 654 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); |
| 677 Stream s = m.Build(); | 655 Stream s = m.Build(); |
| 678 ASSERT_EQ(1U, s.size()); | 656 ASSERT_EQ(1U, s.size()); |
| 679 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); | 657 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); |
| 680 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 658 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 681 ASSERT_EQ(2U, s[0]->InputCount()); | 659 ASSERT_EQ(2U, s[0]->InputCount()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 703 ASSERT_EQ(1U, s.size()); | 681 ASSERT_EQ(1U, s.size()); |
| 704 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); | 682 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); |
| 705 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 683 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
| 706 ASSERT_EQ(3U, s[0]->InputCount()); | 684 ASSERT_EQ(3U, s[0]->InputCount()); |
| 707 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 685 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 708 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); | 686 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); |
| 709 EXPECT_EQ(0U, s[0]->OutputCount()); | 687 EXPECT_EQ(0U, s[0]->OutputCount()); |
| 710 } | 688 } |
| 711 } | 689 } |
| 712 | 690 |
| 713 | |
| 714 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 691 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 715 InstructionSelectorMemoryAccessImmTest, | 692 InstructionSelectorMemoryAccessImmTest, |
| 716 ::testing::ValuesIn(kMemoryAccessesImm)); | 693 ::testing::ValuesIn(kMemoryAccessesImm)); |
| 717 | 694 |
| 718 | 695 |
| 719 // ---------------------------------------------------------------------------- | 696 // ---------------------------------------------------------------------------- |
| 720 // Load/store offsets more than 16 bits. | 697 // Load/store offsets more than 16 bits. |
| 721 // ---------------------------------------------------------------------------- | 698 // ---------------------------------------------------------------------------- |
| 722 | 699 |
| 723 | 700 |
| 724 typedef InstructionSelectorTestWithParam<MemoryAccessImm1> | 701 typedef InstructionSelectorTestWithParam<MemoryAccessImm1> |
| 725 InstructionSelectorMemoryAccessImmMoreThan16bitTest; | 702 InstructionSelectorMemoryAccessImmMoreThan16bitTest; |
| 726 | 703 |
| 727 | |
| 728 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, | 704 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, |
| 729 LoadWithImmediateIndex) { | 705 LoadWithImmediateIndex) { |
| 730 const MemoryAccessImm1 memacc = GetParam(); | 706 const MemoryAccessImm1 memacc = GetParam(); |
| 731 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 707 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
| 732 StreamBuilder m(this, memacc.type, kMachPtr); | 708 StreamBuilder m(this, memacc.type, kMachPtr); |
| 733 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); | 709 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); |
| 734 Stream s = m.Build(); | 710 Stream s = m.Build(); |
| 735 ASSERT_EQ(2U, s.size()); | 711 ASSERT_EQ(2U, s.size()); |
| 736 // kMipsAdd is expected opcode. | 712 // kMips64Dadd is expected opcode |
| 737 // size more than 16 bits wide. | 713 // size more than 16 bits wide |
| 738 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode()); | 714 EXPECT_EQ(kMips64Dadd, s[0]->arch_opcode()); |
| 739 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); | 715 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 740 EXPECT_EQ(2U, s[0]->InputCount()); | 716 EXPECT_EQ(2U, s[0]->InputCount()); |
| 741 EXPECT_EQ(1U, s[0]->OutputCount()); | 717 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 742 } | 718 } |
| 743 } | 719 } |
| 744 | 720 |
| 745 | |
| 746 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, | 721 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, |
| 747 StoreWithImmediateIndex) { | 722 StoreWithImmediateIndex) { |
| 748 const MemoryAccessImm1 memacc = GetParam(); | 723 const MemoryAccessImm1 memacc = GetParam(); |
| 749 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 724 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
| 750 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); | 725 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); |
| 751 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), | 726 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), |
| 752 m.Parameter(1)); | 727 m.Parameter(1)); |
| 753 m.Return(m.Int32Constant(0)); | 728 m.Return(m.Int32Constant(0)); |
| 754 Stream s = m.Build(); | 729 Stream s = m.Build(); |
| 755 ASSERT_EQ(2U, s.size()); | 730 ASSERT_EQ(2U, s.size()); |
| 756 // kMipsAdd is expected opcode | 731 // kMips64Add is expected opcode |
| 757 // size more than 16 bits wide | 732 // size more than 16 bits wide |
| 758 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode()); | 733 EXPECT_EQ(kMips64Dadd, s[0]->arch_opcode()); |
| 759 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); | 734 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 760 EXPECT_EQ(2U, s[0]->InputCount()); | 735 EXPECT_EQ(2U, s[0]->InputCount()); |
| 761 EXPECT_EQ(1U, s[0]->OutputCount()); | 736 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 762 } | 737 } |
| 763 } | 738 } |
| 764 | 739 |
| 765 | |
| 766 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 740 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 767 InstructionSelectorMemoryAccessImmMoreThan16bitTest, | 741 InstructionSelectorMemoryAccessImmMoreThan16bitTest, |
| 768 ::testing::ValuesIn(kMemoryAccessImmMoreThan16bit)); | 742 ::testing::ValuesIn(kMemoryAccessImmMoreThan16bit)); |
| 769 | 743 |
| 770 | 744 |
| 771 // ---------------------------------------------------------------------------- | 745 // ---------------------------------------------------------------------------- |
| 772 // kMipsTst testing. | 746 // kMips64Cmp with zero testing. |
| 773 // ---------------------------------------------------------------------------- | 747 // ---------------------------------------------------------------------------- |
| 774 | 748 |
| 775 | 749 |
| 776 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { | 750 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { |
| 777 { | 751 { |
| 778 StreamBuilder m(this, kMachInt32, kMachInt32); | 752 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 779 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); | 753 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); |
| 780 Stream s = m.Build(); | 754 Stream s = m.Build(); |
| 781 ASSERT_EQ(1U, s.size()); | 755 ASSERT_EQ(1U, s.size()); |
| 782 EXPECT_EQ(kMipsCmp, s[0]->arch_opcode()); | 756 EXPECT_EQ(kMips64Cmp32, s[0]->arch_opcode()); |
| 783 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); | 757 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 784 ASSERT_EQ(2U, s[0]->InputCount()); | 758 ASSERT_EQ(2U, s[0]->InputCount()); |
| 785 EXPECT_EQ(1U, s[0]->OutputCount()); | 759 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 786 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 760 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 787 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 761 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 788 } | 762 } |
| 789 { | 763 { |
| 790 StreamBuilder m(this, kMachInt32, kMachInt32); | 764 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 791 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); | 765 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); |
| 792 Stream s = m.Build(); | 766 Stream s = m.Build(); |
| 793 ASSERT_EQ(1U, s.size()); | 767 ASSERT_EQ(1U, s.size()); |
| 794 EXPECT_EQ(kMipsCmp, s[0]->arch_opcode()); | 768 EXPECT_EQ(kMips64Cmp32, s[0]->arch_opcode()); |
| 795 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); | 769 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 796 ASSERT_EQ(2U, s[0]->InputCount()); | 770 ASSERT_EQ(2U, s[0]->InputCount()); |
| 797 EXPECT_EQ(1U, s[0]->OutputCount()); | 771 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 772 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 773 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 774 } |
| 775 } |
| 776 |
| 777 |
| 778 TEST_F(InstructionSelectorTest, Word64EqualWithZero) { |
| 779 { |
| 780 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 781 m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0))); |
| 782 Stream s = m.Build(); |
| 783 ASSERT_EQ(1U, s.size()); |
| 784 EXPECT_EQ(kMips64Cmp, s[0]->arch_opcode()); |
| 785 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 786 ASSERT_EQ(2U, s[0]->InputCount()); |
| 787 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 788 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 789 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 790 } |
| 791 { |
| 792 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 793 m.Return(m.Word64Equal(m.Int32Constant(0), m.Parameter(0))); |
| 794 Stream s = m.Build(); |
| 795 ASSERT_EQ(1U, s.size()); |
| 796 EXPECT_EQ(kMips64Cmp, s[0]->arch_opcode()); |
| 797 EXPECT_EQ(kMode_None, s[0]->addressing_mode()); |
| 798 ASSERT_EQ(2U, s[0]->InputCount()); |
| 799 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 798 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 800 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 799 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 801 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 800 } | 802 } |
| 801 } | 803 } |
| 802 | 804 |
| 803 } // namespace compiler | 805 } // namespace compiler |
| 804 } // namespace internal | 806 } // namespace internal |
| 805 } // namespace v8 | 807 } // namespace v8 |
| OLD | NEW |