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
3 // found in the LICENSE file.
4 
5 #include "src/compiler/instruction-selector-unittest.h"
6 
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10 
11 // -----------------------------------------------------------------------------
12 // Conversions.
13 
14 
TEST_F(InstructionSelectorTest,ChangeInt32ToInt64WithParameter)15 TEST_F(InstructionSelectorTest, ChangeInt32ToInt64WithParameter) {
16   StreamBuilder m(this, kMachInt64, kMachInt32);
17   m.Return(m.ChangeInt32ToInt64(m.Parameter(0)));
18   Stream s = m.Build();
19   ASSERT_EQ(1U, s.size());
20   EXPECT_EQ(kX64Movsxlq, s[0]->arch_opcode());
21 }
22 
23 
TEST_F(InstructionSelectorTest,ChangeUint32ToUint64WithParameter)24 TEST_F(InstructionSelectorTest, ChangeUint32ToUint64WithParameter) {
25   StreamBuilder m(this, kMachUint64, kMachUint32);
26   m.Return(m.ChangeUint32ToUint64(m.Parameter(0)));
27   Stream s = m.Build();
28   ASSERT_EQ(1U, s.size());
29   EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
30 }
31 
32 
TEST_F(InstructionSelectorTest,TruncateInt64ToInt32WithParameter)33 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithParameter) {
34   StreamBuilder m(this, kMachInt32, kMachInt64);
35   m.Return(m.TruncateInt64ToInt32(m.Parameter(0)));
36   Stream s = m.Build();
37   ASSERT_EQ(1U, s.size());
38   EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
39 }
40 
41 
42 // -----------------------------------------------------------------------------
43 // Loads and stores
44 
45 namespace {
46 
47 struct MemoryAccess {
48   MachineType type;
49   ArchOpcode load_opcode;
50   ArchOpcode store_opcode;
51 };
52 
53 
operator <<(std::ostream & os,const MemoryAccess & memacc)54 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
55   OStringStream ost;
56   ost << memacc.type;
57   return os << ost.c_str();
58 }
59 
60 
61 static const MemoryAccess kMemoryAccesses[] = {
62     {kMachInt8, kX64Movsxbl, kX64Movb},
63     {kMachUint8, kX64Movzxbl, kX64Movb},
64     {kMachInt16, kX64Movsxwl, kX64Movw},
65     {kMachUint16, kX64Movzxwl, kX64Movw},
66     {kMachInt32, kX64Movl, kX64Movl},
67     {kMachUint32, kX64Movl, kX64Movl},
68     {kMachInt64, kX64Movq, kX64Movq},
69     {kMachUint64, kX64Movq, kX64Movq},
70     {kMachFloat32, kX64Movss, kX64Movss},
71     {kMachFloat64, kX64Movsd, kX64Movsd}};
72 
73 }  // namespace
74 
75 
76 typedef InstructionSelectorTestWithParam<MemoryAccess>
77     InstructionSelectorMemoryAccessTest;
78 
79 
TEST_P(InstructionSelectorMemoryAccessTest,LoadWithParameters)80 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
81   const MemoryAccess memacc = GetParam();
82   StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
83   m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
84   Stream s = m.Build();
85   ASSERT_EQ(1U, s.size());
86   EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
87   EXPECT_EQ(2U, s[0]->InputCount());
88   EXPECT_EQ(1U, s[0]->OutputCount());
89 }
90 
91 
TEST_P(InstructionSelectorMemoryAccessTest,StoreWithParameters)92 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
93   const MemoryAccess memacc = GetParam();
94   StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
95   m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
96   m.Return(m.Int32Constant(0));
97   Stream s = m.Build();
98   ASSERT_EQ(1U, s.size());
99   EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
100   EXPECT_EQ(3U, s[0]->InputCount());
101   EXPECT_EQ(0U, s[0]->OutputCount());
102 }
103 
104 
105 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
106                         InstructionSelectorMemoryAccessTest,
107                         ::testing::ValuesIn(kMemoryAccesses));
108 
109 }  // namespace compiler
110 }  // namespace internal
111 }  // namespace v8
112