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