1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <list>
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/instruction-selector-unittest.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef RawMachineAssembler::Label MLabel;
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T>
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct MachInst {
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  T constructor;
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* constructor_name;
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ArchOpcode arch_opcode;
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MachineType machine_type;
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1;
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2;
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T>
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstd::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) {
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os << mi.constructor_name;
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper to build Int32Constant or Int64Constant depending on the given
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// machine type.
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type,
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    int64_t value) {
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (type) {
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMachInt32:
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return m.Int32Constant(value);
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMachInt64:
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return m.Int64Constant(value);
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNIMPLEMENTED();
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 logical instructions.
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const MachInst2 kLogicalInstructions[] = {
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32},
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64},
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32},
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64},
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32, kMachInt32},
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor, kMachInt64}};
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 logical immediates: contiguous set bits, rotated about a power of two
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// sized block. The block is then duplicated across the word. Below is a random
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// subset of the 32-bit immediates.
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const uint32_t kLogicalImmediates[] = {
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0,
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000,
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000,
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000,
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x01800000, 0x01800180, 0x01f801f8, 0x03fe0000, 0x03ffffc0, 0x03fffffc,
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x06000000, 0x07fc0000, 0x07ffc000, 0x07ffffc0, 0x07ffffe0, 0x0ffe0ffe,
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x0ffff800, 0x0ffffff0, 0x0fffffff, 0x18001800, 0x1f001f00, 0x1f801f80,
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x30303030, 0x3ff03ff0, 0x3ff83ff8, 0x3fff0000, 0x3fff8000, 0x3fffffc0,
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x70007000, 0x7f7f7f7f, 0x7fc00000, 0x7fffffc0, 0x8000001f, 0x800001ff,
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0x81818181, 0x9fff9fff, 0xc00007ff, 0xc0ffffff, 0xdddddddd, 0xe00001ff,
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff,
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff,
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000,
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf,
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff,
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff,
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff};
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 arithmetic instructions.
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const MachInst2 kAddSubInstructions[] = {
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32},
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64},
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32},
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}};
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12.
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Below is a combination of a random subset and some edge values.
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int32_t kAddSubImmediates[] = {
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0,        1,        69,       493,      599,      701,      719,
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    768,      818,      842,      945,      1246,     1286,     1429,
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    1669,     2171,     2179,     2182,     2254,     2334,     2338,
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    2343,     2396,     2449,     2610,     2732,     2855,     2876,
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    2944,     3377,     3458,     3475,     3476,     3540,     3574,
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    3601,     3813,     3871,     3917,     4095,     4096,     16384,
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    364544,   462848,   970752,   1523712,  1863680,  2363392,  3219456,
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    3280896,  4247552,  4526080,  4575232,  4960256,  5505024,  5894144,
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    6004736,  6193152,  6385664,  6795264,  7114752,  7233536,  7348224,
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    7499776,  7573504,  7729152,  8634368,  8937472,  9465856,  10354688,
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224,
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    15597568, 15892480, 16773120};
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 flag setting data processing instructions.
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const MachInst2 kDPFlagSetInstructions[] = {
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word32And, "Word32And", kArm64Tst32, kMachInt32},
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Cmn32, kMachInt32},
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32, kMachInt32}};
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 arithmetic with overflow instructions.
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const MachInst2 kOvfAddSubInstructions[] = {
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow",
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kArm64Add32, kMachInt32},
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow",
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kArm64Sub32, kMachInt32}};
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 shift instructions.
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const MachInst2 kShiftInstructions[] = {
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Shl32, kMachInt32},
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Shl, kMachInt64},
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Shr32, kMachInt32},
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Shr, kMachInt64},
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Sar32, kMachInt32},
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Sar, kMachInt64},
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32},
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}};
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 Mul/Div instructions.
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const MachInst2 kMulDivInstructions[] = {
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32},
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64},
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32},
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64},
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int32UDiv, "Int32UDiv", kArm64Udiv32, kMachInt32},
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Int64UDiv, "Int64UDiv", kArm64Udiv, kMachInt64}};
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 FP arithmetic instructions.
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const MachInst2 kFPArithInstructions[] = {
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add,
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachFloat64},
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub,
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachFloat64},
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Float64Mul, "Float64Mul", kArm64Float64Mul,
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachFloat64},
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Float64Div, "Float64Div", kArm64Float64Div,
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachFloat64}};
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct FPCmp {
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MachInst2 mi;
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FlagsCondition cond;
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstd::ostream& operator<<(std::ostream& os, const FPCmp& cmp) {
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os << cmp.mi;
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 FP comparison instructions.
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const FPCmp kFPCmpInstructions[] = {
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp,
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kMachFloat64},
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kUnorderedEqual},
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::Float64LessThan, "Float64LessThan",
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kArm64Float64Cmp, kMachFloat64},
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kUnorderedLessThan},
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kArm64Float64Cmp, kMachFloat64},
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kUnorderedLessThanOrEqual}};
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct Conversion {
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The machine_type field in MachInst1 represents the destination type.
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MachInst1 mi;
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MachineType src_machine_type;
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstd::ostream& operator<<(std::ostream& os, const Conversion& conv) {
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os << conv.mi;
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ARM64 type conversion instructions.
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const Conversion kConversionInstructions[] = {
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::ChangeInt32ToInt64, "ChangeInt32ToInt64",
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kArm64Sxtw, kMachInt64},
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachInt32},
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::ChangeUint32ToUint64, "ChangeUint32ToUint64",
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kArm64Mov32, kMachUint64},
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachUint32},
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::TruncateInt64ToInt32, "TruncateInt64ToInt32",
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kArm64Mov32, kMachInt32},
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachInt64},
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64",
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kArm64Int32ToFloat64, kMachFloat64},
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachInt32},
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64",
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kArm64Uint32ToFloat64, kMachFloat64},
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachUint32},
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32",
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kArm64Float64ToInt32, kMachInt32},
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachFloat64},
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32",
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kArm64Float64ToUint32, kMachUint32},
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     kMachFloat64}};
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Logical instructions.
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<MachInst2>
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorLogicalTest;
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorLogicalTest, Parameter) {
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorLogicalTest, Immediate) {
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(all): Add support for testing 64-bit immediates.
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == kMachInt32) {
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Immediate on the right.
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TRACED_FOREACH(int32_t, imm, kLogicalImmediates) {
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      StreamBuilder m(this, type, type);
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Stream s = m.Build();
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSERT_EQ(1U, s.size());
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSERT_EQ(2U, s[0]->InputCount());
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_EQ(1U, s[0]->OutputCount());
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Immediate on the left; all logical ops should commute.
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TRACED_FOREACH(int32_t, imm, kLogicalImmediates) {
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      StreamBuilder m(this, type, type);
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Stream s = m.Build();
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSERT_EQ(1U, s.size());
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSERT_EQ(2U, s[0]->InputCount());
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_EQ(1U, s[0]->OutputCount());
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest,
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kLogicalInstructions));
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Add and Sub instructions.
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<MachInst2>
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorAddSubTest;
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorAddSubTest, Parameter) {
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) {
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, type, type);
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return((m.*dpi.constructor)(m.Parameter(0), BuildConstant(m, type, imm)));
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorAddSubTest, ImmediateOnLeft) {
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, type, type);
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return((m.*dpi.constructor)(BuildConstant(m, type, imm), m.Parameter(0)));
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Add can support an immediate on the left by commuting, but Sub can't
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // commute. We test zero-on-left Sub later.
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (strstr(dpi.constructor_name, "Add") != NULL) {
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSERT_EQ(1U, s.size());
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSERT_EQ(2U, s[0]->InputCount());
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXPECT_EQ(1U, s[0]->OutputCount());
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest,
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kAddSubInstructions));
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, SubZeroOnLeft) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Subtraction with zero on the left maps to Neg.
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // 32-bit subtract.
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0)));
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Neg32, s[0]->arch_opcode());
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->InputCount());
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // 64-bit subtract.
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int64Sub(m.Int64Constant(0), m.Parameter(0)));
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Neg, s[0]->arch_opcode());
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->InputCount());
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Data processing controlled branches.
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<MachInst2>
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorDPFlagSetTest;
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorDPFlagSetTest, BranchWithParameters) {
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MLabel a, b;
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Bind(&a);
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return(m.Int32Constant(1));
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Bind(&b);
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return(m.Int32Constant(0));
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kNotEqual, s[0]->flags_condition());
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        InstructionSelectorDPFlagSetTest,
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kDPFlagSetInstructions));
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, AndBranchWithImmediateOnRight) {
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kLogicalImmediates) {
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MLabel a, b;
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&a);
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(1));
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&b);
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(0));
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, AddBranchWithImmediateOnRight) {
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MLabel a, b;
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Branch(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&a);
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(1));
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&b);
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(0));
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, SubBranchWithImmediateOnRight) {
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MLabel a, b;
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Branch(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&a);
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(1));
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&b);
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(0));
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, AndBranchWithImmediateOnLeft) {
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kLogicalImmediates) {
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MLabel a, b;
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b);
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&a);
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(1));
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&b);
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(0));
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_LE(1U, s[0]->InputCount());
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, AddBranchWithImmediateOnLeft) {
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MLabel a, b;
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Branch(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)), &a, &b);
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&a);
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(1));
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&b);
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(0));
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_LE(1U, s[0]->InputCount());
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Add and subtract instructions with overflow.
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<MachInst2>
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorOvfAddSubTest;
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorOvfAddSubTest, OvfParameter) {
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return(
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      m.Projection(1, (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))));
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_LE(1U, s[0]->OutputCount());
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kOverflow, s[0]->flags_condition());
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorOvfAddSubTest, OvfImmediateOnRight) {
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, type, type);
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Projection(
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        1, (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_LE(1U, s[0]->OutputCount());
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kOverflow, s[0]->flags_condition());
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorOvfAddSubTest, ValParameter) {
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return(
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      m.Projection(0, (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))));
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_LE(1U, s[0]->OutputCount());
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorOvfAddSubTest, ValImmediateOnRight) {
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, type, type);
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Projection(
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        0, (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_LE(1U, s[0]->OutputCount());
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorOvfAddSubTest, BothParameter) {
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1));
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_LE(1U, s.size());
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->OutputCount());
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kOverflow, s[0]->flags_condition());
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorOvfAddSubTest, BothImmediateOnRight) {
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, type, type);
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_LE(1U, s.size());
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(2U, s[0]->OutputCount());
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kOverflow, s[0]->flags_condition());
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorOvfAddSubTest, BranchWithParameters) {
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MLabel a, b;
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1));
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Branch(m.Projection(1, n), &a, &b);
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Bind(&a);
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return(m.Int32Constant(0));
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Bind(&b);
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return(m.Projection(0, n));
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(4U, s[0]->InputCount());
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kOverflow, s[0]->flags_condition());
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorOvfAddSubTest, BranchWithImmediateOnRight) {
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, type, type);
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MLabel a, b;
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Branch(m.Projection(1, n), &a, &b);
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&a);
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(0));
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&b);
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Projection(0, n));
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(4U, s[0]->InputCount());
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kOverflow, s[0]->flags_condition());
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        InstructionSelectorOvfAddSubTest,
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kOvfAddSubInstructions));
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, OvfFlagAddImmediateOnLeft) {
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Projection(
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        1, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0))));
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(2U, s[0]->InputCount());
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_LE(1U, s[0]->OutputCount());
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kOverflow, s[0]->flags_condition());
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, OvfValAddImmediateOnLeft) {
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Projection(
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        0, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0))));
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_LE(1U, s[0]->OutputCount());
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, OvfBothAddImmediateOnLeft) {
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0));
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_LE(1U, s.size());
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(2U, s[0]->OutputCount());
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kOverflow, s[0]->flags_condition());
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, OvfBranchWithImmediateOnLeft) {
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MLabel a, b;
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0));
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Branch(m.Projection(1, n), &a, &b);
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&a);
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(0));
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Bind(&b);
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Projection(0, n));
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(4U, s[0]->InputCount());
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kOverflow, s[0]->flags_condition());
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shift instructions.
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<MachInst2>
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorShiftTest;
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorShiftTest, Parameter) {
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorShiftTest, Immediate) {
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) {
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, type, type);
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(2U, s[0]->InputCount());
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kShiftInstructions));
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Mul and Div instructions.
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<MachInst2>
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorMulDivTest;
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorMulDivTest, Parameter) {
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 dpi = GetParam();
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = dpi.machine_type;
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest,
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kMulDivInstructions));
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Floating point instructions.
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<MachInst2>
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorFPArithTest;
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorFPArithTest, Parameter) {
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 fpa = GetParam();
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type);
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1)));
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode());
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest,
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kFPArithInstructions));
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest;
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorFPCmpTest, Parameter) {
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const FPCmp cmp = GetParam();
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type);
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(cmp.cond, s[0]->flags_condition());
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest,
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kFPCmpInstructions));
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conversions.
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<Conversion>
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorConversionTest;
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorConversionTest, Parameter) {
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Conversion conv = GetParam();
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type);
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return((m.*conv.mi.constructor)(m.Parameter(0)));
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode());
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->InputCount());
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        InstructionSelectorConversionTest,
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kConversionInstructions));
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Memory access instructions.
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace {
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct MemoryAccess {
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MachineType type;
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ArchOpcode ldr_opcode;
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ArchOpcode str_opcode;
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int32_t immediates[20];
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstd::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OStringStream ost;
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ost << memacc.type;
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os << ost.c_str();
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const MemoryAccess kMemoryAccesses[] = {
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachInt8, kArm64Ldrsb, kArm64Strb,
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001,
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      2121, 2442, 4093, 4094, 4095}},
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachUint8, kArm64Ldrb, kArm64Strb,
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001,
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      2121, 2442, 4093, 4094, 4095}},
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachInt16, kArm64Ldrsh, kArm64Strh,
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098,
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      4100, 4242, 6786, 8188, 8190}},
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachUint16, kArm64Ldrh, kArm64Strh,
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098,
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      4100, 4242, 6786, 8188, 8190}},
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachInt32, kArm64LdrW, kArm64StrW,
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192,
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      8196, 3276, 3280, 16376, 16380}},
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachUint32, kArm64LdrW, kArm64StrW,
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192,
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      8196, 3276, 3280, 16376, 16380}},
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachInt64, kArm64Ldr, kArm64Str,
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192,
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      8200, 16384, 16392, 32752, 32760}},
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachUint64, kArm64Ldr, kArm64Str,
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192,
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      8200, 16384, 16392, 32752, 32760}},
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachFloat32, kArm64LdrS, kArm64StrS,
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192,
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      8196, 3276, 3280, 16376, 16380}},
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {kMachFloat64, kArm64LdrD, kArm64StrD,
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192,
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      8200, 16384, 16392, 32752, 32760}}};
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<MemoryAccess>
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorMemoryAccessTest;
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MemoryAccess memacc = GetParam();
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MemoryAccess memacc = GetParam();
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, index, memacc.immediates) {
944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, memacc.type, kMachPtr);
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(2U, s[0]->InputCount());
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s[0]->OutputCount());
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MemoryAccess memacc = GetParam();
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return(m.Int32Constant(0));
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(3U, s[0]->InputCount());
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(0U, s[0]->OutputCount());
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MemoryAccess memacc = GetParam();
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, index, memacc.immediates) {
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            m.Parameter(1));
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Int32Constant(0));
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(3U, s[0]->InputCount());
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(0U, s[0]->OutputCount());
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        InstructionSelectorMemoryAccessTest,
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kMemoryAccesses));
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Comparison instructions.
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const MachInst2 kComparisonInstructions[] = {
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, kMachInt32},
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {&RawMachineAssembler::Word64Equal, "Word64Equal", kArm64Cmp, kMachInt64},
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef InstructionSelectorTestWithParam<MachInst2>
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionSelectorComparisonTest;
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorComparisonTest, WithParameters) {
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 cmp = GetParam();
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = cmp.machine_type;
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StreamBuilder m(this, type, type, type);
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)));
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Stream s = m.Build();
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_EQ(1U, s.size());
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode());
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(2U, s[0]->InputCount());
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(1U, s[0]->OutputCount());
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(kEqual, s[0]->flags_condition());
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(InstructionSelectorComparisonTest, WithImmediate) {
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachInst2 cmp = GetParam();
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const MachineType type = cmp.machine_type;
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Compare with 0 are turned into tst instruction.
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (imm == 0) continue;
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, type, type);
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return((m.*cmp.constructor)(m.Parameter(0), BuildConstant(m, type, imm)));
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode());
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kEqual, s[0]->flags_condition());
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Compare with 0 are turned into tst instruction.
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (imm == 0) continue;
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, type, type);
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return((m.*cmp.constructor)(m.Parameter(0), BuildConstant(m, type, imm)));
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode());
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kEqual, s[0]->flags_condition());
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        InstructionSelectorComparisonTest,
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kComparisonInstructions));
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, Word32EqualWithZero) {
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kEqual, s[0]->flags_condition());
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt32, kMachInt32);
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kEqual, s[0]->flags_condition());
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(InstructionSelectorTest, Word64EqualWithZero) {
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt64, kMachInt64);
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0)));
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kEqual, s[0]->flags_condition());
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StreamBuilder m(this, kMachInt64, kMachInt64);
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    m.Return(m.Word64Equal(m.Int64Constant(0), m.Parameter(0)));
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Stream s = m.Build();
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(1U, s.size());
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSERT_EQ(2U, s[0]->InputCount());
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1U, s[0]->OutputCount());
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(kEqual, s[0]->flags_condition());
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
1122