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 <limits> | 5 #include <limits> |
6 | 6 |
7 #include "test/unittests/compiler/instruction-selector-unittest.h" | 7 #include "test/unittests/compiler/instruction-selector-unittest.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1391 ASSERT_EQ(1U, s.size()); | 1391 ASSERT_EQ(1U, s.size()); |
1392 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); | 1392 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); |
1393 EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode()); | 1393 EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode()); |
1394 ASSERT_EQ(3U, s[0]->InputCount()); | 1394 ASSERT_EQ(3U, s[0]->InputCount()); |
1395 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1395 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
1396 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); | 1396 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); |
1397 EXPECT_EQ(0U, s[0]->OutputCount()); | 1397 EXPECT_EQ(0U, s[0]->OutputCount()); |
1398 } | 1398 } |
1399 } | 1399 } |
1400 | 1400 |
| 1401 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithWord32And0xff) { |
| 1402 const MemoryAccess mem = GetParam(); |
| 1403 if (!(mem.type == MachineType::Float32() || |
| 1404 mem.type == MachineType::Float64())) { |
| 1405 { |
| 1406 StreamBuilder m(this, mem.type, MachineType::Pointer(), |
| 1407 MachineType::Int32()); |
| 1408 m.Return(m.Word32And(m.Int32Constant(0xff), |
| 1409 m.Load(mem.type, m.Parameter(0), m.Parameter(1)))); |
| 1410 Stream s = m.Build(); |
| 1411 ASSERT_EQ(1U, s.size()); |
| 1412 EXPECT_EQ(kArmLdrb, s[0]->arch_opcode()); |
| 1413 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1414 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1415 } |
| 1416 { |
| 1417 StreamBuilder m(this, mem.type, MachineType::Pointer(), |
| 1418 MachineType::Int32()); |
| 1419 m.Return(m.Word32And(m.Load(mem.type, m.Parameter(0), m.Parameter(1)), |
| 1420 m.Int32Constant(0xff))); |
| 1421 Stream s = m.Build(); |
| 1422 ASSERT_EQ(1U, s.size()); |
| 1423 EXPECT_EQ(kArmLdrb, s[0]->arch_opcode()); |
| 1424 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1425 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1426 } |
| 1427 } |
| 1428 } |
| 1429 |
| 1430 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithWord32And0xffff) { |
| 1431 const MemoryAccess mem = GetParam(); |
| 1432 MachineRepresentation load_rep = mem.type.representation(); |
| 1433 if (!(mem.type == MachineType::Float32() || |
| 1434 mem.type == MachineType::Float64())) { |
| 1435 { |
| 1436 StreamBuilder m(this, mem.type, MachineType::Pointer(), |
| 1437 MachineType::Int32()); |
| 1438 m.Return(m.Word32And(m.Int32Constant(0xffff), |
| 1439 m.Load(mem.type, m.Parameter(0), m.Parameter(1)))); |
| 1440 Stream s = m.Build(); |
| 1441 ASSERT_EQ(1U, s.size()); |
| 1442 EXPECT_EQ( |
| 1443 (load_rep == MachineRepresentation::kWord8) ? kArmLdrb : kArmLdrh, |
| 1444 s[0]->arch_opcode()); |
| 1445 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1446 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1447 } |
| 1448 { |
| 1449 StreamBuilder m(this, mem.type, MachineType::Pointer(), |
| 1450 MachineType::Int32()); |
| 1451 m.Return(m.Word32And(m.Load(mem.type, m.Parameter(0), m.Parameter(1)), |
| 1452 m.Int32Constant(0xffff))); |
| 1453 Stream s = m.Build(); |
| 1454 ASSERT_EQ(1U, s.size()); |
| 1455 EXPECT_EQ( |
| 1456 (load_rep == MachineRepresentation::kWord8) ? kArmLdrb : kArmLdrh, |
| 1457 s[0]->arch_opcode()); |
| 1458 EXPECT_EQ(2U, s[0]->InputCount()); |
| 1459 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1460 } |
| 1461 } |
| 1462 } |
1401 | 1463 |
1402 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 1464 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
1403 InstructionSelectorMemoryAccessTest, | 1465 InstructionSelectorMemoryAccessTest, |
1404 ::testing::ValuesIn(kMemoryAccesses)); | 1466 ::testing::ValuesIn(kMemoryAccesses)); |
1405 | 1467 |
1406 | 1468 |
1407 // ----------------------------------------------------------------------------- | 1469 // ----------------------------------------------------------------------------- |
1408 // Conversions. | 1470 // Conversions. |
1409 | 1471 |
1410 | 1472 |
(...skipping 1521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2932 m.Word32Shr(p0, m.Int32Constant(shr * 8))); | 2994 m.Word32Shr(p0, m.Int32Constant(shr * 8))); |
2933 m.Return(r); | 2995 m.Return(r); |
2934 Stream s = m.Build(); | 2996 Stream s = m.Build(); |
2935 ASSERT_EQ(1U, s.size()); | 2997 ASSERT_EQ(1U, s.size()); |
2936 EXPECT_EQ(kArmUxth, s[0]->arch_opcode()); | 2998 EXPECT_EQ(kArmUxth, s[0]->arch_opcode()); |
2937 ASSERT_EQ(2U, s[0]->InputCount()); | 2999 ASSERT_EQ(2U, s[0]->InputCount()); |
2938 EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1))); | 3000 EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1))); |
2939 } | 3001 } |
2940 } | 3002 } |
2941 | 3003 |
| 3004 TEST_F(InstructionSelectorTest, LoadWordWithWord32And) { |
| 3005 TRACED_FORRANGE(int32_t, shift, 0, 15) { |
| 3006 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 3007 MachineType::Int32()); |
| 3008 uint32_t mask = 0x12340000 | (1 << shift); |
| 3009 Node* const r = m.Word32And( |
| 3010 m.Load(MachineType::Uint16(), m.Parameter(0), m.Parameter(1)), |
| 3011 m.Int32Constant(mask)); |
| 3012 m.Return(r); |
| 3013 Stream s = m.Build(); |
| 3014 ASSERT_EQ(2U, s.size()); |
| 3015 EXPECT_EQ(kArmLdrh, s[0]->arch_opcode()); |
| 3016 EXPECT_EQ(kArmAnd, s[1]->arch_opcode()); |
| 3017 ASSERT_EQ(2U, s[1]->InputCount()); |
| 3018 EXPECT_EQ(mask & 0xffff, s.ToInt32(s[1]->InputAt(1))); |
| 3019 } |
| 3020 TRACED_FORRANGE(int32_t, shift, 0, 15) { |
| 3021 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 3022 MachineType::Int32()); |
| 3023 uint32_t mask = 0x12340000 | (1 << shift); |
| 3024 Node* const r = m.Word32And( |
| 3025 m.Int32Constant(mask), |
| 3026 m.Load(MachineType::Uint16(), m.Parameter(0), m.Parameter(1))); |
| 3027 m.Return(r); |
| 3028 Stream s = m.Build(); |
| 3029 ASSERT_EQ(2U, s.size()); |
| 3030 EXPECT_EQ(kArmLdrh, s[0]->arch_opcode()); |
| 3031 EXPECT_EQ(kArmAnd, s[1]->arch_opcode()); |
| 3032 ASSERT_EQ(2U, s[1]->InputCount()); |
| 3033 EXPECT_EQ(mask & 0xffff, s.ToInt32(s[1]->InputAt(1))); |
| 3034 } |
| 3035 TRACED_FORRANGE(int32_t, shift, 0, 7) { |
| 3036 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 3037 MachineType::Int32()); |
| 3038 uint32_t mask = 0x12345600 | (1 << shift); |
| 3039 Node* const r = m.Word32And( |
| 3040 m.Int32Constant(mask), |
| 3041 m.Load(MachineType::Uint8(), m.Parameter(0), m.Parameter(1))); |
| 3042 m.Return(r); |
| 3043 Stream s = m.Build(); |
| 3044 ASSERT_EQ(2U, s.size()); |
| 3045 EXPECT_EQ(kArmLdrb, s[0]->arch_opcode()); |
| 3046 EXPECT_EQ(kArmAnd, s[1]->arch_opcode()); |
| 3047 ASSERT_EQ(2U, s[1]->InputCount()); |
| 3048 EXPECT_EQ(mask & 0xff, s.ToInt32(s[1]->InputAt(1))); |
| 3049 } |
| 3050 } |
| 3051 |
| 3052 TEST_F(InstructionSelectorTest, LoadWord16WithWord32Bic) { |
| 3053 TRACED_FORRANGE(int32_t, shift, 0, 15) { |
| 3054 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 3055 MachineType::Int32()); |
| 3056 uint32_t mask = 0x12340000 | (0xffff & ~(1 << shift)); |
| 3057 Node* const r = m.Word32And( |
| 3058 m.Load(MachineType::Uint16(), m.Parameter(0), m.Parameter(1)), |
| 3059 m.Int32Constant(mask)); |
| 3060 m.Return(r); |
| 3061 Stream s = m.Build(); |
| 3062 ASSERT_EQ(2U, s.size()); |
| 3063 EXPECT_EQ(kArmLdrh, s[0]->arch_opcode()); |
| 3064 EXPECT_EQ(kArmBic, s[1]->arch_opcode()); |
| 3065 ASSERT_EQ(2U, s[1]->InputCount()); |
| 3066 EXPECT_EQ(~mask & 0xffff, s.ToInt32(s[1]->InputAt(1))); |
| 3067 } |
| 3068 TRACED_FORRANGE(int32_t, shift, 0, 15) { |
| 3069 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 3070 MachineType::Int32()); |
| 3071 uint32_t mask = 0x12340000 | (0xffff & ~(1 << shift)); |
| 3072 Node* const r = m.Word32And( |
| 3073 m.Int32Constant(mask), |
| 3074 m.Load(MachineType::Uint16(), m.Parameter(0), m.Parameter(1))); |
| 3075 m.Return(r); |
| 3076 Stream s = m.Build(); |
| 3077 ASSERT_EQ(2U, s.size()); |
| 3078 EXPECT_EQ(kArmLdrh, s[0]->arch_opcode()); |
| 3079 EXPECT_EQ(kArmBic, s[1]->arch_opcode()); |
| 3080 ASSERT_EQ(2U, s[1]->InputCount()); |
| 3081 EXPECT_EQ(~mask & 0xffff, s.ToInt32(s[1]->InputAt(1))); |
| 3082 } |
| 3083 } |
| 3084 |
| 3085 TEST_F(InstructionSelectorTest, StoreWord16WithWord32And) { |
| 3086 TRACED_FORRANGE(int32_t, shift, 0, 15) { |
| 3087 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 3088 MachineType::Int32()); |
| 3089 uint32_t mask = 0x12340000 | (1 << shift); |
| 3090 Node* const r = m.Store(MachineRepresentation::kWord16, m.Parameter(0), |
| 3091 m.Word32And(m.Parameter(1), m.Int32Constant(mask)), |
| 3092 kNoWriteBarrier); |
| 3093 m.Return(r); |
| 3094 Stream s = m.Build(); |
| 3095 ASSERT_EQ(2U, s.size()); |
| 3096 EXPECT_EQ(kArmAnd, s[0]->arch_opcode()); |
| 3097 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3098 EXPECT_EQ(mask & 0xffff, s.ToInt32(s[0]->InputAt(1))); |
| 3099 EXPECT_EQ(kArmStrh, s[1]->arch_opcode()); |
| 3100 } |
| 3101 TRACED_FORRANGE(int32_t, shift, 0, 15) { |
| 3102 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 3103 MachineType::Int32()); |
| 3104 uint32_t mask = 0x12340000 | (1 << shift); |
| 3105 Node* const r = m.Store(MachineRepresentation::kWord16, m.Parameter(0), |
| 3106 m.Word32And(m.Int32Constant(mask), m.Parameter(1)), |
| 3107 kNoWriteBarrier); |
| 3108 m.Return(r); |
| 3109 Stream s = m.Build(); |
| 3110 ASSERT_EQ(2U, s.size()); |
| 3111 EXPECT_EQ(kArmAnd, s[0]->arch_opcode()); |
| 3112 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3113 EXPECT_EQ(mask & 0xffff, s.ToInt32(s[0]->InputAt(1))); |
| 3114 EXPECT_EQ(kArmStrh, s[1]->arch_opcode()); |
| 3115 } |
| 3116 } |
| 3117 |
| 3118 TEST_F(InstructionSelectorTest, StoreWord16WithWord32Bic) { |
| 3119 TRACED_FORRANGE(int32_t, shift, 0, 15) { |
| 3120 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 3121 MachineType::Int32()); |
| 3122 uint32_t mask = 0x12340000 | (0xffff & ~(1 << shift)); |
| 3123 Node* const r = m.Store(MachineRepresentation::kWord16, m.Parameter(0), |
| 3124 m.Word32And(m.Parameter(1), m.Int32Constant(mask)), |
| 3125 kNoWriteBarrier); |
| 3126 m.Return(r); |
| 3127 Stream s = m.Build(); |
| 3128 ASSERT_EQ(2U, s.size()); |
| 3129 EXPECT_EQ(kArmBic, s[0]->arch_opcode()); |
| 3130 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3131 EXPECT_EQ(~mask & 0xffff, s.ToInt32(s[0]->InputAt(1))); |
| 3132 EXPECT_EQ(kArmStrh, s[1]->arch_opcode()); |
| 3133 } |
| 3134 TRACED_FORRANGE(int32_t, shift, 0, 15) { |
| 3135 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 3136 MachineType::Int32()); |
| 3137 uint32_t mask = 0x12340000 | (0xffff & ~(1 << shift)); |
| 3138 Node* const r = m.Store(MachineRepresentation::kWord16, m.Parameter(0), |
| 3139 m.Word32And(m.Int32Constant(mask), m.Parameter(1)), |
| 3140 kNoWriteBarrier); |
| 3141 m.Return(r); |
| 3142 Stream s = m.Build(); |
| 3143 ASSERT_EQ(2U, s.size()); |
| 3144 EXPECT_EQ(kArmBic, s[0]->arch_opcode()); |
| 3145 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3146 EXPECT_EQ(~mask & 0xffff, s.ToInt32(s[0]->InputAt(1))); |
| 3147 EXPECT_EQ(kArmStrh, s[1]->arch_opcode()); |
| 3148 } |
| 3149 } |
2942 | 3150 |
2943 TEST_F(InstructionSelectorTest, Word32Clz) { | 3151 TEST_F(InstructionSelectorTest, Word32Clz) { |
2944 StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32()); | 3152 StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32()); |
2945 Node* const p0 = m.Parameter(0); | 3153 Node* const p0 = m.Parameter(0); |
2946 Node* const n = m.Word32Clz(p0); | 3154 Node* const n = m.Word32Clz(p0); |
2947 m.Return(n); | 3155 m.Return(n); |
2948 Stream s = m.Build(); | 3156 Stream s = m.Build(); |
2949 ASSERT_EQ(1U, s.size()); | 3157 ASSERT_EQ(1U, s.size()); |
2950 EXPECT_EQ(kArmClz, s[0]->arch_opcode()); | 3158 EXPECT_EQ(kArmClz, s[0]->arch_opcode()); |
2951 ASSERT_EQ(1U, s[0]->InputCount()); | 3159 ASSERT_EQ(1U, s[0]->InputCount()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3022 ASSERT_EQ(2U, s[0]->InputCount()); | 3230 ASSERT_EQ(2U, s[0]->InputCount()); |
3023 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3231 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
3024 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 3232 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
3025 ASSERT_EQ(1U, s[0]->OutputCount()); | 3233 ASSERT_EQ(1U, s[0]->OutputCount()); |
3026 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3234 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
3027 } | 3235 } |
3028 | 3236 |
3029 } // namespace compiler | 3237 } // namespace compiler |
3030 } // namespace internal | 3238 } // namespace internal |
3031 } // namespace v8 | 3239 } // namespace v8 |
OLD | NEW |