assembler_thumb2_test.cc revision 2bcf9bf784a0021630d8fe63d7230d46d6891780
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "assembler_thumb2.h" 18 19#include "base/stl_util.h" 20#include "utils/assembler_test.h" 21 22namespace art { 23 24class AssemblerThumb2Test : public AssemblerTest<arm::Thumb2Assembler, 25 arm::Register, arm::SRegister, 26 uint32_t> { 27 protected: 28 std::string GetArchitectureString() OVERRIDE { 29 return "arm"; 30 } 31 32 std::string GetAssemblerParameters() OVERRIDE { 33 return " -march=armv7-a -mcpu=cortex-a15 -mfpu=neon -mthumb"; 34 } 35 36 const char* GetAssemblyHeader() OVERRIDE { 37 return kThumb2AssemblyHeader; 38 } 39 40 std::string GetDisassembleParameters() OVERRIDE { 41 return " -D -bbinary -marm --disassembler-options=force-thumb --no-show-raw-insn"; 42 } 43 44 void SetUpHelpers() OVERRIDE { 45 if (registers_.size() == 0) { 46 registers_.insert(end(registers_), 47 { // NOLINT(whitespace/braces) 48 new arm::Register(arm::R0), 49 new arm::Register(arm::R1), 50 new arm::Register(arm::R2), 51 new arm::Register(arm::R3), 52 new arm::Register(arm::R4), 53 new arm::Register(arm::R5), 54 new arm::Register(arm::R6), 55 new arm::Register(arm::R7), 56 new arm::Register(arm::R8), 57 new arm::Register(arm::R9), 58 new arm::Register(arm::R10), 59 new arm::Register(arm::R11), 60 new arm::Register(arm::R12), 61 new arm::Register(arm::R13), 62 new arm::Register(arm::R14), 63 new arm::Register(arm::R15) 64 }); 65 } 66 } 67 68 void TearDown() OVERRIDE { 69 AssemblerTest::TearDown(); 70 STLDeleteElements(®isters_); 71 } 72 73 std::vector<arm::Register*> GetRegisters() OVERRIDE { 74 return registers_; 75 } 76 77 uint32_t CreateImmediate(int64_t imm_value) OVERRIDE { 78 return imm_value; 79 } 80 81 private: 82 std::vector<arm::Register*> registers_; 83 84 static constexpr const char* kThumb2AssemblyHeader = ".syntax unified\n.thumb\n"; 85}; 86 87 88TEST_F(AssemblerThumb2Test, Toolchain) { 89 EXPECT_TRUE(CheckTools()); 90} 91 92 93TEST_F(AssemblerThumb2Test, Sbfx) { 94 GetAssembler()->sbfx(arm::R0, arm::R1, 0, 1); 95 GetAssembler()->sbfx(arm::R0, arm::R1, 0, 8); 96 GetAssembler()->sbfx(arm::R0, arm::R1, 0, 16); 97 GetAssembler()->sbfx(arm::R0, arm::R1, 0, 32); 98 99 GetAssembler()->sbfx(arm::R0, arm::R1, 8, 1); 100 GetAssembler()->sbfx(arm::R0, arm::R1, 8, 8); 101 GetAssembler()->sbfx(arm::R0, arm::R1, 8, 16); 102 GetAssembler()->sbfx(arm::R0, arm::R1, 8, 24); 103 104 GetAssembler()->sbfx(arm::R0, arm::R1, 16, 1); 105 GetAssembler()->sbfx(arm::R0, arm::R1, 16, 8); 106 GetAssembler()->sbfx(arm::R0, arm::R1, 16, 16); 107 108 GetAssembler()->sbfx(arm::R0, arm::R1, 31, 1); 109 110 const char* expected = 111 "sbfx r0, r1, #0, #1\n" 112 "sbfx r0, r1, #0, #8\n" 113 "sbfx r0, r1, #0, #16\n" 114 "sbfx r0, r1, #0, #32\n" 115 116 "sbfx r0, r1, #8, #1\n" 117 "sbfx r0, r1, #8, #8\n" 118 "sbfx r0, r1, #8, #16\n" 119 "sbfx r0, r1, #8, #24\n" 120 121 "sbfx r0, r1, #16, #1\n" 122 "sbfx r0, r1, #16, #8\n" 123 "sbfx r0, r1, #16, #16\n" 124 125 "sbfx r0, r1, #31, #1\n"; 126 DriverStr(expected, "sbfx"); 127} 128 129TEST_F(AssemblerThumb2Test, Ubfx) { 130 GetAssembler()->ubfx(arm::R0, arm::R1, 0, 1); 131 GetAssembler()->ubfx(arm::R0, arm::R1, 0, 8); 132 GetAssembler()->ubfx(arm::R0, arm::R1, 0, 16); 133 GetAssembler()->ubfx(arm::R0, arm::R1, 0, 32); 134 135 GetAssembler()->ubfx(arm::R0, arm::R1, 8, 1); 136 GetAssembler()->ubfx(arm::R0, arm::R1, 8, 8); 137 GetAssembler()->ubfx(arm::R0, arm::R1, 8, 16); 138 GetAssembler()->ubfx(arm::R0, arm::R1, 8, 24); 139 140 GetAssembler()->ubfx(arm::R0, arm::R1, 16, 1); 141 GetAssembler()->ubfx(arm::R0, arm::R1, 16, 8); 142 GetAssembler()->ubfx(arm::R0, arm::R1, 16, 16); 143 144 GetAssembler()->ubfx(arm::R0, arm::R1, 31, 1); 145 146 const char* expected = 147 "ubfx r0, r1, #0, #1\n" 148 "ubfx r0, r1, #0, #8\n" 149 "ubfx r0, r1, #0, #16\n" 150 "ubfx r0, r1, #0, #32\n" 151 152 "ubfx r0, r1, #8, #1\n" 153 "ubfx r0, r1, #8, #8\n" 154 "ubfx r0, r1, #8, #16\n" 155 "ubfx r0, r1, #8, #24\n" 156 157 "ubfx r0, r1, #16, #1\n" 158 "ubfx r0, r1, #16, #8\n" 159 "ubfx r0, r1, #16, #16\n" 160 161 "ubfx r0, r1, #31, #1\n"; 162 DriverStr(expected, "ubfx"); 163} 164 165TEST_F(AssemblerThumb2Test, Vmstat) { 166 GetAssembler()->vmstat(); 167 168 const char* expected = "vmrs APSR_nzcv, FPSCR\n"; 169 170 DriverStr(expected, "vmrs"); 171} 172 173TEST_F(AssemblerThumb2Test, ldrexd) { 174 GetAssembler()->ldrexd(arm::R0, arm::R1, arm::R0); 175 GetAssembler()->ldrexd(arm::R0, arm::R1, arm::R1); 176 GetAssembler()->ldrexd(arm::R0, arm::R1, arm::R2); 177 GetAssembler()->ldrexd(arm::R5, arm::R3, arm::R7); 178 179 const char* expected = 180 "ldrexd r0, r1, [r0]\n" 181 "ldrexd r0, r1, [r1]\n" 182 "ldrexd r0, r1, [r2]\n" 183 "ldrexd r5, r3, [r7]\n"; 184 DriverStr(expected, "ldrexd"); 185} 186 187TEST_F(AssemblerThumb2Test, strexd) { 188 GetAssembler()->strexd(arm::R9, arm::R0, arm::R1, arm::R0); 189 GetAssembler()->strexd(arm::R9, arm::R0, arm::R1, arm::R1); 190 GetAssembler()->strexd(arm::R9, arm::R0, arm::R1, arm::R2); 191 GetAssembler()->strexd(arm::R9, arm::R5, arm::R3, arm::R7); 192 193 const char* expected = 194 "strexd r9, r0, r1, [r0]\n" 195 "strexd r9, r0, r1, [r1]\n" 196 "strexd r9, r0, r1, [r2]\n" 197 "strexd r9, r5, r3, [r7]\n"; 198 DriverStr(expected, "strexd"); 199} 200 201TEST_F(AssemblerThumb2Test, LdrdStrd) { 202 GetAssembler()->ldrd(arm::R0, arm::Address(arm::R2, 8)); 203 GetAssembler()->ldrd(arm::R0, arm::Address(arm::R12)); 204 GetAssembler()->strd(arm::R0, arm::Address(arm::R2, 8)); 205 206 const char* expected = 207 "ldrd r0, r1, [r2, #8]\n" 208 "ldrd r0, r1, [r12]\n" 209 "strd r0, r1, [r2, #8]\n"; 210 DriverStr(expected, "ldrdstrd"); 211} 212 213TEST_F(AssemblerThumb2Test, eor) { 214#define __ GetAssembler()-> 215 __ eor(arm::R1, arm::R1, arm::ShifterOperand(arm::R0)); 216 __ eor(arm::R1, arm::R0, arm::ShifterOperand(arm::R1)); 217 __ eor(arm::R1, arm::R8, arm::ShifterOperand(arm::R0)); 218 __ eor(arm::R8, arm::R1, arm::ShifterOperand(arm::R0)); 219 __ eor(arm::R1, arm::R0, arm::ShifterOperand(arm::R8)); 220 221 const char* expected = 222 "eors r1, r0\n" 223 "eor r1, r0, r1\n" 224 "eor r1, r8, r0\n" 225 "eor r8, r1, r0\n" 226 "eor r1, r0, r8\n"; 227 DriverStr(expected, "abs"); 228} 229 230} // namespace art 231