assembler_thumb2_test.cc revision 611d3395e9efc0ab8dbfa4a197fa022fbd8c7204
11a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain/* 21a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * Copyright (C) 2014 The Android Open Source Project 31a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * 41a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * Licensed under the Apache License, Version 2.0 (the "License"); 51a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * you may not use this file except in compliance with the License. 61a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * You may obtain a copy of the License at 71a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * 81a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * http://www.apache.org/licenses/LICENSE-2.0 91a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * 101a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * Unless required by applicable law or agreed to in writing, software 111a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * distributed under the License is distributed on an "AS IS" BASIS, 121a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * See the License for the specific language governing permissions and 141a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain * limitations under the License. 151a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain */ 161a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 171a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain#include "assembler_thumb2.h" 181a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 191a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain#include "base/stl_util.h" 201a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain#include "utils/assembler_test.h" 211a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 221a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillainnamespace art { 231a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 241a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillainclass AssemblerThumb2Test : public AssemblerTest<arm::Thumb2Assembler, 25851df20225593b10e698a760ac3cd5243620700bAndreas Gampe arm::Register, arm::SRegister, 26851df20225593b10e698a760ac3cd5243620700bAndreas Gampe uint32_t> { 271a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain protected: 281a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain std::string GetArchitectureString() OVERRIDE { 291a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain return "arm"; 301a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain } 311a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 321a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain std::string GetAssemblerParameters() OVERRIDE { 33513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe return " -march=armv7-a -mcpu=cortex-a15 -mfpu=neon -mthumb"; 34513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe } 35513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe 36513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe const char* GetAssemblyHeader() OVERRIDE { 37513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe return kThumb2AssemblyHeader; 381a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain } 391a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 401a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain std::string GetDisassembleParameters() OVERRIDE { 41513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe return " -D -bbinary -marm --disassembler-options=force-thumb --no-show-raw-insn"; 421a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain } 431a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 441a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain void SetUpHelpers() OVERRIDE { 451a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain if (registers_.size() == 0) { 461a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain registers_.insert(end(registers_), 471a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain { // NOLINT(whitespace/braces) 481a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R0), 491a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R1), 501a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R2), 511a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R3), 521a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R4), 531a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R5), 541a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R6), 551a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R7), 561a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R8), 571a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R9), 581a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R10), 591a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R11), 601a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R12), 611a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R13), 621a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R14), 631a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain new arm::Register(arm::R15) 641a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain }); 651a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain } 661a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain } 671a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 681a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain void TearDown() OVERRIDE { 691a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain AssemblerTest::TearDown(); 701a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain STLDeleteElements(®isters_); 711a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain } 721a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 731a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain std::vector<arm::Register*> GetRegisters() OVERRIDE { 741a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain return registers_; 751a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain } 761a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 771a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain uint32_t CreateImmediate(int64_t imm_value) OVERRIDE { 781a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain return imm_value; 791a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain } 801a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 81cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string RepeatInsn(size_t count, const std::string& insn) { 82cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string result; 83cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (; count != 0u; --count) { 84cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko result += insn; 85cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 86cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko return result; 87cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 88cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 891a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain private: 901a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain std::vector<arm::Register*> registers_; 91513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe 92513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe static constexpr const char* kThumb2AssemblyHeader = ".syntax unified\n.thumb\n"; 931a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain}; 941a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 951a28fc43ea7daa624ada9af40e30de64d4e946a8Roland LevillainTEST_F(AssemblerThumb2Test, Toolchain) { 961a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain EXPECT_TRUE(CheckTools()); 971a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain} 981a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 99c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu#define __ GetAssembler()-> 1001a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 1011a28fc43ea7daa624ada9af40e30de64d4e946a8Roland LevillainTEST_F(AssemblerThumb2Test, Sbfx) { 102c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 0, 1); 103c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 0, 8); 104c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 0, 16); 105c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 0, 32); 1061a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 107c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 8, 1); 108c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 8, 8); 109c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 8, 16); 110c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 8, 24); 1111a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 112c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 16, 1); 113c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 16, 8); 114c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 16, 16); 1151a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 116c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sbfx(arm::R0, arm::R1, 31, 1); 1171a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 1181a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain const char* expected = 1191a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #0, #1\n" 1201a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #0, #8\n" 1211a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #0, #16\n" 1221a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #0, #32\n" 1231a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 1241a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #8, #1\n" 1251a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #8, #8\n" 1261a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #8, #16\n" 1271a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #8, #24\n" 1281a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 1291a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #16, #1\n" 1301a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #16, #8\n" 1311a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #16, #16\n" 1321a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 1331a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain "sbfx r0, r1, #31, #1\n"; 1341a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain DriverStr(expected, "sbfx"); 1351a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain} 1361a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain 137981e45424f52735b1c61ae0eac7e299ed313f8dbRoland LevillainTEST_F(AssemblerThumb2Test, Ubfx) { 138c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 0, 1); 139c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 0, 8); 140c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 0, 16); 141c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 0, 32); 142981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain 143c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 8, 1); 144c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 8, 8); 145c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 8, 16); 146c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 8, 24); 147981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain 148c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 16, 1); 149c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 16, 8); 150c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 16, 16); 151981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain 152c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ubfx(arm::R0, arm::R1, 31, 1); 153981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain 154981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain const char* expected = 155981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #0, #1\n" 156981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #0, #8\n" 157981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #0, #16\n" 158981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #0, #32\n" 159981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain 160981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #8, #1\n" 161981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #8, #8\n" 162981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #8, #16\n" 163981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #8, #24\n" 164981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain 165981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #16, #1\n" 166981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #16, #8\n" 167981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #16, #16\n" 168981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain 169981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain "ubfx r0, r1, #31, #1\n"; 170981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain DriverStr(expected, "ubfx"); 171981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain} 172981e45424f52735b1c61ae0eac7e299ed313f8dbRoland Levillain 173ddb7df25af45d7cd19ed1138e537973735cc78a5Calin JuravleTEST_F(AssemblerThumb2Test, Vmstat) { 174c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ vmstat(); 175ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle 176ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle const char* expected = "vmrs APSR_nzcv, FPSCR\n"; 177ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle 178ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle DriverStr(expected, "vmrs"); 179ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle} 180ddb7df25af45d7cd19ed1138e537973735cc78a5Calin Juravle 18152c489645b6e9ae33623f1ec24143cde5444906eCalin JuravleTEST_F(AssemblerThumb2Test, ldrexd) { 182c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ldrexd(arm::R0, arm::R1, arm::R0); 183c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ldrexd(arm::R0, arm::R1, arm::R1); 184c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ldrexd(arm::R0, arm::R1, arm::R2); 185c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ldrexd(arm::R5, arm::R3, arm::R7); 18652c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle 18752c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle const char* expected = 18852c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle "ldrexd r0, r1, [r0]\n" 18952c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle "ldrexd r0, r1, [r1]\n" 19052c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle "ldrexd r0, r1, [r2]\n" 19152c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle "ldrexd r5, r3, [r7]\n"; 19252c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle DriverStr(expected, "ldrexd"); 19352c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle} 19452c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle 19552c489645b6e9ae33623f1ec24143cde5444906eCalin JuravleTEST_F(AssemblerThumb2Test, strexd) { 196c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ strexd(arm::R9, arm::R0, arm::R1, arm::R0); 197c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ strexd(arm::R9, arm::R0, arm::R1, arm::R1); 198c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ strexd(arm::R9, arm::R0, arm::R1, arm::R2); 199c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ strexd(arm::R9, arm::R5, arm::R3, arm::R7); 20052c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle 20152c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle const char* expected = 20252c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle "strexd r9, r0, r1, [r0]\n" 20352c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle "strexd r9, r0, r1, [r1]\n" 20452c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle "strexd r9, r0, r1, [r2]\n" 20552c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle "strexd r9, r5, r3, [r7]\n"; 20652c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle DriverStr(expected, "strexd"); 20752c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle} 20852c489645b6e9ae33623f1ec24143cde5444906eCalin Juravle 2092bcf9bf784a0021630d8fe63d7230d46d6891780Andreas GampeTEST_F(AssemblerThumb2Test, LdrdStrd) { 210c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ldrd(arm::R0, arm::Address(arm::R2, 8)); 211c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ ldrd(arm::R0, arm::Address(arm::R12)); 212c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ strd(arm::R0, arm::Address(arm::R2, 8)); 2132bcf9bf784a0021630d8fe63d7230d46d6891780Andreas Gampe 2142bcf9bf784a0021630d8fe63d7230d46d6891780Andreas Gampe const char* expected = 2152bcf9bf784a0021630d8fe63d7230d46d6891780Andreas Gampe "ldrd r0, r1, [r2, #8]\n" 2162bcf9bf784a0021630d8fe63d7230d46d6891780Andreas Gampe "ldrd r0, r1, [r12]\n" 2172bcf9bf784a0021630d8fe63d7230d46d6891780Andreas Gampe "strd r0, r1, [r2, #8]\n"; 2182bcf9bf784a0021630d8fe63d7230d46d6891780Andreas Gampe DriverStr(expected, "ldrdstrd"); 2192bcf9bf784a0021630d8fe63d7230d46d6891780Andreas Gampe} 2202bcf9bf784a0021630d8fe63d7230d46d6891780Andreas Gampe 221513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas GampeTEST_F(AssemblerThumb2Test, eor) { 222513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe __ eor(arm::R1, arm::R1, arm::ShifterOperand(arm::R0)); 223513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe __ eor(arm::R1, arm::R0, arm::ShifterOperand(arm::R1)); 224513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe __ eor(arm::R1, arm::R8, arm::ShifterOperand(arm::R0)); 225513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe __ eor(arm::R8, arm::R1, arm::ShifterOperand(arm::R0)); 226513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe __ eor(arm::R1, arm::R0, arm::ShifterOperand(arm::R8)); 227513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe 228513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe const char* expected = 229513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe "eors r1, r0\n" 230513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe "eor r1, r0, r1\n" 231513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe "eor r1, r8, r0\n" 232513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe "eor r8, r1, r0\n" 233513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe "eor r1, r0, r8\n"; 234513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe DriverStr(expected, "abs"); 235513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe} 236513ea0c203a86e9d81a8630b56cb62704e126cc2Andreas Gampe 237dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" SanchezTEST_F(AssemblerThumb2Test, sub) { 238dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez __ subs(arm::R1, arm::R0, arm::ShifterOperand(42)); 239dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez __ sub(arm::R1, arm::R0, arm::ShifterOperand(42)); 240c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ subs(arm::R1, arm::R0, arm::ShifterOperand(arm::R2, arm::ASR, 31)); 241c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ sub(arm::R1, arm::R0, arm::ShifterOperand(arm::R2, arm::ASR, 31)); 242dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez 243dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez const char* expected = 244dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez "subs r1, r0, #42\n" 245c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu "subw r1, r0, #42\n" 246c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu "subs r1, r0, r2, asr #31\n" 247c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu "sub r1, r0, r2, asr #31\n"; 248dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez DriverStr(expected, "sub"); 249dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez} 250dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez 251dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" SanchezTEST_F(AssemblerThumb2Test, add) { 252dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez __ adds(arm::R1, arm::R0, arm::ShifterOperand(42)); 253dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez __ add(arm::R1, arm::R0, arm::ShifterOperand(42)); 254c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ adds(arm::R1, arm::R0, arm::ShifterOperand(arm::R2, arm::ASR, 31)); 255c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ add(arm::R1, arm::R0, arm::ShifterOperand(arm::R2, arm::ASR, 31)); 256dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez 257dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez const char* expected = 258dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez "adds r1, r0, #42\n" 259c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu "addw r1, r0, #42\n" 260c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu "adds r1, r0, r2, asr #31\n" 261c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu "add r1, r0, r2, asr #31\n"; 262dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez DriverStr(expected, "add"); 263dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez} 264dc62c48937a6476ed9c0d739f6b3b5c26f758371Guillaume "Vermeille" Sanchez 265c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng XuTEST_F(AssemblerThumb2Test, umull) { 266c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ umull(arm::R0, arm::R1, arm::R2, arm::R3); 267c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu 268c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu const char* expected = 269c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu "umull r0, r1, r2, r3\n"; 270c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu DriverStr(expected, "umull"); 271c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu} 272c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu 273c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng XuTEST_F(AssemblerThumb2Test, smull) { 274c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu __ smull(arm::R0, arm::R1, arm::R2, arm::R3); 275c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu 276c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu const char* expected = 277c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu "smull r0, r1, r2, r3\n"; 278c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu DriverStr(expected, "smull"); 279c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu} 280c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu 281c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland LevillainTEST_F(AssemblerThumb2Test, StoreWordToThumbOffset) { 282c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain arm::StoreOperandType type = arm::kStoreWord; 283c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain int32_t offset = 4092; 284c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain ASSERT_TRUE(arm::Address::CanHoldStoreOffsetThumb(type, offset)); 285c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain 286c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain __ StoreToOffset(type, arm::R0, arm::SP, offset); 287c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain __ StoreToOffset(type, arm::IP, arm::SP, offset); 288c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain __ StoreToOffset(type, arm::IP, arm::R5, offset); 289c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain 290c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain const char* expected = 291c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "str r0, [sp, #4092]\n" 292c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "str ip, [sp, #4092]\n" 293c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "str ip, [r5, #4092]\n"; 294c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain DriverStr(expected, "StoreWordToThumbOffset"); 295c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain} 296c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain 297c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland LevillainTEST_F(AssemblerThumb2Test, StoreWordToNonThumbOffset) { 298c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain arm::StoreOperandType type = arm::kStoreWord; 299c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain int32_t offset = 4096; 300c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain ASSERT_FALSE(arm::Address::CanHoldStoreOffsetThumb(type, offset)); 301c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain 302c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain __ StoreToOffset(type, arm::R0, arm::SP, offset); 303c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain __ StoreToOffset(type, arm::IP, arm::SP, offset); 304c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain __ StoreToOffset(type, arm::IP, arm::R5, offset); 305c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain 306c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain const char* expected = 307c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "mov ip, #4096\n" // LoadImmediate(ip, 4096) 308c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "add ip, ip, sp\n" 309c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "str r0, [ip, #0]\n" 310c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain 311c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "str r5, [sp, #-4]!\n" // Push(r5) 312c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "movw r5, #4100\n" // LoadImmediate(r5, 4096 + kRegisterSize) 313c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "add r5, r5, sp\n" 314c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "str ip, [r5, #0]\n" 315c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "ldr r5, [sp], #4\n" // Pop(r5) 316c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain 317c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "str r6, [sp, #-4]!\n" // Push(r6) 318c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "mov r6, #4096\n" // LoadImmediate(r6, 4096) 319c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "add r6, r6, r5\n" 320c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "str ip, [r6, #0]\n" 321c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain "ldr r6, [sp], #4\n"; // Pop(r6) 322c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain DriverStr(expected, "StoreWordToNonThumbOffset"); 323c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain} 324c5a5ac641eb4b32fa6737c390813ce78c66a12d3Roland Levillain 3254af147eb3296a26eea566f53a7f687194638d46bRoland LevillainTEST_F(AssemblerThumb2Test, StoreWordPairToThumbOffset) { 3264af147eb3296a26eea566f53a7f687194638d46bRoland Levillain arm::StoreOperandType type = arm::kStoreWordPair; 3274af147eb3296a26eea566f53a7f687194638d46bRoland Levillain int32_t offset = 1020; 3284af147eb3296a26eea566f53a7f687194638d46bRoland Levillain ASSERT_TRUE(arm::Address::CanHoldStoreOffsetThumb(type, offset)); 3294af147eb3296a26eea566f53a7f687194638d46bRoland Levillain 3304af147eb3296a26eea566f53a7f687194638d46bRoland Levillain __ StoreToOffset(type, arm::R0, arm::SP, offset); 3314af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // We cannot use IP (i.e. R12) as first source register, as it would 3324af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // force us to use SP (i.e. R13) as second source register, which 3334af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // would have an "unpredictable" effect according to the ARMv7 3344af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // specification (the T1 encoding describes the result as 3354af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // UNPREDICTABLE when of the source registers is R13). 3364af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // 3374af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // So we use (R11, IP) (e.g. (R11, R12)) as source registers in the 3384af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // following instructions. 3394af147eb3296a26eea566f53a7f687194638d46bRoland Levillain __ StoreToOffset(type, arm::R11, arm::SP, offset); 3404af147eb3296a26eea566f53a7f687194638d46bRoland Levillain __ StoreToOffset(type, arm::R11, arm::R5, offset); 3414af147eb3296a26eea566f53a7f687194638d46bRoland Levillain 3424af147eb3296a26eea566f53a7f687194638d46bRoland Levillain const char* expected = 3434af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "strd r0, r1, [sp, #1020]\n" 3444af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "strd r11, ip, [sp, #1020]\n" 3454af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "strd r11, ip, [r5, #1020]\n"; 3464af147eb3296a26eea566f53a7f687194638d46bRoland Levillain DriverStr(expected, "StoreWordPairToThumbOffset"); 3474af147eb3296a26eea566f53a7f687194638d46bRoland Levillain} 3484af147eb3296a26eea566f53a7f687194638d46bRoland Levillain 3494af147eb3296a26eea566f53a7f687194638d46bRoland LevillainTEST_F(AssemblerThumb2Test, StoreWordPairToNonThumbOffset) { 3504af147eb3296a26eea566f53a7f687194638d46bRoland Levillain arm::StoreOperandType type = arm::kStoreWordPair; 3514af147eb3296a26eea566f53a7f687194638d46bRoland Levillain int32_t offset = 1024; 3524af147eb3296a26eea566f53a7f687194638d46bRoland Levillain ASSERT_FALSE(arm::Address::CanHoldStoreOffsetThumb(type, offset)); 3534af147eb3296a26eea566f53a7f687194638d46bRoland Levillain 3544af147eb3296a26eea566f53a7f687194638d46bRoland Levillain __ StoreToOffset(type, arm::R0, arm::SP, offset); 3554af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // Same comment as in AssemblerThumb2Test.StoreWordPairToThumbOffset 3564af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // regarding the use of (R11, IP) (e.g. (R11, R12)) as source 3574af147eb3296a26eea566f53a7f687194638d46bRoland Levillain // registers in the following instructions. 3584af147eb3296a26eea566f53a7f687194638d46bRoland Levillain __ StoreToOffset(type, arm::R11, arm::SP, offset); 3594af147eb3296a26eea566f53a7f687194638d46bRoland Levillain __ StoreToOffset(type, arm::R11, arm::R5, offset); 3604af147eb3296a26eea566f53a7f687194638d46bRoland Levillain 3614af147eb3296a26eea566f53a7f687194638d46bRoland Levillain const char* expected = 3624af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "mov ip, #1024\n" // LoadImmediate(ip, 1024) 3634af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "add ip, ip, sp\n" 3644af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "strd r0, r1, [ip, #0]\n" 3654af147eb3296a26eea566f53a7f687194638d46bRoland Levillain 3664af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "str r5, [sp, #-4]!\n" // Push(r5) 3674af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "movw r5, #1028\n" // LoadImmediate(r5, 1024 + kRegisterSize) 3684af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "add r5, r5, sp\n" 3694af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "strd r11, ip, [r5, #0]\n" 3704af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "ldr r5, [sp], #4\n" // Pop(r5) 3714af147eb3296a26eea566f53a7f687194638d46bRoland Levillain 3724af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "str r6, [sp, #-4]!\n" // Push(r6) 3734af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "mov r6, #1024\n" // LoadImmediate(r6, 1024) 3744af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "add r6, r6, r5\n" 3754af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "strd r11, ip, [r6, #0]\n" 3764af147eb3296a26eea566f53a7f687194638d46bRoland Levillain "ldr r6, [sp], #4\n"; // Pop(r6) 3774af147eb3296a26eea566f53a7f687194638d46bRoland Levillain DriverStr(expected, "StoreWordPairToNonThumbOffset"); 3784af147eb3296a26eea566f53a7f687194638d46bRoland Levillain} 3794af147eb3296a26eea566f53a7f687194638d46bRoland Levillain 380cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, TwoCbzMaxOffset) { 381cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label0, label1, label2; 382cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label1); 383cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count1 = 63; 384cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count1; ++i) { 385cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 386cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 387cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label0); 388cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label2); 389cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label1); 390cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count2 = 64; 391cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count2; ++i) { 392cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 393cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 394cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label2); 395cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 396cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 397cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cbz r0, 1f\n" + // cbz r0, label1 398cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count1, "ldr r0, [r0]\n") + 399cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "0:\n" 400cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cbz r0, 2f\n" // cbz r0, label2 401cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" + 402cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count2, "ldr r0, [r0]\n") + 403cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n"; 404cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "TwoCbzMaxOffset"); 405cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 406cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label0.Position()) + 0u, 407cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label0.Position())); 408cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label1.Position()) + 0u, 409cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label1.Position())); 410cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label2.Position()) + 0u, 411cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label2.Position())); 412cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 413cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 414cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, TwoCbzBeyondMaxOffset) { 415cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label0, label1, label2; 416cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label1); 417cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count1 = 63; 418cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count1; ++i) { 419cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 420cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 421cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label0); 422cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label2); 423cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label1); 424cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count2 = 65; 425cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count2; ++i) { 426cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 427cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 428cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label2); 429cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 430cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 431cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cmp r0, #0\n" // cbz r0, label1 432cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "beq.n 1f\n" + 433cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count1, "ldr r0, [r0]\n") + 434cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "0:\n" 435cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cmp r0, #0\n" // cbz r0, label2 436cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "beq.n 2f\n" 437cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" + 438cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count2, "ldr r0, [r0]\n") + 439cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n"; 440cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "TwoCbzBeyondMaxOffset"); 441cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 442cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label0.Position()) + 2u, 443cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label0.Position())); 444cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label1.Position()) + 4u, 445cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label1.Position())); 446cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label2.Position()) + 4u, 447cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label2.Position())); 448cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 449cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 450cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, TwoCbzSecondAtMaxB16Offset) { 451cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label0, label1, label2; 452cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label1); 453cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count1 = 62; 454cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count1; ++i) { 455cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 456cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 457cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label0); 458cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label2); 459cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label1); 460cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count2 = 128; 461cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count2; ++i) { 462cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 463cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 464cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label2); 465cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 466cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 467cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cbz r0, 1f\n" + // cbz r0, label1 468cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count1, "ldr r0, [r0]\n") + 469cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "0:\n" 470cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cmp r0, #0\n" // cbz r0, label2 471cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "beq.n 2f\n" 472cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" + 473cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count2, "ldr r0, [r0]\n") + 474cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n"; 475cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "TwoCbzSecondAtMaxB16Offset"); 476cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 477cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label0.Position()) + 0u, 478cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label0.Position())); 479cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label1.Position()) + 2u, 480cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label1.Position())); 481cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label2.Position()) + 2u, 482cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label2.Position())); 483cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 484cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 485cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, TwoCbzSecondBeyondMaxB16Offset) { 486cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label0, label1, label2; 487cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label1); 488cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count1 = 62; 489cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count1; ++i) { 490cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 491cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 492cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label0); 493cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label2); 494cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label1); 495cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count2 = 129; 496cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count2; ++i) { 497cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 498cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 499cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label2); 500cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 501cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 502cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cmp r0, #0\n" // cbz r0, label1 503cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "beq.n 1f\n" + 504cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count1, "ldr r0, [r0]\n") + 505cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "0:\n" 506cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cmp r0, #0\n" // cbz r0, label2 507cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "beq.w 2f\n" 508cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" + 509cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count2, "ldr r0, [r0]\n") + 510cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n"; 511cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "TwoCbzSecondBeyondMaxB16Offset"); 512cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 513cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label0.Position()) + 2u, 514cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label0.Position())); 515cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label1.Position()) + 6u, 516cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label1.Position())); 517cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label2.Position()) + 6u, 518cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label2.Position())); 519cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 520cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 521cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, TwoCbzFirstAtMaxB16Offset) { 522cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label0, label1, label2; 523cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label1); 524cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count1 = 127; 525cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count1; ++i) { 526cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 527cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 528cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label0); 529cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label2); 530cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label1); 531cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count2 = 64; 532cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count2; ++i) { 533cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 534cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 535cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label2); 536cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 537cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 538cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cmp r0, #0\n" // cbz r0, label1 539cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "beq.n 1f\n" + 540cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count1, "ldr r0, [r0]\n") + 541cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "0:\n" 542cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cbz r0, 2f\n" // cbz r0, label2 543cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" + 544cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count2, "ldr r0, [r0]\n") + 545cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n"; 546cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "TwoCbzFirstAtMaxB16Offset"); 547cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 548cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label0.Position()) + 2u, 549cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label0.Position())); 550cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label1.Position()) + 2u, 551cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label1.Position())); 552cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label2.Position()) + 2u, 553cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label2.Position())); 554cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 555cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 556cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, TwoCbzFirstBeyondMaxB16Offset) { 557cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label0, label1, label2; 558cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label1); 559cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count1 = 127; 560cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count1; ++i) { 561cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 562cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 563cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label0); 564cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ cbz(arm::R0, &label2); 565cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label1); 566cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count2 = 65; 567cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count2; ++i) { 568cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 569cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 570cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label2); 571cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 572cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 573cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cmp r0, #0\n" // cbz r0, label1 574cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "beq.w 1f\n" + 575cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count1, "ldr r0, [r0]\n") + 576cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "0:\n" 577cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "cmp r0, #0\n" // cbz r0, label2 578cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "beq.n 2f\n" 579cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" + 580cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count2, "ldr r0, [r0]\n") + 581cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n"; 582cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "TwoCbzFirstBeyondMaxB16Offset"); 583cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 584cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label0.Position()) + 4u, 585cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label0.Position())); 586cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label1.Position()) + 6u, 587cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label1.Position())); 588cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label2.Position()) + 6u, 589cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label2.Position())); 590cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 591cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 592cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralMax1KiB) { 593cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 594cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R0, literal); 595cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 596cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 597cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = 511; 598cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 599cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 600cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 601cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 602cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 603cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 604cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldr.n r0, [pc, #((2f - 1b - 2) & ~2)]\n" + 605cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 606cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 607cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 608cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 609cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralMax1KiB"); 610cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 611cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 0u, 612cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 613cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 614cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 615cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralBeyondMax1KiB) { 616cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 617cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R0, literal); 618cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 619cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 620cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = 512; 621cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 622cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 623cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 624cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 625cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 626cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 627cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldr.w r0, [pc, #((2f - 1b - 2) & ~2)]\n" + 628cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 629cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 630cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 631cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 632cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralBeyondMax1KiB"); 633cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 634cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 2u, 635cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 636cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 637cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 638cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralMax4KiB) { 639cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 640cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R1, literal); 641cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 642cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 643cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = 2046; 644cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 645cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 646cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 647cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 648cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 649cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 650cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldr.w r1, [pc, #((2f - 1b - 2) & ~2)]\n" + 651cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 652cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 653cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 654cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 655cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralMax4KiB"); 656cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 657cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 2u, 658cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 659cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 660cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 661cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralBeyondMax4KiB) { 662cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 663cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R1, literal); 664cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 665cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 666cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = 2047; 667cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 668cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 669cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 670cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 671cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 672cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movw r1, #4096\n" // "as" does not consider (2f - 1f - 4) a constant expression for movw. 673cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 674cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add r1, pc\n" 675cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldr r1, [r1, #0]\n" + 676cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 677cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 678cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 679cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 680cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralBeyondMax4KiB"); 681cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 682cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 6u, 683cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 684cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 685cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 686cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralMax64KiB) { 687cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 688cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R1, literal); 689cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 690cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 691cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = (1u << 15) - 2u; 692cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 693cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 694cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 695cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 696cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 697cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movw r1, #0xfffc\n" // "as" does not consider (2f - 1f - 4) a constant expression for movw. 698cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 699cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add r1, pc\n" 700cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldr r1, [r1, #0]\n" + 701cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 702cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 703cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 704cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 705cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralMax64KiB"); 706cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 707cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 6u, 708cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 709cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 710cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 711cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralBeyondMax64KiB) { 712cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 713cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R1, literal); 714cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 715cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 716cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = (1u << 15) - 1u; 717cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 718cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 719cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 720cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 721cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 722cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "mov.w r1, #((2f - 1f - 4) & ~0xfff)\n" 723cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 724cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add r1, pc\n" 725cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldr r1, [r1, #((2f - 1b - 4) & 0xfff)]\n" + 726cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 727cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 728cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 729cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 730cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralBeyondMax64KiB"); 731cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 732cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 8u, 733cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 734cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 735cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 736cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralMax1MiB) { 737cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 738cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R1, literal); 739cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 740cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 741cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = (1u << 19) - 3u; 742cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 743cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 744cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 745cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 746cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 747cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "mov.w r1, #((2f - 1f - 4) & ~0xfff)\n" 748cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 749cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add r1, pc\n" 750cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldr r1, [r1, #((2f - 1b - 4) & 0xfff)]\n" + 751cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 752cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 753cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 754cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 755cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralMax1MiB"); 756cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 757cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 8u, 758cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 759cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 760cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 761cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralBeyondMax1MiB) { 762cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 763cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R1, literal); 764cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 765cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 766cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = (1u << 19) - 2u; 767cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 768cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 769cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 770cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 771cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 772cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // "as" does not consider ((2f - 1f - 4) & 0xffff) a constant expression for movw. 773cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movw r1, #(0x100000 & 0xffff)\n" 774cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // "as" does not consider ((2f - 1f - 4) >> 16) a constant expression for movt. 775cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movt r1, #(0x100000 >> 16)\n" 776cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 777cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add r1, pc\n" 778cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldr.w r1, [r1, #0]\n" + 779cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 780cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 781cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 782cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 783cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralBeyondMax1MiB"); 784cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 785cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 12u, 786cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 787cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 788cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 789cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralFar) { 790cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 791cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R1, literal); 792cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 793cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 794cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = (1u << 19) - 2u + 0x1234; 795cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 796cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 797cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 798cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 799cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 800cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // "as" does not consider ((2f - 1f - 4) & 0xffff) a constant expression for movw. 801cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movw r1, #((0x100000 + 2 * 0x1234) & 0xffff)\n" 802cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // "as" does not consider ((2f - 1f - 4) >> 16) a constant expression for movt. 803cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movt r1, #((0x100000 + 2 * 0x1234) >> 16)\n" 804cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 805cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add r1, pc\n" 806cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldr.w r1, [r1, #0]\n" + 807cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 808cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 809cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 810cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 811cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralFar"); 812cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 813cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 12u, 814cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 815cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 816cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 817cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralWideMax1KiB) { 818cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int64_t>(INT64_C(0x1234567887654321)); 819cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R1, arm::R3, literal); 820cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 821cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 822cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = 510; 823cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 824cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 825cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 826cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 827cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 828cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 829cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldrd r1, r3, [pc, #((2f - 1b - 2) & ~2)]\n" + 830cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 831cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 832cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 833cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x87654321\n" 834cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 835cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralWideMax1KiB"); 836cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 837cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 0u, 838cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 839cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 840cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 841cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralWideBeyondMax1KiB) { 842cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int64_t>(INT64_C(0x1234567887654321)); 843cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::R1, arm::R3, literal); 844cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 845cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 846cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = 511; 847cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 848cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 849cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 850cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 851cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 852cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "mov.w ip, #((2f - 1f - 4) & ~0x3ff)\n" 853cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 854cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add ip, pc\n" 855cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "ldrd r1, r3, [ip, #((2f - 1b - 4) & 0x3ff)]\n" + 856cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 857cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 858cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 859cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x87654321\n" 860cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 861cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralWideBeyondMax1KiB"); 862cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 863cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 6u, 864cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 865cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 866cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 867cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralSingleMax256KiB) { 868cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // The literal size must match but the type doesn't, so use an int32_t rather than float. 869cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 870cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::S3, literal); 871cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 872cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 873cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = (1 << 17) - 3u; 874cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 875cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 876cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 877cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 878cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 879cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "mov.w ip, #((2f - 1f - 4) & ~0x3ff)\n" 880cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 881cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add ip, pc\n" 882cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "vldr s3, [ip, #((2f - 1b - 4) & 0x3ff)]\n" + 883cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 884cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 885cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 886cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 887cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralSingleMax256KiB"); 888cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 889cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 6u, 890cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 891cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 892cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 893cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralDoubleBeyondMax256KiB) { 894cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // The literal size must match but the type doesn't, so use an int64_t rather than double. 895cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int64_t>(INT64_C(0x1234567887654321)); 896cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::D3, literal); 897cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 898cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 899cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = (1 << 17) - 2u; 900cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 901cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 902cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 903cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 904cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 905cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // "as" does not consider ((2f - 1f - 4) & 0xffff) a constant expression for movw. 906cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movw ip, #(0x40000 & 0xffff)\n" 907cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // "as" does not consider ((2f - 1f - 4) >> 16) a constant expression for movt. 908cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movt ip, #(0x40000 >> 16)\n" 909cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 910cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add ip, pc\n" 911cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "vldr d3, [ip, #0]\n" + 912cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 913cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 914cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 915cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x87654321\n" 916cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 917cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralDoubleBeyondMax256KiB"); 918cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 919cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 10u, 920cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 921cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 922cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 923cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralDoubleFar) { 924cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // The literal size must match but the type doesn't, so use an int64_t rather than double. 925cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko arm::Literal* literal = __ NewLiteral<int64_t>(INT64_C(0x1234567887654321)); 926cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ LoadLiteral(arm::D3, literal); 927cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko Label label; 928cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ Bind(&label); 929cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko constexpr size_t kLdrR0R0Count = (1 << 17) - 2u + 0x1234; 930cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 931cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 932cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko } 933cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 934cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko std::string expected = 935cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // "as" does not consider ((2f - 1f - 4) & 0xffff) a constant expression for movw. 936cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movw ip, #((0x40000 + 2 * 0x1234) & 0xffff)\n" 937cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko // "as" does not consider ((2f - 1f - 4) >> 16) a constant expression for movt. 938cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "movt ip, #((0x40000 + 2 * 0x1234) >> 16)\n" 939cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "1:\n" 940cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "add ip, pc\n" 941cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "vldr d3, [ip, #0]\n" + 942cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 943cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".align 2, 0\n" 944cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko "2:\n" 945cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x87654321\n" 946cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko ".word 0x12345678\n"; 947cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko DriverStr(expected, "LoadLiteralDoubleFar"); 948cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 949cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 10u, 950cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko __ GetAdjustedPosition(label.Position())); 951cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko} 952cf93a5cd9c978f59113d42f9f642fab5e2cc8877Vladimir Marko 953663c93448e50599d411b2403585b90513dbf8e3aVladimir MarkoTEST_F(AssemblerThumb2Test, LoadLiteralBeyondMax1KiBDueToAlignmentOnSecondPass) { 954663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko // First part: as TwoCbzBeyondMaxOffset but add one 16-bit instruction to the end, 955663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko // so that the size is not Aligned<4>(.). On the first pass, the assembler resizes 956663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko // the second CBZ because it's out of range, then it will resize the first CBZ 957663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko // which has been pushed out of range. Thus, after the first pass, the code size 958663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko // will appear Aligned<4>(.) but the final size will not be. 959663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko Label label0, label1, label2; 960663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ cbz(arm::R0, &label1); 961663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko constexpr size_t kLdrR0R0Count1 = 63; 962663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko for (size_t i = 0; i != kLdrR0R0Count1; ++i) { 963663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 964663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko } 965663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ Bind(&label0); 966663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ cbz(arm::R0, &label2); 967663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ Bind(&label1); 968663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko constexpr size_t kLdrR0R0Count2 = 65; 969663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko for (size_t i = 0; i != kLdrR0R0Count2; ++i) { 970663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 971663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko } 972663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ Bind(&label2); 973663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 974663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko 975663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko std::string expected_part1 = 976663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "cmp r0, #0\n" // cbz r0, label1 977663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "beq.n 1f\n" + 978663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko RepeatInsn(kLdrR0R0Count1, "ldr r0, [r0]\n") + 979663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "0:\n" 980663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "cmp r0, #0\n" // cbz r0, label2 981663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "beq.n 2f\n" 982663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "1:\n" + 983663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko RepeatInsn(kLdrR0R0Count2, "ldr r0, [r0]\n") + 984663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "2:\n" // Here the offset is Aligned<4>(.). 985663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "ldr r0, [r0]\n"; // Make the first part 986663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko 987663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko // Second part: as LoadLiteralMax1KiB with the caveat that the offset of the load 988663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko // literal will not be Aligned<4>(.) but it will appear to be when we process the 989663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko // instruction during the first pass, so the literal will need a padding and it 990663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko // will push the literal out of range, so we shall end up with "ldr.w". 991663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko arm::Literal* literal = __ NewLiteral<int32_t>(0x12345678); 992663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ LoadLiteral(arm::R0, literal); 993663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko Label label; 994663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ Bind(&label); 995663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko constexpr size_t kLdrR0R0Count = 511; 996663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko for (size_t i = 0; i != kLdrR0R0Count; ++i) { 997663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ ldr(arm::R0, arm::Address(arm::R0)); 998663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko } 999663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko 1000663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko std::string expected = 1001663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko expected_part1 + 1002663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "1:\n" 1003663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "ldr.w r0, [pc, #((2f - 1b - 2) & ~2)]\n" + 1004663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko RepeatInsn(kLdrR0R0Count, "ldr r0, [r0]\n") + 1005663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko ".align 2, 0\n" 1006663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko "2:\n" 1007663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko ".word 0x12345678\n"; 1008663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko DriverStr(expected, "LoadLiteralMax1KiB"); 1009663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko 1010663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko EXPECT_EQ(static_cast<uint32_t>(label.Position()) + 6u, 1011663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko __ GetAdjustedPosition(label.Position())); 1012663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko} 1013663c93448e50599d411b2403585b90513dbf8e3aVladimir Marko 1014611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott WakelingTEST_F(AssemblerThumb2Test, Clz) { 1015611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling __ clz(arm::R0, arm::R1); 1016611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling 1017611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling const char* expected = "clz r0, r1\n"; 1018611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling 1019611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling DriverStr(expected, "clz"); 1020611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling} 1021611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling 10221a28fc43ea7daa624ada9af40e30de64d4e946a8Roland Levillain} // namespace art 1023