17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file. 47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/base/bits.h" 67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/instruction-selector-impl.h" 77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node-matchers.h" 87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 { 107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal { 117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler { 127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Adds Arm-specific methods for generating InstructionOperands. 14ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass ArmOperandGenerator FINAL : public OperandGenerator { 157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit ArmOperandGenerator(InstructionSelector* selector) 177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : OperandGenerator(selector) {} 187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* UseOperand(Node* node, InstructionCode opcode) { 207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (CanBeImmediate(node, opcode)) { 217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return UseImmediate(node); 227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return UseRegister(node); 247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool CanBeImmediate(Node* node, InstructionCode opcode) { 27e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org Int32Matcher m(node); 28e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org if (!m.HasValue()) return false; 29e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org int32_t value = m.Value(); 307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (ArchOpcodeField::decode(opcode)) { 317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmAnd: 327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmMov: 337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmMvn: 347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmBic: 357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return ImmediateFitsAddrMode1Instruction(value) || 367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ImmediateFitsAddrMode1Instruction(~value); 377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmAdd: 397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmSub: 407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmCmp: 417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmCmn: 427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return ImmediateFitsAddrMode1Instruction(value) || 437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ImmediateFitsAddrMode1Instruction(-value); 447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmTst: 467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmTeq: 477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmOrr: 487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmEor: 497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmRsb: 507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return ImmediateFitsAddrMode1Instruction(value); 517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 52fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org case kArmVldr32: 53fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org case kArmVstr32: 546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmVldr64: 556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmVstr64: 567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return value >= -1020 && value <= 1020 && (value % 4) == 0; 577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmLdrb: 596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmLdrsb: 606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmStrb: 616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmLdr: 626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmStr: 637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmStoreWriteBarrier: 647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return value >= -4095 && value <= 4095; 657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmLdrh: 676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmLdrsh: 686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kArmStrh: 697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return value >= -255 && value <= 255; 707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 717b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org case kArchCallCodeObject: 727b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org case kArchCallJSFunction: 737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArchJmp: 747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArchNop: 757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArchRet: 767dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org case kArchTruncateDoubleToI: 777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmMul: 787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmMla: 797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmMls: 807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmSdiv: 817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmUdiv: 827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmBfc: 837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmUbfx: 847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVcmpF64: 857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVaddF64: 867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVsubF64: 877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVmulF64: 887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVmlaF64: 897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVmlsF64: 907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVdivF64: 917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVmodF64: 927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVnegF64: 93b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org case kArmVsqrtF64: 947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVcvtF64S32: 957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVcvtF64U32: 967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVcvtS32F64: 977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kArmVcvtU32F64: 987b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org case kArmPush: 997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return false; 1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return false; 1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool ImmediateFitsAddrMode1Instruction(int32_t imm) const { 1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Assembler::ImmediateFitsAddrMode1Instruction(imm); 1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode, 1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* node) { 1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 115fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org selector->Emit(opcode, g.DefineAsRegister(node), 116fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseRegister(node->InputAt(0)), 117fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseRegister(node->InputAt(1))); 1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic bool TryMatchROR(InstructionSelector* selector, 1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode* opcode_return, Node* node, 1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** value_return, 1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** shift_return) { 1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 1265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (node->opcode() != IrOpcode::kWord32Ror) return false; 1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 1285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org *value_return = g.UseRegister(m.left().node()); 1295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (m.right().IsInRange(1, 31)) { 1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I); 1315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org *shift_return = g.UseImmediate(m.right().node()); 1325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org } else { 1337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_R); 1345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org *shift_return = g.UseRegister(m.right().node()); 1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org return true; 1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic inline bool TryMatchASR(InstructionSelector* selector, 1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode* opcode_return, Node* node, 1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** value_return, 1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** shift_return) { 1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (node->opcode() != IrOpcode::kWord32Sar) return false; 1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *value_return = g.UseRegister(m.left().node()); 1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().IsInRange(1, 32)) { 1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ASR_I); 1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *shift_return = g.UseImmediate(m.right().node()); 1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ASR_R); 1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *shift_return = g.UseRegister(m.right().node()); 1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return true; 1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic inline bool TryMatchLSL(InstructionSelector* selector, 1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode* opcode_return, Node* node, 1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** value_return, 1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** shift_return) { 1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (node->opcode() != IrOpcode::kWord32Shl) return false; 1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *value_return = g.UseRegister(m.left().node()); 1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().IsInRange(0, 31)) { 1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSL_I); 1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *shift_return = g.UseImmediate(m.right().node()); 1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSL_R); 1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *shift_return = g.UseRegister(m.right().node()); 1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return true; 1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic inline bool TryMatchLSR(InstructionSelector* selector, 1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode* opcode_return, Node* node, 1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** value_return, 1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** shift_return) { 1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (node->opcode() != IrOpcode::kWord32Shr) return false; 1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 1857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *value_return = g.UseRegister(m.left().node()); 1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().IsInRange(1, 32)) { 1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_I); 1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *shift_return = g.UseImmediate(m.right().node()); 1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_R); 1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *shift_return = g.UseRegister(m.right().node()); 1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return true; 1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 197aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgstatic inline bool TryMatchShift(InstructionSelector* selector, 198aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org InstructionCode* opcode_return, Node* node, 199aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org InstructionOperand** value_return, 200aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org InstructionOperand** shift_return) { 201aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org return ( 202aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org TryMatchASR(selector, opcode_return, node, value_return, shift_return) || 203aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org TryMatchLSL(selector, opcode_return, node, value_return, shift_return) || 204aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org TryMatchLSR(selector, opcode_return, node, value_return, shift_return) || 205aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org TryMatchROR(selector, opcode_return, node, value_return, shift_return)); 206aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org} 207aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org 208aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org 2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic inline bool TryMatchImmediateOrShift(InstructionSelector* selector, 2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode* opcode_return, 2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* node, 2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org size_t* input_count_return, 2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** inputs) { 2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (g.CanBeImmediate(node, *opcode_return)) { 2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *opcode_return |= AddressingModeField::encode(kMode_Operand2_I); 2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inputs[0] = g.UseImmediate(node); 2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *input_count_return = 1; 2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return true; 2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 221aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org if (TryMatchShift(selector, opcode_return, node, &inputs[0], &inputs[1])) { 2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *input_count_return = 2; 2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return true; 2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return false; 2267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitBinop(InstructionSelector* selector, Node* node, 230e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org InstructionCode opcode, InstructionCode reverse_opcode, 231e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org FlagsContinuation* cont) { 232aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org ArmOperandGenerator g(selector); 233aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org Int32BinopMatcher m(node); 234e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org InstructionOperand* inputs[5]; 235aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org size_t input_count = 0; 236aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org InstructionOperand* outputs[2]; 237aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org size_t output_count = 0; 238aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org 239aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(), 240aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org &input_count, &inputs[1])) { 241aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org inputs[0] = g.UseRegister(m.left().node()); 242aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org input_count++; 243aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org } else if (TryMatchImmediateOrShift(selector, &reverse_opcode, 244aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org m.left().node(), &input_count, 245aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org &inputs[1])) { 246aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org inputs[0] = g.UseRegister(m.right().node()); 247aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org opcode = reverse_opcode; 248aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org input_count++; 249aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org } else { 250aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org opcode |= AddressingModeField::encode(kMode_Operand2_R); 251aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org inputs[input_count++] = g.UseRegister(m.left().node()); 252aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org inputs[input_count++] = g.UseRegister(m.right().node()); 253aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org } 254aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org 255e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (cont->IsBranch()) { 256e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org inputs[input_count++] = g.Label(cont->true_block()); 257e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org inputs[input_count++] = g.Label(cont->false_block()); 258aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org } 259e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 260e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org outputs[output_count++] = g.DefineAsRegister(node); 261e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (cont->IsSet()) { 262e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org outputs[output_count++] = g.DefineAsRegister(cont->result()); 263aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org } 264aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org 265e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NE(0, input_count); 266e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NE(0, output_count); 267fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org DCHECK_GE(arraysize(inputs), input_count); 268fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org DCHECK_GE(arraysize(outputs), output_count); 269e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); 270aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org 271e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, 272e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org outputs, input_count, inputs); 273e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (cont->IsBranch()) instr->MarkAsControl(); 274e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org} 275e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 276e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 277e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgstatic void VisitBinop(InstructionSelector* selector, Node* node, 278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org InstructionCode opcode, InstructionCode reverse_opcode) { 279e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org FlagsContinuation cont; 280e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org VisitBinop(selector, node, opcode, reverse_opcode, &cont); 2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitLoad(Node* node) { 2856313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); 2866313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); 2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 2887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* base = node->InputAt(0); 2897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* index = node->InputAt(1); 2907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArchOpcode opcode; 2927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (rep) { 293fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org case kRepFloat32: 294fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org opcode = kArmVldr32; 295fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org break; 2965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepFloat64: 2976474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org opcode = kArmVldr64; 2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepBit: // Fall through. 3005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepWord8: 3016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb; 3027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepWord16: 3046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh; 3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepTagged: // Fall through. 3075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepWord32: 3086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org opcode = kArmLdr; 3097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org default: 3117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 3127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 3137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (g.CanBeImmediate(index, opcode)) { 316fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), 317fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); 3187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 319fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), 320fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); 3217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 3237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitStore(Node* node) { 3267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 3277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* base = node->InputAt(0); 3287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* index = node->InputAt(1); 3297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* value = node->InputAt(2); 3307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); 3326313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org MachineType rep = RepresentationOf(store_rep.machine_type()); 3336313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org if (store_rep.write_barrier_kind() == kFullWriteBarrier) { 3345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK(rep == kRepTagged); 3357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(dcarney): refactor RecordWrite function to take temp registers 3367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // and pass them here instead of using fixed regs 3377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(dcarney): handle immediate indices. 3387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* temps[] = {g.TempRegister(r5), g.TempRegister(r6)}; 3397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), 340fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps), 3417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org temps); 3427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 3437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3446313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); 3457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArchOpcode opcode; 3477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (rep) { 348fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org case kRepFloat32: 349fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org opcode = kArmVstr32; 350fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org break; 3515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepFloat64: 3526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org opcode = kArmVstr64; 3537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3545e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepBit: // Fall through. 3555e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepWord8: 3566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org opcode = kArmStrb; 3577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepWord16: 3596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org opcode = kArmStrh; 3607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepTagged: // Fall through. 3625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kRepWord32: 3636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org opcode = kArmStr; 3647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org default: 3667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 3677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 3687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (g.CanBeImmediate(index, opcode)) { 3717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL, 372fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); 3737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 3747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL, 375fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); 3767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 3787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic inline void EmitBic(InstructionSelector* selector, Node* node, 3817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* left, Node* right) { 3827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 3837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode opcode = kArmBic; 384aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org InstructionOperand* value_operand; 385aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org InstructionOperand* shift_operand; 386aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org if (TryMatchShift(selector, &opcode, right, &value_operand, &shift_operand)) { 387aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), 388aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org value_operand, shift_operand); 389aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org return; 3907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 391aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org selector->Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), 392aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org g.DefineAsRegister(node), g.UseRegister(left), 393aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org g.UseRegister(right)); 3947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 3957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32And(Node* node) { 3987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 3997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 4007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.left().IsWord32Xor() && CanCover(node, m.left().node())) { 4017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mleft(m.left().node()); 4027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (mleft.right().Is(-1)) { 4037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org EmitBic(this, node, m.right().node(), mleft.left().node()); 4047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 4057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) { 4087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mright(m.right().node()); 4097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (mright.right().Is(-1)) { 4107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org EmitBic(this, node, m.left().node(), mright.left().node()); 4117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 4127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (IsSupported(ARMv7) && m.right().HasValue()) { 4157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org uint32_t value = m.right().Value(); 4166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org uint32_t width = base::bits::CountPopulation32(value); 417e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org uint32_t msb = base::bits::CountLeadingZeros32(value); 4187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (width != 0 && msb + width == 32) { 419e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org DCHECK_EQ(0, base::bits::CountTrailingZeros32(value)); 4207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.left().IsWord32Shr()) { 4217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mleft(m.left().node()); 4227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (mleft.right().IsInRange(0, 31)) { 4237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmUbfx, g.DefineAsRegister(node), 4247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mleft.left().node()), 4257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseImmediate(mleft.right().node()), g.TempImmediate(width)); 4267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 4277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(m.left().node()), 4307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.TempImmediate(0), g.TempImmediate(width)); 4317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 4327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Try to interpret this AND as BFC. 4347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org width = 32 - width; 435e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org msb = base::bits::CountLeadingZeros32(~value); 436e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org uint32_t lsb = base::bits::CountTrailingZeros32(~value); 4377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (msb + width + lsb == 32) { 4387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 4397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.TempImmediate(lsb), g.TempImmediate(width)); 4407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 4417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitBinop(this, node, kArmAnd, kArmAnd); 4447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 4457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Or(Node* node) { 4487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitBinop(this, node, kArmOrr, kArmOrr); 4497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 4507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Xor(Node* node) { 4537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 4547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 4557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().Is(-1)) { 456aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org InstructionCode opcode = kArmMvn; 457aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org InstructionOperand* value_operand; 458aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org InstructionOperand* shift_operand; 459aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org if (TryMatchShift(this, &opcode, m.left().node(), &value_operand, 460aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org &shift_operand)) { 461aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org Emit(opcode, g.DefineAsRegister(node), value_operand, shift_operand); 462aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org return; 463aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org } 464aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), 465aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org g.DefineAsRegister(node), g.UseRegister(m.left().node())); 466aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org return; 4677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 468aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org VisitBinop(this, node, kArmEor, kArmEor); 4697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 4707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <typename TryMatchShift> 4737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic inline void VisitShift(InstructionSelector* selector, Node* node, 4745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org TryMatchShift try_match_shift, 4755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org FlagsContinuation* cont) { 4767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 4777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode opcode = kArmMov; 4785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org InstructionOperand* inputs[4]; 4795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org size_t input_count = 2; 4805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org InstructionOperand* outputs[2]; 4815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org size_t output_count = 0; 4825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 4835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org CHECK(try_match_shift(selector, &opcode, node, &inputs[0], &inputs[1])); 4845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 4855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (cont->IsBranch()) { 4865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org inputs[input_count++] = g.Label(cont->true_block()); 4875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org inputs[input_count++] = g.Label(cont->false_block()); 4885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org } 4895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 4905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org outputs[output_count++] = g.DefineAsRegister(node); 4915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (cont->IsSet()) { 4925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org outputs[output_count++] = g.DefineAsRegister(cont->result()); 4935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org } 4945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 4955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK_NE(0, input_count); 4965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK_NE(0, output_count); 497fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org DCHECK_GE(arraysize(inputs), input_count); 498fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org DCHECK_GE(arraysize(outputs), output_count); 4995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); 5005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 5015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, 5025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org outputs, input_count, inputs); 5035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (cont->IsBranch()) instr->MarkAsControl(); 5045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org} 5055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 5065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 5075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgtemplate <typename TryMatchShift> 5085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgstatic inline void VisitShift(InstructionSelector* selector, Node* node, 5095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org TryMatchShift try_match_shift) { 5105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org FlagsContinuation cont; 5115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org VisitShift(selector, node, try_match_shift, &cont); 5127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 5137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Shl(Node* node) { 5167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitShift(this, node, TryMatchLSL); 5177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 5187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Shr(Node* node) { 5217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 5227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 5233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (IsSupported(ARMv7) && m.left().IsWord32And() && 5247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org m.right().IsInRange(0, 31)) { 5257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int32_t lsb = m.right().Value(); 5267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mleft(m.left().node()); 5277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (mleft.right().HasValue()) { 5287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org uint32_t value = (mleft.right().Value() >> lsb) << lsb; 5296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org uint32_t width = base::bits::CountPopulation32(value); 530e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org uint32_t msb = base::bits::CountLeadingZeros32(value); 5317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (msb + width + lsb == 32) { 532e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(value)); 5337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmUbfx, g.DefineAsRegister(node), 5347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), 5357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.TempImmediate(width)); 5367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 5377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitShift(this, node, TryMatchLSR); 5417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 5427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Sar(Node* node) { 5457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitShift(this, node, TryMatchASR); 5467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 5477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitWord32Ror(Node* node) { 5505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org VisitShift(this, node, TryMatchROR); 5515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org} 5525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 5535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 5547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32Add(Node* node) { 5557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 5567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 5577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.left().IsInt32Mul() && CanCover(node, m.left().node())) { 5587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mleft(m.left().node()); 5597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmMla, g.DefineAsRegister(node), g.UseRegister(mleft.left().node()), 5607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node())); 5617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 5627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) { 5647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mright(m.right().node()); 5657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmMla, g.DefineAsRegister(node), g.UseRegister(mright.left().node()), 5667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); 5677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 5687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitBinop(this, node, kArmAdd, kArmAdd); 5707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 5717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32Sub(Node* node) { 5747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 5757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 5763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (IsSupported(MLS) && m.right().IsInt32Mul() && 5777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CanCover(node, m.right().node())) { 5787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mright(m.right().node()); 5797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmMls, g.DefineAsRegister(node), g.UseRegister(mright.left().node()), 5807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); 5817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 5827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitBinop(this, node, kArmSub, kArmRsb); 5847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 5857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32Mul(Node* node) { 5887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 5897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 5907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().HasValue() && m.right().Value() > 0) { 5917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int32_t value = m.right().Value(); 59221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (base::bits::IsPowerOfTwo32(value - 1)) { 5937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmAdd | AddressingModeField::encode(kMode_Operand2_R_LSL_I), 5947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.DefineAsRegister(node), g.UseRegister(m.left().node()), 5957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(m.left().node()), 5967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.TempImmediate(WhichPowerOf2(value - 1))); 5977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 5987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 59921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (value < kMaxInt && base::bits::IsPowerOfTwo32(value + 1)) { 6007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmRsb | AddressingModeField::encode(kMode_Operand2_R_LSL_I), 6017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.DefineAsRegister(node), g.UseRegister(m.left().node()), 6027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(m.left().node()), 6037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.TempImmediate(WhichPowerOf2(value + 1))); 6047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 6057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmMul, g.DefineAsRegister(node), g.UseRegister(m.left().node()), 6087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(m.right().node())); 6097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void EmitDiv(InstructionSelector* selector, ArchOpcode div_opcode, 6137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode, 6147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* result_operand, 6157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* left_operand, 6167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* right_operand) { 6177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 6183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (selector->IsSupported(SUDIV)) { 6197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org selector->Emit(div_opcode, result_operand, left_operand, right_operand); 6207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 6217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* left_double_operand = g.TempDoubleRegister(); 6237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* right_double_operand = g.TempDoubleRegister(); 6247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* result_double_operand = g.TempDoubleRegister(); 6257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org selector->Emit(f64i32_opcode, left_double_operand, left_operand); 6267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org selector->Emit(f64i32_opcode, right_double_operand, right_operand); 6277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org selector->Emit(kArmVdivF64, result_double_operand, left_double_operand, 6287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org right_double_operand); 6297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org selector->Emit(i32f64_opcode, result_operand, result_double_operand); 6307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitDiv(InstructionSelector* selector, Node* node, 6347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArchOpcode div_opcode, ArchOpcode f64i32_opcode, 6357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArchOpcode i32f64_opcode) { 6367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 6377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 6387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, 6397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.DefineAsRegister(node), g.UseRegister(m.left().node()), 6407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(m.right().node())); 6417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32Div(Node* node) { 6457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitDiv(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64); 6467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32UDiv(Node* node) { 6507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitDiv(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64); 6517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitMod(InstructionSelector* selector, Node* node, 6557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArchOpcode div_opcode, ArchOpcode f64i32_opcode, 6567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArchOpcode i32f64_opcode) { 6577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 6587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 6597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* div_operand = g.TempRegister(); 6607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* result_operand = g.DefineAsRegister(node); 6617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* left_operand = g.UseRegister(m.left().node()); 6627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* right_operand = g.UseRegister(m.right().node()); 6637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, div_operand, 6647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org left_operand, right_operand); 6653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (selector->IsSupported(MLS)) { 6667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org selector->Emit(kArmMls, result_operand, div_operand, right_operand, 6677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org left_operand); 6687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 6697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* mul_operand = g.TempRegister(); 6717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org selector->Emit(kArmMul, mul_operand, div_operand, right_operand); 6727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org selector->Emit(kArmSub, result_operand, left_operand, mul_operand); 6737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32Mod(Node* node) { 6777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitMod(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64); 6787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32UMod(Node* node) { 6827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitMod(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64); 6837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 686aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { 6877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 688fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Emit(kArmVcvtF64S32, g.DefineAsRegister(node), 6897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(node->InputAt(0))); 6907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 693aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { 6947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 695fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Emit(kArmVcvtF64U32, g.DefineAsRegister(node), 6967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(node->InputAt(0))); 6977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 6987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 700aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { 7017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 7027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmVcvtS32F64, g.DefineAsRegister(node), 703fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseRegister(node->InputAt(0))); 7047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 7057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 707aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { 7087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 7097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmVcvtU32F64, g.DefineAsRegister(node), 710fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseRegister(node->InputAt(0))); 7117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 7127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Add(Node* node) { 7157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 7167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 7177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { 7187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mleft(m.left().node()); 7197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmVmlaF64, g.DefineSameAsFirst(node), 7207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), 7217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mleft.right().node())); 7227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 7237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) { 7257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mright(m.right().node()); 7267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmVmlaF64, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 7277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mright.left().node()), 7287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mright.right().node())); 7297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 7307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitRRRFloat64(this, kArmVaddF64, node); 7327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 7337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Sub(Node* node) { 7367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 7377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 7387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) { 7397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher mright(m.right().node()); 7407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(kArmVmlsF64, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 7417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mright.left().node()), 7427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(mright.right().node())); 7437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 7447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitRRRFloat64(this, kArmVsubF64, node); 7467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 7477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Mul(Node* node) { 7507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 7517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Float64BinopMatcher m(node); 7527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (m.right().Is(-1.0)) { 753fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Emit(kArmVnegF64, g.DefineAsRegister(node), g.UseRegister(m.left().node())); 7547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 7557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitRRRFloat64(this, kArmVmulF64, node); 7567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 7587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Div(Node* node) { 7617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VisitRRRFloat64(this, kArmVdivF64, node); 7627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 7637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Mod(Node* node) { 7667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 767fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Emit(kArmVmodF64, g.DefineAsFixed(node, d0), g.UseFixed(node->InputAt(0), d0), 768fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseFixed(node->InputAt(1), d1))->MarkAsCall(); 7697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 7707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 772b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Sqrt(Node* node) { 773b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org ArmOperandGenerator g(this); 774b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org Emit(kArmVsqrtF64, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); 775b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org} 776b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org 777b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org 7787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, 7797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BasicBlock* deoptimization) { 7807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 7817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call); 782a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 783a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org FrameStateDescriptor* frame_state_descriptor = NULL; 784a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (descriptor->NeedsFrameState()) { 785a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org frame_state_descriptor = 786a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org GetFrameStateDescriptor(call->InputAt(descriptor->InputCount())); 787a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 788a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 789a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org CallBuffer buffer(zone(), descriptor, frame_state_descriptor); 7907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Compute InstructionOperands for inputs and outputs. 7927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(turbofan): on ARM64 it's probably better to use the code object in a 7937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // register if there are multiple uses of it. Improve constant pool and the 7947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // heuristics in the register allocator for where to emit constants. 795ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org InitializeCallBuffer(call, &buffer, true, false); 7967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(dcarney): might be possible to use claim/poke instead 7987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Push any stack arguments. 799a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org for (NodeVectorRIter input = buffer.pushed_nodes.rbegin(); 800a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org input != buffer.pushed_nodes.rend(); input++) { 801a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Emit(kArmPush, NULL, g.UseRegister(*input)); 8027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Select the appropriate opcode based on the call type. 8057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode opcode; 8067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (descriptor->kind()) { 8077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case CallDescriptor::kCallCodeObject: { 8087b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org opcode = kArchCallCodeObject; 8097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 8107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case CallDescriptor::kCallJSFunction: 8127b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org opcode = kArchCallJSFunction; 8137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 8147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org default: 8157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 8167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return; 8177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 818d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org opcode |= MiscField::encode(descriptor->flags()); 8197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Emit the call instruction. 8217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Instruction* call_instr = 822a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(), 823a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org buffer.instruction_args.size(), &buffer.instruction_args.front()); 8247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org call_instr->MarkAsCall(); 8267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (deoptimization != NULL) { 827e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(continuation != NULL); 8287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org call_instr->MarkAsControl(); 8297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 8317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 833e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid InstructionSelector::VisitInt32AddWithOverflow(Node* node, 834e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org FlagsContinuation* cont) { 835e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org VisitBinop(this, node, kArmAdd, kArmAdd, cont); 836e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org} 837e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 838e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 839e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid InstructionSelector::VisitInt32SubWithOverflow(Node* node, 840e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org FlagsContinuation* cont) { 841e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org VisitBinop(this, node, kArmSub, kArmRsb, cont); 842e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org} 843e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 844e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 8457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Shared routine for multiple compare operations. 8467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitWordCompare(InstructionSelector* selector, Node* node, 8477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode opcode, FlagsContinuation* cont, 848e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org bool commutative) { 8497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(selector); 8507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Int32BinopMatcher m(node); 8517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* inputs[5]; 8527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org size_t input_count = 0; 8537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* outputs[1]; 8547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org size_t output_count = 0; 8557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(), 8577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org &input_count, &inputs[1])) { 8587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inputs[0] = g.UseRegister(m.left().node()); 8597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org input_count++; 8607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (TryMatchImmediateOrShift(selector, &opcode, m.left().node(), 8617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org &input_count, &inputs[1])) { 8627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (!commutative) cont->Commute(); 8637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inputs[0] = g.UseRegister(m.right().node()); 8647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org input_count++; 8657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 8667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org opcode |= AddressingModeField::encode(kMode_Operand2_R); 8677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inputs[input_count++] = g.UseRegister(m.left().node()); 8687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inputs[input_count++] = g.UseRegister(m.right().node()); 8697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (cont->IsBranch()) { 8727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inputs[input_count++] = g.Label(cont->true_block()); 8737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inputs[input_count++] = g.Label(cont->false_block()); 8747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 875e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cont->IsSet()); 8767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org outputs[output_count++] = g.DefineAsRegister(cont->result()); 8777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 879e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NE(0, input_count); 880fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org DCHECK_GE(arraysize(inputs), input_count); 881fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org DCHECK_GE(arraysize(outputs), output_count); 8827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, 8847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org outputs, input_count, inputs); 8857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (cont->IsBranch()) instr->MarkAsControl(); 8867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 8877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) { 8907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (node->opcode()) { 8917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kInt32Add: 892e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return VisitWordCompare(this, node, kArmCmn, cont, true); 8937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kInt32Sub: 894e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return VisitWordCompare(this, node, kArmCmp, cont, false); 8957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kWord32And: 896e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return VisitWordCompare(this, node, kArmTst, cont, true); 8977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kWord32Or: 898e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return VisitBinop(this, node, kArmOrr, kArmOrr, cont); 8997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kWord32Xor: 900e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return VisitWordCompare(this, node, kArmTeq, cont, true); 9015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case IrOpcode::kWord32Sar: 9025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org return VisitShift(this, node, TryMatchASR, cont); 9035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case IrOpcode::kWord32Shl: 9045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org return VisitShift(this, node, TryMatchLSL, cont); 9055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case IrOpcode::kWord32Shr: 9065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org return VisitShift(this, node, TryMatchLSR, cont); 9075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case IrOpcode::kWord32Ror: 9085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org return VisitShift(this, node, TryMatchROR, cont); 9097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org default: 9107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 9117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 9127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 9147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode opcode = 9157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R); 9167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (cont->IsBranch()) { 9177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(opcode, NULL, g.UseRegister(node), g.UseRegister(node), 9187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.Label(cont->true_block()), 9197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.Label(cont->false_block()))->MarkAsControl(); 9207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 9217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(opcode, g.DefineAsRegister(cont->result()), g.UseRegister(node), 9227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.UseRegister(node)); 9237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 9247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 9257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Compare(Node* node, 9287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FlagsContinuation* cont) { 929e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org VisitWordCompare(this, node, kArmCmp, cont, false); 9307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 9317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Compare(Node* node, 9347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FlagsContinuation* cont) { 9357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArmOperandGenerator g(this); 9367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Float64BinopMatcher m(node); 9377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (cont->IsBranch()) { 938fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Emit(cont->Encode(kArmVcmpF64), NULL, g.UseRegister(m.left().node()), 939fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseRegister(m.right().node()), g.Label(cont->true_block()), 9407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org g.Label(cont->false_block()))->MarkAsControl(); 9417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 942e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cont->IsSet()); 9437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), 944fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org g.UseRegister(m.left().node()), g.UseRegister(m.right().node())); 9457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 9467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 9477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace compiler 9497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace internal 9507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace v8 951